PageSourceSearch

https://justica.gov.pt/Resources/libraries/jQuery-UI/01_12_01/jquery-ui.js?cdv=3591

js justica.gov.pt collected 2026-10-01 09:06:55 UTC 539,419 bytes, 18,706 lines download raw bytes

vendor: 21,387 bytes, lines 1-729
1/*! jQuery UI - v1.12.1 - 2017-08-24
2* http://jqueryui.com
3* Includes: widget.js, position.js, data.js, disable-selection.js, focusable.js, form-reset-mixin.js, jquery-1-7.js, keycode.js, labels.js, scroll-parent.js, tabbable.js, unique-id.js, widgets/draggable.js, widgets/droppable.js, widgets/resizable.js, widgets/selectable.js, widgets/sortable.js, widgets/accordion.js, widgets/autocomplete.js, widgets/button.js, widgets/checkboxradio.js, widgets/controlgroup.js, widgets/datepicker.js, widgets/dialog.js, widgets/menu.js, widgets/mouse.js, widgets/progressbar.js, widgets/selectmenu.js, widgets/slider.js, widgets/spinner.js, widgets/tabs.js, widgets/tooltip.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
4* Copyright jQuery Foundation and other contributors; Licensed MIT */
5
6(function( factory ) {
7	if ( typeof define === "function" && define.amd ) {
8
9		// AMD. Register as an anonymous module.
10		define([ "jquery" ], factory );
11	} else {
12
13		// Browser globals
14		factory( jQuery );
15	}
16}(function( $ ) {
17
18$.ui = $.ui || {};
19
20var version = $.ui.version = "1.12.1";
21
22
23/*!
24 * jQuery UI Widget 1.12.1
25 * http://jqueryui.com
26 *
27 * Copyright jQuery Foundation and other contributors
28 * Released under the MIT license.
29 * http://jquery.org/license
30 */
31
32//>>label: Widget
33//>>group: Core
34//>>description: Provides a factory for creating stateful widgets with a common API.
35//>>docs: http://api.jqueryui.com/jQuery.widget/
36//>>demos: http://jqueryui.com/widget/
37
38
39
40var widgetUuid = 0;
41var widgetSlice = Array.prototype.slice;
42
43$.cleanData = ( function( orig ) {
44	return function( elems ) {
45		var events, elem, i;
46		for ( i = 0; ( elem = elems[ i ] ) != null; i++ ) {
47			try {
48
49				// Only trigger remove when necessary to save time
50				events = $._data( elem, "events" );
51				if ( events && events.remove ) {
52					$( elem ).triggerHandler( "remove" );
53				}
54
55			// Http://bugs.jquery.com/ticket/8235
56			} catch ( e ) {}
57		}
58		orig( elems );
59	};
60} )( $.cleanData );
61
62$.widget = function( name, base, prototype ) {
63	var existingConstructor, constructor, basePrototype;
64
65	// ProxiedPrototype allows the provided prototype to remain unmodified
66	// so that it can be used as a mixin for multiple widgets (#8876)
67	var proxiedPrototype = {};
68
69	var namespace = name.split( "." )[ 0 ];
70	name = name.split( "." )[ 1 ];
71	var fullName = namespace + "-" + name;
72
73	if ( !prototype ) {
74		prototype = base;
75		base = $.Widget;
76	}
77
78	if ( $.isArray( prototype ) ) {
79		prototype = $.extend.apply( null, [ {} ].concat( prototype ) );
80	}
81
82	// Create selector for plugin
83	$.expr[ ":" ][ fullName.toLowerCase() ] = function( elem ) {
84		return !!$.data( elem, fullName );
85	};
86
87	$[ namespace ] = $[ namespace ] || {};
88	existingConstructor = $[ namespace ][ name ];
89	constructor = $[ namespace ][ name ] = function( options, element ) {
90
91		// Allow instantiation without "new" keyword
92		if ( !this._createWidget ) {
93			return new constructor( options, element );
94		}
95
96		// Allow instantiation without initializing for simple inheritance
97		// must use "new" keyword (the code above always passes args)
98		if ( arguments.length ) {
99			this._createWidget( options, element );
100		}
101	};
102
103	// Extend with the existing constructor to carry over any static properties
104	$.extend( constructor, existingConstructor, {
105		version: prototype.version,
106
107		// Copy the object used to create the prototype in case we need to
108		// redefine the widget later
109		_proto: $.extend( {}, prototype ),
110
111		// Track widgets that inherit from this widget in case this widget is
112		// redefined after a widget inherits from it
113		_childConstructors: []
114	} );
115
116	basePrototype = new base();
117
118	// We need to make the options hash a property directly on the new instance
119	// otherwise we'll modify the options hash on the prototype that we're
120	// inheriting from
121	basePrototype.options = $.widget.extend( {}, basePrototype.options );
122	$.each( prototype, function( prop, value ) {
123		if ( !$.isFunction( value ) ) {
124			proxiedPrototype[ prop ] = value;
125			return;
126		}
127		proxiedPrototype[ prop ] = ( function() {
128			function _super() {
129				return base.prototype[ prop ].apply( this, arguments );
130			}
131
132			function _superApply( args ) {
133				return base.prototype[ prop ].apply( this, args );
134			}
135
136			return function() {
137				var __super = this._super;
138				var __superApply = this._superApply;
139				var returnValue;
140
141				this._super = _super;
142				this._superApply = _superApply;
143
144				returnValue = value.apply( this, arguments );
145
146				this._super = __super;
147				this._superApply = __superApply;
148
149				return returnValue;
150			};
151		} )();
152	} );
153	constructor.prototype = $.widget.extend( basePrototype, {
154
155		// TODO: remove support for widgetEventPrefix
156		// always use the name + a colon as the prefix, e.g., draggable:start
157		// don't prefix for widgets that aren't DOM-based
158		widgetEventPrefix: existingConstructor ? ( basePrototype.widgetEventPrefix || name ) : name
159	}, proxiedPrototype, {
160		constructor: constructor,
161		namespace: namespace,
162		widgetName: name,
163		widgetFullName: fullName
164	} );
165
166	// If this widget is being redefined then we need to find all widgets that
167	// are inheriting from it and redefine all of them so that they inherit from
168	// the new version of this widget. We're essentially trying to replace one
169	// level in the prototype chain.
170	if ( existingConstructor ) {
171		$.each( existingConstructor._childConstructors, function( i, child ) {
172			var childPrototype = child.prototype;
173
174			// Redefine the child widget using the same prototype that was
175			// originally used, but inherit from the new version of the base
176			$.widget( childPrototype.namespace + "." + childPrototype.widgetName, constructor,
177				child._proto );
178		} );
179
180		// Remove the list of existing child constructors from the old constructor
181		// so the old child constructors can be garbage collected
182		delete existingConstructor._childConstructors;
183	} else {
184		base._childConstructors.push( constructor );
185	}
186
187	$.widget.bridge( name, constructor );
188
189	return constructor;
190};
191
192$.widget.extend = function( target ) {
193	var input = widgetSlice.call( arguments, 1 );
194	var inputIndex = 0;
195	var inputLength = input.length;
196	var key;
197	var value;
198
199	for ( ; inputIndex < inputLength; inputIndex++ ) {
200		for ( key in input[ inputIndex ] ) {
201			value = input[ inputIndex ][ key ];
202			if ( input[ inputIndex ].hasOwnProperty( key ) && value !== undefined ) {
203
204				// Clone objects
205				if ( $.isPlainObject( value ) ) {
206					target[ key ] = $.isPlainObject( target[ key ] ) ?
207						$.widget.extend( {}, target[ key ], value ) :
208
209						// Don't extend strings, arrays, etc. with objects
210						$.widget.extend( {}, value );
211
212				// Copy everything else by reference
213				} else {
214					target[ key ] = value;
215				}
216			}
217		}
218	}
219	return target;
220};
221
222$.widget.bridge = function( name, object ) {
223	var fullName = object.prototype.widgetFullName || name;
224	$.fn[ name ] = function( options ) {
225		var isMethodCall = typeof options === "string";
226		var args = widgetSlice.call( arguments, 1 );
227		var returnValue = this;
228
229		if ( isMethodCall ) {
230
231			// If this is an empty collection, we need to have the instance method
232			// return undefined instead of the jQuery instance
233			if ( !this.length && options === "instance" ) {
234				returnValue = undefined;
235			} else {
236				this.each( function() {
237					var methodValue;
238					var instance = $.data( this, fullName );
239
240					if ( options === "instance" ) {
241						returnValue = instance;
242						return false;
243					}
244
245					if ( !instance ) {
246						return $.error( "cannot call methods on " + name +
247							" prior to initialization; " +
248							"attempted to call method '" + options + "'" );
249					}
250
251					if ( !$.isFunction( instance[ options ] ) || options.charAt( 0 ) === "_" ) {
252						return $.error( "no such method '" + options + "' for " + name +
253							" widget instance" );
254					}
255
256					methodValue = instance[ options ].apply( instance, args );
257
258					if ( methodValue !== instance && methodValue !== undefined ) {
259						returnValue = methodValue && methodValue.jquery ?
260							returnValue.pushStack( methodValue.get() ) :
261							methodValue;
262						return false;
263					}
264				} );
265			}
266		} else {
267
268			// Allow multiple hashes to be passed on init
269			if ( args.length ) {
270				options = $.widget.extend.apply( null, [ options ].concat( args ) );
271			}
272
273			this.each( function() {
274				var instance = $.data( this, fullName );
275				if ( instance ) {
276					instance.option( options || {} );
277					if ( instance._init ) {
278						instance._init();
279					}
280				} else {
281					$.data( this, fullName, new object( options, this ) );
282				}
283			} );
284		}
285
286		return returnValue;
287	};
288};
289
290$.Widget = function( /* options, element */ ) {};
291$.Widget._childConstructors = [];
292
293$.Widget.prototype = {
294	widgetName: "widget",
295	widgetEventPrefix: "",
296	defaultElement: "<div>",
297
298	options: {
299		classes: {},
300		disabled: false,
301
302		// Callbacks
303		create: null
304	},
305
306	_createWidget: function( options, element ) {
307		element = $( element || this.defaultElement || this )[ 0 ];
308		this.element = $( element );
309		this.uuid = widgetUuid++;
310		this.eventNamespace = "." + this.widgetName + this.uuid;
311
312		this.bindings = $();
313		this.hoverable = $();
314		this.focusable = $();
315		this.classesElementLookup = {};
316
317		if ( element !== this ) {
318			$.data( element, this.widgetFullName, this );
319			this._on( true, this.element, {
320				remove: function( event ) {
321					if ( event.target === element ) {
322						this.destroy();
323					}
324				}
325			} );
326			this.document = $( element.style ?
327
328				// Element within the document
329				element.ownerDocument :
330
331				// Element is window or document
332				element.document || element );
333			this.window = $( this.document[ 0 ].defaultView || this.document[ 0 ].parentWindow );
334		}
335
336		this.options = $.widget.extend( {},
337			this.options,
338			this._getCreateOptions(),
339			options );
340
341		this._create();
342
343		if ( this.options.disabled ) {
344			this._setOptionDisabled( this.options.disabled );
345		}
346
347		this._trigger( "create", null, this._getCreateEventData() );
348		this._init();
349	},
350
351	_getCreateOptions: function() {
352		return {};
353	},
354
355	_getCreateEventData: $.noop,
356
357	_create: $.noop,
358
359	_init: $.noop,
360
361	destroy: function() {
362		var that = this;
363
364		this._destroy();
365		$.each( this.classesElementLookup, function( key, value ) {
366			that._removeClass( value, key );
367		} );
368
369		// We can probably remove the unbind calls in 2.0
370		// all event bindings should go through this._on()
371		this.element
372			.off( this.eventNamespace )
373			.removeData( this.widgetFullName );
374		this.widget()
375			.off( this.eventNamespace )
376			.removeAttr( "aria-disabled" );
377
378		// Clean up events and states
379		this.bindings.off( this.eventNamespace );
380	},
381
382	_destroy: $.noop,
383
384	widget: function() {
385		return this.element;
386	},
387
388	option: function( key, value ) {
389		var options = key;
390		var parts;
391		var curOption;
392		var i;
393
394		if ( arguments.length === 0 ) {
395
396			// Don't return a reference to the internal hash
397			return $.widget.extend( {}, this.options );
398		}
399
400		if ( typeof key === "string" ) {
401
402			// Handle nested keys, e.g., "foo.bar" => { foo: { bar: ___ } }
403			options = {};
404			parts = key.split( "." );
405			key = parts.shift();
406			if ( parts.length ) {
407				curOption = options[ key ] = $.widget.extend( {}, this.options[ key ] );
408				for ( i = 0; i < parts.length - 1; i++ ) {
409					curOption[ parts[ i ] ] = curOption[ parts[ i ] ] || {};
410					curOption = curOption[ parts[ i ] ];
411				}
412				key = parts.pop();
413				if ( arguments.length === 1 ) {
414					return curOption[ key ] === undefined ? null : curOption[ key ];
415				}
416				curOption[ key ] = value;
417			} else {
418				if ( arguments.length === 1 ) {
419					return this.options[ key ] === undefined ? null : this.options[ key ];
420				}
421				options[ key ] = value;
422			}
423		}
424
425		this._setOptions( options );
426
427		return this;
428	},
429
430	_setOptions: function( options ) {
431		var key;
432
433		for ( key in options ) {
434			this._setOption( key, options[ key ] );
435		}
436
437		return this;
438	},
439
440	_setOption: function( key, value ) {
441		if ( key === "classes" ) {
442			this._setOptionClasses( value );
443		}
444
445		this.options[ key ] = value;
446
447		if ( key === "disabled" ) {
448			this._setOptionDisabled( value );
449		}
450
451		return this;
452	},
453
454	_setOptionClasses: function( value ) {
455		var classKey, elements, currentElements;
456
457		for ( classKey in value ) {
458			currentElements = this.classesElementLookup[ classKey ];
459			if ( value[ classKey ] === this.options.classes[ classKey ] ||
460					!currentElements ||
461					!currentElements.length ) {
462				continue;
463			}
464
465			// We are doing this to create a new jQuery object because the _removeClass() call
466			// on the next line is going to destroy the reference to the current elements being
467			// tracked. We need to save a copy of this collection so that we can add the new classes
468			// below.
469			elements = $( currentElements.get() );
470			this._removeClass( currentElements, classKey );
471
472			// We don't use _addClass() here, because that uses this.options.classes
473			// for generating the string of classes. We want to use the value passed in from
474			// _setOption(), this is the new value of the classes option which was passed to
475			// _setOption(). We pass this value directly to _classes().
476			elements.addClass( this._classes( {
477				element: elements,
478				keys: classKey,
479				classes: value,
480				add: true
481			} ) );
482		}
483	},
484
485	_setOptionDisabled: function( value ) {
486		this._toggleClass( this.widget(), this.widgetFullName + "-disabled", null, !!value );
487
488		// If the widget is becoming disabled, then nothing is interactive
489		if ( value ) {
490			this._removeClass( this.hoverable, null, "ui-state-hover" );
491			this._removeClass( this.focusable, null, "ui-state-focus" );
492		}
493	},
494
495	enable: function() {
496		return this._setOptions( { disabled: false } );
497	},
498
499	disable: function() {
500		return this._setOptions( { disabled: true } );
501	},
502
503	_classes: function( options ) {
504		var full = [];
505		var that = this;
506
507		options = $.extend( {
508			element: this.element,
509			classes: this.options.classes || {}
510		}, options );
511
512		function processClassString( classes, checkOption ) {
513			var current, i;
514			for ( i = 0; i < classes.length; i++ ) {
515				current = that.classesElementLookup[ classes[ i ] ] || $();
516				if ( options.add ) {
517					current = $( $.unique( current.get().concat( options.element.get() ) ) );
518				} else {
519					current = $( current.not( options.element ).get() );
520				}
521				that.classesElementLookup[ classes[ i ] ] = current;
522				full.push( classes[ i ] );
523				if ( checkOption && options.classes[ classes[ i ] ] ) {
524					full.push( options.classes[ classes[ i ] ] );
525				}
526			}
527		}
528
529		this._on( options.element, {
530			"remove": "_untrackClassesElement"
531		} );
532
533		if ( options.keys ) {
534			processClassString( options.keys.match( /\S+/g ) || [], true );
535		}
536		if ( options.extra ) {
537			processClassString( options.extra.match( /\S+/g ) || [] );
538		}
539
540		return full.join( " " );
541	},
542
543	_untrackClassesElement: function( event ) {
544		var that = this;
545		$.each( that.classesElementLookup, function( key, value ) {
546			if ( $.inArray( event.target, value ) !== -1 ) {
547				that.classesElementLookup[ key ] = $( value.not( event.target ).get() );
548			}
549		} );
550	},
551
552	_removeClass: function( element, keys, extra ) {
553		return this._toggleClass( element, keys, extra, false );
554	},
555
556	_addClass: function( element, keys, extra ) {
557		return this._toggleClass( element, keys, extra, true );
558	},
559
560	_toggleClass: function( element, keys, extra, add ) {
561		add = ( typeof add === "boolean" ) ? add : extra;
562		var shift = ( typeof element === "string" || element === null ),
563			options = {
564				extra: shift ? keys : extra,
565				keys: shift ? element : keys,
566				element: shift ? this.element : element,
567				add: add
568			};
569		options.element.toggleClass( this._classes( options ), add );
570		return this;
571	},
572
573	_on: function( suppressDisabledCheck, element, handlers ) {
574		var delegateElement;
575		var instance = this;
576
577		// No suppressDisabledCheck flag, shuffle arguments
578		if ( typeof suppressDisabledCheck !== "boolean" ) {
579			handlers = element;
580			element = suppressDisabledCheck;
581			suppressDisabledCheck = false;
582		}
583
584		// No element argument, shuffle and use this.element
585		if ( !handlers ) {
586			handlers = element;
587			element = this.element;
588			delegateElement = this.widget();
589		} else {
590			element = delegateElement = $( element );
591			this.bindings = this.bindings.add( element );
592		}
593
594		$.each( handlers, function( event, handler ) {
595			function handlerProxy() {
596
597				// Allow widgets to customize the disabled handling
598				// - disabled as an array instead of boolean
599				// - disabled class as method for disabling individual parts
600				if ( !suppressDisabledCheck &&
601						( instance.options.disabled === true ||
602						$( this ).hasClass( "ui-state-disabled" ) ) ) {
603					return;
604				}
605				return ( typeof handler === "string" ? instance[ handler ] : handler )
606					.apply( instance, arguments );
607			}
608
609			// Copy the guid so direct unbinding works
610			if ( typeof handler !== "string" ) {
611				handlerProxy.guid = handler.guid =
612					handler.guid || handlerProxy.guid || $.guid++;
613			}
614
615			var match = event.match( /^([\w:-]*)\s*(.*)$/ );
616			var eventName = match[ 1 ] + instance.eventNamespace;
617			var selector = match[ 2 ];
618
619			if ( selector ) {
620				delegateElement.on( eventName, selector, handlerProxy );
621			} else {
622				element.on( eventName, handlerProxy );
623			}
624		} );
625	},
626
627	_off: function( element, eventName ) {
628		eventName = ( eventName || "" ).split( " " ).join( this.eventNamespace + " " ) +
629			this.eventNamespace;
630		element.off( eventName ).off( eventName );
631
632		// Clear the stack to avoid memory leaks (#10056)
633		this.bindings = $( this.bindings.not( element ).get() );
634		this.focusable = $( this.focusable.not( element ).get() );
635		this.hoverable = $( this.hoverable.not( element ).get() );
636	},
637
638	_delay: function( handler, delay ) {
639		function handlerProxy() {
640			return ( typeof handler === "string" ? instance[ handler ] : handler )
641				.apply( instance, arguments );
642		}
643		var instance = this;
644		return setTimeout( handlerProxy, delay || 0 );
645	},
646
647	_hoverable: function( element ) {
648		this.hoverable = this.hoverable.add( element );
649		this._on( element, {
650			mouseenter: function( event ) {
651				this._addClass( $( event.currentTarget ), null, "ui-state-hover" );
652			},
653			mouseleave: function( event ) {
654				this._removeClass( $( event.currentTarget ), null, "ui-state-hover" );
655			}
656		} );
657	},
658
659	_focusable: function( element ) {
660		this.focusable = this.focusable.add( element );
661		this._on( element, {
662			focusin: function( event ) {
663				this._addClass( $( event.currentTarget ), null, "ui-state-focus" );
664			},
665			focusout: function( event ) {
666				this._removeClass( $( event.currentTarget ), null, "ui-state-focus" );
667			}
668		} );
669	},
670
671	_trigger: function( type, event, data ) {
672		var prop, orig;
673		var callback = this.options[ type ];
674
675		data = data || {};
676		event = $.Event( event );
677		event.type = ( type === this.widgetEventPrefix ?
678			type :
679			this.widgetEventPrefix + type ).toLowerCase();
680
681		// The original event may come from any element
682		// so we need to reset the target on the new event
683		event.target = this.element[ 0 ];
684
685		// Copy original event properties over to the new event
686		orig = event.originalEvent;
687		if ( orig ) {
688			for ( prop in orig ) {
689				if ( !( prop in event ) ) {
690					event[ prop ] = orig[ prop ];
691				}
692			}
693		}
694
695		this.element.trigger( event, data );
696		return !( $.isFunction( callback ) &&
697			callback.apply( this.element[ 0 ], [ event ].concat( data ) ) === false ||
698			event.isDefaultPrevented() );
699	}
700};
701
702$.each( { show: "fadeIn", hide: "fadeOut" }, function( method, defaultEffect ) {
703	$.Widget.prototype[ "_" + method ] = function( element, options, callback ) {
704		if ( typeof options === "string" ) {
705			options = { effect: options };
706		}
707
708		var hasOptions;
709		var effectName = !options ?
710			method :
711			options === true || typeof options === "number" ?
712				defaultEffect :
713				options.effect || defaultEffect;
714
715		options = options || {};
716		if ( typeof options === "number" ) {
717			options = { duration: options };
718		}
719
720		hasOptions = !$.isEmptyObject( options );
721		options.complete = callback;
722
723		if ( options.delay ) {
724			element.delay( options.delay );
725		}
726
727		if ( hasOptions && $.effects && $.effects.effect[ effectName ] ) {
728			element[ method ]( options );
729		} else if ( effectName !== method && element[ effectName ] ) {
vendor: 4,982 bytes, lines 730-909
730			element[ effectName ]( options.duration, options.easing, callback );
731		} else {
732			element.queue( function( next ) {
733				$( this )[ method ]();
734				if ( callback ) {
735					callback.call( element[ 0 ] );
736				}
737				next();
738			} );
739		}
740	};
741} );
742
743var widget = $.widget;
744
745
746/*!
747 * jQuery UI Position 1.12.1
748 * http://jqueryui.com
749 *
750 * Copyright jQuery Foundation and other contributors
751 * Released under the MIT license.
752 * http://jquery.org/license
753 *
754 * http://api.jqueryui.com/position/
755 */
756
757//>>label: Position
758//>>group: Core
759//>>description: Positions elements relative to other elements.
760//>>docs: http://api.jqueryui.com/position/
761//>>demos: http://jqueryui.com/position/
762
763
764( function() {
765var cachedScrollbarWidth,
766	max = Math.max,
767	abs = Math.abs,
768	rhorizontal = /left|center|right/,
769	rvertical = /top|center|bottom/,
770	roffset = /[\+\-]\d+(\.[\d]+)?%?/,
771	rposition = /^\w+/,
772	rpercent = /%$/,
773	_position = $.fn.position;
774
775function getOffsets( offsets, width, height ) {
776	return [
777		parseFloat( offsets[ 0 ] ) * ( rpercent.test( offsets[ 0 ] ) ? width / 100 : 1 ),
778		parseFloat( offsets[ 1 ] ) * ( rpercent.test( offsets[ 1 ] ) ? height / 100 : 1 )
779	];
780}
781
782function parseCss( element, property ) {
783	return parseInt( $.css( element, property ), 10 ) || 0;
784}
785
786function getDimensions( elem ) {
787	var raw = elem[ 0 ];
788	if ( raw.nodeType === 9 ) {
789		return {
790			width: elem.width(),
791			height: elem.height(),
792			offset: { top: 0, left: 0 }
793		};
794	}
795	if ( $.isWindow( raw ) ) {
796		return {
797			width: elem.width(),
798			height: elem.height(),
799			offset: { top: elem.scrollTop(), left: elem.scrollLeft() }
800		};
801	}
802	if ( raw.preventDefault ) {
803		return {
804			width: 0,
805			height: 0,
806			offset: { top: raw.pageY, left: raw.pageX }
807		};
808	}
809	return {
810		width: elem.outerWidth(),
811		height: elem.outerHeight(),
812		offset: elem.offset()
813	};
814}
815
816$.position = {
817	scrollbarWidth: function() {
818		if ( cachedScrollbarWidth !== undefined ) {
819			return cachedScrollbarWidth;
820		}
821		var w1, w2,
822			div = $( "<div " +
823				"style='display:block;position:absolute;width:50px;height:50px;overflow:hidden;'>" +
824				"<div style='height:100px;width:auto;'></div></div>" ),
825			innerDiv = div.children()[ 0 ];
826
827		$( "body" ).append( div );
828		w1 = innerDiv.offsetWidth;
829		div.css( "overflow", "scroll" );
830
831		w2 = innerDiv.offsetWidth;
832
833		if ( w1 === w2 ) {
834			w2 = div[ 0 ].clientWidth;
835		}
836
837		div.remove();
838
839		return ( cachedScrollbarWidth = w1 - w2 );
840	},
841	getScrollInfo: function( within ) {
842		var overflowX = within.isWindow || within.isDocument ? "" :
843				within.element.css( "overflow-x" ),
844			overflowY = within.isWindow || within.isDocument ? "" :
845				within.element.css( "overflow-y" ),
846			hasOverflowX = overflowX === "scroll" ||
847				( overflowX === "auto" && within.width < within.element[ 0 ].scrollWidth ),
848			hasOverflowY = overflowY === "scroll" ||
849				( overflowY === "auto" && within.height < within.element[ 0 ].scrollHeight );
850		return {
851			width: hasOverflowY ? $.position.scrollbarWidth() : 0,
852			height: hasOverflowX ? $.position.scrollbarWidth() : 0
853		};
854	},
855	getWithinInfo: function( element ) {
856		var withinElement = $( element || window ),
857			isWindow = $.isWindow( withinElement[ 0 ] ),
858			isDocument = !!withinElement[ 0 ] && withinElement[ 0 ].nodeType === 9,
859			hasOffset = !isWindow && !isDocument;
860		return {
861			element: withinElement,
862			isWindow: isWindow,
863			isDocument: isDocument,
864			offset: hasOffset ? $( element ).offset() : { left: 0, top: 0 },
865			scrollLeft: withinElement.scrollLeft(),
866			scrollTop: withinElement.scrollTop(),
867			width: withinElement.outerWidth(),
868			height: withinElement.outerHeight()
869		};
870	}
871};
872
873$.fn.position = function( options ) {
874	if ( !options || !options.of ) {
875		return _position.apply( this, arguments );
876	}
877
878	// Make a copy, we don't want to modify arguments
879	options = $.extend( {}, options );
880
881	var atOffset, targetWidth, targetHeight, targetOffset, basePosition, dimensions,
882		target = $( options.of ),
883		within = $.position.getWithinInfo( options.within ),
884		scrollInfo = $.position.getScrollInfo( within ),
885		collision = ( options.collision || "flip" ).split( " " ),
886		offsets = {};
887
888	dimensions = getDimensions( target );
889	if ( target[ 0 ].preventDefault ) {
890
891		// Force left top to allow flipping
892		options.at = "left top";
893	}
894	targetWidth = dimensions.width;
895	targetHeight = dimensions.height;
896	targetOffset = dimensions.offset;
897
898	// Clone to reuse original targetOffset later
899	basePosition = $.extend( {}, targetOffset );
900
901	// Force my and at to have valid horizontal and vertical positions
902	// if a value is missing or invalid, it will be converted to center
903	$.each( [ "my", "at" ], function() {
904		var pos = ( options[ this ] || "" ).split( " " ),
905			horizontalOffset,
906			verticalOffset;
907
908		if ( pos.length === 1 ) {
909			pos = rhorizontal.test( pos[ 0 ] ) ?
vendor: 10,483 bytes, lines 910-1236
910				pos.concat( [ "center" ] ) :
911				rvertical.test( pos[ 0 ] ) ?
912					[ "center" ].concat( pos ) :
913					[ "center", "center" ];
914		}
915		pos[ 0 ] = rhorizontal.test( pos[ 0 ] ) ? pos[ 0 ] : "center";
916		pos[ 1 ] = rvertical.test( pos[ 1 ] ) ? pos[ 1 ] : "center";
917
918		// Calculate offsets
919		horizontalOffset = roffset.exec( pos[ 0 ] );
920		verticalOffset = roffset.exec( pos[ 1 ] );
921		offsets[ this ] = [
922			horizontalOffset ? horizontalOffset[ 0 ] : 0,
923			verticalOffset ? verticalOffset[ 0 ] : 0
924		];
925
926		// Reduce to just the positions without the offsets
927		options[ this ] = [
928			rposition.exec( pos[ 0 ] )[ 0 ],
929			rposition.exec( pos[ 1 ] )[ 0 ]
930		];
931	} );
932
933	// Normalize collision option
934	if ( collision.length === 1 ) {
935		collision[ 1 ] = collision[ 0 ];
936	}
937
938	if ( options.at[ 0 ] === "right" ) {
939		basePosition.left += targetWidth;
940	} else if ( options.at[ 0 ] === "center" ) {
941		basePosition.left += targetWidth / 2;
942	}
943
944	if ( options.at[ 1 ] === "bottom" ) {
945		basePosition.top += targetHeight;
946	} else if ( options.at[ 1 ] === "center" ) {
947		basePosition.top += targetHeight / 2;
948	}
949
950	atOffset = getOffsets( offsets.at, targetWidth, targetHeight );
951	basePosition.left += atOffset[ 0 ];
952	basePosition.top += atOffset[ 1 ];
953
954	return this.each( function() {
955		var collisionPosition, using,
956			elem = $( this ),
957			elemWidth = elem.outerWidth(),
958			elemHeight = elem.outerHeight(),
959			marginLeft = parseCss( this, "marginLeft" ),
960			marginTop = parseCss( this, "marginTop" ),
961			collisionWidth = elemWidth + marginLeft + parseCss( this, "marginRight" ) +
962				scrollInfo.width,
963			collisionHeight = elemHeight + marginTop + parseCss( this, "marginBottom" ) +
964				scrollInfo.height,
965			position = $.extend( {}, basePosition ),
966			myOffset = getOffsets( offsets.my, elem.outerWidth(), elem.outerHeight() );
967
968		if ( options.my[ 0 ] === "right" ) {
969			position.left -= elemWidth;
970		} else if ( options.my[ 0 ] === "center" ) {
971			position.left -= elemWidth / 2;
972		}
973
974		if ( options.my[ 1 ] === "bottom" ) {
975			position.top -= elemHeight;
976		} else if ( options.my[ 1 ] === "center" ) {
977			position.top -= elemHeight / 2;
978		}
979
980		position.left += myOffset[ 0 ];
981		position.top += myOffset[ 1 ];
982
983		collisionPosition = {
984			marginLeft: marginLeft,
985			marginTop: marginTop
986		};
987
988		$.each( [ "left", "top" ], function( i, dir ) {
989			if ( $.ui.position[ collision[ i ] ] ) {
990				$.ui.position[ collision[ i ] ][ dir ]( position, {
991					targetWidth: targetWidth,
992					targetHeight: targetHeight,
993					elemWidth: elemWidth,
994					elemHeight: elemHeight,
995					collisionPosition: collisionPosition,
996					collisionWidth: collisionWidth,
997					collisionHeight: collisionHeight,
998					offset: [ atOffset[ 0 ] + myOffset[ 0 ], atOffset [ 1 ] + myOffset[ 1 ] ],
999					my: options.my,
1000					at: options.at,
1001					within: within,
1002					elem: elem
1003				} );
1004			}
1005		} );
1006
1007		if ( options.using ) {
1008
1009			// Adds feedback as second argument to using callback, if present
1010			using = function( props ) {
1011				var left = targetOffset.left - position.left,
1012					right = left + targetWidth - elemWidth,
1013					top = targetOffset.top - position.top,
1014					bottom = top + targetHeight - elemHeight,
1015					feedback = {
1016						target: {
1017							element: target,
1018							left: targetOffset.left,
1019							top: targetOffset.top,
1020							width: targetWidth,
1021							height: targetHeight
1022						},
1023						element: {
1024							element: elem,
1025							left: position.left,
1026							top: position.top,
1027							width: elemWidth,
1028							height: elemHeight
1029						},
1030						horizontal: right < 0 ? "left" : left > 0 ? "right" : "center",
1031						vertical: bottom < 0 ? "top" : top > 0 ? "bottom" : "middle"
1032					};
1033				if ( targetWidth < elemWidth && abs( left + right ) < targetWidth ) {
1034					feedback.horizontal = "center";
1035				}
1036				if ( targetHeight < elemHeight && abs( top + bottom ) < targetHeight ) {
1037					feedback.vertical = "middle";
1038				}
1039				if ( max( abs( left ), abs( right ) ) > max( abs( top ), abs( bottom ) ) ) {
1040					feedback.important = "horizontal";
1041				} else {
1042					feedback.important = "vertical";
1043				}
1044				options.using.call( this, props, feedback );
1045			};
1046		}
1047
1048		elem.offset( $.extend( position, { using: using } ) );
1049	} );
1050};
1051
1052$.ui.position = {
1053	fit: {
1054		left: function( position, data ) {
1055			var within = data.within,
1056				withinOffset = within.isWindow ? within.scrollLeft : within.offset.left,
1057				outerWidth = within.width,
1058				collisionPosLeft = position.left - data.collisionPosition.marginLeft,
1059				overLeft = withinOffset - collisionPosLeft,
1060				overRight = collisionPosLeft + data.collisionWidth - outerWidth - withinOffset,
1061				newOverRight;
1062
1063			// Element is wider than within
1064			if ( data.collisionWidth > outerWidth ) {
1065
1066				// Element is initially over the left side of within
1067				if ( overLeft > 0 && overRight <= 0 ) {
1068					newOverRight = position.left + overLeft + data.collisionWidth - outerWidth -
1069						withinOffset;
1070					position.left += overLeft - newOverRight;
1071
1072				// Element is initially over right side of within
1073				} else if ( overRight > 0 && overLeft <= 0 ) {
1074					position.left = withinOffset;
1075
1076				// Element is initially over both left and right sides of within
1077				} else {
1078					if ( overLeft > overRight ) {
1079						position.left = withinOffset + outerWidth - data.collisionWidth;
1080					} else {
1081						position.left = withinOffset;
1082					}
1083				}
1084
1085			// Too far left -> align with left edge
1086			} else if ( overLeft > 0 ) {
1087				position.left += overLeft;
1088
1089			// Too far right -> align with right edge
1090			} else if ( overRight > 0 ) {
1091				position.left -= overRight;
1092
1093			// Adjust based on position and margin
1094			} else {
1095				position.left = max( position.left - collisionPosLeft, position.left );
1096			}
1097		},
1098		top: function( position, data ) {
1099			var within = data.within,
1100				withinOffset = within.isWindow ? within.scrollTop : within.offset.top,
1101				outerHeight = data.within.height,
1102				collisionPosTop = position.top - data.collisionPosition.marginTop,
1103				overTop = withinOffset - collisionPosTop,
1104				overBottom = collisionPosTop + data.collisionHeight - outerHeight - withinOffset,
1105				newOverBottom;
1106
1107			// Element is taller than within
1108			if ( data.collisionHeight > outerHeight ) {
1109
1110				// Element is initially over the top of within
1111				if ( overTop > 0 && overBottom <= 0 ) {
1112					newOverBottom = position.top + overTop + data.collisionHeight - outerHeight -
1113						withinOffset;
1114					position.top += overTop - newOverBottom;
1115
1116				// Element is initially over bottom of within
1117				} else if ( overBottom > 0 && overTop <= 0 ) {
1118					position.top = withinOffset;
1119
1120				// Element is initially over both top and bottom of within
1121				} else {
1122					if ( overTop > overBottom ) {
1123						position.top = withinOffset + outerHeight - data.collisionHeight;
1124					} else {
1125						position.top = withinOffset;
1126					}
1127				}
1128
1129			// Too far up -> align with top
1130			} else if ( overTop > 0 ) {
1131				position.top += overTop;
1132
1133			// Too far down -> align with bottom edge
1134			} else if ( overBottom > 0 ) {
1135				position.top -= overBottom;
1136
1137			// Adjust based on position and margin
1138			} else {
1139				position.top = max( position.top - collisionPosTop, position.top );
1140			}
1141		}
1142	},
1143	flip: {
1144		left: function( position, data ) {
1145			var within = data.within,
1146				withinOffset = within.offset.left + within.scrollLeft,
1147				outerWidth = within.width,
1148				offsetLeft = within.isWindow ? within.scrollLeft : within.offset.left,
1149				collisionPosLeft = position.left - data.collisionPosition.marginLeft,
1150				overLeft = collisionPosLeft - offsetLeft,
1151				overRight = collisionPosLeft + data.collisionWidth - outerWidth - offsetLeft,
1152				myOffset = data.my[ 0 ] === "left" ?
1153					-data.elemWidth :
1154					data.my[ 0 ] === "right" ?
1155						data.elemWidth :
1156						0,
1157				atOffset = data.at[ 0 ] === "left" ?
1158					data.targetWidth :
1159					data.at[ 0 ] === "right" ?
1160						-data.targetWidth :
1161						0,
1162				offset = -2 * data.offset[ 0 ],
1163				newOverRight,
1164				newOverLeft;
1165
1166			if ( overLeft < 0 ) {
1167				newOverRight = position.left + myOffset + atOffset + offset + data.collisionWidth -
1168					outerWidth - withinOffset;
1169				if ( newOverRight < 0 || newOverRight < abs( overLeft ) ) {
1170					position.left += myOffset + atOffset + offset;
1171				}
1172			} else if ( overRight > 0 ) {
1173				newOverLeft = position.left - data.collisionPosition.marginLeft + myOffset +
1174					atOffset + offset - offsetLeft;
1175				if ( newOverLeft > 0 || abs( newOverLeft ) < overRight ) {
1176					position.left += myOffset + atOffset + offset;
1177				}
1178			}
1179		},
1180		top: function( position, data ) {
1181			var within = data.within,
1182				withinOffset = within.offset.top + within.scrollTop,
1183				outerHeight = within.height,
1184				offsetTop = within.isWindow ? within.scrollTop : within.offset.top,
1185				collisionPosTop = position.top - data.collisionPosition.marginTop,
1186				overTop = collisionPosTop - offsetTop,
1187				overBottom = collisionPosTop + data.collisionHeight - outerHeight - offsetTop,
1188				top = data.my[ 1 ] === "top",
1189				myOffset = top ?
1190					-data.elemHeight :
1191					data.my[ 1 ] === "bottom" ?
1192						data.elemHeight :
1193						0,
1194				atOffset = data.at[ 1 ] === "top" ?
1195					data.targetHeight :
1196					data.at[ 1 ] === "bottom" ?
1197						-data.targetHeight :
1198						0,
1199				offset = -2 * data.offset[ 1 ],
1200				newOverTop,
1201				newOverBottom;
1202			if ( overTop < 0 ) {
1203				newOverBottom = position.top + myOffset + atOffset + offset + data.collisionHeight -
1204					outerHeight - withinOffset;
1205				if ( newOverBottom < 0 || newOverBottom < abs( overTop ) ) {
1206					position.top += myOffset + atOffset + offset;
1207				}
1208			} else if ( overBottom > 0 ) {
1209				newOverTop = position.top - data.collisionPosition.marginTop + myOffset + atOffset +
1210					offset - offsetTop;
1211				if ( newOverTop > 0 || abs( newOverTop ) < overBottom ) {
1212					position.top += myOffset + atOffset + offset;
1213				}
1214			}
1215		}
1216	},
1217	flipfit: {
1218		left: function() {
1219			$.ui.position.flip.left.apply( this, arguments );
1220			$.ui.position.fit.left.apply( this, arguments );
1221		},
1222		top: function() {
1223			$.ui.position.flip.top.apply( this, arguments );
1224			$.ui.position.fit.top.apply( this, arguments );
1225		}
1226	}
1227};
1228
1229} )();
1230
1231var position = $.ui.position;
1232
1233
1234/*!
1235 * jQuery UI :data 1.12.1
1236 * http://jqueryui.com
vendor: 4,582 bytes, lines 1237-1407
1237 *
1238 * Copyright jQuery Foundation and other contributors
1239 * Released under the MIT license.
1240 * http://jquery.org/license
1241 */
1242
1243//>>label: :data Selector
1244//>>group: Core
1245//>>description: Selects elements which have data stored under the specified key.
1246//>>docs: http://api.jqueryui.com/data-selector/
1247
1248
1249var data = $.extend( $.expr[ ":" ], {
1250	data: $.expr.createPseudo ?
1251		$.expr.createPseudo( function( dataName ) {
1252			return function( elem ) {
1253				return !!$.data( elem, dataName );
1254			};
1255		} ) :
1256
1257		// Support: jQuery <1.8
1258		function( elem, i, match ) {
1259			return !!$.data( elem, match[ 3 ] );
1260		}
1261} );
1262
1263/*!
1264 * jQuery UI Disable Selection 1.12.1
1265 * http://jqueryui.com
1266 *
1267 * Copyright jQuery Foundation and other contributors
1268 * Released under the MIT license.
1269 * http://jquery.org/license
1270 */
1271
1272//>>label: disableSelection
1273//>>group: Core
1274//>>description: Disable selection of text content within the set of matched elements.
1275//>>docs: http://api.jqueryui.com/disableSelection/
1276
1277// This file is deprecated
1278
1279
1280var disableSelection = $.fn.extend( {
1281	disableSelection: ( function() {
1282		var eventType = "onselectstart" in document.createElement( "div" ) ?
1283			"selectstart" :
1284			"mousedown";
1285
1286		return function() {
1287			return this.on( eventType + ".ui-disableSelection", function( event ) {
1288				event.preventDefault();
1289			} );
1290		};
1291	} )(),
1292
1293	enableSelection: function() {
1294		return this.off( ".ui-disableSelection" );
1295	}
1296} );
1297
1298
1299/*!
1300 * jQuery UI Focusable 1.12.1
1301 * http://jqueryui.com
1302 *
1303 * Copyright jQuery Foundation and other contributors
1304 * Released under the MIT license.
1305 * http://jquery.org/license
1306 */
1307
1308//>>label: :focusable Selector
1309//>>group: Core
1310//>>description: Selects elements which can be focused.
1311//>>docs: http://api.jqueryui.com/focusable-selector/
1312
1313
1314
1315// Selectors
1316$.ui.focusable = function( element, hasTabindex ) {
1317	var map, mapName, img, focusableIfVisible, fieldset,
1318		nodeName = element.nodeName.toLowerCase();
1319
1320	if ( "area" === nodeName ) {
1321		map = element.parentNode;
1322		mapName = map.name;
1323		if ( !element.href || !mapName || map.nodeName.toLowerCase() !== "map" ) {
1324			return false;
1325		}
1326		img = $( "img[usemap='#" + mapName + "']" );
1327		return img.length > 0 && img.is( ":visible" );
1328	}
1329
1330	if ( /^(input|select|textarea|button|object)$/.test( nodeName ) ) {
1331		focusableIfVisible = !element.disabled;
1332
1333		if ( focusableIfVisible ) {
1334
1335			// Form controls within a disabled fieldset are disabled.
1336			// However, controls within the fieldset's legend do not get disabled.
1337			// Since controls generally aren't placed inside legends, we skip
1338			// this portion of the check.
1339			fieldset = $( element ).closest( "fieldset" )[ 0 ];
1340			if ( fieldset ) {
1341				focusableIfVisible = !fieldset.disabled;
1342			}
1343		}
1344	} else if ( "a" === nodeName ) {
1345		focusableIfVisible = element.href || hasTabindex;
1346	} else {
1347		focusableIfVisible = hasTabindex;
1348	}
1349
1350	return focusableIfVisible && $( element ).is( ":visible" ) && visible( $( element ) );
1351};
1352
1353// Support: IE 8 only
1354// IE 8 doesn't resolve inherit to visible/hidden for computed values
1355function visible( element ) {
1356	var visibility = element.css( "visibility" );
1357	while ( visibility === "inherit" ) {
1358		element = element.parent();
1359		visibility = element.css( "visibility" );
1360	}
1361	return visibility !== "hidden";
1362}
1363
1364$.extend( $.expr[ ":" ], {
1365	focusable: function( element ) {
1366		return $.ui.focusable( element, $.attr( element, "tabindex" ) != null );
1367	}
1368} );
1369
1370var focusable = $.ui.focusable;
1371
1372
1373
1374
1375// Support: IE8 Only
1376// IE8 does not support the form attribute and when it is supplied. It overwrites the form prop
1377// with a string, so we need to find the proper form.
1378var form = $.fn.form = function() {
1379	return typeof this[ 0 ].form === "string" ? this.closest( "form" ) : $( this[ 0 ].form );
1380};
1381
1382
1383/*!
1384 * jQuery UI Form Reset Mixin 1.12.1
1385 * http://jqueryui.com
1386 *
1387 * Copyright jQuery Foundation and other contributors
1388 * Released under the MIT license.
1389 * http://jquery.org/license
1390 */
1391
1392//>>label: Form Reset Mixin
1393//>>group: Core
1394//>>description: Refresh input widgets when their form is reset
1395//>>docs: http://api.jqueryui.com/form-reset-mixin/
1396
1397
1398
1399var formResetMixin = $.ui.formResetMixin = {
1400	_formResetHandler: function() {
1401		var form = $( this );
1402
1403		// Wait for the form reset to actually happen before refreshing
1404		setTimeout( function() {
1405			var instances = form.data( "ui-form-reset-instances" );
1406			$.each( instances, function() {
1407				this.refresh();
vendor: 4,158 bytes, lines 1408-1573
1408			} );
1409		} );
1410	},
1411
1412	_bindFormResetHandler: function() {
1413		this.form = this.element.form();
1414		if ( !this.form.length ) {
1415			return;
1416		}
1417
1418		var instances = this.form.data( "ui-form-reset-instances" ) || [];
1419		if ( !instances.length ) {
1420
1421			// We don't use _on() here because we use a single event handler per form
1422			this.form.on( "reset.ui-form-reset", this._formResetHandler );
1423		}
1424		instances.push( this );
1425		this.form.data( "ui-form-reset-instances", instances );
1426	},
1427
1428	_unbindFormResetHandler: function() {
1429		if ( !this.form.length ) {
1430			return;
1431		}
1432
1433		var instances = this.form.data( "ui-form-reset-instances" );
1434		instances.splice( $.inArray( this, instances ), 1 );
1435		if ( instances.length ) {
1436			this.form.data( "ui-form-reset-instances", instances );
1437		} else {
1438			this.form
1439				.removeData( "ui-form-reset-instances" )
1440				.off( "reset.ui-form-reset" );
1441		}
1442	}
1443};
1444
1445
1446/*!
1447 * jQuery UI Support for jQuery core 1.7.x 1.12.1
1448 * http://jqueryui.com
1449 *
1450 * Copyright jQuery Foundation and other contributors
1451 * Released under the MIT license.
1452 * http://jquery.org/license
1453 *
1454 */
1455
1456//>>label: jQuery 1.7 Support
1457//>>group: Core
1458//>>description: Support version 1.7.x of jQuery core
1459
1460
1461
1462// Support: jQuery 1.7 only
1463// Not a great way to check versions, but since we only support 1.7+ and only
1464// need to detect <1.8, this is a simple check that should suffice. Checking
1465// for "1.7." would be a bit safer, but the version string is 1.7, not 1.7.0
1466// and we'll never reach 1.70.0 (if we do, we certainly won't be supporting
1467// 1.7 anymore). See #11197 for why we're not using feature detection.
1468if ( $.fn.jquery.substring( 0, 3 ) === "1.7" ) {
1469
1470	// Setters for .innerWidth(), .innerHeight(), .outerWidth(), .outerHeight()
1471	// Unlike jQuery Core 1.8+, these only support numeric values to set the
1472	// dimensions in pixels
1473	$.each( [ "Width", "Height" ], function( i, name ) {
1474		var side = name === "Width" ? [ "Left", "Right" ] : [ "Top", "Bottom" ],
1475			type = name.toLowerCase(),
1476			orig = {
1477				innerWidth: $.fn.innerWidth,
1478				innerHeight: $.fn.innerHeight,
1479				outerWidth: $.fn.outerWidth,
1480				outerHeight: $.fn.outerHeight
1481			};
1482
1483		function reduce( elem, size, border, margin ) {
1484			$.each( side, function() {
1485				size -= parseFloat( $.css( elem, "padding" + this ) ) || 0;
1486				if ( border ) {
1487					size -= parseFloat( $.css( elem, "border" + this + "Width" ) ) || 0;
1488				}
1489				if ( margin ) {
1490					size -= parseFloat( $.css( elem, "margin" + this ) ) || 0;
1491				}
1492			} );
1493			return size;
1494		}
1495
1496		$.fn[ "inner" + name ] = function( size ) {
1497			if ( size === undefined ) {
1498				return orig[ "inner" + name ].call( this );
1499			}
1500
1501			return this.each( function() {
1502				$( this ).css( type, reduce( this, size ) + "px" );
1503			} );
1504		};
1505
1506		$.fn[ "outer" + name ] = function( size, margin ) {
1507			if ( typeof size !== "number" ) {
1508				return orig[ "outer" + name ].call( this, size );
1509			}
1510
1511			return this.each( function() {
1512				$( this ).css( type, reduce( this, size, true, margin ) + "px" );
1513			} );
1514		};
1515	} );
1516
1517	$.fn.addBack = function( selector ) {
1518		return this.add( selector == null ?
1519			this.prevObject : this.prevObject.filter( selector )
1520		);
1521	};
1522}
1523
1524;
1525/*!
1526 * jQuery UI Keycode 1.12.1
1527 * http://jqueryui.com
1528 *
1529 * Copyright jQuery Foundation and other contributors
1530 * Released under the MIT license.
1531 * http://jquery.org/license
1532 */
1533
1534//>>label: Keycode
1535//>>group: Core
1536//>>description: Provide keycodes as keynames
1537//>>docs: http://api.jqueryui.com/jQuery.ui.keyCode/
1538
1539
1540var keycode = $.ui.keyCode = {
1541	BACKSPACE: 8,
1542	COMMA: 188,
1543	DELETE: 46,
1544	DOWN: 40,
1545	END: 35,
1546	ENTER: 13,
1547	ESCAPE: 27,
1548	HOME: 36,
1549	LEFT: 37,
1550	PAGE_DOWN: 34,
1551	PAGE_UP: 33,
1552	PERIOD: 190,
1553	RIGHT: 39,
1554	SPACE: 32,
1555	TAB: 9,
1556	UP: 38
1557};
1558
1559
1560
1561
1562// Internal use only
1563var escapeSelector = $.ui.escapeSelector = ( function() {
1564	var selectorEscape = /([!"#$%&'()*+,./:;<=>?@[\]^`{|}~])/g;
1565	return function( selector ) {
1566		return selector.replace( selectorEscape, "\\$1" );
1567	};
1568} )();
1569
1570
1571/*!
1572 * jQuery UI Labels 1.12.1
1573 * http://jqueryui.com
vendor: 4,601 bytes, lines 1574-1754
1574 *
1575 * Copyright jQuery Foundation and other contributors
1576 * Released under the MIT license.
1577 * http://jquery.org/license
1578 */
1579
1580//>>label: labels
1581//>>group: Core
1582//>>description: Find all the labels associated with a given input
1583//>>docs: http://api.jqueryui.com/labels/
1584
1585
1586
1587var labels = $.fn.labels = function() {
1588	var ancestor, selector, id, labels, ancestors;
1589
1590	// Check control.labels first
1591	if ( this[ 0 ].labels && this[ 0 ].labels.length ) {
1592		return this.pushStack( this[ 0 ].labels );
1593	}
1594
1595	// Support: IE <= 11, FF <= 37, Android <= 2.3 only
1596	// Above browsers do not support control.labels. Everything below is to support them
1597	// as well as document fragments. control.labels does not work on document fragments
1598	labels = this.eq( 0 ).parents( "label" );
1599
1600	// Look for the label based on the id
1601	id = this.attr( "id" );
1602	if ( id ) {
1603
1604		// We don't search against the document in case the element
1605		// is disconnected from the DOM
1606		ancestor = this.eq( 0 ).parents().last();
1607
1608		// Get a full set of top level ancestors
1609		ancestors = ancestor.add( ancestor.length ? ancestor.siblings() : this.siblings() );
1610
1611		// Create a selector for the label based on the id
1612		selector = "label[for='" + $.ui.escapeSelector( id ) + "']";
1613
1614		labels = labels.add( ancestors.find( selector ).addBack( selector ) );
1615
1616	}
1617
1618	// Return whatever we have found for labels
1619	return this.pushStack( labels );
1620};
1621
1622
1623/*!
1624 * jQuery UI Scroll Parent 1.12.1
1625 * http://jqueryui.com
1626 *
1627 * Copyright jQuery Foundation and other contributors
1628 * Released under the MIT license.
1629 * http://jquery.org/license
1630 */
1631
1632//>>label: scrollParent
1633//>>group: Core
1634//>>description: Get the closest ancestor element that is scrollable.
1635//>>docs: http://api.jqueryui.com/scrollParent/
1636
1637
1638
1639var scrollParent = $.fn.scrollParent = function( includeHidden ) {
1640	var position = this.css( "position" ),
1641		excludeStaticParent = position === "absolute",
1642		overflowRegex = includeHidden ? /(auto|scroll|hidden)/ : /(auto|scroll)/,
1643		scrollParent = this.parents().filter( function() {
1644			var parent = $( this );
1645			if ( excludeStaticParent && parent.css( "position" ) === "static" ) {
1646				return false;
1647			}
1648			return overflowRegex.test( parent.css( "overflow" ) + parent.css( "overflow-y" ) +
1649				parent.css( "overflow-x" ) );
1650		} ).eq( 0 );
1651
1652	return position === "fixed" || !scrollParent.length ?
1653		$( this[ 0 ].ownerDocument || document ) :
1654		scrollParent;
1655};
1656
1657
1658/*!
1659 * jQuery UI Tabbable 1.12.1
1660 * http://jqueryui.com
1661 *
1662 * Copyright jQuery Foundation and other contributors
1663 * Released under the MIT license.
1664 * http://jquery.org/license
1665 */
1666
1667//>>label: :tabbable Selector
1668//>>group: Core
1669//>>description: Selects elements which can be tabbed to.
1670//>>docs: http://api.jqueryui.com/tabbable-selector/
1671
1672
1673
1674var tabbable = $.extend( $.expr[ ":" ], {
1675	tabbable: function( element ) {
1676		var tabIndex = $.attr( element, "tabindex" ),
1677			hasTabindex = tabIndex != null;
1678		return ( !hasTabindex || tabIndex >= 0 ) && $.ui.focusable( element, hasTabindex );
1679	}
1680} );
1681
1682
1683/*!
1684 * jQuery UI Unique ID 1.12.1
1685 * http://jqueryui.com
1686 *
1687 * Copyright jQuery Foundation and other contributors
1688 * Released under the MIT license.
1689 * http://jquery.org/license
1690 */
1691
1692//>>label: uniqueId
1693//>>group: Core
1694//>>description: Functions to generate and remove uniqueId's
1695//>>docs: http://api.jqueryui.com/uniqueId/
1696
1697
1698
1699var uniqueId = $.fn.extend( {
1700	uniqueId: ( function() {
1701		var uuid = 0;
1702
1703		return function() {
1704			return this.each( function() {
1705				if ( !this.id ) {
1706					this.id = "ui-id-" + ( ++uuid );
1707				}
1708			} );
1709		};
1710	} )(),
1711
1712	removeUniqueId: function() {
1713		return this.each( function() {
1714			if ( /^ui-id-\d+$/.test( this.id ) ) {
1715				$( this ).removeAttr( "id" );
1716			}
1717		} );
1718	}
1719} );
1720
1721
1722
1723
1724// This file is deprecated
1725var ie = $.ui.ie = !!/msie [\w.]+/.exec( navigator.userAgent.toLowerCase() );
1726
1727/*!
1728 * jQuery UI Mouse 1.12.1
1729 * http://jqueryui.com
1730 *
1731 * Copyright jQuery Foundation and other contributors
1732 * Released under the MIT license.
1733 * http://jquery.org/license
1734 */
1735
1736//>>label: Mouse
1737//>>group: Widgets
1738//>>description: Abstracts mouse-based interactions to assist in creating certain widgets.
1739//>>docs: http://api.jqueryui.com/mouse/
1740
1741
1742
1743var mouseHandled = false;
1744$( document ).on( "mouseup", function() {
1745	mouseHandled = false;
1746} );
1747
1748var widgetsMouse = $.widget( "ui.mouse", {
1749	version: "1.12.1",
1750	options: {
1751		cancel: "input, textarea, button, select, option",
1752		distance: 1,
1753		delay: 0
1754	},
vendor: 2,991 bytes, lines 1755-1851
1755	_mouseInit: function() {
1756		var that = this;
1757
1758		this.element
1759			.on( "mousedown." + this.widgetName, function( event ) {
1760				return that._mouseDown( event );
1761			} )
1762			.on( "click." + this.widgetName, function( event ) {
1763				if ( true === $.data( event.target, that.widgetName + ".preventClickEvent" ) ) {
1764					$.removeData( event.target, that.widgetName + ".preventClickEvent" );
1765					event.stopImmediatePropagation();
1766					return false;
1767				}
1768			} );
1769
1770		this.started = false;
1771	},
1772
1773	// TODO: make sure destroying one instance of mouse doesn't mess with
1774	// other instances of mouse
1775	_mouseDestroy: function() {
1776		this.element.off( "." + this.widgetName );
1777		if ( this._mouseMoveDelegate ) {
1778			this.document
1779				.off( "mousemove." + this.widgetName, this._mouseMoveDelegate )
1780				.off( "mouseup." + this.widgetName, this._mouseUpDelegate );
1781		}
1782	},
1783
1784	_mouseDown: function( event ) {
1785
1786		// don't let more than one widget handle mouseStart
1787		if ( mouseHandled ) {
1788			return;
1789		}
1790
1791		this._mouseMoved = false;
1792
1793		// We may have missed mouseup (out of window)
1794		( this._mouseStarted && this._mouseUp( event ) );
1795
1796		this._mouseDownEvent = event;
1797
1798		var that = this,
1799			btnIsLeft = ( event.which === 1 ),
1800
1801			// event.target.nodeName works around a bug in IE 8 with
1802			// disabled inputs (#7620)
1803			elIsCancel = ( typeof this.options.cancel === "string" && event.target.nodeName ?
1804				$( event.target ).closest( this.options.cancel ).length : false );
1805		if ( !btnIsLeft || elIsCancel || !this._mouseCapture( event ) ) {
1806			return true;
1807		}
1808
1809		this.mouseDelayMet = !this.options.delay;
1810		if ( !this.mouseDelayMet ) {
1811			this._mouseDelayTimer = setTimeout( function() {
1812				that.mouseDelayMet = true;
1813			}, this.options.delay );
1814		}
1815
1816		if ( this._mouseDistanceMet( event ) && this._mouseDelayMet( event ) ) {
1817			this._mouseStarted = ( this._mouseStart( event ) !== false );
1818			if ( !this._mouseStarted ) {
1819				event.preventDefault();
1820				return true;
1821			}
1822		}
1823
1824		// Click event may never have fired (Gecko & Opera)
1825		if ( true === $.data( event.target, this.widgetName + ".preventClickEvent" ) ) {
1826			$.removeData( event.target, this.widgetName + ".preventClickEvent" );
1827		}
1828
1829		// These delegates are required to keep context
1830		this._mouseMoveDelegate = function( event ) {
1831			return that._mouseMove( event );
1832		};
1833		this._mouseUpDelegate = function( event ) {
1834			return that._mouseUp( event );
1835		};
1836
1837		this.document
1838			.on( "mousemove." + this.widgetName, this._mouseMoveDelegate )
1839			.on( "mouseup." + this.widgetName, this._mouseUpDelegate );
1840
1841		event.preventDefault();
1842
1843		mouseHandled = true;
1844		return true;
1845	},
1846
1847	_mouseMove: function( event ) {
1848
1849		// Only check for mouseups outside the document if you've moved inside the document
1850		// at least once. This prevents the firing of mouseup in the case of IE<9, which will
1851		// fire a mousemove event if content is placed under the cursor. See #7778
vendor: 4,352 bytes, lines 1852-2015
1852		// Support: IE <9
1853		if ( this._mouseMoved ) {
1854
1855			// IE mouseup check - mouseup happened when mouse was out of window
1856			if ( $.ui.ie && ( !document.documentMode || document.documentMode < 9 ) &&
1857					!event.button ) {
1858				return this._mouseUp( event );
1859
1860			// Iframe mouseup check - mouseup occurred in another document
1861			} else if ( !event.which ) {
1862
1863				// Support: Safari <=8 - 9
1864				// Safari sets which to 0 if you press any of the following keys
1865				// during a drag (#14461)
1866				if ( event.originalEvent.altKey || event.originalEvent.ctrlKey ||
1867						event.originalEvent.metaKey || event.originalEvent.shiftKey ) {
1868					this.ignoreMissingWhich = true;
1869				} else if ( !this.ignoreMissingWhich ) {
1870					return this._mouseUp( event );
1871				}
1872			}
1873		}
1874
1875		if ( event.which || event.button ) {
1876			this._mouseMoved = true;
1877		}
1878
1879		if ( this._mouseStarted ) {
1880			this._mouseDrag( event );
1881			return event.preventDefault();
1882		}
1883
1884		if ( this._mouseDistanceMet( event ) && this._mouseDelayMet( event ) ) {
1885			this._mouseStarted =
1886				( this._mouseStart( this._mouseDownEvent, event ) !== false );
1887			( this._mouseStarted ? this._mouseDrag( event ) : this._mouseUp( event ) );
1888		}
1889
1890		return !this._mouseStarted;
1891	},
1892
1893	_mouseUp: function( event ) {
1894		this.document
1895			.off( "mousemove." + this.widgetName, this._mouseMoveDelegate )
1896			.off( "mouseup." + this.widgetName, this._mouseUpDelegate );
1897
1898		if ( this._mouseStarted ) {
1899			this._mouseStarted = false;
1900
1901			if ( event.target === this._mouseDownEvent.target ) {
1902				$.data( event.target, this.widgetName + ".preventClickEvent", true );
1903			}
1904
1905			this._mouseStop( event );
1906		}
1907
1908		if ( this._mouseDelayTimer ) {
1909			clearTimeout( this._mouseDelayTimer );
1910			delete this._mouseDelayTimer;
1911		}
1912
1913		this.ignoreMissingWhich = false;
1914		mouseHandled = false;
1915		event.preventDefault();
1916	},
1917
1918	_mouseDistanceMet: function( event ) {
1919		return ( Math.max(
1920				Math.abs( this._mouseDownEvent.pageX - event.pageX ),
1921				Math.abs( this._mouseDownEvent.pageY - event.pageY )
1922			) >= this.options.distance
1923		);
1924	},
1925
1926	_mouseDelayMet: function( /* event */ ) {
1927		return this.mouseDelayMet;
1928	},
1929
1930	// These are placeholder methods, to be overriden by extending plugin
1931	_mouseStart: function( /* event */ ) {},
1932	_mouseDrag: function( /* event */ ) {},
1933	_mouseStop: function( /* event */ ) {},
1934	_mouseCapture: function( /* event */ ) { return true; }
1935} );
1936
1937
1938
1939
1940// $.ui.plugin is deprecated. Use $.widget() extensions instead.
1941var plugin = $.ui.plugin = {
1942	add: function( module, option, set ) {
1943		var i,
1944			proto = $.ui[ module ].prototype;
1945		for ( i in set ) {
1946			proto.plugins[ i ] = proto.plugins[ i ] || [];
1947			proto.plugins[ i ].push( [ option, set[ i ] ] );
1948		}
1949	},
1950	call: function( instance, name, args, allowDisconnected ) {
1951		var i,
1952			set = instance.plugins[ name ];
1953
1954		if ( !set ) {
1955			return;
1956		}
1957
1958		if ( !allowDisconnected && ( !instance.element[ 0 ].parentNode ||
1959				instance.element[ 0 ].parentNode.nodeType === 11 ) ) {
1960			return;
1961		}
1962
1963		for ( i = 0; i < set.length; i++ ) {
1964			if ( instance.options[ set[ i ][ 0 ] ] ) {
1965				set[ i ][ 1 ].apply( instance.element, args );
1966			}
1967		}
1968	}
1969};
1970
1971
1972
1973var safeActiveElement = $.ui.safeActiveElement = function( document ) {
1974	var activeElement;
1975
1976	// Support: IE 9 only
1977	// IE9 throws an "Unspecified error" accessing document.activeElement from an <iframe>
1978	try {
1979		activeElement = document.activeElement;
1980	} catch ( error ) {
1981		activeElement = document.body;
1982	}
1983
1984	// Support: IE 9 - 11 only
1985	// IE may return null instead of an element
1986	// Interestingly, this only seems to occur when NOT in an iframe
1987	if ( !activeElement ) {
1988		activeElement = document.body;
1989	}
1990
1991	// Support: IE 11 only
1992	// IE11 returns a seemingly empty object in some cases when accessing
1993	// document.activeElement from an <iframe>
1994	if ( !activeElement.nodeName ) {
1995		activeElement = document.body;
1996	}
1997
1998	return activeElement;
1999};
2000
2001
2002
2003var safeBlur = $.ui.safeBlur = function( element ) {
2004
2005	// Support: IE9 - 10 only
2006	// If the <body> is blurred, IE will switch windows, see #9420
2007	if ( element && element.nodeName.toLowerCase() !== "body" ) {
2008		$( element ).trigger( "blur" );
2009	}
2010};
2011
2012
2013/*!
2014 * jQuery UI Draggable 1.12.1
2015 * http://jqueryui.com
vendor: 4,141 bytes, lines 2016-2184
2016 *
2017 * Copyright jQuery Foundation and other contributors
2018 * Released under the MIT license.
2019 * http://jquery.org/license
2020 */
2021
2022//>>label: Draggable
2023//>>group: Interactions
2024//>>description: Enables dragging functionality for any element.
2025//>>docs: http://api.jqueryui.com/draggable/
2026//>>demos: http://jqueryui.com/draggable/
2027//>>css.structure: ../../themes/base/draggable.css
2028
2029
2030
2031$.widget( "ui.draggable", $.ui.mouse, {
2032	version: "1.12.1",
2033	widgetEventPrefix: "drag",
2034	options: {
2035		addClasses: true,
2036		appendTo: "parent",
2037		axis: false,
2038		connectToSortable: false,
2039		containment: false,
2040		cursor: "auto",
2041		cursorAt: false,
2042		grid: false,
2043		handle: false,
2044		helper: "original",
2045		iframeFix: false,
2046		opacity: false,
2047		refreshPositions: false,
2048		revert: false,
2049		revertDuration: 500,
2050		scope: "default",
2051		scroll: true,
2052		scrollSensitivity: 20,
2053		scrollSpeed: 20,
2054		snap: false,
2055		snapMode: "both",
2056		snapTolerance: 20,
2057		stack: false,
2058		zIndex: false,
2059
2060		// Callbacks
2061		drag: null,
2062		start: null,
2063		stop: null
2064	},
2065	_create: function() {
2066
2067		if ( this.options.helper === "original" ) {
2068			this._setPositionRelative();
2069		}
2070		if ( this.options.addClasses ) {
2071			this._addClass( "ui-draggable" );
2072		}
2073		this._setHandleClassName();
2074
2075		this._mouseInit();
2076	},
2077
2078	_setOption: function( key, value ) {
2079		this._super( key, value );
2080		if ( key === "handle" ) {
2081			this._removeHandleClassName();
2082			this._setHandleClassName();
2083		}
2084	},
2085
2086	_destroy: function() {
2087		if ( ( this.helper || this.element ).is( ".ui-draggable-dragging" ) ) {
2088			this.destroyOnClear = true;
2089			return;
2090		}
2091		this._removeHandleClassName();
2092		this._mouseDestroy();
2093	},
2094
2095	_mouseCapture: function( event ) {
2096		var o = this.options;
2097
2098		// Among others, prevent a drag on a resizable-handle
2099		if ( this.helper || o.disabled ||
2100				$( event.target ).closest( ".ui-resizable-handle" ).length > 0 ) {
2101			return false;
2102		}
2103
2104		//Quit if we're not on a valid handle
2105		this.handle = this._getHandle( event );
2106		if ( !this.handle ) {
2107			return false;
2108		}
2109
2110		this._blurActiveElement( event );
2111
2112		this._blockFrames( o.iframeFix === true ? "iframe" : o.iframeFix );
2113
2114		return true;
2115
2116	},
2117
2118	_blockFrames: function( selector ) {
2119		this.iframeBlocks = this.document.find( selector ).map( function() {
2120			var iframe = $( this );
2121
2122			return $( "<div>" )
2123				.css( "position", "absolute" )
2124				.appendTo( iframe.parent() )
2125				.outerWidth( iframe.outerWidth() )
2126				.outerHeight( iframe.outerHeight() )
2127				.offset( iframe.offset() )[ 0 ];
2128		} );
2129	},
2130
2131	_unblockFrames: function() {
2132		if ( this.iframeBlocks ) {
2133			this.iframeBlocks.remove();
2134			delete this.iframeBlocks;
2135		}
2136	},
2137
2138	_blurActiveElement: function( event ) {
2139		var activeElement = $.ui.safeActiveElement( this.document[ 0 ] ),
2140			target = $( event.target );
2141
2142		// Don't blur if the event occurred on an element that is within
2143		// the currently focused element
2144		// See #10527, #12472
2145		if ( target.closest( activeElement ).length ) {
2146			return;
2147		}
2148
2149		// Blur any element that currently has focus, see #4261
2150		$.ui.safeBlur( activeElement );
2151	},
2152
2153	_mouseStart: function( event ) {
2154
2155		var o = this.options;
2156
2157		//Create and append the visible helper
2158		this.helper = this._createHelper( event );
2159
2160		this._addClass( this.helper, "ui-draggable-dragging" );
2161
2162		//Cache the helper size
2163		this._cacheHelperProportions();
2164
2165		//If ddmanager is used for droppables, set the global draggable
2166		if ( $.ui.ddmanager ) {
2167			$.ui.ddmanager.current = this;
2168		}
2169
2170		/*
2171		 * - Position generation -
2172		 * This block generates everything position related - it's the core of draggables.
2173		 */
2174
2175		//Cache the margins of the original element
2176		this._cacheMargins();
2177
2178		//Store the helper's css position
2179		this.cssPosition = this.helper.css( "position" );
2180		this.scrollParent = this.helper.scrollParent( true );
2181		this.offsetParent = this.helper.offsetParent();
2182		this.hasFixedAncestor = this.helper.parents().filter( function() {
2183				return $( this ).css( "position" ) === "fixed";
2184			} ).length > 0;
vendor: 5,410 bytes, lines 2185-2377
2185
2186		//The element's absolute position on the page minus margins
2187		this.positionAbs = this.element.offset();
2188		this._refreshOffsets( event );
2189
2190		//Generate the original position
2191		this.originalPosition = this.position = this._generatePosition( event, false );
2192		this.originalPageX = event.pageX;
2193		this.originalPageY = event.pageY;
2194
2195		//Adjust the mouse offset relative to the helper if "cursorAt" is supplied
2196		( o.cursorAt && this._adjustOffsetFromHelper( o.cursorAt ) );
2197
2198		//Set a containment if given in the options
2199		this._setContainment();
2200
2201		//Trigger event + callbacks
2202		if ( this._trigger( "start", event ) === false ) {
2203			this._clear();
2204			return false;
2205		}
2206
2207		//Recache the helper size
2208		this._cacheHelperProportions();
2209
2210		//Prepare the droppable offsets
2211		if ( $.ui.ddmanager && !o.dropBehaviour ) {
2212			$.ui.ddmanager.prepareOffsets( this, event );
2213		}
2214
2215		// Execute the drag once - this causes the helper not to be visible before getting its
2216		// correct position
2217		this._mouseDrag( event, true );
2218
2219		// If the ddmanager is used for droppables, inform the manager that dragging has started
2220		// (see #5003)
2221		if ( $.ui.ddmanager ) {
2222			$.ui.ddmanager.dragStart( this, event );
2223		}
2224
2225		return true;
2226	},
2227
2228	_refreshOffsets: function( event ) {
2229		this.offset = {
2230			top: this.positionAbs.top - this.margins.top,
2231			left: this.positionAbs.left - this.margins.left,
2232			scroll: false,
2233			parent: this._getParentOffset(),
2234			relative: this._getRelativeOffset()
2235		};
2236
2237		this.offset.click = {
2238			left: event.pageX - this.offset.left,
2239			top: event.pageY - this.offset.top
2240		};
2241	},
2242
2243	_mouseDrag: function( event, noPropagation ) {
2244
2245		// reset any necessary cached properties (see #5009)
2246		if ( this.hasFixedAncestor ) {
2247			this.offset.parent = this._getParentOffset();
2248		}
2249
2250		//Compute the helpers position
2251		this.position = this._generatePosition( event, true );
2252		this.positionAbs = this._convertPositionTo( "absolute" );
2253
2254		//Call plugins and callbacks and use the resulting position if something is returned
2255		if ( !noPropagation ) {
2256			var ui = this._uiHash();
2257			if ( this._trigger( "drag", event, ui ) === false ) {
2258				this._mouseUp( new $.Event( "mouseup", event ) );
2259				return false;
2260			}
2261			this.position = ui.position;
2262		}
2263
2264		this.helper[ 0 ].style.left = this.position.left + "px";
2265		this.helper[ 0 ].style.top = this.position.top + "px";
2266
2267		if ( $.ui.ddmanager ) {
2268			$.ui.ddmanager.drag( this, event );
2269		}
2270
2271		return false;
2272	},
2273
2274	_mouseStop: function( event ) {
2275
2276		//If we are using droppables, inform the manager about the drop
2277		var that = this,
2278			dropped = false;
2279		if ( $.ui.ddmanager && !this.options.dropBehaviour ) {
2280			dropped = $.ui.ddmanager.drop( this, event );
2281		}
2282
2283		//if a drop comes from outside (a sortable)
2284		if ( this.dropped ) {
2285			dropped = this.dropped;
2286			this.dropped = false;
2287		}
2288
2289		if ( ( this.options.revert === "invalid" && !dropped ) ||
2290				( this.options.revert === "valid" && dropped ) ||
2291				this.options.revert === true || ( $.isFunction( this.options.revert ) &&
2292				this.options.revert.call( this.element, dropped ) )
2293		) {
2294			$( this.helper ).animate(
2295				this.originalPosition,
2296				parseInt( this.options.revertDuration, 10 ),
2297				function() {
2298					if ( that._trigger( "stop", event ) !== false ) {
2299						that._clear();
2300					}
2301				}
2302			);
2303		} else {
2304			if ( this._trigger( "stop", event ) !== false ) {
2305				this._clear();
2306			}
2307		}
2308
2309		return false;
2310	},
2311
2312	_mouseUp: function( event ) {
2313		this._unblockFrames();
2314
2315		// If the ddmanager is used for droppables, inform the manager that dragging has stopped
2316		// (see #5003)
2317		if ( $.ui.ddmanager ) {
2318			$.ui.ddmanager.dragStop( this, event );
2319		}
2320
2321		// Only need to focus if the event occurred on the draggable itself, see #10527
2322		if ( this.handleElement.is( event.target ) ) {
2323
2324			// The interaction is over; whether or not the click resulted in a drag,
2325			// focus the element
2326			this.element.trigger( "focus" );
2327		}
2328
2329		return $.ui.mouse.prototype._mouseUp.call( this, event );
2330	},
2331
2332	cancel: function() {
2333
2334		if ( this.helper.is( ".ui-draggable-dragging" ) ) {
2335			this._mouseUp( new $.Event( "mouseup", { target: this.element[ 0 ] } ) );
2336		} else {
2337			this._clear();
2338		}
2339
2340		return this;
2341
2342	},
2343
2344	_getHandle: function( event ) {
2345		return this.options.handle ?
2346			!!$( event.target ).closest( this.element.find( this.options.handle ) ).length :
2347			true;
2348	},
2349
2350	_setHandleClassName: function() {
2351		this.handleElement = this.options.handle ?
2352			this.element.find( this.options.handle ) : this.element;
2353		this._addClass( this.handleElement, "ui-draggable-handle" );
2354	},
2355
2356	_removeHandleClassName: function() {
2357		this._removeClass( this.handleElement, "ui-draggable-handle" );
2358	},
2359
2360	_createHelper: function( event ) {
2361
2362		var o = this.options,
2363			helperIsFunction = $.isFunction( o.helper ),
2364			helper = helperIsFunction ?
2365				$( o.helper.apply( this.element[ 0 ], [ event ] ) ) :
2366				( o.helper === "clone" ?
2367					this.element.clone().removeAttr( "id" ) :
2368					this.element );
2369
2370		if ( !helper.parents( "body" ).length ) {
2371			helper.appendTo( ( o.appendTo === "parent" ?
2372				this.element[ 0 ].parentNode :
2373				o.appendTo ) );
2374		}
2375
2376		// Http://bugs.jqueryui.com/ticket/9446
2377		// a helper function can return the original element
vendor: 15,341 bytes, lines 2378-2870
2378		// which wouldn't have been set to relative in _create
2379		if ( helperIsFunction && helper[ 0 ] === this.element[ 0 ] ) {
2380			this._setPositionRelative();
2381		}
2382
2383		if ( helper[ 0 ] !== this.element[ 0 ] &&
2384				!( /(fixed|absolute)/ ).test( helper.css( "position" ) ) ) {
2385			helper.css( "position", "absolute" );
2386		}
2387
2388		return helper;
2389
2390	},
2391
2392	_setPositionRelative: function() {
2393		if ( !( /^(?:r|a|f)/ ).test( this.element.css( "position" ) ) ) {
2394			this.element[ 0 ].style.position = "relative";
2395		}
2396	},
2397
2398	_adjustOffsetFromHelper: function( obj ) {
2399		if ( typeof obj === "string" ) {
2400			obj = obj.split( " " );
2401		}
2402		if ( $.isArray( obj ) ) {
2403			obj = { left: +obj[ 0 ], top: +obj[ 1 ] || 0 };
2404		}
2405		if ( "left" in obj ) {
2406			this.offset.click.left = obj.left + this.margins.left;
2407		}
2408		if ( "right" in obj ) {
2409			this.offset.click.left = this.helperProportions.width - obj.right + this.margins.left;
2410		}
2411		if ( "top" in obj ) {
2412			this.offset.click.top = obj.top + this.margins.top;
2413		}
2414		if ( "bottom" in obj ) {
2415			this.offset.click.top = this.helperProportions.height - obj.bottom + this.margins.top;
2416		}
2417	},
2418
2419	_isRootNode: function( element ) {
2420		return ( /(html|body)/i ).test( element.tagName ) || element === this.document[ 0 ];
2421	},
2422
2423	_getParentOffset: function() {
2424
2425		//Get the offsetParent and cache its position
2426		var po = this.offsetParent.offset(),
2427			document = this.document[ 0 ];
2428
2429		// This is a special case where we need to modify a offset calculated on start, since the
2430		// following happened:
2431		// 1. The position of the helper is absolute, so it's position is calculated based on the
2432		// next positioned parent
2433		// 2. The actual offset parent is a child of the scroll parent, and the scroll parent isn't
2434		// the document, which means that the scroll is included in the initial calculation of the
2435		// offset of the parent, and never recalculated upon drag
2436		if ( this.cssPosition === "absolute" && this.scrollParent[ 0 ] !== document &&
2437				$.contains( this.scrollParent[ 0 ], this.offsetParent[ 0 ] ) ) {
2438			po.left += this.scrollParent.scrollLeft();
2439			po.top += this.scrollParent.scrollTop();
2440		}
2441
2442		if ( this._isRootNode( this.offsetParent[ 0 ] ) ) {
2443			po = { top: 0, left: 0 };
2444		}
2445
2446		return {
2447			top: po.top + ( parseInt( this.offsetParent.css( "borderTopWidth" ), 10 ) || 0 ),
2448			left: po.left + ( parseInt( this.offsetParent.css( "borderLeftWidth" ), 10 ) || 0 )
2449		};
2450
2451	},
2452
2453	_getRelativeOffset: function() {
2454		if ( this.cssPosition !== "relative" ) {
2455			return { top: 0, left: 0 };
2456		}
2457
2458		var p = this.element.position(),
2459			scrollIsRootNode = this._isRootNode( this.scrollParent[ 0 ] );
2460
2461		return {
2462			top: p.top - ( parseInt( this.helper.css( "top" ), 10 ) || 0 ) +
2463				( !scrollIsRootNode ? this.scrollParent.scrollTop() : 0 ),
2464			left: p.left - ( parseInt( this.helper.css( "left" ), 10 ) || 0 ) +
2465				( !scrollIsRootNode ? this.scrollParent.scrollLeft() : 0 )
2466		};
2467
2468	},
2469
2470	_cacheMargins: function() {
2471		this.margins = {
2472			left: ( parseInt( this.element.css( "marginLeft" ), 10 ) || 0 ),
2473			top: ( parseInt( this.element.css( "marginTop" ), 10 ) || 0 ),
2474			right: ( parseInt( this.element.css( "marginRight" ), 10 ) || 0 ),
2475			bottom: ( parseInt( this.element.css( "marginBottom" ), 10 ) || 0 )
2476		};
2477	},
2478
2479	_cacheHelperProportions: function() {
2480		this.helperProportions = {
2481			width: this.helper.outerWidth(),
2482			height: this.helper.outerHeight()
2483		};
2484	},
2485
2486	_setContainment: function() {
2487
2488		var isUserScrollable, c, ce,
2489			o = this.options,
2490			document = this.document[ 0 ];
2491
2492		this.relativeContainer = null;
2493
2494		if ( !o.containment ) {
2495			this.containment = null;
2496			return;
2497		}
2498
2499		if ( o.containment === "window" ) {
2500			this.containment = [
2501				$( window ).scrollLeft() - this.offset.relative.left - this.offset.parent.left,
2502				$( window ).scrollTop() - this.offset.relative.top - this.offset.parent.top,
2503				$( window ).scrollLeft() + $( window ).width() -
2504					this.helperProportions.width - this.margins.left,
2505				$( window ).scrollTop() +
2506					( $( window ).height() || document.body.parentNode.scrollHeight ) -
2507					this.helperProportions.height - this.margins.top
2508			];
2509			return;
2510		}
2511
2512		if ( o.containment === "document" ) {
2513			this.containment = [
2514				0,
2515				0,
2516				$( document ).width() - this.helperProportions.width - this.margins.left,
2517				( $( document ).height() || document.body.parentNode.scrollHeight ) -
2518					this.helperProportions.height - this.margins.top
2519			];
2520			return;
2521		}
2522
2523		if ( o.containment.constructor === Array ) {
2524			this.containment = o.containment;
2525			return;
2526		}
2527
2528		if ( o.containment === "parent" ) {
2529			o.containment = this.helper[ 0 ].parentNode;
2530		}
2531
2532		c = $( o.containment );
2533		ce = c[ 0 ];
2534
2535		if ( !ce ) {
2536			return;
2537		}
2538
2539		isUserScrollable = /(scroll|auto)/.test( c.css( "overflow" ) );
2540
2541		this.containment = [
2542			( parseInt( c.css( "borderLeftWidth" ), 10 ) || 0 ) +
2543				( parseInt( c.css( "paddingLeft" ), 10 ) || 0 ),
2544			( parseInt( c.css( "borderTopWidth" ), 10 ) || 0 ) +
2545				( parseInt( c.css( "paddingTop" ), 10 ) || 0 ),
2546			( isUserScrollable ? Math.max( ce.scrollWidth, ce.offsetWidth ) : ce.offsetWidth ) -
2547				( parseInt( c.css( "borderRightWidth" ), 10 ) || 0 ) -
2548				( parseInt( c.css( "paddingRight" ), 10 ) || 0 ) -
2549				this.helperProportions.width -
2550				this.margins.left -
2551				this.margins.right,
2552			( isUserScrollable ? Math.max( ce.scrollHeight, ce.offsetHeight ) : ce.offsetHeight ) -
2553				( parseInt( c.css( "borderBottomWidth" ), 10 ) || 0 ) -
2554				( parseInt( c.css( "paddingBottom" ), 10 ) || 0 ) -
2555				this.helperProportions.height -
2556				this.margins.top -
2557				this.margins.bottom
2558		];
2559		this.relativeContainer = c;
2560	},
2561
2562	_convertPositionTo: function( d, pos ) {
2563
2564		if ( !pos ) {
2565			pos = this.position;
2566		}
2567
2568		var mod = d === "absolute" ? 1 : -1,
2569			scrollIsRootNode = this._isRootNode( this.scrollParent[ 0 ] );
2570
2571		return {
2572			top: (
2573
2574				// The absolute mouse position
2575				pos.top	+
2576
2577				// Only for relative positioned nodes: Relative offset from element to offset parent
2578				this.offset.relative.top * mod +
2579
2580				// The offsetParent's offset without borders (offset + border)
2581				this.offset.parent.top * mod -
2582				( ( this.cssPosition === "fixed" ?
2583					-this.offset.scroll.top :
2584					( scrollIsRootNode ? 0 : this.offset.scroll.top ) ) * mod )
2585			),
2586			left: (
2587
2588				// The absolute mouse position
2589				pos.left +
2590
2591				// Only for relative positioned nodes: Relative offset from element to offset parent
2592				this.offset.relative.left * mod +
2593
2594				// The offsetParent's offset without borders (offset + border)
2595				this.offset.parent.left * mod	-
2596				( ( this.cssPosition === "fixed" ?
2597					-this.offset.scroll.left :
2598					( scrollIsRootNode ? 0 : this.offset.scroll.left ) ) * mod )
2599			)
2600		};
2601
2602	},
2603
2604	_generatePosition: function( event, constrainPosition ) {
2605
2606		var containment, co, top, left,
2607			o = this.options,
2608			scrollIsRootNode = this._isRootNode( this.scrollParent[ 0 ] ),
2609			pageX = event.pageX,
2610			pageY = event.pageY;
2611
2612		// Cache the scroll
2613		if ( !scrollIsRootNode || !this.offset.scroll ) {
2614			this.offset.scroll = {
2615				top: this.scrollParent.scrollTop(),
2616				left: this.scrollParent.scrollLeft()
2617			};
2618		}
2619
2620		/*
2621		 * - Position constraining -
2622		 * Constrain the position to a mix of grid, containment.
2623		 */
2624
2625		// If we are not dragging yet, we won't check for options
2626		if ( constrainPosition ) {
2627			if ( this.containment ) {
2628				if ( this.relativeContainer ) {
2629					co = this.relativeContainer.offset();
2630					containment = [
2631						this.containment[ 0 ] + co.left,
2632						this.containment[ 1 ] + co.top,
2633						this.containment[ 2 ] + co.left,
2634						this.containment[ 3 ] + co.top
2635					];
2636				} else {
2637					containment = this.containment;
2638				}
2639
2640				if ( event.pageX - this.offset.click.left < containment[ 0 ] ) {
2641					pageX = containment[ 0 ] + this.offset.click.left;
2642				}
2643				if ( event.pageY - this.offset.click.top < containment[ 1 ] ) {
2644					pageY = containment[ 1 ] + this.offset.click.top;
2645				}
2646				if ( event.pageX - this.offset.click.left > containment[ 2 ] ) {
2647					pageX = containment[ 2 ] + this.offset.click.left;
2648				}
2649				if ( event.pageY - this.offset.click.top > containment[ 3 ] ) {
2650					pageY = containment[ 3 ] + this.offset.click.top;
2651				}
2652			}
2653
2654			if ( o.grid ) {
2655
2656				//Check for grid elements set to 0 to prevent divide by 0 error causing invalid
2657				// argument errors in IE (see ticket #6950)
2658				top = o.grid[ 1 ] ? this.originalPageY + Math.round( ( pageY -
2659					this.originalPageY ) / o.grid[ 1 ] ) * o.grid[ 1 ] : this.originalPageY;
2660				pageY = containment ? ( ( top - this.offset.click.top >= containment[ 1 ] ||
2661					top - this.offset.click.top > containment[ 3 ] ) ?
2662						top :
2663						( ( top - this.offset.click.top >= containment[ 1 ] ) ?
2664							top - o.grid[ 1 ] : top + o.grid[ 1 ] ) ) : top;
2665
2666				left = o.grid[ 0 ] ? this.originalPageX +
2667					Math.round( ( pageX - this.originalPageX ) / o.grid[ 0 ] ) * o.grid[ 0 ] :
2668					this.originalPageX;
2669				pageX = containment ? ( ( left - this.offset.click.left >= containment[ 0 ] ||
2670					left - this.offset.click.left > containment[ 2 ] ) ?
2671						left :
2672						( ( left - this.offset.click.left >= containment[ 0 ] ) ?
2673							left - o.grid[ 0 ] : left + o.grid[ 0 ] ) ) : left;
2674			}
2675
2676			if ( o.axis === "y" ) {
2677				pageX = this.originalPageX;
2678			}
2679
2680			if ( o.axis === "x" ) {
2681				pageY = this.originalPageY;
2682			}
2683		}
2684
2685		return {
2686			top: (
2687
2688				// The absolute mouse position
2689				pageY -
2690
2691				// Click offset (relative to the element)
2692				this.offset.click.top -
2693
2694				// Only for relative positioned nodes: Relative offset from element to offset parent
2695				this.offset.relative.top -
2696
2697				// The offsetParent's offset without borders (offset + border)
2698				this.offset.parent.top +
2699				( this.cssPosition === "fixed" ?
2700					-this.offset.scroll.top :
2701					( scrollIsRootNode ? 0 : this.offset.scroll.top ) )
2702			),
2703			left: (
2704
2705				// The absolute mouse position
2706				pageX -
2707
2708				// Click offset (relative to the element)
2709				this.offset.click.left -
2710
2711				// Only for relative positioned nodes: Relative offset from element to offset parent
2712				this.offset.relative.left -
2713
2714				// The offsetParent's offset without borders (offset + border)
2715				this.offset.parent.left +
2716				( this.cssPosition === "fixed" ?
2717					-this.offset.scroll.left :
2718					( scrollIsRootNode ? 0 : this.offset.scroll.left ) )
2719			)
2720		};
2721
2722	},
2723
2724	_clear: function() {
2725		this._removeClass( this.helper, "ui-draggable-dragging" );
2726		if ( this.helper[ 0 ] !== this.element[ 0 ] && !this.cancelHelperRemoval ) {
2727			this.helper.remove();
2728		}
2729		this.helper = null;
2730		this.cancelHelperRemoval = false;
2731		if ( this.destroyOnClear ) {
2732			this.destroy();
2733		}
2734	},
2735
2736	// From now on bulk stuff - mainly helpers
2737
2738	_trigger: function( type, event, ui ) {
2739		ui = ui || this._uiHash();
2740		$.ui.plugin.call( this, type, [ event, ui, this ], true );
2741
2742		// Absolute position and offset (see #6884 ) have to be recalculated after plugins
2743		if ( /^(drag|start|stop)/.test( type ) ) {
2744			this.positionAbs = this._convertPositionTo( "absolute" );
2745			ui.offset = this.positionAbs;
2746		}
2747		return $.Widget.prototype._trigger.call( this, type, event, ui );
2748	},
2749
2750	plugins: {},
2751
2752	_uiHash: function() {
2753		return {
2754			helper: this.helper,
2755			position: this.position,
2756			originalPosition: this.originalPosition,
2757			offset: this.positionAbs
2758		};
2759	}
2760
2761} );
2762
2763$.ui.plugin.add( "draggable", "connectToSortable", {
2764	start: function( event, ui, draggable ) {
2765		var uiSortable = $.extend( {}, ui, {
2766			item: draggable.element
2767		} );
2768
2769		draggable.sortables = [];
2770		$( draggable.options.connectToSortable ).each( function() {
2771			var sortable = $( this ).sortable( "instance" );
2772
2773			if ( sortable && !sortable.options.disabled ) {
2774				draggable.sortables.push( sortable );
2775
2776				// RefreshPositions is called at drag start to refresh the containerCache
2777				// which is used in drag. This ensures it's initialized and synchronized
2778				// with any changes that might have happened on the page since initialization.
2779				sortable.refreshPositions();
2780				sortable._trigger( "activate", event, uiSortable );
2781			}
2782		} );
2783	},
2784	stop: function( event, ui, draggable ) {
2785		var uiSortable = $.extend( {}, ui, {
2786			item: draggable.element
2787		} );
2788
2789		draggable.cancelHelperRemoval = false;
2790
2791		$.each( draggable.sortables, function() {
2792			var sortable = this;
2793
2794			if ( sortable.isOver ) {
2795				sortable.isOver = 0;
2796
2797				// Allow this sortable to handle removing the helper
2798				draggable.cancelHelperRemoval = true;
2799				sortable.cancelHelperRemoval = false;
2800
2801				// Use _storedCSS To restore properties in the sortable,
2802				// as this also handles revert (#9675) since the draggable
2803				// may have modified them in unexpected ways (#8809)
2804				sortable._storedCSS = {
2805					position: sortable.placeholder.css( "position" ),
2806					top: sortable.placeholder.css( "top" ),
2807					left: sortable.placeholder.css( "left" )
2808				};
2809
2810				sortable._mouseStop( event );
2811
2812				// Once drag has ended, the sortable should return to using
2813				// its original helper, not the shared helper from draggable
2814				sortable.options.helper = sortable.options._helper;
2815			} else {
2816
2817				// Prevent this Sortable from removing the helper.
2818				// However, don't set the draggable to remove the helper
2819				// either as another connected Sortable may yet handle the removal.
2820				sortable.cancelHelperRemoval = true;
2821
2822				sortable._trigger( "deactivate", event, uiSortable );
2823			}
2824		} );
2825	},
2826	drag: function( event, ui, draggable ) {
2827		$.each( draggable.sortables, function() {
2828			var innermostIntersecting = false,
2829				sortable = this;
2830
2831			// Copy over variables that sortable's _intersectsWith uses
2832			sortable.positionAbs = draggable.positionAbs;
2833			sortable.helperProportions = draggable.helperProportions;
2834			sortable.offset.click = draggable.offset.click;
2835
2836			if ( sortable._intersectsWith( sortable.containerCache ) ) {
2837				innermostIntersecting = true;
2838
2839				$.each( draggable.sortables, function() {
2840
2841					// Copy over variables that sortable's _intersectsWith uses
2842					this.positionAbs = draggable.positionAbs;
2843					this.helperProportions = draggable.helperProportions;
2844					this.offset.click = draggable.offset.click;
2845
2846					if ( this !== sortable &&
2847							this._intersectsWith( this.containerCache ) &&
2848							$.contains( sortable.element[ 0 ], this.element[ 0 ] ) ) {
2849						innermostIntersecting = false;
2850					}
2851
2852					return innermostIntersecting;
2853				} );
2854			}
2855
2856			if ( innermostIntersecting ) {
2857
2858				// If it intersects, we use a little isOver variable and set it once,
2859				// so that the move-in stuff gets fired only once.
2860				if ( !sortable.isOver ) {
2861					sortable.isOver = 1;
2862
2863					// Store draggable's parent in case we need to reappend to it later.
2864					draggable._parent = ui.helper.parent();
2865
2866					sortable.currentItem = ui.helper
2867						.appendTo( sortable.element )
2868						.data( "ui-sortable-item", true );
2869
2870					// Store helper option to later restore it
vendor: 11,429 bytes, lines 2871-3245
2871					sortable.options._helper = sortable.options.helper;
2872
2873					sortable.options.helper = function() {
2874						return ui.helper[ 0 ];
2875					};
2876
2877					// Fire the start events of the sortable with our passed browser event,
2878					// and our own helper (so it doesn't create a new one)
2879					event.target = sortable.currentItem[ 0 ];
2880					sortable._mouseCapture( event, true );
2881					sortable._mouseStart( event, true, true );
2882
2883					// Because the browser event is way off the new appended portlet,
2884					// modify necessary variables to reflect the changes
2885					sortable.offset.click.top = draggable.offset.click.top;
2886					sortable.offset.click.left = draggable.offset.click.left;
2887					sortable.offset.parent.left -= draggable.offset.parent.left -
2888						sortable.offset.parent.left;
2889					sortable.offset.parent.top -= draggable.offset.parent.top -
2890						sortable.offset.parent.top;
2891
2892					draggable._trigger( "toSortable", event );
2893
2894					// Inform draggable that the helper is in a valid drop zone,
2895					// used solely in the revert option to handle "valid/invalid".
2896					draggable.dropped = sortable.element;
2897
2898					// Need to refreshPositions of all sortables in the case that
2899					// adding to one sortable changes the location of the other sortables (#9675)
2900					$.each( draggable.sortables, function() {
2901						this.refreshPositions();
2902					} );
2903
2904					// Hack so receive/update callbacks work (mostly)
2905					draggable.currentItem = draggable.element;
2906					sortable.fromOutside = draggable;
2907				}
2908
2909				if ( sortable.currentItem ) {
2910					sortable._mouseDrag( event );
2911
2912					// Copy the sortable's position because the draggable's can potentially reflect
2913					// a relative position, while sortable is always absolute, which the dragged
2914					// element has now become. (#8809)
2915					ui.position = sortable.position;
2916				}
2917			} else {
2918
2919				// If it doesn't intersect with the sortable, and it intersected before,
2920				// we fake the drag stop of the sortable, but make sure it doesn't remove
2921				// the helper by using cancelHelperRemoval.
2922				if ( sortable.isOver ) {
2923
2924					sortable.isOver = 0;
2925					sortable.cancelHelperRemoval = true;
2926
2927					// Calling sortable's mouseStop would trigger a revert,
2928					// so revert must be temporarily false until after mouseStop is called.
2929					sortable.options._revert = sortable.options.revert;
2930					sortable.options.revert = false;
2931
2932					sortable._trigger( "out", event, sortable._uiHash( sortable ) );
2933					sortable._mouseStop( event, true );
2934
2935					// Restore sortable behaviors that were modfied
2936					// when the draggable entered the sortable area (#9481)
2937					sortable.options.revert = sortable.options._revert;
2938					sortable.options.helper = sortable.options._helper;
2939
2940					if ( sortable.placeholder ) {
2941						sortable.placeholder.remove();
2942					}
2943
2944					// Restore and recalculate the draggable's offset considering the sortable
2945					// may have modified them in unexpected ways. (#8809, #10669)
2946					ui.helper.appendTo( draggable._parent );
2947					draggable._refreshOffsets( event );
2948					ui.position = draggable._generatePosition( event, true );
2949
2950					draggable._trigger( "fromSortable", event );
2951
2952					// Inform draggable that the helper is no longer in a valid drop zone
2953					draggable.dropped = false;
2954
2955					// Need to refreshPositions of all sortables just in case removing
2956					// from one sortable changes the location of other sortables (#9675)
2957					$.each( draggable.sortables, function() {
2958						this.refreshPositions();
2959					} );
2960				}
2961			}
2962		} );
2963	}
2964} );
2965
2966$.ui.plugin.add( "draggable", "cursor", {
2967	start: function( event, ui, instance ) {
2968		var t = $( "body" ),
2969			o = instance.options;
2970
2971		if ( t.css( "cursor" ) ) {
2972			o._cursor = t.css( "cursor" );
2973		}
2974		t.css( "cursor", o.cursor );
2975	},
2976	stop: function( event, ui, instance ) {
2977		var o = instance.options;
2978		if ( o._cursor ) {
2979			$( "body" ).css( "cursor", o._cursor );
2980		}
2981	}
2982} );
2983
2984$.ui.plugin.add( "draggable", "opacity", {
2985	start: function( event, ui, instance ) {
2986		var t = $( ui.helper ),
2987			o = instance.options;
2988		if ( t.css( "opacity" ) ) {
2989			o._opacity = t.css( "opacity" );
2990		}
2991		t.css( "opacity", o.opacity );
2992	},
2993	stop: function( event, ui, instance ) {
2994		var o = instance.options;
2995		if ( o._opacity ) {
2996			$( ui.helper ).css( "opacity", o._opacity );
2997		}
2998	}
2999} );
3000
3001$.ui.plugin.add( "draggable", "scroll", {
3002	start: function( event, ui, i ) {
3003		if ( !i.scrollParentNotHidden ) {
3004			i.scrollParentNotHidden = i.helper.scrollParent( false );
3005		}
3006
3007		if ( i.scrollParentNotHidden[ 0 ] !== i.document[ 0 ] &&
3008				i.scrollParentNotHidden[ 0 ].tagName !== "HTML" ) {
3009			i.overflowOffset = i.scrollParentNotHidden.offset();
3010		}
3011	},
3012	drag: function( event, ui, i  ) {
3013
3014		var o = i.options,
3015			scrolled = false,
3016			scrollParent = i.scrollParentNotHidden[ 0 ],
3017			document = i.document[ 0 ];
3018
3019		if ( scrollParent !== document && scrollParent.tagName !== "HTML" ) {
3020			if ( !o.axis || o.axis !== "x" ) {
3021				if ( ( i.overflowOffset.top + scrollParent.offsetHeight ) - event.pageY <
3022						o.scrollSensitivity ) {
3023					scrollParent.scrollTop = scrolled = scrollParent.scrollTop + o.scrollSpeed;
3024				} else if ( event.pageY - i.overflowOffset.top < o.scrollSensitivity ) {
3025					scrollParent.scrollTop = scrolled = scrollParent.scrollTop - o.scrollSpeed;
3026				}
3027			}
3028
3029			if ( !o.axis || o.axis !== "y" ) {
3030				if ( ( i.overflowOffset.left + scrollParent.offsetWidth ) - event.pageX <
3031						o.scrollSensitivity ) {
3032					scrollParent.scrollLeft = scrolled = scrollParent.scrollLeft + o.scrollSpeed;
3033				} else if ( event.pageX - i.overflowOffset.left < o.scrollSensitivity ) {
3034					scrollParent.scrollLeft = scrolled = scrollParent.scrollLeft - o.scrollSpeed;
3035				}
3036			}
3037
3038		} else {
3039
3040			if ( !o.axis || o.axis !== "x" ) {
3041				if ( event.pageY - $( document ).scrollTop() < o.scrollSensitivity ) {
3042					scrolled = $( document ).scrollTop( $( document ).scrollTop() - o.scrollSpeed );
3043				} else if ( $( window ).height() - ( event.pageY - $( document ).scrollTop() ) <
3044						o.scrollSensitivity ) {
3045					scrolled = $( document ).scrollTop( $( document ).scrollTop() + o.scrollSpeed );
3046				}
3047			}
3048
3049			if ( !o.axis || o.axis !== "y" ) {
3050				if ( event.pageX - $( document ).scrollLeft() < o.scrollSensitivity ) {
3051					scrolled = $( document ).scrollLeft(
3052						$( document ).scrollLeft() - o.scrollSpeed
3053					);
3054				} else if ( $( window ).width() - ( event.pageX - $( document ).scrollLeft() ) <
3055						o.scrollSensitivity ) {
3056					scrolled = $( document ).scrollLeft(
3057						$( document ).scrollLeft() + o.scrollSpeed
3058					);
3059				}
3060			}
3061
3062		}
3063
3064		if ( scrolled !== false && $.ui.ddmanager && !o.dropBehaviour ) {
3065			$.ui.ddmanager.prepareOffsets( i, event );
3066		}
3067
3068	}
3069} );
3070
3071$.ui.plugin.add( "draggable", "snap", {
3072	start: function( event, ui, i ) {
3073
3074		var o = i.options;
3075
3076		i.snapElements = [];
3077
3078		$( o.snap.constructor !== String ? ( o.snap.items || ":data(ui-draggable)" ) : o.snap )
3079			.each( function() {
3080				var $t = $( this ),
3081					$o = $t.offset();
3082				if ( this !== i.element[ 0 ] ) {
3083					i.snapElements.push( {
3084						item: this,
3085						width: $t.outerWidth(), height: $t.outerHeight(),
3086						top: $o.top, left: $o.left
3087					} );
3088				}
3089			} );
3090
3091	},
3092	drag: function( event, ui, inst ) {
3093
3094		var ts, bs, ls, rs, l, r, t, b, i, first,
3095			o = inst.options,
3096			d = o.snapTolerance,
3097			x1 = ui.offset.left, x2 = x1 + inst.helperProportions.width,
3098			y1 = ui.offset.top, y2 = y1 + inst.helperProportions.height;
3099
3100		for ( i = inst.snapElements.length - 1; i >= 0; i-- ) {
3101
3102			l = inst.snapElements[ i ].left - inst.margins.left;
3103			r = l + inst.snapElements[ i ].width;
3104			t = inst.snapElements[ i ].top - inst.margins.top;
3105			b = t + inst.snapElements[ i ].height;
3106
3107			if ( x2 < l - d || x1 > r + d || y2 < t - d || y1 > b + d ||
3108					!$.contains( inst.snapElements[ i ].item.ownerDocument,
3109					inst.snapElements[ i ].item ) ) {
3110				if ( inst.snapElements[ i ].snapping ) {
3111					( inst.options.snap.release &&
3112						inst.options.snap.release.call(
3113							inst.element,
3114							event,
3115							$.extend( inst._uiHash(), { snapItem: inst.snapElements[ i ].item } )
3116						) );
3117				}
3118				inst.snapElements[ i ].snapping = false;
3119				continue;
3120			}
3121
3122			if ( o.snapMode !== "inner" ) {
3123				ts = Math.abs( t - y2 ) <= d;
3124				bs = Math.abs( b - y1 ) <= d;
3125				ls = Math.abs( l - x2 ) <= d;
3126				rs = Math.abs( r - x1 ) <= d;
3127				if ( ts ) {
3128					ui.position.top = inst._convertPositionTo( "relative", {
3129						top: t - inst.helperProportions.height,
3130						left: 0
3131					} ).top;
3132				}
3133				if ( bs ) {
3134					ui.position.top = inst._convertPositionTo( "relative", {
3135						top: b,
3136						left: 0
3137					} ).top;
3138				}
3139				if ( ls ) {
3140					ui.position.left = inst._convertPositionTo( "relative", {
3141						top: 0,
3142						left: l - inst.helperProportions.width
3143					} ).left;
3144				}
3145				if ( rs ) {
3146					ui.position.left = inst._convertPositionTo( "relative", {
3147						top: 0,
3148						left: r
3149					} ).left;
3150				}
3151			}
3152
3153			first = ( ts || bs || ls || rs );
3154
3155			if ( o.snapMode !== "outer" ) {
3156				ts = Math.abs( t - y1 ) <= d;
3157				bs = Math.abs( b - y2 ) <= d;
3158				ls = Math.abs( l - x1 ) <= d;
3159				rs = Math.abs( r - x2 ) <= d;
3160				if ( ts ) {
3161					ui.position.top = inst._convertPositionTo( "relative", {
3162						top: t,
3163						left: 0
3164					} ).top;
3165				}
3166				if ( bs ) {
3167					ui.position.top = inst._convertPositionTo( "relative", {
3168						top: b - inst.helperProportions.height,
3169						left: 0
3170					} ).top;
3171				}
3172				if ( ls ) {
3173					ui.position.left = inst._convertPositionTo( "relative", {
3174						top: 0,
3175						left: l
3176					} ).left;
3177				}
3178				if ( rs ) {
3179					ui.position.left = inst._convertPositionTo( "relative", {
3180						top: 0,
3181						left: r - inst.helperProportions.width
3182					} ).left;
3183				}
3184			}
3185
3186			if ( !inst.snapElements[ i ].snapping && ( ts || bs || ls || rs || first ) ) {
3187				( inst.options.snap.snap &&
3188					inst.options.snap.snap.call(
3189						inst.element,
3190						event,
3191						$.extend( inst._uiHash(), {
3192							snapItem: inst.snapElements[ i ].item
3193						} ) ) );
3194			}
3195			inst.snapElements[ i ].snapping = ( ts || bs || ls || rs || first );
3196
3197		}
3198
3199	}
3200} );
3201
3202$.ui.plugin.add( "draggable", "stack", {
3203	start: function( event, ui, instance ) {
3204		var min,
3205			o = instance.options,
3206			group = $.makeArray( $( o.stack ) ).sort( function( a, b ) {
3207				return ( parseInt( $( a ).css( "zIndex" ), 10 ) || 0 ) -
3208					( parseInt( $( b ).css( "zIndex" ), 10 ) || 0 );
3209			} );
3210
3211		if ( !group.length ) { return; }
3212
3213		min = parseInt( $( group[ 0 ] ).css( "zIndex" ), 10 ) || 0;
3214		$( group ).each( function( i ) {
3215			$( this ).css( "zIndex", min + i );
3216		} );
3217		this.css( "zIndex", ( min + group.length ) );
3218	}
3219} );
3220
3221$.ui.plugin.add( "draggable", "zIndex", {
3222	start: function( event, ui, instance ) {
3223		var t = $( ui.helper ),
3224			o = instance.options;
3225
3226		if ( t.css( "zIndex" ) ) {
3227			o._zIndex = t.css( "zIndex" );
3228		}
3229		t.css( "zIndex", o.zIndex );
3230	},
3231	stop: function( event, ui, instance ) {
3232		var o = instance.options;
3233
3234		if ( o._zIndex ) {
3235			$( ui.helper ).css( "zIndex", o._zIndex );
3236		}
3237	}
3238} );
3239
3240var widgetsDraggable = $.ui.draggable;
3241
3242
3243/*!
3244 * jQuery UI Droppable 1.12.1
3245 * http://jqueryui.com
vendor: 19,960 bytes, lines 3246-4005
3246 *
3247 * Copyright jQuery Foundation and other contributors
3248 * Released under the MIT license.
3249 * http://jquery.org/license
3250 */
3251
3252//>>label: Droppable
3253//>>group: Interactions
3254//>>description: Enables drop targets for draggable elements.
3255//>>docs: http://api.jqueryui.com/droppable/
3256//>>demos: http://jqueryui.com/droppable/
3257
3258
3259
3260$.widget( "ui.droppable", {
3261	version: "1.12.1",
3262	widgetEventPrefix: "drop",
3263	options: {
3264		accept: "*",
3265		addClasses: true,
3266		greedy: false,
3267		scope: "default",
3268		tolerance: "intersect",
3269
3270		// Callbacks
3271		activate: null,
3272		deactivate: null,
3273		drop: null,
3274		out: null,
3275		over: null
3276	},
3277	_create: function() {
3278
3279		var proportions,
3280			o = this.options,
3281			accept = o.accept;
3282
3283		this.isover = false;
3284		this.isout = true;
3285
3286		this.accept = $.isFunction( accept ) ? accept : function( d ) {
3287			return d.is( accept );
3288		};
3289
3290		this.proportions = function( /* valueToWrite */ ) {
3291			if ( arguments.length ) {
3292
3293				// Store the droppable's proportions
3294				proportions = arguments[ 0 ];
3295			} else {
3296
3297				// Retrieve or derive the droppable's proportions
3298				return proportions ?
3299					proportions :
3300					proportions = {
3301						width: this.element[ 0 ].offsetWidth,
3302						height: this.element[ 0 ].offsetHeight
3303					};
3304			}
3305		};
3306
3307		this._addToManager( o.scope );
3308
3309		o.addClasses && this._addClass( "ui-droppable" );
3310
3311	},
3312
3313	_addToManager: function( scope ) {
3314
3315		// Add the reference and positions to the manager
3316		$.ui.ddmanager.droppables[ scope ] = $.ui.ddmanager.droppables[ scope ] || [];
3317		$.ui.ddmanager.droppables[ scope ].push( this );
3318	},
3319
3320	_splice: function( drop ) {
3321		var i = 0;
3322		for ( ; i < drop.length; i++ ) {
3323			if ( drop[ i ] === this ) {
3324				drop.splice( i, 1 );
3325			}
3326		}
3327	},
3328
3329	_destroy: function() {
3330		var drop = $.ui.ddmanager.droppables[ this.options.scope ];
3331
3332		this._splice( drop );
3333	},
3334
3335	_setOption: function( key, value ) {
3336
3337		if ( key === "accept" ) {
3338			this.accept = $.isFunction( value ) ? value : function( d ) {
3339				return d.is( value );
3340			};
3341		} else if ( key === "scope" ) {
3342			var drop = $.ui.ddmanager.droppables[ this.options.scope ];
3343
3344			this._splice( drop );
3345			this._addToManager( value );
3346		}
3347
3348		this._super( key, value );
3349	},
3350
3351	_activate: function( event ) {
3352		var draggable = $.ui.ddmanager.current;
3353
3354		this._addActiveClass();
3355		if ( draggable ) {
3356			this._trigger( "activate", event, this.ui( draggable ) );
3357		}
3358	},
3359
3360	_deactivate: function( event ) {
3361		var draggable = $.ui.ddmanager.current;
3362
3363		this._removeActiveClass();
3364		if ( draggable ) {
3365			this._trigger( "deactivate", event, this.ui( draggable ) );
3366		}
3367	},
3368
3369	_over: function( event ) {
3370
3371		var draggable = $.ui.ddmanager.current;
3372
3373		// Bail if draggable and droppable are same element
3374		if ( !draggable || ( draggable.currentItem ||
3375				draggable.element )[ 0 ] === this.element[ 0 ] ) {
3376			return;
3377		}
3378
3379		if ( this.accept.call( this.element[ 0 ], ( draggable.currentItem ||
3380				draggable.element ) ) ) {
3381			this._addHoverClass();
3382			this._trigger( "over", event, this.ui( draggable ) );
3383		}
3384
3385	},
3386
3387	_out: function( event ) {
3388
3389		var draggable = $.ui.ddmanager.current;
3390
3391		// Bail if draggable and droppable are same element
3392		if ( !draggable || ( draggable.currentItem ||
3393				draggable.element )[ 0 ] === this.element[ 0 ] ) {
3394			return;
3395		}
3396
3397		if ( this.accept.call( this.element[ 0 ], ( draggable.currentItem ||
3398				draggable.element ) ) ) {
3399			this._removeHoverClass();
3400			this._trigger( "out", event, this.ui( draggable ) );
3401		}
3402
3403	},
3404
3405	_drop: function( event, custom ) {
3406
3407		var draggable = custom || $.ui.ddmanager.current,
3408			childrenIntersection = false;
3409
3410		// Bail if draggable and droppable are same element
3411		if ( !draggable || ( draggable.currentItem ||
3412				draggable.element )[ 0 ] === this.element[ 0 ] ) {
3413			return false;
3414		}
3415
3416		this.element
3417			.find( ":data(ui-droppable)" )
3418			.not( ".ui-draggable-dragging" )
3419			.each( function() {
3420				var inst = $( this ).droppable( "instance" );
3421				if (
3422					inst.options.greedy &&
3423					!inst.options.disabled &&
3424					inst.options.scope === draggable.options.scope &&
3425					inst.accept.call(
3426						inst.element[ 0 ], ( draggable.currentItem || draggable.element )
3427					) &&
3428					intersect(
3429						draggable,
3430						$.extend( inst, { offset: inst.element.offset() } ),
3431						inst.options.tolerance, event
3432					)
3433				) {
3434					childrenIntersection = true;
3435					return false; }
3436			} );
3437		if ( childrenIntersection ) {
3438			return false;
3439		}
3440
3441		if ( this.accept.call( this.element[ 0 ],
3442				( draggable.currentItem || draggable.element ) ) ) {
3443			this._removeActiveClass();
3444			this._removeHoverClass();
3445
3446			this._trigger( "drop", event, this.ui( draggable ) );
3447			return this.element;
3448		}
3449
3450		return false;
3451
3452	},
3453
3454	ui: function( c ) {
3455		return {
3456			draggable: ( c.currentItem || c.element ),
3457			helper: c.helper,
3458			position: c.position,
3459			offset: c.positionAbs
3460		};
3461	},
3462
3463	// Extension points just to make backcompat sane and avoid duplicating logic
3464	// TODO: Remove in 1.13 along with call to it below
3465	_addHoverClass: function() {
3466		this._addClass( "ui-droppable-hover" );
3467	},
3468
3469	_removeHoverClass: function() {
3470		this._removeClass( "ui-droppable-hover" );
3471	},
3472
3473	_addActiveClass: function() {
3474		this._addClass( "ui-droppable-active" );
3475	},
3476
3477	_removeActiveClass: function() {
3478		this._removeClass( "ui-droppable-active" );
3479	}
3480} );
3481
3482var intersect = $.ui.intersect = ( function() {
3483	function isOverAxis( x, reference, size ) {
3484		return ( x >= reference ) && ( x < ( reference + size ) );
3485	}
3486
3487	return function( draggable, droppable, toleranceMode, event ) {
3488
3489		if ( !droppable.offset ) {
3490			return false;
3491		}
3492
3493		var x1 = ( draggable.positionAbs ||
3494				draggable.position.absolute ).left + draggable.margins.left,
3495			y1 = ( draggable.positionAbs ||
3496				draggable.position.absolute ).top + draggable.margins.top,
3497			x2 = x1 + draggable.helperProportions.width,
3498			y2 = y1 + draggable.helperProportions.height,
3499			l = droppable.offset.left,
3500			t = droppable.offset.top,
3501			r = l + droppable.proportions().width,
3502			b = t + droppable.proportions().height;
3503
3504		switch ( toleranceMode ) {
3505		case "fit":
3506			return ( l <= x1 && x2 <= r && t <= y1 && y2 <= b );
3507		case "intersect":
3508			return ( l < x1 + ( draggable.helperProportions.width / 2 ) && // Right Half
3509				x2 - ( draggable.helperProportions.width / 2 ) < r && // Left Half
3510				t < y1 + ( draggable.helperProportions.height / 2 ) && // Bottom Half
3511				y2 - ( draggable.helperProportions.height / 2 ) < b ); // Top Half
3512		case "pointer":
3513			return isOverAxis( event.pageY, t, droppable.proportions().height ) &&
3514				isOverAxis( event.pageX, l, droppable.proportions().width );
3515		case "touch":
3516			return (
3517				( y1 >= t && y1 <= b ) || // Top edge touching
3518				( y2 >= t && y2 <= b ) || // Bottom edge touching
3519				( y1 < t && y2 > b ) // Surrounded vertically
3520			) && (
3521				( x1 >= l && x1 <= r ) || // Left edge touching
3522				( x2 >= l && x2 <= r ) || // Right edge touching
3523				( x1 < l && x2 > r ) // Surrounded horizontally
3524			);
3525		default:
3526			return false;
3527		}
3528	};
3529} )();
3530
3531/*
3532	This manager tracks offsets of draggables and droppables
3533*/
3534$.ui.ddmanager = {
3535	current: null,
3536	droppables: { "default": [] },
3537	prepareOffsets: function( t, event ) {
3538
3539		var i, j,
3540			m = $.ui.ddmanager.droppables[ t.options.scope ] || [],
3541			type = event ? event.type : null, // workaround for #2317
3542			list = ( t.currentItem || t.element ).find( ":data(ui-droppable)" ).addBack();
3543
3544		droppablesLoop: for ( i = 0; i < m.length; i++ ) {
3545
3546			// No disabled and non-accepted
3547			if ( m[ i ].options.disabled || ( t && !m[ i ].accept.call( m[ i ].element[ 0 ],
3548					( t.currentItem || t.element ) ) ) ) {
3549				continue;
3550			}
3551
3552			// Filter out elements in the current dragged item
3553			for ( j = 0; j < list.length; j++ ) {
3554				if ( list[ j ] === m[ i ].element[ 0 ] ) {
3555					m[ i ].proportions().height = 0;
3556					continue droppablesLoop;
3557				}
3558			}
3559
3560			m[ i ].visible = m[ i ].element.css( "display" ) !== "none";
3561			if ( !m[ i ].visible ) {
3562				continue;
3563			}
3564
3565			// Activate the droppable if used directly from draggables
3566			if ( type === "mousedown" ) {
3567				m[ i ]._activate.call( m[ i ], event );
3568			}
3569
3570			m[ i ].offset = m[ i ].element.offset();
3571			m[ i ].proportions( {
3572				width: m[ i ].element[ 0 ].offsetWidth,
3573				height: m[ i ].element[ 0 ].offsetHeight
3574			} );
3575
3576		}
3577
3578	},
3579	drop: function( draggable, event ) {
3580
3581		var dropped = false;
3582
3583		// Create a copy of the droppables in case the list changes during the drop (#9116)
3584		$.each( ( $.ui.ddmanager.droppables[ draggable.options.scope ] || [] ).slice(), function() {
3585
3586			if ( !this.options ) {
3587				return;
3588			}
3589			if ( !this.options.disabled && this.visible &&
3590					intersect( draggable, this, this.options.tolerance, event ) ) {
3591				dropped = this._drop.call( this, event ) || dropped;
3592			}
3593
3594			if ( !this.options.disabled && this.visible && this.accept.call( this.element[ 0 ],
3595					( draggable.currentItem || draggable.element ) ) ) {
3596				this.isout = true;
3597				this.isover = false;
3598				this._deactivate.call( this, event );
3599			}
3600
3601		} );
3602		return dropped;
3603
3604	},
3605	dragStart: function( draggable, event ) {
3606
3607		// Listen for scrolling so that if the dragging causes scrolling the position of the
3608		// droppables can be recalculated (see #5003)
3609		draggable.element.parentsUntil( "body" ).on( "scroll.droppable", function() {
3610			if ( !draggable.options.refreshPositions ) {
3611				$.ui.ddmanager.prepareOffsets( draggable, event );
3612			}
3613		} );
3614	},
3615	drag: function( draggable, event ) {
3616
3617		// If you have a highly dynamic page, you might try this option. It renders positions
3618		// every time you move the mouse.
3619		if ( draggable.options.refreshPositions ) {
3620			$.ui.ddmanager.prepareOffsets( draggable, event );
3621		}
3622
3623		// Run through all droppables and check their positions based on specific tolerance options
3624		$.each( $.ui.ddmanager.droppables[ draggable.options.scope ] || [], function() {
3625
3626			if ( this.options.disabled || this.greedyChild || !this.visible ) {
3627				return;
3628			}
3629
3630			var parentInstance, scope, parent,
3631				intersects = intersect( draggable, this, this.options.tolerance, event ),
3632				c = !intersects && this.isover ?
3633					"isout" :
3634					( intersects && !this.isover ? "isover" : null );
3635			if ( !c ) {
3636				return;
3637			}
3638
3639			if ( this.options.greedy ) {
3640
3641				// find droppable parents with same scope
3642				scope = this.options.scope;
3643				parent = this.element.parents( ":data(ui-droppable)" ).filter( function() {
3644					return $( this ).droppable( "instance" ).options.scope === scope;
3645				} );
3646
3647				if ( parent.length ) {
3648					parentInstance = $( parent[ 0 ] ).droppable( "instance" );
3649					parentInstance.greedyChild = ( c === "isover" );
3650				}
3651			}
3652
3653			// We just moved into a greedy child
3654			if ( parentInstance && c === "isover" ) {
3655				parentInstance.isover = false;
3656				parentInstance.isout = true;
3657				parentInstance._out.call( parentInstance, event );
3658			}
3659
3660			this[ c ] = true;
3661			this[ c === "isout" ? "isover" : "isout" ] = false;
3662			this[ c === "isover" ? "_over" : "_out" ].call( this, event );
3663
3664			// We just moved out of a greedy child
3665			if ( parentInstance && c === "isout" ) {
3666				parentInstance.isout = false;
3667				parentInstance.isover = true;
3668				parentInstance._over.call( parentInstance, event );
3669			}
3670		} );
3671
3672	},
3673	dragStop: function( draggable, event ) {
3674		draggable.element.parentsUntil( "body" ).off( "scroll.droppable" );
3675
3676		// Call prepareOffsets one final time since IE does not fire return scroll events when
3677		// overflow was caused by drag (see #5003)
3678		if ( !draggable.options.refreshPositions ) {
3679			$.ui.ddmanager.prepareOffsets( draggable, event );
3680		}
3681	}
3682};
3683
3684// DEPRECATED
3685// TODO: switch return back to widget declaration at top of file when this is removed
3686if ( $.uiBackCompat !== false ) {
3687
3688	// Backcompat for activeClass and hoverClass options
3689	$.widget( "ui.droppable", $.ui.droppable, {
3690		options: {
3691			hoverClass: false,
3692			activeClass: false
3693		},
3694		_addActiveClass: function() {
3695			this._super();
3696			if ( this.options.activeClass ) {
3697				this.element.addClass( this.options.activeClass );
3698			}
3699		},
3700		_removeActiveClass: function() {
3701			this._super();
3702			if ( this.options.activeClass ) {
3703				this.element.removeClass( this.options.activeClass );
3704			}
3705		},
3706		_addHoverClass: function() {
3707			this._super();
3708			if ( this.options.hoverClass ) {
3709				this.element.addClass( this.options.hoverClass );
3710			}
3711		},
3712		_removeHoverClass: function() {
3713			this._super();
3714			if ( this.options.hoverClass ) {
3715				this.element.removeClass( this.options.hoverClass );
3716			}
3717		}
3718	} );
3719}
3720
3721var widgetsDroppable = $.ui.droppable;
3722
3723
3724/*!
3725 * jQuery UI Resizable 1.12.1
3726 * http://jqueryui.com
3727 *
3728 * Copyright jQuery Foundation and other contributors
3729 * Released under the MIT license.
3730 * http://jquery.org/license
3731 */
3732
3733//>>label: Resizable
3734//>>group: Interactions
3735//>>description: Enables resize functionality for any element.
3736//>>docs: http://api.jqueryui.com/resizable/
3737//>>demos: http://jqueryui.com/resizable/
3738//>>css.structure: ../../themes/base/core.css
3739//>>css.structure: ../../themes/base/resizable.css
3740//>>css.theme: ../../themes/base/theme.css
3741
3742
3743
3744$.widget( "ui.resizable", $.ui.mouse, {
3745	version: "1.12.1",
3746	widgetEventPrefix: "resize",
3747	options: {
3748		alsoResize: false,
3749		animate: false,
3750		animateDuration: "slow",
3751		animateEasing: "swing",
3752		aspectRatio: false,
3753		autoHide: false,
3754		classes: {
3755			"ui-resizable-se": "ui-icon ui-icon-gripsmall-diagonal-se"
3756		},
3757		containment: false,
3758		ghost: false,
3759		grid: false,
3760		handles: "e,s,se",
3761		helper: false,
3762		maxHeight: null,
3763		maxWidth: null,
3764		minHeight: 10,
3765		minWidth: 10,
3766
3767		// See #7960
3768		zIndex: 90,
3769
3770		// Callbacks
3771		resize: null,
3772		start: null,
3773		stop: null
3774	},
3775
3776	_num: function( value ) {
3777		return parseFloat( value ) || 0;
3778	},
3779
3780	_isNumber: function( value ) {
3781		return !isNaN( parseFloat( value ) );
3782	},
3783
3784	_hasScroll: function( el, a ) {
3785
3786		if ( $( el ).css( "overflow" ) === "hidden" ) {
3787			return false;
3788		}
3789
3790		var scroll = ( a && a === "left" ) ? "scrollLeft" : "scrollTop",
3791			has = false;
3792
3793		if ( el[ scroll ] > 0 ) {
3794			return true;
3795		}
3796
3797		// TODO: determine which cases actually cause this to happen
3798		// if the element doesn't have the scroll set, see if it's possible to
3799		// set the scroll
3800		el[ scroll ] = 1;
3801		has = ( el[ scroll ] > 0 );
3802		el[ scroll ] = 0;
3803		return has;
3804	},
3805
3806	_create: function() {
3807
3808		var margins,
3809			o = this.options,
3810			that = this;
3811		this._addClass( "ui-resizable" );
3812
3813		$.extend( this, {
3814			_aspectRatio: !!( o.aspectRatio ),
3815			aspectRatio: o.aspectRatio,
3816			originalElement: this.element,
3817			_proportionallyResizeElements: [],
3818			_helper: o.helper || o.ghost || o.animate ? o.helper || "ui-resizable-helper" : null
3819		} );
3820
3821		// Wrap the element if it cannot hold child nodes
3822		if ( this.element[ 0 ].nodeName.match( /^(canvas|textarea|input|select|button|img)$/i ) ) {
3823
3824			this.element.wrap(
3825				$( "<div class='ui-wrapper' style='overflow: hidden;'></div>" ).css( {
3826					position: this.element.css( "position" ),
3827					width: this.element.outerWidth(),
3828					height: this.element.outerHeight(),
3829					top: this.element.css( "top" ),
3830					left: this.element.css( "left" )
3831				} )
3832			);
3833
3834			this.element = this.element.parent().data(
3835				"ui-resizable", this.element.resizable( "instance" )
3836			);
3837
3838			this.elementIsWrapper = true;
3839
3840			margins = {
3841				marginTop: this.originalElement.css( "marginTop" ),
3842				marginRight: this.originalElement.css( "marginRight" ),
3843				marginBottom: this.originalElement.css( "marginBottom" ),
3844				marginLeft: this.originalElement.css( "marginLeft" )
3845			};
3846
3847			this.element.css( margins );
3848			this.originalElement.css( "margin", 0 );
3849
3850			// support: Safari
3851			// Prevent Safari textarea resize
3852			this.originalResizeStyle = this.originalElement.css( "resize" );
3853			this.originalElement.css( "resize", "none" );
3854
3855			this._proportionallyResizeElements.push( this.originalElement.css( {
3856				position: "static",
3857				zoom: 1,
3858				display: "block"
3859			} ) );
3860
3861			// Support: IE9
3862			// avoid IE jump (hard set the margin)
3863			this.originalElement.css( margins );
3864
3865			this._proportionallyResize();
3866		}
3867
3868		this._setupHandles();
3869
3870		if ( o.autoHide ) {
3871			$( this.element )
3872				.on( "mouseenter", function() {
3873					if ( o.disabled ) {
3874						return;
3875					}
3876					that._removeClass( "ui-resizable-autohide" );
3877					that._handles.show();
3878				} )
3879				.on( "mouseleave", function() {
3880					if ( o.disabled ) {
3881						return;
3882					}
3883					if ( !that.resizing ) {
3884						that._addClass( "ui-resizable-autohide" );
3885						that._handles.hide();
3886					}
3887				} );
3888		}
3889
3890		this._mouseInit();
3891	},
3892
3893	_destroy: function() {
3894
3895		this._mouseDestroy();
3896
3897		var wrapper,
3898			_destroy = function( exp ) {
3899				$( exp )
3900					.removeData( "resizable" )
3901					.removeData( "ui-resizable" )
3902					.off( ".resizable" )
3903					.find( ".ui-resizable-handle" )
3904						.remove();
3905			};
3906
3907		// TODO: Unwrap at same DOM position
3908		if ( this.elementIsWrapper ) {
3909			_destroy( this.element );
3910			wrapper = this.element;
3911			this.originalElement.css( {
3912				position: wrapper.css( "position" ),
3913				width: wrapper.outerWidth(),
3914				height: wrapper.outerHeight(),
3915				top: wrapper.css( "top" ),
3916				left: wrapper.css( "left" )
3917			} ).insertAfter( wrapper );
3918			wrapper.remove();
3919		}
3920
3921		this.originalElement.css( "resize", this.originalResizeStyle );
3922		_destroy( this.originalElement );
3923
3924		return this;
3925	},
3926
3927	_setOption: function( key, value ) {
3928		this._super( key, value );
3929
3930		switch ( key ) {
3931		case "handles":
3932			this._removeHandles();
3933			this._setupHandles();
3934			break;
3935		default:
3936			break;
3937		}
3938	},
3939
3940	_setupHandles: function() {
3941		var o = this.options, handle, i, n, hname, axis, that = this;
3942		this.handles = o.handles ||
3943			( !$( ".ui-resizable-handle", this.element ).length ?
3944				"e,s,se" : {
3945					n: ".ui-resizable-n",
3946					e: ".ui-resizable-e",
3947					s: ".ui-resizable-s",
3948					w: ".ui-resizable-w",
3949					se: ".ui-resizable-se",
3950					sw: ".ui-resizable-sw",
3951					ne: ".ui-resizable-ne",
3952					nw: ".ui-resizable-nw"
3953				} );
3954
3955		this._handles = $();
3956		if ( this.handles.constructor === String ) {
3957
3958			if ( this.handles === "all" ) {
3959				this.handles = "n,e,s,w,se,sw,ne,nw";
3960			}
3961
3962			n = this.handles.split( "," );
3963			this.handles = {};
3964
3965			for ( i = 0; i < n.length; i++ ) {
3966
3967				handle = $.trim( n[ i ] );
3968				hname = "ui-resizable-" + handle;
3969				axis = $( "<div>" );
3970				this._addClass( axis, "ui-resizable-handle " + hname );
3971
3972				axis.css( { zIndex: o.zIndex } );
3973
3974				this.handles[ handle ] = ".ui-resizable-" + handle;
3975				this.element.append( axis );
3976			}
3977
3978		}
3979
3980		this._renderAxis = function( target ) {
3981
3982			var i, axis, padPos, padWrapper;
3983
3984			target = target || this.element;
3985
3986			for ( i in this.handles ) {
3987
3988				if ( this.handles[ i ].constructor === String ) {
3989					this.handles[ i ] = this.element.children( this.handles[ i ] ).first().show();
3990				} else if ( this.handles[ i ].jquery || this.handles[ i ].nodeType ) {
3991					this.handles[ i ] = $( this.handles[ i ] );
3992					this._on( this.handles[ i ], { "mousedown": that._mouseDown } );
3993				}
3994
3995				if ( this.elementIsWrapper &&
3996						this.originalElement[ 0 ]
3997							.nodeName
3998							.match( /^(textarea|input|select|button)$/i ) ) {
3999					axis = $( this.handles[ i ], this.element );
4000
4001					padWrapper = /sw|ne|nw|se|n|s/.test( i ) ?
4002						axis.outerHeight() :
4003						axis.outerWidth();
4004
4005					padPos = [ "padding",
vendor: 4,678 bytes, lines 4006-4186
4006						/ne|nw|n/.test( i ) ? "Top" :
4007						/se|sw|s/.test( i ) ? "Bottom" :
4008						/^e$/.test( i ) ? "Right" : "Left" ].join( "" );
4009
4010					target.css( padPos, padWrapper );
4011
4012					this._proportionallyResize();
4013				}
4014
4015				this._handles = this._handles.add( this.handles[ i ] );
4016			}
4017		};
4018
4019		// TODO: make renderAxis a prototype function
4020		this._renderAxis( this.element );
4021
4022		this._handles = this._handles.add( this.element.find( ".ui-resizable-handle" ) );
4023		this._handles.disableSelection();
4024
4025		this._handles.on( "mouseover", function() {
4026			if ( !that.resizing ) {
4027				if ( this.className ) {
4028					axis = this.className.match( /ui-resizable-(se|sw|ne|nw|n|e|s|w)/i );
4029				}
4030				that.axis = axis && axis[ 1 ] ? axis[ 1 ] : "se";
4031			}
4032		} );
4033
4034		if ( o.autoHide ) {
4035			this._handles.hide();
4036			this._addClass( "ui-resizable-autohide" );
4037		}
4038	},
4039
4040	_removeHandles: function() {
4041		this._handles.remove();
4042	},
4043
4044	_mouseCapture: function( event ) {
4045		var i, handle,
4046			capture = false;
4047
4048		for ( i in this.handles ) {
4049			handle = $( this.handles[ i ] )[ 0 ];
4050			if ( handle === event.target || $.contains( handle, event.target ) ) {
4051				capture = true;
4052			}
4053		}
4054
4055		return !this.options.disabled && capture;
4056	},
4057
4058	_mouseStart: function( event ) {
4059
4060		var curleft, curtop, cursor,
4061			o = this.options,
4062			el = this.element;
4063
4064		this.resizing = true;
4065
4066		this._renderProxy();
4067
4068		curleft = this._num( this.helper.css( "left" ) );
4069		curtop = this._num( this.helper.css( "top" ) );
4070
4071		if ( o.containment ) {
4072			curleft += $( o.containment ).scrollLeft() || 0;
4073			curtop += $( o.containment ).scrollTop() || 0;
4074		}
4075
4076		this.offset = this.helper.offset();
4077		this.position = { left: curleft, top: curtop };
4078
4079		this.size = this._helper ? {
4080				width: this.helper.width(),
4081				height: this.helper.height()
4082			} : {
4083				width: el.width(),
4084				height: el.height()
4085			};
4086
4087		this.originalSize = this._helper ? {
4088				width: el.outerWidth(),
4089				height: el.outerHeight()
4090			} : {
4091				width: el.width(),
4092				height: el.height()
4093			};
4094
4095		this.sizeDiff = {
4096			width: el.outerWidth() - el.width(),
4097			height: el.outerHeight() - el.height()
4098		};
4099
4100		this.originalPosition = { left: curleft, top: curtop };
4101		this.originalMousePosition = { left: event.pageX, top: event.pageY };
4102
4103		this.aspectRatio = ( typeof o.aspectRatio === "number" ) ?
4104			o.aspectRatio :
4105			( ( this.originalSize.width / this.originalSize.height ) || 1 );
4106
4107		cursor = $( ".ui-resizable-" + this.axis ).css( "cursor" );
4108		$( "body" ).css( "cursor", cursor === "auto" ? this.axis + "-resize" : cursor );
4109
4110		this._addClass( "ui-resizable-resizing" );
4111		this._propagate( "start", event );
4112		return true;
4113	},
4114
4115	_mouseDrag: function( event ) {
4116
4117		var data, props,
4118			smp = this.originalMousePosition,
4119			a = this.axis,
4120			dx = ( event.pageX - smp.left ) || 0,
4121			dy = ( event.pageY - smp.top ) || 0,
4122			trigger = this._change[ a ];
4123
4124		this._updatePrevProperties();
4125
4126		if ( !trigger ) {
4127			return false;
4128		}
4129
4130		data = trigger.apply( this, [ event, dx, dy ] );
4131
4132		this._updateVirtualBoundaries( event.shiftKey );
4133		if ( this._aspectRatio || event.shiftKey ) {
4134			data = this._updateRatio( data, event );
4135		}
4136
4137		data = this._respectSize( data, event );
4138
4139		this._updateCache( data );
4140
4141		this._propagate( "resize", event );
4142
4143		props = this._applyChanges();
4144
4145		if ( !this._helper && this._proportionallyResizeElements.length ) {
4146			this._proportionallyResize();
4147		}
4148
4149		if ( !$.isEmptyObject( props ) ) {
4150			this._updatePrevProperties();
4151			this._trigger( "resize", event, this.ui() );
4152			this._applyChanges();
4153		}
4154
4155		return false;
4156	},
4157
4158	_mouseStop: function( event ) {
4159
4160		this.resizing = false;
4161		var pr, ista, soffseth, soffsetw, s, left, top,
4162			o = this.options, that = this;
4163
4164		if ( this._helper ) {
4165
4166			pr = this._proportionallyResizeElements;
4167			ista = pr.length && ( /textarea/i ).test( pr[ 0 ].nodeName );
4168			soffseth = ista && this._hasScroll( pr[ 0 ], "left" ) ? 0 : that.sizeDiff.height;
4169			soffsetw = ista ? 0 : that.sizeDiff.width;
4170
4171			s = {
4172				width: ( that.helper.width()  - soffsetw ),
4173				height: ( that.helper.height() - soffseth )
4174			};
4175			left = ( parseFloat( that.element.css( "left" ) ) +
4176				( that.position.left - that.originalPosition.left ) ) || null;
4177			top = ( parseFloat( that.element.css( "top" ) ) +
4178				( that.position.top - that.originalPosition.top ) ) || null;
4179
4180			if ( !o.animate ) {
4181				this.element.css( $.extend( s, { top: top, left: left } ) );
4182			}
4183
4184			that.helper.height( that.size.height );
4185			that.helper.width( that.size.width );
4186
vendor: 6,168 bytes, lines 4187-4427
4187			if ( this._helper && !o.animate ) {
4188				this._proportionallyResize();
4189			}
4190		}
4191
4192		$( "body" ).css( "cursor", "auto" );
4193
4194		this._removeClass( "ui-resizable-resizing" );
4195
4196		this._propagate( "stop", event );
4197
4198		if ( this._helper ) {
4199			this.helper.remove();
4200		}
4201
4202		return false;
4203
4204	},
4205
4206	_updatePrevProperties: function() {
4207		this.prevPosition = {
4208			top: this.position.top,
4209			left: this.position.left
4210		};
4211		this.prevSize = {
4212			width: this.size.width,
4213			height: this.size.height
4214		};
4215	},
4216
4217	_applyChanges: function() {
4218		var props = {};
4219
4220		if ( this.position.top !== this.prevPosition.top ) {
4221			props.top = this.position.top + "px";
4222		}
4223		if ( this.position.left !== this.prevPosition.left ) {
4224			props.left = this.position.left + "px";
4225		}
4226		if ( this.size.width !== this.prevSize.width ) {
4227			props.width = this.size.width + "px";
4228		}
4229		if ( this.size.height !== this.prevSize.height ) {
4230			props.height = this.size.height + "px";
4231		}
4232
4233		this.helper.css( props );
4234
4235		return props;
4236	},
4237
4238	_updateVirtualBoundaries: function( forceAspectRatio ) {
4239		var pMinWidth, pMaxWidth, pMinHeight, pMaxHeight, b,
4240			o = this.options;
4241
4242		b = {
4243			minWidth: this._isNumber( o.minWidth ) ? o.minWidth : 0,
4244			maxWidth: this._isNumber( o.maxWidth ) ? o.maxWidth : Infinity,
4245			minHeight: this._isNumber( o.minHeight ) ? o.minHeight : 0,
4246			maxHeight: this._isNumber( o.maxHeight ) ? o.maxHeight : Infinity
4247		};
4248
4249		if ( this._aspectRatio || forceAspectRatio ) {
4250			pMinWidth = b.minHeight * this.aspectRatio;
4251			pMinHeight = b.minWidth / this.aspectRatio;
4252			pMaxWidth = b.maxHeight * this.aspectRatio;
4253			pMaxHeight = b.maxWidth / this.aspectRatio;
4254
4255			if ( pMinWidth > b.minWidth ) {
4256				b.minWidth = pMinWidth;
4257			}
4258			if ( pMinHeight > b.minHeight ) {
4259				b.minHeight = pMinHeight;
4260			}
4261			if ( pMaxWidth < b.maxWidth ) {
4262				b.maxWidth = pMaxWidth;
4263			}
4264			if ( pMaxHeight < b.maxHeight ) {
4265				b.maxHeight = pMaxHeight;
4266			}
4267		}
4268		this._vBoundaries = b;
4269	},
4270
4271	_updateCache: function( data ) {
4272		this.offset = this.helper.offset();
4273		if ( this._isNumber( data.left ) ) {
4274			this.position.left = data.left;
4275		}
4276		if ( this._isNumber( data.top ) ) {
4277			this.position.top = data.top;
4278		}
4279		if ( this._isNumber( data.height ) ) {
4280			this.size.height = data.height;
4281		}
4282		if ( this._isNumber( data.width ) ) {
4283			this.size.width = data.width;
4284		}
4285	},
4286
4287	_updateRatio: function( data ) {
4288
4289		var cpos = this.position,
4290			csize = this.size,
4291			a = this.axis;
4292
4293		if ( this._isNumber( data.height ) ) {
4294			data.width = ( data.height * this.aspectRatio );
4295		} else if ( this._isNumber( data.width ) ) {
4296			data.height = ( data.width / this.aspectRatio );
4297		}
4298
4299		if ( a === "sw" ) {
4300			data.left = cpos.left + ( csize.width - data.width );
4301			data.top = null;
4302		}
4303		if ( a === "nw" ) {
4304			data.top = cpos.top + ( csize.height - data.height );
4305			data.left = cpos.left + ( csize.width - data.width );
4306		}
4307
4308		return data;
4309	},
4310
4311	_respectSize: function( data ) {
4312
4313		var o = this._vBoundaries,
4314			a = this.axis,
4315			ismaxw = this._isNumber( data.width ) && o.maxWidth && ( o.maxWidth < data.width ),
4316			ismaxh = this._isNumber( data.height ) && o.maxHeight && ( o.maxHeight < data.height ),
4317			isminw = this._isNumber( data.width ) && o.minWidth && ( o.minWidth > data.width ),
4318			isminh = this._isNumber( data.height ) && o.minHeight && ( o.minHeight > data.height ),
4319			dw = this.originalPosition.left + this.originalSize.width,
4320			dh = this.originalPosition.top + this.originalSize.height,
4321			cw = /sw|nw|w/.test( a ), ch = /nw|ne|n/.test( a );
4322		if ( isminw ) {
4323			data.width = o.minWidth;
4324		}
4325		if ( isminh ) {
4326			data.height = o.minHeight;
4327		}
4328		if ( ismaxw ) {
4329			data.width = o.maxWidth;
4330		}
4331		if ( ismaxh ) {
4332			data.height = o.maxHeight;
4333		}
4334
4335		if ( isminw && cw ) {
4336			data.left = dw - o.minWidth;
4337		}
4338		if ( ismaxw && cw ) {
4339			data.left = dw - o.maxWidth;
4340		}
4341		if ( isminh && ch ) {
4342			data.top = dh - o.minHeight;
4343		}
4344		if ( ismaxh && ch ) {
4345			data.top = dh - o.maxHeight;
4346		}
4347
4348		// Fixing jump error on top/left - bug #2330
4349		if ( !data.width && !data.height && !data.left && data.top ) {
4350			data.top = null;
4351		} else if ( !data.width && !data.height && !data.top && data.left ) {
4352			data.left = null;
4353		}
4354
4355		return data;
4356	},
4357
4358	_getPaddingPlusBorderDimensions: function( element ) {
4359		var i = 0,
4360			widths = [],
4361			borders = [
4362				element.css( "borderTopWidth" ),
4363				element.css( "borderRightWidth" ),
4364				element.css( "borderBottomWidth" ),
4365				element.css( "borderLeftWidth" )
4366			],
4367			paddings = [
4368				element.css( "paddingTop" ),
4369				element.css( "paddingRight" ),
4370				element.css( "paddingBottom" ),
4371				element.css( "paddingLeft" )
4372			];
4373
4374		for ( ; i < 4; i++ ) {
4375			widths[ i ] = ( parseFloat( borders[ i ] ) || 0 );
4376			widths[ i ] += ( parseFloat( paddings[ i ] ) || 0 );
4377		}
4378
4379		return {
4380			height: widths[ 0 ] + widths[ 2 ],
4381			width: widths[ 1 ] + widths[ 3 ]
4382		};
4383	},
4384
4385	_proportionallyResize: function() {
4386
4387		if ( !this._proportionallyResizeElements.length ) {
4388			return;
4389		}
4390
4391		var prel,
4392			i = 0,
4393			element = this.helper || this.element;
4394
4395		for ( ; i < this._proportionallyResizeElements.length; i++ ) {
4396
4397			prel = this._proportionallyResizeElements[ i ];
4398
4399			// TODO: Seems like a bug to cache this.outerDimensions
4400			// considering that we are in a loop.
4401			if ( !this.outerDimensions ) {
4402				this.outerDimensions = this._getPaddingPlusBorderDimensions( prel );
4403			}
4404
4405			prel.css( {
4406				height: ( element.height() - this.outerDimensions.height ) || 0,
4407				width: ( element.width() - this.outerDimensions.width ) || 0
4408			} );
4409
4410		}
4411
4412	},
4413
4414	_renderProxy: function() {
4415
4416		var el = this.element, o = this.options;
4417		this.elementOffset = el.offset();
4418
4419		if ( this._helper ) {
4420
4421			this.helper = this.helper || $( "<div style='overflow:hidden;'></div>" );
4422
4423			this._addClass( this.helper, this._helper );
4424			this.helper.css( {
4425				width: this.element.outerWidth(),
4426				height: this.element.outerHeight(),
4427				position: "absolute",
vendor: 1,421 bytes, lines 4428-4475
4428				left: this.elementOffset.left + "px",
4429				top: this.elementOffset.top + "px",
4430				zIndex: ++o.zIndex //TODO: Don't modify option
4431			} );
4432
4433			this.helper
4434				.appendTo( "body" )
4435				.disableSelection();
4436
4437		} else {
4438			this.helper = this.element;
4439		}
4440
4441	},
4442
4443	_change: {
4444		e: function( event, dx ) {
4445			return { width: this.originalSize.width + dx };
4446		},
4447		w: function( event, dx ) {
4448			var cs = this.originalSize, sp = this.originalPosition;
4449			return { left: sp.left + dx, width: cs.width - dx };
4450		},
4451		n: function( event, dx, dy ) {
4452			var cs = this.originalSize, sp = this.originalPosition;
4453			return { top: sp.top + dy, height: cs.height - dy };
4454		},
4455		s: function( event, dx, dy ) {
4456			return { height: this.originalSize.height + dy };
4457		},
4458		se: function( event, dx, dy ) {
4459			return $.extend( this._change.s.apply( this, arguments ),
4460				this._change.e.apply( this, [ event, dx, dy ] ) );
4461		},
4462		sw: function( event, dx, dy ) {
4463			return $.extend( this._change.s.apply( this, arguments ),
4464				this._change.w.apply( this, [ event, dx, dy ] ) );
4465		},
4466		ne: function( event, dx, dy ) {
4467			return $.extend( this._change.n.apply( this, arguments ),
4468				this._change.e.apply( this, [ event, dx, dy ] ) );
4469		},
4470		nw: function( event, dx, dy ) {
4471			return $.extend( this._change.n.apply( this, arguments ),
4472				this._change.w.apply( this, [ event, dx, dy ] ) );
4473		}
4474	},
4475
vendor: 9,740 bytes, lines 4476-4841
4476	_propagate: function( n, event ) {
4477		$.ui.plugin.call( this, n, [ event, this.ui() ] );
4478		( n !== "resize" && this._trigger( n, event, this.ui() ) );
4479	},
4480
4481	plugins: {},
4482
4483	ui: function() {
4484		return {
4485			originalElement: this.originalElement,
4486			element: this.element,
4487			helper: this.helper,
4488			position: this.position,
4489			size: this.size,
4490			originalSize: this.originalSize,
4491			originalPosition: this.originalPosition
4492		};
4493	}
4494
4495} );
4496
4497/*
4498 * Resizable Extensions
4499 */
4500
4501$.ui.plugin.add( "resizable", "animate", {
4502
4503	stop: function( event ) {
4504		var that = $( this ).resizable( "instance" ),
4505			o = that.options,
4506			pr = that._proportionallyResizeElements,
4507			ista = pr.length && ( /textarea/i ).test( pr[ 0 ].nodeName ),
4508			soffseth = ista && that._hasScroll( pr[ 0 ], "left" ) ? 0 : that.sizeDiff.height,
4509			soffsetw = ista ? 0 : that.sizeDiff.width,
4510			style = {
4511				width: ( that.size.width - soffsetw ),
4512				height: ( that.size.height - soffseth )
4513			},
4514			left = ( parseFloat( that.element.css( "left" ) ) +
4515				( that.position.left - that.originalPosition.left ) ) || null,
4516			top = ( parseFloat( that.element.css( "top" ) ) +
4517				( that.position.top - that.originalPosition.top ) ) || null;
4518
4519		that.element.animate(
4520			$.extend( style, top && left ? { top: top, left: left } : {} ), {
4521				duration: o.animateDuration,
4522				easing: o.animateEasing,
4523				step: function() {
4524
4525					var data = {
4526						width: parseFloat( that.element.css( "width" ) ),
4527						height: parseFloat( that.element.css( "height" ) ),
4528						top: parseFloat( that.element.css( "top" ) ),
4529						left: parseFloat( that.element.css( "left" ) )
4530					};
4531
4532					if ( pr && pr.length ) {
4533						$( pr[ 0 ] ).css( { width: data.width, height: data.height } );
4534					}
4535
4536					// Propagating resize, and updating values for each animation step
4537					that._updateCache( data );
4538					that._propagate( "resize", event );
4539
4540				}
4541			}
4542		);
4543	}
4544
4545} );
4546
4547$.ui.plugin.add( "resizable", "containment", {
4548
4549	start: function() {
4550		var element, p, co, ch, cw, width, height,
4551			that = $( this ).resizable( "instance" ),
4552			o = that.options,
4553			el = that.element,
4554			oc = o.containment,
4555			ce = ( oc instanceof $ ) ?
4556				oc.get( 0 ) :
4557				( /parent/.test( oc ) ) ? el.parent().get( 0 ) : oc;
4558
4559		if ( !ce ) {
4560			return;
4561		}
4562
4563		that.containerElement = $( ce );
4564
4565		if ( /document/.test( oc ) || oc === document ) {
4566			that.containerOffset = {
4567				left: 0,
4568				top: 0
4569			};
4570			that.containerPosition = {
4571				left: 0,
4572				top: 0
4573			};
4574
4575			that.parentData = {
4576				element: $( document ),
4577				left: 0,
4578				top: 0,
4579				width: $( document ).width(),
4580				height: $( document ).height() || document.body.parentNode.scrollHeight
4581			};
4582		} else {
4583			element = $( ce );
4584			p = [];
4585			$( [ "Top", "Right", "Left", "Bottom" ] ).each( function( i, name ) {
4586				p[ i ] = that._num( element.css( "padding" + name ) );
4587			} );
4588
4589			that.containerOffset = element.offset();
4590			that.containerPosition = element.position();
4591			that.containerSize = {
4592				height: ( element.innerHeight() - p[ 3 ] ),
4593				width: ( element.innerWidth() - p[ 1 ] )
4594			};
4595
4596			co = that.containerOffset;
4597			ch = that.containerSize.height;
4598			cw = that.containerSize.width;
4599			width = ( that._hasScroll ( ce, "left" ) ? ce.scrollWidth : cw );
4600			height = ( that._hasScroll ( ce ) ? ce.scrollHeight : ch ) ;
4601
4602			that.parentData = {
4603				element: ce,
4604				left: co.left,
4605				top: co.top,
4606				width: width,
4607				height: height
4608			};
4609		}
4610	},
4611
4612	resize: function( event ) {
4613		var woset, hoset, isParent, isOffsetRelative,
4614			that = $( this ).resizable( "instance" ),
4615			o = that.options,
4616			co = that.containerOffset,
4617			cp = that.position,
4618			pRatio = that._aspectRatio || event.shiftKey,
4619			cop = {
4620				top: 0,
4621				left: 0
4622			},
4623			ce = that.containerElement,
4624			continueResize = true;
4625
4626		if ( ce[ 0 ] !== document && ( /static/ ).test( ce.css( "position" ) ) ) {
4627			cop = co;
4628		}
4629
4630		if ( cp.left < ( that._helper ? co.left : 0 ) ) {
4631			that.size.width = that.size.width +
4632				( that._helper ?
4633					( that.position.left - co.left ) :
4634					( that.position.left - cop.left ) );
4635
4636			if ( pRatio ) {
4637				that.size.height = that.size.width / that.aspectRatio;
4638				continueResize = false;
4639			}
4640			that.position.left = o.helper ? co.left : 0;
4641		}
4642
4643		if ( cp.top < ( that._helper ? co.top : 0 ) ) {
4644			that.size.height = that.size.height +
4645				( that._helper ?
4646					( that.position.top - co.top ) :
4647					that.position.top );
4648
4649			if ( pRatio ) {
4650				that.size.width = that.size.height * that.aspectRatio;
4651				continueResize = false;
4652			}
4653			that.position.top = that._helper ? co.top : 0;
4654		}
4655
4656		isParent = that.containerElement.get( 0 ) === that.element.parent().get( 0 );
4657		isOffsetRelative = /relative|absolute/.test( that.containerElement.css( "position" ) );
4658
4659		if ( isParent && isOffsetRelative ) {
4660			that.offset.left = that.parentData.left + that.position.left;
4661			that.offset.top = that.parentData.top + that.position.top;
4662		} else {
4663			that.offset.left = that.element.offset().left;
4664			that.offset.top = that.element.offset().top;
4665		}
4666
4667		woset = Math.abs( that.sizeDiff.width +
4668			( that._helper ?
4669				that.offset.left - cop.left :
4670				( that.offset.left - co.left ) ) );
4671
4672		hoset = Math.abs( that.sizeDiff.height +
4673			( that._helper ?
4674				that.offset.top - cop.top :
4675				( that.offset.top - co.top ) ) );
4676
4677		if ( woset + that.size.width >= that.parentData.width ) {
4678			that.size.width = that.parentData.width - woset;
4679			if ( pRatio ) {
4680				that.size.height = that.size.width / that.aspectRatio;
4681				continueResize = false;
4682			}
4683		}
4684
4685		if ( hoset + that.size.height >= that.parentData.height ) {
4686			that.size.height = that.parentData.height - hoset;
4687			if ( pRatio ) {
4688				that.size.width = that.size.height * that.aspectRatio;
4689				continueResize = false;
4690			}
4691		}
4692
4693		if ( !continueResize ) {
4694			that.position.left = that.prevPosition.left;
4695			that.position.top = that.prevPosition.top;
4696			that.size.width = that.prevSize.width;
4697			that.size.height = that.prevSize.height;
4698		}
4699	},
4700
4701	stop: function() {
4702		var that = $( this ).resizable( "instance" ),
4703			o = that.options,
4704			co = that.containerOffset,
4705			cop = that.containerPosition,
4706			ce = that.containerElement,
4707			helper = $( that.helper ),
4708			ho = helper.offset(),
4709			w = helper.outerWidth() - that.sizeDiff.width,
4710			h = helper.outerHeight() - that.sizeDiff.height;
4711
4712		if ( that._helper && !o.animate && ( /relative/ ).test( ce.css( "position" ) ) ) {
4713			$( this ).css( {
4714				left: ho.left - cop.left - co.left,
4715				width: w,
4716				height: h
4717			} );
4718		}
4719
4720		if ( that._helper && !o.animate && ( /static/ ).test( ce.css( "position" ) ) ) {
4721			$( this ).css( {
4722				left: ho.left - cop.left - co.left,
4723				width: w,
4724				height: h
4725			} );
4726		}
4727	}
4728} );
4729
4730$.ui.plugin.add( "resizable", "alsoResize", {
4731
4732	start: function() {
4733		var that = $( this ).resizable( "instance" ),
4734			o = that.options;
4735
4736		$( o.alsoResize ).each( function() {
4737			var el = $( this );
4738			el.data( "ui-resizable-alsoresize", {
4739				width: parseFloat( el.width() ), height: parseFloat( el.height() ),
4740				left: parseFloat( el.css( "left" ) ), top: parseFloat( el.css( "top" ) )
4741			} );
4742		} );
4743	},
4744
4745	resize: function( event, ui ) {
4746		var that = $( this ).resizable( "instance" ),
4747			o = that.options,
4748			os = that.originalSize,
4749			op = that.originalPosition,
4750			delta = {
4751				height: ( that.size.height - os.height ) || 0,
4752				width: ( that.size.width - os.width ) || 0,
4753				top: ( that.position.top - op.top ) || 0,
4754				left: ( that.position.left - op.left ) || 0
4755			};
4756
4757			$( o.alsoResize ).each( function() {
4758				var el = $( this ), start = $( this ).data( "ui-resizable-alsoresize" ), style = {},
4759					css = el.parents( ui.originalElement[ 0 ] ).length ?
4760							[ "width", "height" ] :
4761							[ "width", "height", "top", "left" ];
4762
4763				$.each( css, function( i, prop ) {
4764					var sum = ( start[ prop ] || 0 ) + ( delta[ prop ] || 0 );
4765					if ( sum && sum >= 0 ) {
4766						style[ prop ] = sum || null;
4767					}
4768				} );
4769
4770				el.css( style );
4771			} );
4772	},
4773
4774	stop: function() {
4775		$( this ).removeData( "ui-resizable-alsoresize" );
4776	}
4777} );
4778
4779$.ui.plugin.add( "resizable", "ghost", {
4780
4781	start: function() {
4782
4783		var that = $( this ).resizable( "instance" ), cs = that.size;
4784
4785		that.ghost = that.originalElement.clone();
4786		that.ghost.css( {
4787			opacity: 0.25,
4788			display: "block",
4789			position: "relative",
4790			height: cs.height,
4791			width: cs.width,
4792			margin: 0,
4793			left: 0,
4794			top: 0
4795		} );
4796
4797		that._addClass( that.ghost, "ui-resizable-ghost" );
4798
4799		// DEPRECATED
4800		// TODO: remove after 1.12
4801		if ( $.uiBackCompat !== false && typeof that.options.ghost === "string" ) {
4802
4803			// Ghost option
4804			that.ghost.addClass( this.options.ghost );
4805		}
4806
4807		that.ghost.appendTo( that.helper );
4808
4809	},
4810
4811	resize: function() {
4812		var that = $( this ).resizable( "instance" );
4813		if ( that.ghost ) {
4814			that.ghost.css( {
4815				position: "relative",
4816				height: that.size.height,
4817				width: that.size.width
4818			} );
4819		}
4820	},
4821
4822	stop: function() {
4823		var that = $( this ).resizable( "instance" );
4824		if ( that.ghost && that.helper ) {
4825			that.helper.get( 0 ).removeChild( that.ghost.get( 0 ) );
4826		}
4827	}
4828
4829} );
4830
4831$.ui.plugin.add( "resizable", "grid", {
4832
4833	resize: function() {
4834		var outerDimensions,
4835			that = $( this ).resizable( "instance" ),
4836			o = that.options,
4837			cs = that.size,
4838			os = that.originalSize,
4839			op = that.originalPosition,
4840			a = that.axis,
4841			grid = typeof o.grid === "number" ? [ o.grid, o.grid ] : o.grid,
vendor: 10,025 bytes, lines 4842-5205
4842			gridX = ( grid[ 0 ] || 1 ),
4843			gridY = ( grid[ 1 ] || 1 ),
4844			ox = Math.round( ( cs.width - os.width ) / gridX ) * gridX,
4845			oy = Math.round( ( cs.height - os.height ) / gridY ) * gridY,
4846			newWidth = os.width + ox,
4847			newHeight = os.height + oy,
4848			isMaxWidth = o.maxWidth && ( o.maxWidth < newWidth ),
4849			isMaxHeight = o.maxHeight && ( o.maxHeight < newHeight ),
4850			isMinWidth = o.minWidth && ( o.minWidth > newWidth ),
4851			isMinHeight = o.minHeight && ( o.minHeight > newHeight );
4852
4853		o.grid = grid;
4854
4855		if ( isMinWidth ) {
4856			newWidth += gridX;
4857		}
4858		if ( isMinHeight ) {
4859			newHeight += gridY;
4860		}
4861		if ( isMaxWidth ) {
4862			newWidth -= gridX;
4863		}
4864		if ( isMaxHeight ) {
4865			newHeight -= gridY;
4866		}
4867
4868		if ( /^(se|s|e)$/.test( a ) ) {
4869			that.size.width = newWidth;
4870			that.size.height = newHeight;
4871		} else if ( /^(ne)$/.test( a ) ) {
4872			that.size.width = newWidth;
4873			that.size.height = newHeight;
4874			that.position.top = op.top - oy;
4875		} else if ( /^(sw)$/.test( a ) ) {
4876			that.size.width = newWidth;
4877			that.size.height = newHeight;
4878			that.position.left = op.left - ox;
4879		} else {
4880			if ( newHeight - gridY <= 0 || newWidth - gridX <= 0 ) {
4881				outerDimensions = that._getPaddingPlusBorderDimensions( this );
4882			}
4883
4884			if ( newHeight - gridY > 0 ) {
4885				that.size.height = newHeight;
4886				that.position.top = op.top - oy;
4887			} else {
4888				newHeight = gridY - outerDimensions.height;
4889				that.size.height = newHeight;
4890				that.position.top = op.top + os.height - newHeight;
4891			}
4892			if ( newWidth - gridX > 0 ) {
4893				that.size.width = newWidth;
4894				that.position.left = op.left - ox;
4895			} else {
4896				newWidth = gridX - outerDimensions.width;
4897				that.size.width = newWidth;
4898				that.position.left = op.left + os.width - newWidth;
4899			}
4900		}
4901	}
4902
4903} );
4904
4905var widgetsResizable = $.ui.resizable;
4906
4907
4908/*!
4909 * jQuery UI Selectable 1.12.1
4910 * http://jqueryui.com
4911 *
4912 * Copyright jQuery Foundation and other contributors
4913 * Released under the MIT license.
4914 * http://jquery.org/license
4915 */
4916
4917//>>label: Selectable
4918//>>group: Interactions
4919//>>description: Allows groups of elements to be selected with the mouse.
4920//>>docs: http://api.jqueryui.com/selectable/
4921//>>demos: http://jqueryui.com/selectable/
4922//>>css.structure: ../../themes/base/selectable.css
4923
4924
4925
4926var widgetsSelectable = $.widget( "ui.selectable", $.ui.mouse, {
4927	version: "1.12.1",
4928	options: {
4929		appendTo: "body",
4930		autoRefresh: true,
4931		distance: 0,
4932		filter: "*",
4933		tolerance: "touch",
4934
4935		// Callbacks
4936		selected: null,
4937		selecting: null,
4938		start: null,
4939		stop: null,
4940		unselected: null,
4941		unselecting: null
4942	},
4943	_create: function() {
4944		var that = this;
4945
4946		this._addClass( "ui-selectable" );
4947
4948		this.dragged = false;
4949
4950		// Cache selectee children based on filter
4951		this.refresh = function() {
4952			that.elementPos = $( that.element[ 0 ] ).offset();
4953			that.selectees = $( that.options.filter, that.element[ 0 ] );
4954			that._addClass( that.selectees, "ui-selectee" );
4955			that.selectees.each( function() {
4956				var $this = $( this ),
4957					selecteeOffset = $this.offset(),
4958					pos = {
4959						left: selecteeOffset.left - that.elementPos.left,
4960						top: selecteeOffset.top - that.elementPos.top
4961					};
4962				$.data( this, "selectable-item", {
4963					element: this,
4964					$element: $this,
4965					left: pos.left,
4966					top: pos.top,
4967					right: pos.left + $this.outerWidth(),
4968					bottom: pos.top + $this.outerHeight(),
4969					startselected: false,
4970					selected: $this.hasClass( "ui-selected" ),
4971					selecting: $this.hasClass( "ui-selecting" ),
4972					unselecting: $this.hasClass( "ui-unselecting" )
4973				} );
4974			} );
4975		};
4976		this.refresh();
4977
4978		this._mouseInit();
4979
4980		this.helper = $( "<div>" );
4981		this._addClass( this.helper, "ui-selectable-helper" );
4982	},
4983
4984	_destroy: function() {
4985		this.selectees.removeData( "selectable-item" );
4986		this._mouseDestroy();
4987	},
4988
4989	_mouseStart: function( event ) {
4990		var that = this,
4991			options = this.options;
4992
4993		this.opos = [ event.pageX, event.pageY ];
4994		this.elementPos = $( this.element[ 0 ] ).offset();
4995
4996		if ( this.options.disabled ) {
4997			return;
4998		}
4999
5000		this.selectees = $( options.filter, this.element[ 0 ] );
5001
5002		this._trigger( "start", event );
5003
5004		$( options.appendTo ).append( this.helper );
5005
5006		// position helper (lasso)
5007		this.helper.css( {
5008			"left": event.pageX,
5009			"top": event.pageY,
5010			"width": 0,
5011			"height": 0
5012		} );
5013
5014		if ( options.autoRefresh ) {
5015			this.refresh();
5016		}
5017
5018		this.selectees.filter( ".ui-selected" ).each( function() {
5019			var selectee = $.data( this, "selectable-item" );
5020			selectee.startselected = true;
5021			if ( !event.metaKey && !event.ctrlKey ) {
5022				that._removeClass( selectee.$element, "ui-selected" );
5023				selectee.selected = false;
5024				that._addClass( selectee.$element, "ui-unselecting" );
5025				selectee.unselecting = true;
5026
5027				// selectable UNSELECTING callback
5028				that._trigger( "unselecting", event, {
5029					unselecting: selectee.element
5030				} );
5031			}
5032		} );
5033
5034		$( event.target ).parents().addBack().each( function() {
5035			var doSelect,
5036				selectee = $.data( this, "selectable-item" );
5037			if ( selectee ) {
5038				doSelect = ( !event.metaKey && !event.ctrlKey ) ||
5039					!selectee.$element.hasClass( "ui-selected" );
5040				that._removeClass( selectee.$element, doSelect ? "ui-unselecting" : "ui-selected" )
5041					._addClass( selectee.$element, doSelect ? "ui-selecting" : "ui-unselecting" );
5042				selectee.unselecting = !doSelect;
5043				selectee.selecting = doSelect;
5044				selectee.selected = doSelect;
5045
5046				// selectable (UN)SELECTING callback
5047				if ( doSelect ) {
5048					that._trigger( "selecting", event, {
5049						selecting: selectee.element
5050					} );
5051				} else {
5052					that._trigger( "unselecting", event, {
5053						unselecting: selectee.element
5054					} );
5055				}
5056				return false;
5057			}
5058		} );
5059
5060	},
5061
5062	_mouseDrag: function( event ) {
5063
5064		this.dragged = true;
5065
5066		if ( this.options.disabled ) {
5067			return;
5068		}
5069
5070		var tmp,
5071			that = this,
5072			options = this.options,
5073			x1 = this.opos[ 0 ],
5074			y1 = this.opos[ 1 ],
5075			x2 = event.pageX,
5076			y2 = event.pageY;
5077
5078		if ( x1 > x2 ) { tmp = x2; x2 = x1; x1 = tmp; }
5079		if ( y1 > y2 ) { tmp = y2; y2 = y1; y1 = tmp; }
5080		this.helper.css( { left: x1, top: y1, width: x2 - x1, height: y2 - y1 } );
5081
5082		this.selectees.each( function() {
5083			var selectee = $.data( this, "selectable-item" ),
5084				hit = false,
5085				offset = {};
5086
5087			//prevent helper from being selected if appendTo: selectable
5088			if ( !selectee || selectee.element === that.element[ 0 ] ) {
5089				return;
5090			}
5091
5092			offset.left   = selectee.left   + that.elementPos.left;
5093			offset.right  = selectee.right  + that.elementPos.left;
5094			offset.top    = selectee.top    + that.elementPos.top;
5095			offset.bottom = selectee.bottom + that.elementPos.top;
5096
5097			if ( options.tolerance === "touch" ) {
5098				hit = ( !( offset.left > x2 || offset.right < x1 || offset.top > y2 ||
5099                    offset.bottom < y1 ) );
5100			} else if ( options.tolerance === "fit" ) {
5101				hit = ( offset.left > x1 && offset.right < x2 && offset.top > y1 &&
5102                    offset.bottom < y2 );
5103			}
5104
5105			if ( hit ) {
5106
5107				// SELECT
5108				if ( selectee.selected ) {
5109					that._removeClass( selectee.$element, "ui-selected" );
5110					selectee.selected = false;
5111				}
5112				if ( selectee.unselecting ) {
5113					that._removeClass( selectee.$element, "ui-unselecting" );
5114					selectee.unselecting = false;
5115				}
5116				if ( !selectee.selecting ) {
5117					that._addClass( selectee.$element, "ui-selecting" );
5118					selectee.selecting = true;
5119
5120					// selectable SELECTING callback
5121					that._trigger( "selecting", event, {
5122						selecting: selectee.element
5123					} );
5124				}
5125			} else {
5126
5127				// UNSELECT
5128				if ( selectee.selecting ) {
5129					if ( ( event.metaKey || event.ctrlKey ) && selectee.startselected ) {
5130						that._removeClass( selectee.$element, "ui-selecting" );
5131						selectee.selecting = false;
5132						that._addClass( selectee.$element, "ui-selected" );
5133						selectee.selected = true;
5134					} else {
5135						that._removeClass( selectee.$element, "ui-selecting" );
5136						selectee.selecting = false;
5137						if ( selectee.startselected ) {
5138							that._addClass( selectee.$element, "ui-unselecting" );
5139							selectee.unselecting = true;
5140						}
5141
5142						// selectable UNSELECTING callback
5143						that._trigger( "unselecting", event, {
5144							unselecting: selectee.element
5145						} );
5146					}
5147				}
5148				if ( selectee.selected ) {
5149					if ( !event.metaKey && !event.ctrlKey && !selectee.startselected ) {
5150						that._removeClass( selectee.$element, "ui-selected" );
5151						selectee.selected = false;
5152
5153						that._addClass( selectee.$element, "ui-unselecting" );
5154						selectee.unselecting = true;
5155
5156						// selectable UNSELECTING callback
5157						that._trigger( "unselecting", event, {
5158							unselecting: selectee.element
5159						} );
5160					}
5161				}
5162			}
5163		} );
5164
5165		return false;
5166	},
5167
5168	_mouseStop: function( event ) {
5169		var that = this;
5170
5171		this.dragged = false;
5172
5173		$( ".ui-unselecting", this.element[ 0 ] ).each( function() {
5174			var selectee = $.data( this, "selectable-item" );
5175			that._removeClass( selectee.$element, "ui-unselecting" );
5176			selectee.unselecting = false;
5177			selectee.startselected = false;
5178			that._trigger( "unselected", event, {
5179				unselected: selectee.element
5180			} );
5181		} );
5182		$( ".ui-selecting", this.element[ 0 ] ).each( function() {
5183			var selectee = $.data( this, "selectable-item" );
5184			that._removeClass( selectee.$element, "ui-selecting" )
5185				._addClass( selectee.$element, "ui-selected" );
5186			selectee.selecting = false;
5187			selectee.selected = true;
5188			selectee.startselected = true;
5189			that._trigger( "selected", event, {
5190				selected: selectee.element
5191			} );
5192		} );
5193		this._trigger( "stop", event );
5194
5195		this.helper.remove();
5196
5197		return false;
5198	}
5199
5200} );
5201
5202
5203/*!
5204 * jQuery UI Sortable 1.12.1
5205 * http://jqueryui.com
vendor: 35,818 bytes, lines 5206-6393
5206 *
5207 * Copyright jQuery Foundation and other contributors
5208 * Released under the MIT license.
5209 * http://jquery.org/license
5210 */
5211
5212//>>label: Sortable
5213//>>group: Interactions
5214//>>description: Enables items in a list to be sorted using the mouse.
5215//>>docs: http://api.jqueryui.com/sortable/
5216//>>demos: http://jqueryui.com/sortable/
5217//>>css.structure: ../../themes/base/sortable.css
5218
5219
5220
5221var widgetsSortable = $.widget( "ui.sortable", $.ui.mouse, {
5222	version: "1.12.1",
5223	widgetEventPrefix: "sort",
5224	ready: false,
5225	options: {
5226		appendTo: "parent",
5227		axis: false,
5228		connectWith: false,
5229		containment: false,
5230		cursor: "auto",
5231		cursorAt: false,
5232		dropOnEmpty: true,
5233		forcePlaceholderSize: false,
5234		forceHelperSize: false,
5235		grid: false,
5236		handle: false,
5237		helper: "original",
5238		items: "> *",
5239		opacity: false,
5240		placeholder: false,
5241		revert: false,
5242		scroll: true,
5243		scrollSensitivity: 20,
5244		scrollSpeed: 20,
5245		scope: "default",
5246		tolerance: "intersect",
5247		zIndex: 1000,
5248
5249		// Callbacks
5250		activate: null,
5251		beforeStop: null,
5252		change: null,
5253		deactivate: null,
5254		out: null,
5255		over: null,
5256		receive: null,
5257		remove: null,
5258		sort: null,
5259		start: null,
5260		stop: null,
5261		update: null
5262	},
5263
5264	_isOverAxis: function( x, reference, size ) {
5265		return ( x >= reference ) && ( x < ( reference + size ) );
5266	},
5267
5268	_isFloating: function( item ) {
5269		return ( /left|right/ ).test( item.css( "float" ) ) ||
5270			( /inline|table-cell/ ).test( item.css( "display" ) );
5271	},
5272
5273	_create: function() {
5274		this.containerCache = {};
5275		this._addClass( "ui-sortable" );
5276
5277		//Get the items
5278		this.refresh();
5279
5280		//Let's determine the parent's offset
5281		this.offset = this.element.offset();
5282
5283		//Initialize mouse events for interaction
5284		this._mouseInit();
5285
5286		this._setHandleClassName();
5287
5288		//We're ready to go
5289		this.ready = true;
5290
5291	},
5292
5293	_setOption: function( key, value ) {
5294		this._super( key, value );
5295
5296		if ( key === "handle" ) {
5297			this._setHandleClassName();
5298		}
5299	},
5300
5301	_setHandleClassName: function() {
5302		var that = this;
5303		this._removeClass( this.element.find( ".ui-sortable-handle" ), "ui-sortable-handle" );
5304		$.each( this.items, function() {
5305			that._addClass(
5306				this.instance.options.handle ?
5307					this.item.find( this.instance.options.handle ) :
5308					this.item,
5309				"ui-sortable-handle"
5310			);
5311		} );
5312	},
5313
5314	_destroy: function() {
5315		this._mouseDestroy();
5316
5317		for ( var i = this.items.length - 1; i >= 0; i-- ) {
5318			this.items[ i ].item.removeData( this.widgetName + "-item" );
5319		}
5320
5321		return this;
5322	},
5323
5324	_mouseCapture: function( event, overrideHandle ) {
5325		var currentItem = null,
5326			validHandle = false,
5327			that = this;
5328
5329		if ( this.reverting ) {
5330			return false;
5331		}
5332
5333		if ( this.options.disabled || this.options.type === "static" ) {
5334			return false;
5335		}
5336
5337		//We have to refresh the items data once first
5338		this._refreshItems( event );
5339
5340		//Find out if the clicked node (or one of its parents) is a actual item in this.items
5341		$( event.target ).parents().each( function() {
5342			if ( $.data( this, that.widgetName + "-item" ) === that ) {
5343				currentItem = $( this );
5344				return false;
5345			}
5346		} );
5347		if ( $.data( event.target, that.widgetName + "-item" ) === that ) {
5348			currentItem = $( event.target );
5349		}
5350
5351		if ( !currentItem ) {
5352			return false;
5353		}
5354		if ( this.options.handle && !overrideHandle ) {
5355			$( this.options.handle, currentItem ).find( "*" ).addBack().each( function() {
5356				if ( this === event.target ) {
5357					validHandle = true;
5358				}
5359			} );
5360			if ( !validHandle ) {
5361				return false;
5362			}
5363		}
5364
5365		this.currentItem = currentItem;
5366		this._removeCurrentsFromItems();
5367		return true;
5368
5369	},
5370
5371	_mouseStart: function( event, overrideHandle, noActivation ) {
5372
5373		var i, body,
5374			o = this.options;
5375
5376		this.currentContainer = this;
5377
5378		//We only need to call refreshPositions, because the refreshItems call has been moved to
5379		// mouseCapture
5380		this.refreshPositions();
5381
5382		//Create and append the visible helper
5383		this.helper = this._createHelper( event );
5384
5385		//Cache the helper size
5386		this._cacheHelperProportions();
5387
5388		/*
5389		 * - Position generation -
5390		 * This block generates everything position related - it's the core of draggables.
5391		 */
5392
5393		//Cache the margins of the original element
5394		this._cacheMargins();
5395
5396		//Get the next scrolling parent
5397		this.scrollParent = this.helper.scrollParent();
5398
5399		//The element's absolute position on the page minus margins
5400		this.offset = this.currentItem.offset();
5401		this.offset = {
5402			top: this.offset.top - this.margins.top,
5403			left: this.offset.left - this.margins.left
5404		};
5405
5406		$.extend( this.offset, {
5407			click: { //Where the click happened, relative to the element
5408				left: event.pageX - this.offset.left,
5409				top: event.pageY - this.offset.top
5410			},
5411			parent: this._getParentOffset(),
5412
5413			// This is a relative to absolute position minus the actual position calculation -
5414			// only used for relative positioned helper
5415			relative: this._getRelativeOffset()
5416		} );
5417
5418		// Only after we got the offset, we can change the helper's position to absolute
5419		// TODO: Still need to figure out a way to make relative sorting possible
5420		this.helper.css( "position", "absolute" );
5421		this.cssPosition = this.helper.css( "position" );
5422
5423		//Generate the original position
5424		this.originalPosition = this._generatePosition( event );
5425		this.originalPageX = event.pageX;
5426		this.originalPageY = event.pageY;
5427
5428		//Adjust the mouse offset relative to the helper if "cursorAt" is supplied
5429		( o.cursorAt && this._adjustOffsetFromHelper( o.cursorAt ) );
5430
5431		//Cache the former DOM position
5432		this.domPosition = {
5433			prev: this.currentItem.prev()[ 0 ],
5434			parent: this.currentItem.parent()[ 0 ]
5435		};
5436
5437		// If the helper is not the original, hide the original so it's not playing any role during
5438		// the drag, won't cause anything bad this way
5439		if ( this.helper[ 0 ] !== this.currentItem[ 0 ] ) {
5440			this.currentItem.hide();
5441		}
5442
5443		//Create the placeholder
5444		this._createPlaceholder();
5445
5446		//Set a containment if given in the options
5447		if ( o.containment ) {
5448			this._setContainment();
5449		}
5450
5451		if ( o.cursor && o.cursor !== "auto" ) { // cursor option
5452			body = this.document.find( "body" );
5453
5454			// Support: IE
5455			this.storedCursor = body.css( "cursor" );
5456			body.css( "cursor", o.cursor );
5457
5458			this.storedStylesheet =
5459				$( "<style>*{ cursor: " + o.cursor + " !important; }</style>" ).appendTo( body );
5460		}
5461
5462		if ( o.opacity ) { // opacity option
5463			if ( this.helper.css( "opacity" ) ) {
5464				this._storedOpacity = this.helper.css( "opacity" );
5465			}
5466			this.helper.css( "opacity", o.opacity );
5467		}
5468
5469		if ( o.zIndex ) { // zIndex option
5470			if ( this.helper.css( "zIndex" ) ) {
5471				this._storedZIndex = this.helper.css( "zIndex" );
5472			}
5473			this.helper.css( "zIndex", o.zIndex );
5474		}
5475
5476		//Prepare scrolling
5477		if ( this.scrollParent[ 0 ] !== this.document[ 0 ] &&
5478				this.scrollParent[ 0 ].tagName !== "HTML" ) {
5479			this.overflowOffset = this.scrollParent.offset();
5480		}
5481
5482		//Call callbacks
5483		this._trigger( "start", event, this._uiHash() );
5484
5485		//Recache the helper size
5486		if ( !this._preserveHelperProportions ) {
5487			this._cacheHelperProportions();
5488		}
5489
5490		//Post "activate" events to possible containers
5491		if ( !noActivation ) {
5492			for ( i = this.containers.length - 1; i >= 0; i-- ) {
5493				this.containers[ i ]._trigger( "activate", event, this._uiHash( this ) );
5494			}
5495		}
5496
5497		//Prepare possible droppables
5498		if ( $.ui.ddmanager ) {
5499			$.ui.ddmanager.current = this;
5500		}
5501
5502		if ( $.ui.ddmanager && !o.dropBehaviour ) {
5503			$.ui.ddmanager.prepareOffsets( this, event );
5504		}
5505
5506		this.dragging = true;
5507
5508		this._addClass( this.helper, "ui-sortable-helper" );
5509
5510		// Execute the drag once - this causes the helper not to be visiblebefore getting its
5511		// correct position
5512		this._mouseDrag( event );
5513		return true;
5514
5515	},
5516
5517	_mouseDrag: function( event ) {
5518		var i, item, itemElement, intersection,
5519			o = this.options,
5520			scrolled = false;
5521
5522		//Compute the helpers position
5523		this.position = this._generatePosition( event );
5524		this.positionAbs = this._convertPositionTo( "absolute" );
5525
5526		if ( !this.lastPositionAbs ) {
5527			this.lastPositionAbs = this.positionAbs;
5528		}
5529
5530		//Do scrolling
5531		if ( this.options.scroll ) {
5532			if ( this.scrollParent[ 0 ] !== this.document[ 0 ] &&
5533					this.scrollParent[ 0 ].tagName !== "HTML" ) {
5534
5535				if ( ( this.overflowOffset.top + this.scrollParent[ 0 ].offsetHeight ) -
5536						event.pageY < o.scrollSensitivity ) {
5537					this.scrollParent[ 0 ].scrollTop =
5538						scrolled = this.scrollParent[ 0 ].scrollTop + o.scrollSpeed;
5539				} else if ( event.pageY - this.overflowOffset.top < o.scrollSensitivity ) {
5540					this.scrollParent[ 0 ].scrollTop =
5541						scrolled = this.scrollParent[ 0 ].scrollTop - o.scrollSpeed;
5542				}
5543
5544				if ( ( this.overflowOffset.left + this.scrollParent[ 0 ].offsetWidth ) -
5545						event.pageX < o.scrollSensitivity ) {
5546					this.scrollParent[ 0 ].scrollLeft = scrolled =
5547						this.scrollParent[ 0 ].scrollLeft + o.scrollSpeed;
5548				} else if ( event.pageX - this.overflowOffset.left < o.scrollSensitivity ) {
5549					this.scrollParent[ 0 ].scrollLeft = scrolled =
5550						this.scrollParent[ 0 ].scrollLeft - o.scrollSpeed;
5551				}
5552
5553			} else {
5554
5555				if ( event.pageY - this.document.scrollTop() < o.scrollSensitivity ) {
5556					scrolled = this.document.scrollTop( this.document.scrollTop() - o.scrollSpeed );
5557				} else if ( this.window.height() - ( event.pageY - this.document.scrollTop() ) <
5558						o.scrollSensitivity ) {
5559					scrolled = this.document.scrollTop( this.document.scrollTop() + o.scrollSpeed );
5560				}
5561
5562				if ( event.pageX - this.document.scrollLeft() < o.scrollSensitivity ) {
5563					scrolled = this.document.scrollLeft(
5564						this.document.scrollLeft() - o.scrollSpeed
5565					);
5566				} else if ( this.window.width() - ( event.pageX - this.document.scrollLeft() ) <
5567						o.scrollSensitivity ) {
5568					scrolled = this.document.scrollLeft(
5569						this.document.scrollLeft() + o.scrollSpeed
5570					);
5571				}
5572
5573			}
5574
5575			if ( scrolled !== false && $.ui.ddmanager && !o.dropBehaviour ) {
5576				$.ui.ddmanager.prepareOffsets( this, event );
5577			}
5578		}
5579
5580		//Regenerate the absolute position used for position checks
5581		this.positionAbs = this._convertPositionTo( "absolute" );
5582
5583		//Set the helper position
5584		if ( !this.options.axis || this.options.axis !== "y" ) {
5585			this.helper[ 0 ].style.left = this.position.left + "px";
5586		}
5587		if ( !this.options.axis || this.options.axis !== "x" ) {
5588			this.helper[ 0 ].style.top = this.position.top + "px";
5589		}
5590
5591		//Rearrange
5592		for ( i = this.items.length - 1; i >= 0; i-- ) {
5593
5594			//Cache variables and intersection, continue if no intersection
5595			item = this.items[ i ];
5596			itemElement = item.item[ 0 ];
5597			intersection = this._intersectsWithPointer( item );
5598			if ( !intersection ) {
5599				continue;
5600			}
5601
5602			// Only put the placeholder inside the current Container, skip all
5603			// items from other containers. This works because when moving
5604			// an item from one container to another the
5605			// currentContainer is switched before the placeholder is moved.
5606			//
5607			// Without this, moving items in "sub-sortables" can cause
5608			// the placeholder to jitter between the outer and inner container.
5609			if ( item.instance !== this.currentContainer ) {
5610				continue;
5611			}
5612
5613			// Cannot intersect with itself
5614			// no useless actions that have been done before
5615			// no action if the item moved is the parent of the item checked
5616			if ( itemElement !== this.currentItem[ 0 ] &&
5617				this.placeholder[ intersection === 1 ? "next" : "prev" ]()[ 0 ] !== itemElement &&
5618				!$.contains( this.placeholder[ 0 ], itemElement ) &&
5619				( this.options.type === "semi-dynamic" ?
5620					!$.contains( this.element[ 0 ], itemElement ) :
5621					true
5622				)
5623			) {
5624
5625				this.direction = intersection === 1 ? "down" : "up";
5626
5627				if ( this.options.tolerance === "pointer" || this._intersectsWithSides( item ) ) {
5628					this._rearrange( event, item );
5629				} else {
5630					break;
5631				}
5632
5633				this._trigger( "change", event, this._uiHash() );
5634				break;
5635			}
5636		}
5637
5638		//Post events to containers
5639		this._contactContainers( event );
5640
5641		//Interconnect with droppables
5642		if ( $.ui.ddmanager ) {
5643			$.ui.ddmanager.drag( this, event );
5644		}
5645
5646		//Call callbacks
5647		this._trigger( "sort", event, this._uiHash() );
5648
5649		this.lastPositionAbs = this.positionAbs;
5650		return false;
5651
5652	},
5653
5654	_mouseStop: function( event, noPropagation ) {
5655
5656		if ( !event ) {
5657			return;
5658		}
5659
5660		//If we are using droppables, inform the manager about the drop
5661		if ( $.ui.ddmanager && !this.options.dropBehaviour ) {
5662			$.ui.ddmanager.drop( this, event );
5663		}
5664
5665		if ( this.options.revert ) {
5666			var that = this,
5667				cur = this.placeholder.offset(),
5668				axis = this.options.axis,
5669				animation = {};
5670
5671			if ( !axis || axis === "x" ) {
5672				animation.left = cur.left - this.offset.parent.left - this.margins.left +
5673					( this.offsetParent[ 0 ] === this.document[ 0 ].body ?
5674						0 :
5675						this.offsetParent[ 0 ].scrollLeft
5676					);
5677			}
5678			if ( !axis || axis === "y" ) {
5679				animation.top = cur.top - this.offset.parent.top - this.margins.top +
5680					( this.offsetParent[ 0 ] === this.document[ 0 ].body ?
5681						0 :
5682						this.offsetParent[ 0 ].scrollTop
5683					);
5684			}
5685			this.reverting = true;
5686			$( this.helper ).animate(
5687				animation,
5688				parseInt( this.options.revert, 10 ) || 500,
5689				function() {
5690					that._clear( event );
5691				}
5692			);
5693		} else {
5694			this._clear( event, noPropagation );
5695		}
5696
5697		return false;
5698
5699	},
5700
5701	cancel: function() {
5702
5703		if ( this.dragging ) {
5704
5705			this._mouseUp( new $.Event( "mouseup", { target: null } ) );
5706
5707			if ( this.options.helper === "original" ) {
5708				this.currentItem.css( this._storedCSS );
5709				this._removeClass( this.currentItem, "ui-sortable-helper" );
5710			} else {
5711				this.currentItem.show();
5712			}
5713
5714			//Post deactivating events to containers
5715			for ( var i = this.containers.length - 1; i >= 0; i-- ) {
5716				this.containers[ i ]._trigger( "deactivate", null, this._uiHash( this ) );
5717				if ( this.containers[ i ].containerCache.over ) {
5718					this.containers[ i ]._trigger( "out", null, this._uiHash( this ) );
5719					this.containers[ i ].containerCache.over = 0;
5720				}
5721			}
5722
5723		}
5724
5725		if ( this.placeholder ) {
5726
5727			//$(this.placeholder[0]).remove(); would have been the jQuery way - unfortunately,
5728			// it unbinds ALL events from the original node!
5729			if ( this.placeholder[ 0 ].parentNode ) {
5730				this.placeholder[ 0 ].parentNode.removeChild( this.placeholder[ 0 ] );
5731			}
5732			if ( this.options.helper !== "original" && this.helper &&
5733					this.helper[ 0 ].parentNode ) {
5734				this.helper.remove();
5735			}
5736
5737			$.extend( this, {
5738				helper: null,
5739				dragging: false,
5740				reverting: false,
5741				_noFinalSort: null
5742			} );
5743
5744			if ( this.domPosition.prev ) {
5745				$( this.domPosition.prev ).after( this.currentItem );
5746			} else {
5747				$( this.domPosition.parent ).prepend( this.currentItem );
5748			}
5749		}
5750
5751		return this;
5752
5753	},
5754
5755	serialize: function( o ) {
5756
5757		var items = this._getItemsAsjQuery( o && o.connected ),
5758			str = [];
5759		o = o || {};
5760
5761		$( items ).each( function() {
5762			var res = ( $( o.item || this ).attr( o.attribute || "id" ) || "" )
5763				.match( o.expression || ( /(.+)[\-=_](.+)/ ) );
5764			if ( res ) {
5765				str.push(
5766					( o.key || res[ 1 ] + "[]" ) +
5767					"=" + ( o.key && o.expression ? res[ 1 ] : res[ 2 ] ) );
5768			}
5769		} );
5770
5771		if ( !str.length && o.key ) {
5772			str.push( o.key + "=" );
5773		}
5774
5775		return str.join( "&" );
5776
5777	},
5778
5779	toArray: function( o ) {
5780
5781		var items = this._getItemsAsjQuery( o && o.connected ),
5782			ret = [];
5783
5784		o = o || {};
5785
5786		items.each( function() {
5787			ret.push( $( o.item || this ).attr( o.attribute || "id" ) || "" );
5788		} );
5789		return ret;
5790
5791	},
5792
5793	/* Be careful with the following core functions */
5794	_intersectsWith: function( item ) {
5795
5796		var x1 = this.positionAbs.left,
5797			x2 = x1 + this.helperProportions.width,
5798			y1 = this.positionAbs.top,
5799			y2 = y1 + this.helperProportions.height,
5800			l = item.left,
5801			r = l + item.width,
5802			t = item.top,
5803			b = t + item.height,
5804			dyClick = this.offset.click.top,
5805			dxClick = this.offset.click.left,
5806			isOverElementHeight = ( this.options.axis === "x" ) || ( ( y1 + dyClick ) > t &&
5807				( y1 + dyClick ) < b ),
5808			isOverElementWidth = ( this.options.axis === "y" ) || ( ( x1 + dxClick ) > l &&
5809				( x1 + dxClick ) < r ),
5810			isOverElement = isOverElementHeight && isOverElementWidth;
5811
5812		if ( this.options.tolerance === "pointer" ||
5813			this.options.forcePointerForContainers ||
5814			( this.options.tolerance !== "pointer" &&
5815				this.helperProportions[ this.floating ? "width" : "height" ] >
5816				item[ this.floating ? "width" : "height" ] )
5817		) {
5818			return isOverElement;
5819		} else {
5820
5821			return ( l < x1 + ( this.helperProportions.width / 2 ) && // Right Half
5822				x2 - ( this.helperProportions.width / 2 ) < r && // Left Half
5823				t < y1 + ( this.helperProportions.height / 2 ) && // Bottom Half
5824				y2 - ( this.helperProportions.height / 2 ) < b ); // Top Half
5825
5826		}
5827	},
5828
5829	_intersectsWithPointer: function( item ) {
5830		var verticalDirection, horizontalDirection,
5831			isOverElementHeight = ( this.options.axis === "x" ) ||
5832				this._isOverAxis(
5833					this.positionAbs.top + this.offset.click.top, item.top, item.height ),
5834			isOverElementWidth = ( this.options.axis === "y" ) ||
5835				this._isOverAxis(
5836					this.positionAbs.left + this.offset.click.left, item.left, item.width ),
5837			isOverElement = isOverElementHeight && isOverElementWidth;
5838
5839		if ( !isOverElement ) {
5840			return false;
5841		}
5842
5843		verticalDirection = this._getDragVerticalDirection();
5844		horizontalDirection = this._getDragHorizontalDirection();
5845
5846		return this.floating ?
5847			( ( horizontalDirection === "right" || verticalDirection === "down" ) ? 2 : 1 )
5848			: ( verticalDirection && ( verticalDirection === "down" ? 2 : 1 ) );
5849
5850	},
5851
5852	_intersectsWithSides: function( item ) {
5853
5854		var isOverBottomHalf = this._isOverAxis( this.positionAbs.top +
5855				this.offset.click.top, item.top + ( item.height / 2 ), item.height ),
5856			isOverRightHalf = this._isOverAxis( this.positionAbs.left +
5857				this.offset.click.left, item.left + ( item.width / 2 ), item.width ),
5858			verticalDirection = this._getDragVerticalDirection(),
5859			horizontalDirection = this._getDragHorizontalDirection();
5860
5861		if ( this.floating && horizontalDirection ) {
5862			return ( ( horizontalDirection === "right" && isOverRightHalf ) ||
5863				( horizontalDirection === "left" && !isOverRightHalf ) );
5864		} else {
5865			return verticalDirection && ( ( verticalDirection === "down" && isOverBottomHalf ) ||
5866				( verticalDirection === "up" && !isOverBottomHalf ) );
5867		}
5868
5869	},
5870
5871	_getDragVerticalDirection: function() {
5872		var delta = this.positionAbs.top - this.lastPositionAbs.top;
5873		return delta !== 0 && ( delta > 0 ? "down" : "up" );
5874	},
5875
5876	_getDragHorizontalDirection: function() {
5877		var delta = this.positionAbs.left - this.lastPositionAbs.left;
5878		return delta !== 0 && ( delta > 0 ? "right" : "left" );
5879	},
5880
5881	refresh: function( event ) {
5882		this._refreshItems( event );
5883		this._setHandleClassName();
5884		this.refreshPositions();
5885		return this;
5886	},
5887
5888	_connectWith: function() {
5889		var options = this.options;
5890		return options.connectWith.constructor === String ?
5891			[ options.connectWith ] :
5892			options.connectWith;
5893	},
5894
5895	_getItemsAsjQuery: function( connected ) {
5896
5897		var i, j, cur, inst,
5898			items = [],
5899			queries = [],
5900			connectWith = this._connectWith();
5901
5902		if ( connectWith && connected ) {
5903			for ( i = connectWith.length - 1; i >= 0; i-- ) {
5904				cur = $( connectWith[ i ], this.document[ 0 ] );
5905				for ( j = cur.length - 1; j >= 0; j-- ) {
5906					inst = $.data( cur[ j ], this.widgetFullName );
5907					if ( inst && inst !== this && !inst.options.disabled ) {
5908						queries.push( [ $.isFunction( inst.options.items ) ?
5909							inst.options.items.call( inst.element ) :
5910							$( inst.options.items, inst.element )
5911								.not( ".ui-sortable-helper" )
5912								.not( ".ui-sortable-placeholder" ), inst ] );
5913					}
5914				}
5915			}
5916		}
5917
5918		queries.push( [ $.isFunction( this.options.items ) ?
5919			this.options.items
5920				.call( this.element, null, { options: this.options, item: this.currentItem } ) :
5921			$( this.options.items, this.element )
5922				.not( ".ui-sortable-helper" )
5923				.not( ".ui-sortable-placeholder" ), this ] );
5924
5925		function addItems() {
5926			items.push( this );
5927		}
5928		for ( i = queries.length - 1; i >= 0; i-- ) {
5929			queries[ i ][ 0 ].each( addItems );
5930		}
5931
5932		return $( items );
5933
5934	},
5935
5936	_removeCurrentsFromItems: function() {
5937
5938		var list = this.currentItem.find( ":data(" + this.widgetName + "-item)" );
5939
5940		this.items = $.grep( this.items, function( item ) {
5941			for ( var j = 0; j < list.length; j++ ) {
5942				if ( list[ j ] === item.item[ 0 ] ) {
5943					return false;
5944				}
5945			}
5946			return true;
5947		} );
5948
5949	},
5950
5951	_refreshItems: function( event ) {
5952
5953		this.items = [];
5954		this.containers = [ this ];
5955
5956		var i, j, cur, inst, targetData, _queries, item, queriesLength,
5957			items = this.items,
5958			queries = [ [ $.isFunction( this.options.items ) ?
5959				this.options.items.call( this.element[ 0 ], event, { item: this.currentItem } ) :
5960				$( this.options.items, this.element ), this ] ],
5961			connectWith = this._connectWith();
5962
5963		//Shouldn't be run the first time through due to massive slow-down
5964		if ( connectWith && this.ready ) {
5965			for ( i = connectWith.length - 1; i >= 0; i-- ) {
5966				cur = $( connectWith[ i ], this.document[ 0 ] );
5967				for ( j = cur.length - 1; j >= 0; j-- ) {
5968					inst = $.data( cur[ j ], this.widgetFullName );
5969					if ( inst && inst !== this && !inst.options.disabled ) {
5970						queries.push( [ $.isFunction( inst.options.items ) ?
5971							inst.options.items
5972								.call( inst.element[ 0 ], event, { item: this.currentItem } ) :
5973							$( inst.options.items, inst.element ), inst ] );
5974						this.containers.push( inst );
5975					}
5976				}
5977			}
5978		}
5979
5980		for ( i = queries.length - 1; i >= 0; i-- ) {
5981			targetData = queries[ i ][ 1 ];
5982			_queries = queries[ i ][ 0 ];
5983
5984			for ( j = 0, queriesLength = _queries.length; j < queriesLength; j++ ) {
5985				item = $( _queries[ j ] );
5986
5987				// Data for target checking (mouse manager)
5988				item.data( this.widgetName + "-item", targetData );
5989
5990				items.push( {
5991					item: item,
5992					instance: targetData,
5993					width: 0, height: 0,
5994					left: 0, top: 0
5995				} );
5996			}
5997		}
5998
5999	},
6000
6001	refreshPositions: function( fast ) {
6002
6003		// Determine whether items are being displayed horizontally
6004		this.floating = this.items.length ?
6005			this.options.axis === "x" || this._isFloating( this.items[ 0 ].item ) :
6006			false;
6007
6008		//This has to be redone because due to the item being moved out/into the offsetParent,
6009		// the offsetParent's position will change
6010		if ( this.offsetParent && this.helper ) {
6011			this.offset.parent = this._getParentOffset();
6012		}
6013
6014		var i, item, t, p;
6015
6016		for ( i = this.items.length - 1; i >= 0; i-- ) {
6017			item = this.items[ i ];
6018
6019			//We ignore calculating positions of all connected containers when we're not over them
6020			if ( item.instance !== this.currentContainer && this.currentContainer &&
6021					item.item[ 0 ] !== this.currentItem[ 0 ] ) {
6022				continue;
6023			}
6024
6025			t = this.options.toleranceElement ?
6026				$( this.options.toleranceElement, item.item ) :
6027				item.item;
6028
6029			if ( !fast ) {
6030				item.width = t.outerWidth();
6031				item.height = t.outerHeight();
6032			}
6033
6034			p = t.offset();
6035			item.left = p.left;
6036			item.top = p.top;
6037		}
6038
6039		if ( this.options.custom && this.options.custom.refreshContainers ) {
6040			this.options.custom.refreshContainers.call( this );
6041		} else {
6042			for ( i = this.containers.length - 1; i >= 0; i-- ) {
6043				p = this.containers[ i ].element.offset();
6044				this.containers[ i ].containerCache.left = p.left;
6045				this.containers[ i ].containerCache.top = p.top;
6046				this.containers[ i ].containerCache.width =
6047					this.containers[ i ].element.outerWidth();
6048				this.containers[ i ].containerCache.height =
6049					this.containers[ i ].element.outerHeight();
6050			}
6051		}
6052
6053		return this;
6054	},
6055
6056	_createPlaceholder: function( that ) {
6057		that = that || this;
6058		var className,
6059			o = that.options;
6060
6061		if ( !o.placeholder || o.placeholder.constructor === String ) {
6062			className = o.placeholder;
6063			o.placeholder = {
6064				element: function() {
6065
6066					var nodeName = that.currentItem[ 0 ].nodeName.toLowerCase(),
6067						element = $( "<" + nodeName + ">", that.document[ 0 ] );
6068
6069						that._addClass( element, "ui-sortable-placeholder",
6070								className || that.currentItem[ 0 ].className )
6071							._removeClass( element, "ui-sortable-helper" );
6072
6073					if ( nodeName === "tbody" ) {
6074						that._createTrPlaceholder(
6075							that.currentItem.find( "tr" ).eq( 0 ),
6076							$( "<tr>", that.document[ 0 ] ).appendTo( element )
6077						);
6078					} else if ( nodeName === "tr" ) {
6079						that._createTrPlaceholder( that.currentItem, element );
6080					} else if ( nodeName === "img" ) {
6081						element.attr( "src", that.currentItem.attr( "src" ) );
6082					}
6083
6084					if ( !className ) {
6085						element.css( "visibility", "hidden" );
6086					}
6087
6088					return element;
6089				},
6090				update: function( container, p ) {
6091
6092					// 1. If a className is set as 'placeholder option, we don't force sizes -
6093					// the class is responsible for that
6094					// 2. The option 'forcePlaceholderSize can be enabled to force it even if a
6095					// class name is specified
6096					if ( className && !o.forcePlaceholderSize ) {
6097						return;
6098					}
6099
6100					//If the element doesn't have a actual height by itself (without styles coming
6101					// from a stylesheet), it receives the inline height from the dragged item
6102					if ( !p.height() ) {
6103						p.height(
6104							that.currentItem.innerHeight() -
6105							parseInt( that.currentItem.css( "paddingTop" ) || 0, 10 ) -
6106							parseInt( that.currentItem.css( "paddingBottom" ) || 0, 10 ) );
6107					}
6108					if ( !p.width() ) {
6109						p.width(
6110							that.currentItem.innerWidth() -
6111							parseInt( that.currentItem.css( "paddingLeft" ) || 0, 10 ) -
6112							parseInt( that.currentItem.css( "paddingRight" ) || 0, 10 ) );
6113					}
6114				}
6115			};
6116		}
6117
6118		//Create the placeholder
6119		that.placeholder = $( o.placeholder.element.call( that.element, that.currentItem ) );
6120
6121		//Append it after the actual current item
6122		that.currentItem.after( that.placeholder );
6123
6124		//Update the size of the placeholder (TODO: Logic to fuzzy, see line 316/317)
6125		o.placeholder.update( that, that.placeholder );
6126
6127	},
6128
6129	_createTrPlaceholder: function( sourceTr, targetTr ) {
6130		var that = this;
6131
6132		sourceTr.children().each( function() {
6133			$( "<td>&#160;</td>", that.document[ 0 ] )
6134				.attr( "colspan", $( this ).attr( "colspan" ) || 1 )
6135				.appendTo( targetTr );
6136		} );
6137	},
6138
6139	_contactContainers: function( event ) {
6140		var i, j, dist, itemWithLeastDistance, posProperty, sizeProperty, cur, nearBottom,
6141			floating, axis,
6142			innermostContainer = null,
6143			innermostIndex = null;
6144
6145		// Get innermost container that intersects with item
6146		for ( i = this.containers.length - 1; i >= 0; i-- ) {
6147
6148			// Never consider a container that's located within the item itself
6149			if ( $.contains( this.currentItem[ 0 ], this.containers[ i ].element[ 0 ] ) ) {
6150				continue;
6151			}
6152
6153			if ( this._intersectsWith( this.containers[ i ].containerCache ) ) {
6154
6155				// If we've already found a container and it's more "inner" than this, then continue
6156				if ( innermostContainer &&
6157						$.contains(
6158							this.containers[ i ].element[ 0 ],
6159							innermostContainer.element[ 0 ] ) ) {
6160					continue;
6161				}
6162
6163				innermostContainer = this.containers[ i ];
6164				innermostIndex = i;
6165
6166			} else {
6167
6168				// container doesn't intersect. trigger "out" event if necessary
6169				if ( this.containers[ i ].containerCache.over ) {
6170					this.containers[ i ]._trigger( "out", event, this._uiHash( this ) );
6171					this.containers[ i ].containerCache.over = 0;
6172				}
6173			}
6174
6175		}
6176
6177		// If no intersecting containers found, return
6178		if ( !innermostContainer ) {
6179			return;
6180		}
6181
6182		// Move the item into the container if it's not there already
6183		if ( this.containers.length === 1 ) {
6184			if ( !this.containers[ innermostIndex ].containerCache.over ) {
6185				this.containers[ innermostIndex ]._trigger( "over", event, this._uiHash( this ) );
6186				this.containers[ innermostIndex ].containerCache.over = 1;
6187			}
6188		} else {
6189
6190			// When entering a new container, we will find the item with the least distance and
6191			// append our item near it
6192			dist = 10000;
6193			itemWithLeastDistance = null;
6194			floating = innermostContainer.floating || this._isFloating( this.currentItem );
6195			posProperty = floating ? "left" : "top";
6196			sizeProperty = floating ? "width" : "height";
6197			axis = floating ? "pageX" : "pageY";
6198
6199			for ( j = this.items.length - 1; j >= 0; j-- ) {
6200				if ( !$.contains(
6201						this.containers[ innermostIndex ].element[ 0 ], this.items[ j ].item[ 0 ] )
6202				) {
6203					continue;
6204				}
6205				if ( this.items[ j ].item[ 0 ] === this.currentItem[ 0 ] ) {
6206					continue;
6207				}
6208
6209				cur = this.items[ j ].item.offset()[ posProperty ];
6210				nearBottom = false;
6211				if ( event[ axis ] - cur > this.items[ j ][ sizeProperty ] / 2 ) {
6212					nearBottom = true;
6213				}
6214
6215				if ( Math.abs( event[ axis ] - cur ) < dist ) {
6216					dist = Math.abs( event[ axis ] - cur );
6217					itemWithLeastDistance = this.items[ j ];
6218					this.direction = nearBottom ? "up" : "down";
6219				}
6220			}
6221
6222			//Check if dropOnEmpty is enabled
6223			if ( !itemWithLeastDistance && !this.options.dropOnEmpty ) {
6224				return;
6225			}
6226
6227			if ( this.currentContainer === this.containers[ innermostIndex ] ) {
6228				if ( !this.currentContainer.containerCache.over ) {
6229					this.containers[ innermostIndex ]._trigger( "over", event, this._uiHash() );
6230					this.currentContainer.containerCache.over = 1;
6231				}
6232				return;
6233			}
6234
6235			itemWithLeastDistance ?
6236				this._rearrange( event, itemWithLeastDistance, null, true ) :
6237				this._rearrange( event, null, this.containers[ innermostIndex ].element, true );
6238			this._trigger( "change", event, this._uiHash() );
6239			this.containers[ innermostIndex ]._trigger( "change", event, this._uiHash( this ) );
6240			this.currentContainer = this.containers[ innermostIndex ];
6241
6242			//Update the placeholder
6243			this.options.placeholder.update( this.currentContainer, this.placeholder );
6244
6245			this.containers[ innermostIndex ]._trigger( "over", event, this._uiHash( this ) );
6246			this.containers[ innermostIndex ].containerCache.over = 1;
6247		}
6248
6249	},
6250
6251	_createHelper: function( event ) {
6252
6253		var o = this.options,
6254			helper = $.isFunction( o.helper ) ?
6255				$( o.helper.apply( this.element[ 0 ], [ event, this.currentItem ] ) ) :
6256				( o.helper === "clone" ? this.currentItem.clone() : this.currentItem );
6257
6258		//Add the helper to the DOM if that didn't happen already
6259		if ( !helper.parents( "body" ).length ) {
6260			$( o.appendTo !== "parent" ?
6261				o.appendTo :
6262				this.currentItem[ 0 ].parentNode )[ 0 ].appendChild( helper[ 0 ] );
6263		}
6264
6265		if ( helper[ 0 ] === this.currentItem[ 0 ] ) {
6266			this._storedCSS = {
6267				width: this.currentItem[ 0 ].style.width,
6268				height: this.currentItem[ 0 ].style.height,
6269				position: this.currentItem.css( "position" ),
6270				top: this.currentItem.css( "top" ),
6271				left: this.currentItem.css( "left" )
6272			};
6273		}
6274
6275		if ( !helper[ 0 ].style.width || o.forceHelperSize ) {
6276			helper.width( this.currentItem.width() );
6277		}
6278		if ( !helper[ 0 ].style.height || o.forceHelperSize ) {
6279			helper.height( this.currentItem.height() );
6280		}
6281
6282		return helper;
6283
6284	},
6285
6286	_adjustOffsetFromHelper: function( obj ) {
6287		if ( typeof obj === "string" ) {
6288			obj = obj.split( " " );
6289		}
6290		if ( $.isArray( obj ) ) {
6291			obj = { left: +obj[ 0 ], top: +obj[ 1 ] || 0 };
6292		}
6293		if ( "left" in obj ) {
6294			this.offset.click.left = obj.left + this.margins.left;
6295		}
6296		if ( "right" in obj ) {
6297			this.offset.click.left = this.helperProportions.width - obj.right + this.margins.left;
6298		}
6299		if ( "top" in obj ) {
6300			this.offset.click.top = obj.top + this.margins.top;
6301		}
6302		if ( "bottom" in obj ) {
6303			this.offset.click.top = this.helperProportions.height - obj.bottom + this.margins.top;
6304		}
6305	},
6306
6307	_getParentOffset: function() {
6308
6309		//Get the offsetParent and cache its position
6310		this.offsetParent = this.helper.offsetParent();
6311		var po = this.offsetParent.offset();
6312
6313		// This is a special case where we need to modify a offset calculated on start, since the
6314		// following happened:
6315		// 1. The position of the helper is absolute, so it's position is calculated based on the
6316		// next positioned parent
6317		// 2. The actual offset parent is a child of the scroll parent, and the scroll parent isn't
6318		// the document, which means that the scroll is included in the initial calculation of the
6319		// offset of the parent, and never recalculated upon drag
6320		if ( this.cssPosition === "absolute" && this.scrollParent[ 0 ] !== this.document[ 0 ] &&
6321				$.contains( this.scrollParent[ 0 ], this.offsetParent[ 0 ] ) ) {
6322			po.left += this.scrollParent.scrollLeft();
6323			po.top += this.scrollParent.scrollTop();
6324		}
6325
6326		// This needs to be actually done for all browsers, since pageX/pageY includes this
6327		// information with an ugly IE fix
6328		if ( this.offsetParent[ 0 ] === this.document[ 0 ].body ||
6329				( this.offsetParent[ 0 ].tagName &&
6330				this.offsetParent[ 0 ].tagName.toLowerCase() === "html" && $.ui.ie ) ) {
6331			po = { top: 0, left: 0 };
6332		}
6333
6334		return {
6335			top: po.top + ( parseInt( this.offsetParent.css( "borderTopWidth" ), 10 ) || 0 ),
6336			left: po.left + ( parseInt( this.offsetParent.css( "borderLeftWidth" ), 10 ) || 0 )
6337		};
6338
6339	},
6340
6341	_getRelativeOffset: function() {
6342
6343		if ( this.cssPosition === "relative" ) {
6344			var p = this.currentItem.position();
6345			return {
6346				top: p.top - ( parseInt( this.helper.css( "top" ), 10 ) || 0 ) +
6347					this.scrollParent.scrollTop(),
6348				left: p.left - ( parseInt( this.helper.css( "left" ), 10 ) || 0 ) +
6349					this.scrollParent.scrollLeft()
6350			};
6351		} else {
6352			return { top: 0, left: 0 };
6353		}
6354
6355	},
6356
6357	_cacheMargins: function() {
6358		this.margins = {
6359			left: ( parseInt( this.currentItem.css( "marginLeft" ), 10 ) || 0 ),
6360			top: ( parseInt( this.currentItem.css( "marginTop" ), 10 ) || 0 )
6361		};
6362	},
6363
6364	_cacheHelperProportions: function() {
6365		this.helperProportions = {
6366			width: this.helper.outerWidth(),
6367			height: this.helper.outerHeight()
6368		};
6369	},
6370
6371	_setContainment: function() {
6372
6373		var ce, co, over,
6374			o = this.options;
6375		if ( o.containment === "parent" ) {
6376			o.containment = this.helper[ 0 ].parentNode;
6377		}
6378		if ( o.containment === "document" || o.containment === "window" ) {
6379			this.containment = [
6380				0 - this.offset.relative.left - this.offset.parent.left,
6381				0 - this.offset.relative.top - this.offset.parent.top,
6382				o.containment === "document" ?
6383					this.document.width() :
6384					this.window.width() - this.helperProportions.width - this.margins.left,
6385				( o.containment === "document" ?
6386					( this.document.height() || document.body.parentNode.scrollHeight ) :
6387					this.window.height() || this.document[ 0 ].body.parentNode.scrollHeight
6388				) - this.helperProportions.height - this.margins.top
6389			];
6390		}
6391
6392		if ( !( /^(document|window|parent)$/ ).test( o.containment ) ) {
6393			ce = $( o.containment )[ 0 ];
vendor: 2,294 bytes, lines 6394-6454
6394			co = $( o.containment ).offset();
6395			over = ( $( ce ).css( "overflow" ) !== "hidden" );
6396
6397			this.containment = [
6398				co.left + ( parseInt( $( ce ).css( "borderLeftWidth" ), 10 ) || 0 ) +
6399					( parseInt( $( ce ).css( "paddingLeft" ), 10 ) || 0 ) - this.margins.left,
6400				co.top + ( parseInt( $( ce ).css( "borderTopWidth" ), 10 ) || 0 ) +
6401					( parseInt( $( ce ).css( "paddingTop" ), 10 ) || 0 ) - this.margins.top,
6402				co.left + ( over ? Math.max( ce.scrollWidth, ce.offsetWidth ) : ce.offsetWidth ) -
6403					( parseInt( $( ce ).css( "borderLeftWidth" ), 10 ) || 0 ) -
6404					( parseInt( $( ce ).css( "paddingRight" ), 10 ) || 0 ) -
6405					this.helperProportions.width - this.margins.left,
6406				co.top + ( over ? Math.max( ce.scrollHeight, ce.offsetHeight ) : ce.offsetHeight ) -
6407					( parseInt( $( ce ).css( "borderTopWidth" ), 10 ) || 0 ) -
6408					( parseInt( $( ce ).css( "paddingBottom" ), 10 ) || 0 ) -
6409					this.helperProportions.height - this.margins.top
6410			];
6411		}
6412
6413	},
6414
6415	_convertPositionTo: function( d, pos ) {
6416
6417		if ( !pos ) {
6418			pos = this.position;
6419		}
6420		var mod = d === "absolute" ? 1 : -1,
6421			scroll = this.cssPosition === "absolute" &&
6422				!( this.scrollParent[ 0 ] !== this.document[ 0 ] &&
6423				$.contains( this.scrollParent[ 0 ], this.offsetParent[ 0 ] ) ) ?
6424					this.offsetParent :
6425					this.scrollParent,
6426			scrollIsRootNode = ( /(html|body)/i ).test( scroll[ 0 ].tagName );
6427
6428		return {
6429			top: (
6430
6431				// The absolute mouse position
6432				pos.top	+
6433
6434				// Only for relative positioned nodes: Relative offset from element to offset parent
6435				this.offset.relative.top * mod +
6436
6437				// The offsetParent's offset without borders (offset + border)
6438				this.offset.parent.top * mod -
6439				( ( this.cssPosition === "fixed" ?
6440					-this.scrollParent.scrollTop() :
6441					( scrollIsRootNode ? 0 : scroll.scrollTop() ) ) * mod )
6442			),
6443			left: (
6444
6445				// The absolute mouse position
6446				pos.left +
6447
6448				// Only for relative positioned nodes: Relative offset from element to offset parent
6449				this.offset.relative.left * mod +
6450
6451				// The offsetParent's offset without borders (offset + border)
6452				this.offset.parent.left * mod	-
6453				( ( this.cssPosition === "fixed" ?
6454					-this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 :
vendor: 9,205 bytes, lines 6455-6741
6455					scroll.scrollLeft() ) * mod )
6456			)
6457		};
6458
6459	},
6460
6461	_generatePosition: function( event ) {
6462
6463		var top, left,
6464			o = this.options,
6465			pageX = event.pageX,
6466			pageY = event.pageY,
6467			scroll = this.cssPosition === "absolute" &&
6468				!( this.scrollParent[ 0 ] !== this.document[ 0 ] &&
6469				$.contains( this.scrollParent[ 0 ], this.offsetParent[ 0 ] ) ) ?
6470					this.offsetParent :
6471					this.scrollParent,
6472				scrollIsRootNode = ( /(html|body)/i ).test( scroll[ 0 ].tagName );
6473
6474		// This is another very weird special case that only happens for relative elements:
6475		// 1. If the css position is relative
6476		// 2. and the scroll parent is the document or similar to the offset parent
6477		// we have to refresh the relative offset during the scroll so there are no jumps
6478		if ( this.cssPosition === "relative" && !( this.scrollParent[ 0 ] !== this.document[ 0 ] &&
6479				this.scrollParent[ 0 ] !== this.offsetParent[ 0 ] ) ) {
6480			this.offset.relative = this._getRelativeOffset();
6481		}
6482
6483		/*
6484		 * - Position constraining -
6485		 * Constrain the position to a mix of grid, containment.
6486		 */
6487
6488		if ( this.originalPosition ) { //If we are not dragging yet, we won't check for options
6489
6490			if ( this.containment ) {
6491				if ( event.pageX - this.offset.click.left < this.containment[ 0 ] ) {
6492					pageX = this.containment[ 0 ] + this.offset.click.left;
6493				}
6494				if ( event.pageY - this.offset.click.top < this.containment[ 1 ] ) {
6495					pageY = this.containment[ 1 ] + this.offset.click.top;
6496				}
6497				if ( event.pageX - this.offset.click.left > this.containment[ 2 ] ) {
6498					pageX = this.containment[ 2 ] + this.offset.click.left;
6499				}
6500				if ( event.pageY - this.offset.click.top > this.containment[ 3 ] ) {
6501					pageY = this.containment[ 3 ] + this.offset.click.top;
6502				}
6503			}
6504
6505			if ( o.grid ) {
6506				top = this.originalPageY + Math.round( ( pageY - this.originalPageY ) /
6507					o.grid[ 1 ] ) * o.grid[ 1 ];
6508				pageY = this.containment ?
6509					( ( top - this.offset.click.top >= this.containment[ 1 ] &&
6510						top - this.offset.click.top <= this.containment[ 3 ] ) ?
6511							top :
6512							( ( top - this.offset.click.top >= this.containment[ 1 ] ) ?
6513								top - o.grid[ 1 ] : top + o.grid[ 1 ] ) ) :
6514								top;
6515
6516				left = this.originalPageX + Math.round( ( pageX - this.originalPageX ) /
6517					o.grid[ 0 ] ) * o.grid[ 0 ];
6518				pageX = this.containment ?
6519					( ( left - this.offset.click.left >= this.containment[ 0 ] &&
6520						left - this.offset.click.left <= this.containment[ 2 ] ) ?
6521							left :
6522							( ( left - this.offset.click.left >= this.containment[ 0 ] ) ?
6523								left - o.grid[ 0 ] : left + o.grid[ 0 ] ) ) :
6524								left;
6525			}
6526
6527		}
6528
6529		return {
6530			top: (
6531
6532				// The absolute mouse position
6533				pageY -
6534
6535				// Click offset (relative to the element)
6536				this.offset.click.top -
6537
6538				// Only for relative positioned nodes: Relative offset from element to offset parent
6539				this.offset.relative.top -
6540
6541				// The offsetParent's offset without borders (offset + border)
6542				this.offset.parent.top +
6543				( ( this.cssPosition === "fixed" ?
6544					-this.scrollParent.scrollTop() :
6545					( scrollIsRootNode ? 0 : scroll.scrollTop() ) ) )
6546			),
6547			left: (
6548
6549				// The absolute mouse position
6550				pageX -
6551
6552				// Click offset (relative to the element)
6553				this.offset.click.left -
6554
6555				// Only for relative positioned nodes: Relative offset from element to offset parent
6556				this.offset.relative.left -
6557
6558				// The offsetParent's offset without borders (offset + border)
6559				this.offset.parent.left +
6560				( ( this.cssPosition === "fixed" ?
6561					-this.scrollParent.scrollLeft() :
6562					scrollIsRootNode ? 0 : scroll.scrollLeft() ) )
6563			)
6564		};
6565
6566	},
6567
6568	_rearrange: function( event, i, a, hardRefresh ) {
6569
6570		a ? a[ 0 ].appendChild( this.placeholder[ 0 ] ) :
6571			i.item[ 0 ].parentNode.insertBefore( this.placeholder[ 0 ],
6572				( this.direction === "down" ? i.item[ 0 ] : i.item[ 0 ].nextSibling ) );
6573
6574		//Various things done here to improve the performance:
6575		// 1. we create a setTimeout, that calls refreshPositions
6576		// 2. on the instance, we have a counter variable, that get's higher after every append
6577		// 3. on the local scope, we copy the counter variable, and check in the timeout,
6578		// if it's still the same
6579		// 4. this lets only the last addition to the timeout stack through
6580		this.counter = this.counter ? ++this.counter : 1;
6581		var counter = this.counter;
6582
6583		this._delay( function() {
6584			if ( counter === this.counter ) {
6585
6586				//Precompute after each DOM insertion, NOT on mousemove
6587				this.refreshPositions( !hardRefresh );
6588			}
6589		} );
6590
6591	},
6592
6593	_clear: function( event, noPropagation ) {
6594
6595		this.reverting = false;
6596
6597		// We delay all events that have to be triggered to after the point where the placeholder
6598		// has been removed and everything else normalized again
6599		var i,
6600			delayedTriggers = [];
6601
6602		// We first have to update the dom position of the actual currentItem
6603		// Note: don't do it if the current item is already removed (by a user), or it gets
6604		// reappended (see #4088)
6605		if ( !this._noFinalSort && this.currentItem.parent().length ) {
6606			this.placeholder.before( this.currentItem );
6607		}
6608		this._noFinalSort = null;
6609
6610		if ( this.helper[ 0 ] === this.currentItem[ 0 ] ) {
6611			for ( i in this._storedCSS ) {
6612				if ( this._storedCSS[ i ] === "auto" || this._storedCSS[ i ] === "static" ) {
6613					this._storedCSS[ i ] = "";
6614				}
6615			}
6616			this.currentItem.css( this._storedCSS );
6617			this._removeClass( this.currentItem, "ui-sortable-helper" );
6618		} else {
6619			this.currentItem.show();
6620		}
6621
6622		if ( this.fromOutside && !noPropagation ) {
6623			delayedTriggers.push( function( event ) {
6624				this._trigger( "receive", event, this._uiHash( this.fromOutside ) );
6625			} );
6626		}
6627		if ( ( this.fromOutside ||
6628				this.domPosition.prev !==
6629				this.currentItem.prev().not( ".ui-sortable-helper" )[ 0 ] ||
6630				this.domPosition.parent !== this.currentItem.parent()[ 0 ] ) && !noPropagation ) {
6631
6632			// Trigger update callback if the DOM position has changed
6633			delayedTriggers.push( function( event ) {
6634				this._trigger( "update", event, this._uiHash() );
6635			} );
6636		}
6637
6638		// Check if the items Container has Changed and trigger appropriate
6639		// events.
6640		if ( this !== this.currentContainer ) {
6641			if ( !noPropagation ) {
6642				delayedTriggers.push( function( event ) {
6643					this._trigger( "remove", event, this._uiHash() );
6644				} );
6645				delayedTriggers.push( ( function( c ) {
6646					return function( event ) {
6647						c._trigger( "receive", event, this._uiHash( this ) );
6648					};
6649				} ).call( this, this.currentContainer ) );
6650				delayedTriggers.push( ( function( c ) {
6651					return function( event ) {
6652						c._trigger( "update", event, this._uiHash( this ) );
6653					};
6654				} ).call( this, this.currentContainer ) );
6655			}
6656		}
6657
6658		//Post events to containers
6659		function delayEvent( type, instance, container ) {
6660			return function( event ) {
6661				container._trigger( type, event, instance._uiHash( instance ) );
6662			};
6663		}
6664		for ( i = this.containers.length - 1; i >= 0; i-- ) {
6665			if ( !noPropagation ) {
6666				delayedTriggers.push( delayEvent( "deactivate", this, this.containers[ i ] ) );
6667			}
6668			if ( this.containers[ i ].containerCache.over ) {
6669				delayedTriggers.push( delayEvent( "out", this, this.containers[ i ] ) );
6670				this.containers[ i ].containerCache.over = 0;
6671			}
6672		}
6673
6674		//Do what was originally in plugins
6675		if ( this.storedCursor ) {
6676			this.document.find( "body" ).css( "cursor", this.storedCursor );
6677			this.storedStylesheet.remove();
6678		}
6679		if ( this._storedOpacity ) {
6680			this.helper.css( "opacity", this._storedOpacity );
6681		}
6682		if ( this._storedZIndex ) {
6683			this.helper.css( "zIndex", this._storedZIndex === "auto" ? "" : this._storedZIndex );
6684		}
6685
6686		this.dragging = false;
6687
6688		if ( !noPropagation ) {
6689			this._trigger( "beforeStop", event, this._uiHash() );
6690		}
6691
6692		//$(this.placeholder[0]).remove(); would have been the jQuery way - unfortunately,
6693		// it unbinds ALL events from the original node!
6694		this.placeholder[ 0 ].parentNode.removeChild( this.placeholder[ 0 ] );
6695
6696		if ( !this.cancelHelperRemoval ) {
6697			if ( this.helper[ 0 ] !== this.currentItem[ 0 ] ) {
6698				this.helper.remove();
6699			}
6700			this.helper = null;
6701		}
6702
6703		if ( !noPropagation ) {
6704			for ( i = 0; i < delayedTriggers.length; i++ ) {
6705
6706				// Trigger all delayed events
6707				delayedTriggers[ i ].call( this, event );
6708			}
6709			this._trigger( "stop", event, this._uiHash() );
6710		}
6711
6712		this.fromOutside = false;
6713		return !this.cancelHelperRemoval;
6714
6715	},
6716
6717	_trigger: function() {
6718		if ( $.Widget.prototype._trigger.apply( this, arguments ) === false ) {
6719			this.cancel();
6720		}
6721	},
6722
6723	_uiHash: function( _inst ) {
6724		var inst = _inst || this;
6725		return {
6726			helper: inst.helper,
6727			placeholder: inst.placeholder || $( [] ),
6728			position: inst.position,
6729			originalPosition: inst.originalPosition,
6730			offset: inst.positionAbs,
6731			item: inst.currentItem,
6732			sender: _inst ? _inst.element : null
6733		};
6734	}
6735
6736} );
6737
6738
6739/*!
6740 * jQuery UI Accordion 1.12.1
6741 * http://jqueryui.com
vendor: 4,128 bytes, lines 6742-6907
6742 *
6743 * Copyright jQuery Foundation and other contributors
6744 * Released under the MIT license.
6745 * http://jquery.org/license
6746 */
6747
6748//>>label: Accordion
6749//>>group: Widgets
6750// jscs:disable maximumLineLength
6751//>>description: Displays collapsible content panels for presenting information in a limited amount of space.
6752// jscs:enable maximumLineLength
6753//>>docs: http://api.jqueryui.com/accordion/
6754//>>demos: http://jqueryui.com/accordion/
6755//>>css.structure: ../../themes/base/core.css
6756//>>css.structure: ../../themes/base/accordion.css
6757//>>css.theme: ../../themes/base/theme.css
6758
6759
6760
6761var widgetsAccordion = $.widget( "ui.accordion", {
6762	version: "1.12.1",
6763	options: {
6764		active: 0,
6765		animate: {},
6766		classes: {
6767			"ui-accordion-header": "ui-corner-top",
6768			"ui-accordion-header-collapsed": "ui-corner-all",
6769			"ui-accordion-content": "ui-corner-bottom"
6770		},
6771		collapsible: false,
6772		event: "click",
6773		header: "> li > :first-child, > :not(li):even",
6774		heightStyle: "auto",
6775		icons: {
6776			activeHeader: "ui-icon-triangle-1-s",
6777			header: "ui-icon-triangle-1-e"
6778		},
6779
6780		// Callbacks
6781		activate: null,
6782		beforeActivate: null
6783	},
6784
6785	hideProps: {
6786		borderTopWidth: "hide",
6787		borderBottomWidth: "hide",
6788		paddingTop: "hide",
6789		paddingBottom: "hide",
6790		height: "hide"
6791	},
6792
6793	showProps: {
6794		borderTopWidth: "show",
6795		borderBottomWidth: "show",
6796		paddingTop: "show",
6797		paddingBottom: "show",
6798		height: "show"
6799	},
6800
6801	_create: function() {
6802		var options = this.options;
6803
6804		this.prevShow = this.prevHide = $();
6805		this._addClass( "ui-accordion", "ui-widget ui-helper-reset" );
6806		this.element.attr( "role", "tablist" );
6807
6808		// Don't allow collapsible: false and active: false / null
6809		if ( !options.collapsible && ( options.active === false || options.active == null ) ) {
6810			options.active = 0;
6811		}
6812
6813		this._processPanels();
6814
6815		// handle negative values
6816		if ( options.active < 0 ) {
6817			options.active += this.headers.length;
6818		}
6819		this._refresh();
6820	},
6821
6822	_getCreateEventData: function() {
6823		return {
6824			header: this.active,
6825			panel: !this.active.length ? $() : this.active.next()
6826		};
6827	},
6828
6829	_createIcons: function() {
6830		var icon, children,
6831			icons = this.options.icons;
6832
6833		if ( icons ) {
6834			icon = $( "<span>" );
6835			this._addClass( icon, "ui-accordion-header-icon", "ui-icon " + icons.header );
6836			icon.prependTo( this.headers );
6837			children = this.active.children( ".ui-accordion-header-icon" );
6838			this._removeClass( children, icons.header )
6839				._addClass( children, null, icons.activeHeader )
6840				._addClass( this.headers, "ui-accordion-icons" );
6841		}
6842	},
6843
6844	_destroyIcons: function() {
6845		this._removeClass( this.headers, "ui-accordion-icons" );
6846		this.headers.children( ".ui-accordion-header-icon" ).remove();
6847	},
6848
6849	_destroy: function() {
6850		var contents;
6851
6852		// Clean up main element
6853		this.element.removeAttr( "role" );
6854
6855		// Clean up headers
6856		this.headers
6857			.removeAttr( "role aria-expanded aria-selected aria-controls tabIndex" )
6858			.removeUniqueId();
6859
6860		this._destroyIcons();
6861
6862		// Clean up content panels
6863		contents = this.headers.next()
6864			.css( "display", "" )
6865			.removeAttr( "role aria-hidden aria-labelledby" )
6866			.removeUniqueId();
6867
6868		if ( this.options.heightStyle !== "content" ) {
6869			contents.css( "height", "" );
6870		}
6871	},
6872
6873	_setOption: function( key, value ) {
6874		if ( key === "active" ) {
6875
6876			// _activate() will handle invalid values and update this.options
6877			this._activate( value );
6878			return;
6879		}
6880
6881		if ( key === "event" ) {
6882			if ( this.options.event ) {
6883				this._off( this.headers, this.options.event );
6884			}
6885			this._setupEvents( value );
6886		}
6887
6888		this._super( key, value );
6889
6890		// Setting collapsible: false while collapsed; open first panel
6891		if ( key === "collapsible" && !value && this.options.active === false ) {
6892			this._activate( 0 );
6893		}
6894
6895		if ( key === "icons" ) {
6896			this._destroyIcons();
6897			if ( value ) {
6898				this._createIcons();
6899			}
6900		}
6901	},
6902
6903	_setOptionDisabled: function( value ) {
6904		this._super( value );
6905
6906		this.element.attr( "aria-disabled", value );
6907
vendor: 20,452 bytes, lines 6908-7640
6908		// Support: IE8 Only
6909		// #5332 / #6059 - opacity doesn't cascade to positioned elements in IE
6910		// so we need to add the disabled class to the headers and panels
6911		this._toggleClass( null, "ui-state-disabled", !!value );
6912		this._toggleClass( this.headers.add( this.headers.next() ), null, "ui-state-disabled",
6913			!!value );
6914	},
6915
6916	_keydown: function( event ) {
6917		if ( event.altKey || event.ctrlKey ) {
6918			return;
6919		}
6920
6921		var keyCode = $.ui.keyCode,
6922			length = this.headers.length,
6923			currentIndex = this.headers.index( event.target ),
6924			toFocus = false;
6925
6926		switch ( event.keyCode ) {
6927		case keyCode.RIGHT:
6928		case keyCode.DOWN:
6929			toFocus = this.headers[ ( currentIndex + 1 ) % length ];
6930			break;
6931		case keyCode.LEFT:
6932		case keyCode.UP:
6933			toFocus = this.headers[ ( currentIndex - 1 + length ) % length ];
6934			break;
6935		case keyCode.SPACE:
6936		case keyCode.ENTER:
6937			this._eventHandler( event );
6938			break;
6939		case keyCode.HOME:
6940			toFocus = this.headers[ 0 ];
6941			break;
6942		case keyCode.END:
6943			toFocus = this.headers[ length - 1 ];
6944			break;
6945		}
6946
6947		if ( toFocus ) {
6948			$( event.target ).attr( "tabIndex", -1 );
6949			$( toFocus ).attr( "tabIndex", 0 );
6950			$( toFocus ).trigger( "focus" );
6951			event.preventDefault();
6952		}
6953	},
6954
6955	_panelKeyDown: function( event ) {
6956		if ( event.keyCode === $.ui.keyCode.UP && event.ctrlKey ) {
6957			$( event.currentTarget ).prev().trigger( "focus" );
6958		}
6959	},
6960
6961	refresh: function() {
6962		var options = this.options;
6963		this._processPanels();
6964
6965		// Was collapsed or no panel
6966		if ( ( options.active === false && options.collapsible === true ) ||
6967				!this.headers.length ) {
6968			options.active = false;
6969			this.active = $();
6970
6971		// active false only when collapsible is true
6972		} else if ( options.active === false ) {
6973			this._activate( 0 );
6974
6975		// was active, but active panel is gone
6976		} else if ( this.active.length && !$.contains( this.element[ 0 ], this.active[ 0 ] ) ) {
6977
6978			// all remaining panel are disabled
6979			if ( this.headers.length === this.headers.find( ".ui-state-disabled" ).length ) {
6980				options.active = false;
6981				this.active = $();
6982
6983			// activate previous panel
6984			} else {
6985				this._activate( Math.max( 0, options.active - 1 ) );
6986			}
6987
6988		// was active, active panel still exists
6989		} else {
6990
6991			// make sure active index is correct
6992			options.active = this.headers.index( this.active );
6993		}
6994
6995		this._destroyIcons();
6996
6997		this._refresh();
6998	},
6999
7000	_processPanels: function() {
7001		var prevHeaders = this.headers,
7002			prevPanels = this.panels;
7003
7004		this.headers = this.element.find( this.options.header );
7005		this._addClass( this.headers, "ui-accordion-header ui-accordion-header-collapsed",
7006			"ui-state-default" );
7007
7008		this.panels = this.headers.next().filter( ":not(.ui-accordion-content-active)" ).hide();
7009		this._addClass( this.panels, "ui-accordion-content", "ui-helper-reset ui-widget-content" );
7010
7011		// Avoid memory leaks (#10056)
7012		if ( prevPanels ) {
7013			this._off( prevHeaders.not( this.headers ) );
7014			this._off( prevPanels.not( this.panels ) );
7015		}
7016	},
7017
7018	_refresh: function() {
7019		var maxHeight,
7020			options = this.options,
7021			heightStyle = options.heightStyle,
7022			parent = this.element.parent();
7023
7024		this.active = this._findActive( options.active );
7025		this._addClass( this.active, "ui-accordion-header-active", "ui-state-active" )
7026			._removeClass( this.active, "ui-accordion-header-collapsed" );
7027		this._addClass( this.active.next(), "ui-accordion-content-active" );
7028		this.active.next().show();
7029
7030		this.headers
7031			.attr( "role", "tab" )
7032			.each( function() {
7033				var header = $( this ),
7034					headerId = header.uniqueId().attr( "id" ),
7035					panel = header.next(),
7036					panelId = panel.uniqueId().attr( "id" );
7037				header.attr( "aria-controls", panelId );
7038				panel.attr( "aria-labelledby", headerId );
7039			} )
7040			.next()
7041				.attr( "role", "tabpanel" );
7042
7043		this.headers
7044			.not( this.active )
7045				.attr( {
7046					"aria-selected": "false",
7047					"aria-expanded": "false",
7048					tabIndex: -1
7049				} )
7050				.next()
7051					.attr( {
7052						"aria-hidden": "true"
7053					} )
7054					.hide();
7055
7056		// Make sure at least one header is in the tab order
7057		if ( !this.active.length ) {
7058			this.headers.eq( 0 ).attr( "tabIndex", 0 );
7059		} else {
7060			this.active.attr( {
7061				"aria-selected": "true",
7062				"aria-expanded": "true",
7063				tabIndex: 0
7064			} )
7065				.next()
7066					.attr( {
7067						"aria-hidden": "false"
7068					} );
7069		}
7070
7071		this._createIcons();
7072
7073		this._setupEvents( options.event );
7074
7075		if ( heightStyle === "fill" ) {
7076			maxHeight = parent.height();
7077			this.element.siblings( ":visible" ).each( function() {
7078				var elem = $( this ),
7079					position = elem.css( "position" );
7080
7081				if ( position === "absolute" || position === "fixed" ) {
7082					return;
7083				}
7084				maxHeight -= elem.outerHeight( true );
7085			} );
7086
7087			this.headers.each( function() {
7088				maxHeight -= $( this ).outerHeight( true );
7089			} );
7090
7091			this.headers.next()
7092				.each( function() {
7093					$( this ).height( Math.max( 0, maxHeight -
7094						$( this ).innerHeight() + $( this ).height() ) );
7095				} )
7096				.css( "overflow", "auto" );
7097		} else if ( heightStyle === "auto" ) {
7098			maxHeight = 0;
7099			this.headers.next()
7100				.each( function() {
7101					var isVisible = $( this ).is( ":visible" );
7102					if ( !isVisible ) {
7103						$( this ).show();
7104					}
7105					maxHeight = Math.max( maxHeight, $( this ).css( "height", "" ).height() );
7106					if ( !isVisible ) {
7107						$( this ).hide();
7108					}
7109				} )
7110				.height( maxHeight );
7111		}
7112	},
7113
7114	_activate: function( index ) {
7115		var active = this._findActive( index )[ 0 ];
7116
7117		// Trying to activate the already active panel
7118		if ( active === this.active[ 0 ] ) {
7119			return;
7120		}
7121
7122		// Trying to collapse, simulate a click on the currently active header
7123		active = active || this.active[ 0 ];
7124
7125		this._eventHandler( {
7126			target: active,
7127			currentTarget: active,
7128			preventDefault: $.noop
7129		} );
7130	},
7131
7132	_findActive: function( selector ) {
7133		return typeof selector === "number" ? this.headers.eq( selector ) : $();
7134	},
7135
7136	_setupEvents: function( event ) {
7137		var events = {
7138			keydown: "_keydown"
7139		};
7140		if ( event ) {
7141			$.each( event.split( " " ), function( index, eventName ) {
7142				events[ eventName ] = "_eventHandler";
7143			} );
7144		}
7145
7146		this._off( this.headers.add( this.headers.next() ) );
7147		this._on( this.headers, events );
7148		this._on( this.headers.next(), { keydown: "_panelKeyDown" } );
7149		this._hoverable( this.headers );
7150		this._focusable( this.headers );
7151	},
7152
7153	_eventHandler: function( event ) {
7154		var activeChildren, clickedChildren,
7155			options = this.options,
7156			active = this.active,
7157			clicked = $( event.currentTarget ),
7158			clickedIsActive = clicked[ 0 ] === active[ 0 ],
7159			collapsing = clickedIsActive && options.collapsible,
7160			toShow = collapsing ? $() : clicked.next(),
7161			toHide = active.next(),
7162			eventData = {
7163				oldHeader: active,
7164				oldPanel: toHide,
7165				newHeader: collapsing ? $() : clicked,
7166				newPanel: toShow
7167			};
7168
7169		event.preventDefault();
7170
7171		if (
7172
7173				// click on active header, but not collapsible
7174				( clickedIsActive && !options.collapsible ) ||
7175
7176				// allow canceling activation
7177				( this._trigger( "beforeActivate", event, eventData ) === false ) ) {
7178			return;
7179		}
7180
7181		options.active = collapsing ? false : this.headers.index( clicked );
7182
7183		// When the call to ._toggle() comes after the class changes
7184		// it causes a very odd bug in IE 8 (see #6720)
7185		this.active = clickedIsActive ? $() : clicked;
7186		this._toggle( eventData );
7187
7188		// Switch classes
7189		// corner classes on the previously active header stay after the animation
7190		this._removeClass( active, "ui-accordion-header-active", "ui-state-active" );
7191		if ( options.icons ) {
7192			activeChildren = active.children( ".ui-accordion-header-icon" );
7193			this._removeClass( activeChildren, null, options.icons.activeHeader )
7194				._addClass( activeChildren, null, options.icons.header );
7195		}
7196
7197		if ( !clickedIsActive ) {
7198			this._removeClass( clicked, "ui-accordion-header-collapsed" )
7199				._addClass( clicked, "ui-accordion-header-active", "ui-state-active" );
7200			if ( options.icons ) {
7201				clickedChildren = clicked.children( ".ui-accordion-header-icon" );
7202				this._removeClass( clickedChildren, null, options.icons.header )
7203					._addClass( clickedChildren, null, options.icons.activeHeader );
7204			}
7205
7206			this._addClass( clicked.next(), "ui-accordion-content-active" );
7207		}
7208	},
7209
7210	_toggle: function( data ) {
7211		var toShow = data.newPanel,
7212			toHide = this.prevShow.length ? this.prevShow : data.oldPanel;
7213
7214		// Handle activating a panel during the animation for another activation
7215		this.prevShow.add( this.prevHide ).stop( true, true );
7216		this.prevShow = toShow;
7217		this.prevHide = toHide;
7218
7219		if ( this.options.animate ) {
7220			this._animate( toShow, toHide, data );
7221		} else {
7222			toHide.hide();
7223			toShow.show();
7224			this._toggleComplete( data );
7225		}
7226
7227		toHide.attr( {
7228			"aria-hidden": "true"
7229		} );
7230		toHide.prev().attr( {
7231			"aria-selected": "false",
7232			"aria-expanded": "false"
7233		} );
7234
7235		// if we're switching panels, remove the old header from the tab order
7236		// if we're opening from collapsed state, remove the previous header from the tab order
7237		// if we're collapsing, then keep the collapsing header in the tab order
7238		if ( toShow.length && toHide.length ) {
7239			toHide.prev().attr( {
7240				"tabIndex": -1,
7241				"aria-expanded": "false"
7242			} );
7243		} else if ( toShow.length ) {
7244			this.headers.filter( function() {
7245				return parseInt( $( this ).attr( "tabIndex" ), 10 ) === 0;
7246			} )
7247				.attr( "tabIndex", -1 );
7248		}
7249
7250		toShow
7251			.attr( "aria-hidden", "false" )
7252			.prev()
7253				.attr( {
7254					"aria-selected": "true",
7255					"aria-expanded": "true",
7256					tabIndex: 0
7257				} );
7258	},
7259
7260	_animate: function( toShow, toHide, data ) {
7261		var total, easing, duration,
7262			that = this,
7263			adjust = 0,
7264			boxSizing = toShow.css( "box-sizing" ),
7265			down = toShow.length &&
7266				( !toHide.length || ( toShow.index() < toHide.index() ) ),
7267			animate = this.options.animate || {},
7268			options = down && animate.down || animate,
7269			complete = function() {
7270				that._toggleComplete( data );
7271			};
7272
7273		if ( typeof options === "number" ) {
7274			duration = options;
7275		}
7276		if ( typeof options === "string" ) {
7277			easing = options;
7278		}
7279
7280		// fall back from options to animation in case of partial down settings
7281		easing = easing || options.easing || animate.easing;
7282		duration = duration || options.duration || animate.duration;
7283
7284		if ( !toHide.length ) {
7285			return toShow.animate( this.showProps, duration, easing, complete );
7286		}
7287		if ( !toShow.length ) {
7288			return toHide.animate( this.hideProps, duration, easing, complete );
7289		}
7290
7291		total = toShow.show().outerHeight();
7292		toHide.animate( this.hideProps, {
7293			duration: duration,
7294			easing: easing,
7295			step: function( now, fx ) {
7296				fx.now = Math.round( now );
7297			}
7298		} );
7299		toShow
7300			.hide()
7301			.animate( this.showProps, {
7302				duration: duration,
7303				easing: easing,
7304				complete: complete,
7305				step: function( now, fx ) {
7306					fx.now = Math.round( now );
7307					if ( fx.prop !== "height" ) {
7308						if ( boxSizing === "content-box" ) {
7309							adjust += fx.now;
7310						}
7311					} else if ( that.options.heightStyle !== "content" ) {
7312						fx.now = Math.round( total - toHide.outerHeight() - adjust );
7313						adjust = 0;
7314					}
7315				}
7316			} );
7317	},
7318
7319	_toggleComplete: function( data ) {
7320		var toHide = data.oldPanel,
7321			prev = toHide.prev();
7322
7323		this._removeClass( toHide, "ui-accordion-content-active" );
7324		this._removeClass( prev, "ui-accordion-header-active" )
7325			._addClass( prev, "ui-accordion-header-collapsed" );
7326
7327		// Work around for rendering bug in IE (#5421)
7328		if ( toHide.length ) {
7329			toHide.parent()[ 0 ].className = toHide.parent()[ 0 ].className;
7330		}
7331		this._trigger( "activate", null, data );
7332	}
7333} );
7334
7335
7336/*!
7337 * jQuery UI Menu 1.12.1
7338 * http://jqueryui.com
7339 *
7340 * Copyright jQuery Foundation and other contributors
7341 * Released under the MIT license.
7342 * http://jquery.org/license
7343 */
7344
7345//>>label: Menu
7346//>>group: Widgets
7347//>>description: Creates nestable menus.
7348//>>docs: http://api.jqueryui.com/menu/
7349//>>demos: http://jqueryui.com/menu/
7350//>>css.structure: ../../themes/base/core.css
7351//>>css.structure: ../../themes/base/menu.css
7352//>>css.theme: ../../themes/base/theme.css
7353
7354
7355
7356var widgetsMenu = $.widget( "ui.menu", {
7357	version: "1.12.1",
7358	defaultElement: "<ul>",
7359	delay: 300,
7360	options: {
7361		icons: {
7362			submenu: "ui-icon-caret-1-e"
7363		},
7364		items: "> *",
7365		menus: "ul",
7366		position: {
7367			my: "left top",
7368			at: "right top"
7369		},
7370		role: "menu",
7371
7372		// Callbacks
7373		blur: null,
7374		focus: null,
7375		select: null
7376	},
7377
7378	_create: function() {
7379		this.activeMenu = this.element;
7380
7381		// Flag used to prevent firing of the click handler
7382		// as the event bubbles up through nested menus
7383		this.mouseHandled = false;
7384		this.element
7385			.uniqueId()
7386			.attr( {
7387				role: this.options.role,
7388				tabIndex: 0
7389			} );
7390
7391		this._addClass( "ui-menu", "ui-widget ui-widget-content" );
7392		this._on( {
7393
7394			// Prevent focus from sticking to links inside menu after clicking
7395			// them (focus should always stay on UL during navigation).
7396			"mousedown .ui-menu-item": function( event ) {
7397				event.preventDefault();
7398			},
7399			"click .ui-menu-item": function( event ) {
7400				var target = $( event.target );
7401				var active = $( $.ui.safeActiveElement( this.document[ 0 ] ) );
7402				if ( !this.mouseHandled && target.not( ".ui-state-disabled" ).length ) {
7403					this.select( event );
7404
7405					// Only set the mouseHandled flag if the event will bubble, see #9469.
7406					if ( !event.isPropagationStopped() ) {
7407						this.mouseHandled = true;
7408					}
7409
7410					// Open submenu on click
7411					if ( target.has( ".ui-menu" ).length ) {
7412						this.expand( event );
7413					} else if ( !this.element.is( ":focus" ) &&
7414							active.closest( ".ui-menu" ).length ) {
7415
7416						// Redirect focus to the menu
7417						this.element.trigger( "focus", [ true ] );
7418
7419						// If the active item is on the top level, let it stay active.
7420						// Otherwise, blur the active item since it is no longer visible.
7421						if ( this.active && this.active.parents( ".ui-menu" ).length === 1 ) {
7422							clearTimeout( this.timer );
7423						}
7424					}
7425				}
7426			},
7427			"mouseenter .ui-menu-item": function( event ) {
7428
7429				// Ignore mouse events while typeahead is active, see #10458.
7430				// Prevents focusing the wrong item when typeahead causes a scroll while the mouse
7431				// is over an item in the menu
7432				if ( this.previousFilter ) {
7433					return;
7434				}
7435
7436				var actualTarget = $( event.target ).closest( ".ui-menu-item" ),
7437					target = $( event.currentTarget );
7438
7439				// Ignore bubbled events on parent items, see #11641
7440				if ( actualTarget[ 0 ] !== target[ 0 ] ) {
7441					return;
7442				}
7443
7444				// Remove ui-state-active class from siblings of the newly focused menu item
7445				// to avoid a jump caused by adjacent elements both having a class with a border
7446				this._removeClass( target.siblings().children( ".ui-state-active" ),
7447					null, "ui-state-active" );
7448				this.focus( event, target );
7449			},
7450			mouseleave: "collapseAll",
7451			"mouseleave .ui-menu": "collapseAll",
7452			focus: function( event, keepActiveItem ) {
7453
7454				// If there's already an active item, keep it active
7455				// If not, activate the first item
7456				var item = this.active || this.element.find( this.options.items ).eq( 0 );
7457
7458				if ( !keepActiveItem ) {
7459					this.focus( event, item );
7460				}
7461			},
7462			blur: function( event ) {
7463				this._delay( function() {
7464					var notContained = !$.contains(
7465						this.element[ 0 ],
7466						$.ui.safeActiveElement( this.document[ 0 ] )
7467					);
7468					if ( notContained ) {
7469						this.collapseAll( event );
7470					}
7471				} );
7472			},
7473			keydown: "_keydown"
7474		} );
7475
7476		this.refresh();
7477
7478		// Clicks outside of a menu collapse any open menus
7479		this._on( this.document, {
7480			click: function( event ) {
7481				if ( this._closeOnDocumentClick( event ) ) {
7482					this.collapseAll( event );
7483				}
7484
7485				// Reset the mouseHandled flag
7486				this.mouseHandled = false;
7487			}
7488		} );
7489	},
7490
7491	_destroy: function() {
7492		var items = this.element.find( ".ui-menu-item" )
7493				.removeAttr( "role aria-disabled" ),
7494			submenus = items.children( ".ui-menu-item-wrapper" )
7495				.removeUniqueId()
7496				.removeAttr( "tabIndex role aria-haspopup" );
7497
7498		// Destroy (sub)menus
7499		this.element
7500			.removeAttr( "aria-activedescendant" )
7501			.find( ".ui-menu" ).addBack()
7502				.removeAttr( "role aria-labelledby aria-expanded aria-hidden aria-disabled " +
7503					"tabIndex" )
7504				.removeUniqueId()
7505				.show();
7506
7507		submenus.children().each( function() {
7508			var elem = $( this );
7509			if ( elem.data( "ui-menu-submenu-caret" ) ) {
7510				elem.remove();
7511			}
7512		} );
7513	},
7514
7515	_keydown: function( event ) {
7516		var match, prev, character, skip,
7517			preventDefault = true;
7518
7519		switch ( event.keyCode ) {
7520		case $.ui.keyCode.PAGE_UP:
7521			this.previousPage( event );
7522			break;
7523		case $.ui.keyCode.PAGE_DOWN:
7524			this.nextPage( event );
7525			break;
7526		case $.ui.keyCode.HOME:
7527			this._move( "first", "first", event );
7528			break;
7529		case $.ui.keyCode.END:
7530			this._move( "last", "last", event );
7531			break;
7532		case $.ui.keyCode.UP:
7533			this.previous( event );
7534			break;
7535		case $.ui.keyCode.DOWN:
7536			this.next( event );
7537			break;
7538		case $.ui.keyCode.LEFT:
7539			this.collapse( event );
7540			break;
7541		case $.ui.keyCode.RIGHT:
7542			if ( this.active && !this.active.is( ".ui-state-disabled" ) ) {
7543				this.expand( event );
7544			}
7545			break;
7546		case $.ui.keyCode.ENTER:
7547		case $.ui.keyCode.SPACE:
7548			this._activate( event );
7549			break;
7550		case $.ui.keyCode.ESCAPE:
7551			this.collapse( event );
7552			break;
7553		default:
7554			preventDefault = false;
7555			prev = this.previousFilter || "";
7556			skip = false;
7557
7558			// Support number pad values
7559			character = event.keyCode >= 96 && event.keyCode <= 105 ?
7560				( event.keyCode - 96 ).toString() : String.fromCharCode( event.keyCode );
7561
7562			clearTimeout( this.filterTimer );
7563
7564			if ( character === prev ) {
7565				skip = true;
7566			} else {
7567				character = prev + character;
7568			}
7569
7570			match = this._filterMenuItems( character );
7571			match = skip && match.index( this.active.next() ) !== -1 ?
7572				this.active.nextAll( ".ui-menu-item" ) :
7573				match;
7574
7575			// If no matches on the current filter, reset to the last character pressed
7576			// to move down the menu to the first item that starts with that character
7577			if ( !match.length ) {
7578				character = String.fromCharCode( event.keyCode );
7579				match = this._filterMenuItems( character );
7580			}
7581
7582			if ( match.length ) {
7583				this.focus( event, match );
7584				this.previousFilter = character;
7585				this.filterTimer = this._delay( function() {
7586					delete this.previousFilter;
7587				}, 1000 );
7588			} else {
7589				delete this.previousFilter;
7590			}
7591		}
7592
7593		if ( preventDefault ) {
7594			event.preventDefault();
7595		}
7596	},
7597
7598	_activate: function( event ) {
7599		if ( this.active && !this.active.is( ".ui-state-disabled" ) ) {
7600			if ( this.active.children( "[aria-haspopup='true']" ).length ) {
7601				this.expand( event );
7602			} else {
7603				this.select( event );
7604			}
7605		}
7606	},
7607
7608	refresh: function() {
7609		var menus, items, newSubmenus, newItems, newWrappers,
7610			that = this,
7611			icon = this.options.icons.submenu,
7612			submenus = this.element.find( this.options.menus );
7613
7614		this._toggleClass( "ui-menu-icons", null, !!this.element.find( ".ui-icon" ).length );
7615
7616		// Initialize nested menus
7617		newSubmenus = submenus.filter( ":not(.ui-menu)" )
7618			.hide()
7619			.attr( {
7620				role: this.options.role,
7621				"aria-hidden": "true",
7622				"aria-expanded": "false"
7623			} )
7624			.each( function() {
7625				var menu = $( this ),
7626					item = menu.prev(),
7627					submenuCaret = $( "<span>" ).data( "ui-menu-submenu-caret", true );
7628
7629				that._addClass( submenuCaret, "ui-menu-icon", "ui-icon " + icon );
7630				item
7631					.attr( "aria-haspopup", "true" )
7632					.prepend( submenuCaret );
7633				menu.attr( "aria-labelledby", item.attr( "id" ) );
7634			} );
7635
7636		this._addClass( newSubmenus, "ui-menu", "ui-widget ui-widget-content ui-front" );
7637
7638		menus = submenus.add( this.element );
7639		items = menus.find( this.options.items );
7640
vendor: 4,715 bytes, lines 7641-7803
7641		// Initialize menu-items containing spaces and/or dashes only as dividers
7642		items.not( ".ui-menu-item" ).each( function() {
7643			var item = $( this );
7644			if ( that._isDivider( item ) ) {
7645				that._addClass( item, "ui-menu-divider", "ui-widget-content" );
7646			}
7647		} );
7648
7649		// Don't refresh list items that are already adapted
7650		newItems = items.not( ".ui-menu-item, .ui-menu-divider" );
7651		newWrappers = newItems.children()
7652			.not( ".ui-menu" )
7653				.uniqueId()
7654				.attr( {
7655					tabIndex: -1,
7656					role: this._itemRole()
7657				} );
7658		this._addClass( newItems, "ui-menu-item" )
7659			._addClass( newWrappers, "ui-menu-item-wrapper" );
7660
7661		// Add aria-disabled attribute to any disabled menu item
7662		items.filter( ".ui-state-disabled" ).attr( "aria-disabled", "true" );
7663
7664		// If the active item has been removed, blur the menu
7665		if ( this.active && !$.contains( this.element[ 0 ], this.active[ 0 ] ) ) {
7666			this.blur();
7667		}
7668	},
7669
7670	_itemRole: function() {
7671		return {
7672			menu: "menuitem",
7673			listbox: "option"
7674		}[ this.options.role ];
7675	},
7676
7677	_setOption: function( key, value ) {
7678		if ( key === "icons" ) {
7679			var icons = this.element.find( ".ui-menu-icon" );
7680			this._removeClass( icons, null, this.options.icons.submenu )
7681				._addClass( icons, null, value.submenu );
7682		}
7683		this._super( key, value );
7684	},
7685
7686	_setOptionDisabled: function( value ) {
7687		this._super( value );
7688
7689		this.element.attr( "aria-disabled", String( value ) );
7690		this._toggleClass( null, "ui-state-disabled", !!value );
7691	},
7692
7693	focus: function( event, item ) {
7694		var nested, focused, activeParent;
7695		this.blur( event, event && event.type === "focus" );
7696
7697		this._scrollIntoView( item );
7698
7699		this.active = item.first();
7700
7701		focused = this.active.children( ".ui-menu-item-wrapper" );
7702		this._addClass( focused, null, "ui-state-active" );
7703
7704		// Only update aria-activedescendant if there's a role
7705		// otherwise we assume focus is managed elsewhere
7706		if ( this.options.role ) {
7707			this.element.attr( "aria-activedescendant", focused.attr( "id" ) );
7708		}
7709
7710		// Highlight active parent menu item, if any
7711		activeParent = this.active
7712			.parent()
7713				.closest( ".ui-menu-item" )
7714					.children( ".ui-menu-item-wrapper" );
7715		this._addClass( activeParent, null, "ui-state-active" );
7716
7717		if ( event && event.type === "keydown" ) {
7718			this._close();
7719		} else {
7720			this.timer = this._delay( function() {
7721				this._close();
7722			}, this.delay );
7723		}
7724
7725		nested = item.children( ".ui-menu" );
7726		if ( nested.length && event && ( /^mouse/.test( event.type ) ) ) {
7727			this._startOpening( nested );
7728		}
7729		this.activeMenu = item.parent();
7730
7731		this._trigger( "focus", event, { item: item } );
7732	},
7733
7734	_scrollIntoView: function( item ) {
7735		var borderTop, paddingTop, offset, scroll, elementHeight, itemHeight;
7736		if ( this._hasScroll() ) {
7737			borderTop = parseFloat( $.css( this.activeMenu[ 0 ], "borderTopWidth" ) ) || 0;
7738			paddingTop = parseFloat( $.css( this.activeMenu[ 0 ], "paddingTop" ) ) || 0;
7739			offset = item.offset().top - this.activeMenu.offset().top - borderTop - paddingTop;
7740			scroll = this.activeMenu.scrollTop();
7741			elementHeight = this.activeMenu.height();
7742			itemHeight = item.outerHeight();
7743
7744			if ( offset < 0 ) {
7745				this.activeMenu.scrollTop( scroll + offset );
7746			} else if ( offset + itemHeight > elementHeight ) {
7747				this.activeMenu.scrollTop( scroll + offset - elementHeight + itemHeight );
7748			}
7749		}
7750	},
7751
7752	blur: function( event, fromFocus ) {
7753		if ( !fromFocus ) {
7754			clearTimeout( this.timer );
7755		}
7756
7757		if ( !this.active ) {
7758			return;
7759		}
7760
7761		this._removeClass( this.active.children( ".ui-menu-item-wrapper" ),
7762			null, "ui-state-active" );
7763
7764		this._trigger( "blur", event, { item: this.active } );
7765		this.active = null;
7766	},
7767
7768	_startOpening: function( submenu ) {
7769		clearTimeout( this.timer );
7770
7771		// Don't open if already open fixes a Firefox bug that caused a .5 pixel
7772		// shift in the submenu position when mousing over the caret icon
7773		if ( submenu.attr( "aria-hidden" ) !== "true" ) {
7774			return;
7775		}
7776
7777		this.timer = this._delay( function() {
7778			this._close();
7779			this._open( submenu );
7780		}, this.delay );
7781	},
7782
7783	_open: function( submenu ) {
7784		var position = $.extend( {
7785			of: this.active
7786		}, this.options.position );
7787
7788		clearTimeout( this.timer );
7789		this.element.find( ".ui-menu" ).not( submenu.parents( ".ui-menu" ) )
7790			.hide()
7791			.attr( "aria-hidden", "true" );
7792
7793		submenu
7794			.show()
7795			.removeAttr( "aria-hidden" )
7796			.attr( "aria-expanded", "true" )
7797			.position( position );
7798	},
7799
7800	collapseAll: function( event, all ) {
7801		clearTimeout( this.timer );
7802		this.timer = this._delay( function() {
7803
vendor: 36,980 bytes, lines 7804-9123
7804			// If we were passed an event, look for the submenu that contains the event
7805			var currentMenu = all ? this.element :
7806				$( event && event.target ).closest( this.element.find( ".ui-menu" ) );
7807
7808			// If we found no valid submenu ancestor, use the main menu to close all
7809			// sub menus anyway
7810			if ( !currentMenu.length ) {
7811				currentMenu = this.element;
7812			}
7813
7814			this._close( currentMenu );
7815
7816			this.blur( event );
7817
7818			// Work around active item staying active after menu is blurred
7819			this._removeClass( currentMenu.find( ".ui-state-active" ), null, "ui-state-active" );
7820
7821			this.activeMenu = currentMenu;
7822		}, this.delay );
7823	},
7824
7825	// With no arguments, closes the currently active menu - if nothing is active
7826	// it closes all menus.  If passed an argument, it will search for menus BELOW
7827	_close: function( startMenu ) {
7828		if ( !startMenu ) {
7829			startMenu = this.active ? this.active.parent() : this.element;
7830		}
7831
7832		startMenu.find( ".ui-menu" )
7833			.hide()
7834			.attr( "aria-hidden", "true" )
7835			.attr( "aria-expanded", "false" );
7836	},
7837
7838	_closeOnDocumentClick: function( event ) {
7839		return !$( event.target ).closest( ".ui-menu" ).length;
7840	},
7841
7842	_isDivider: function( item ) {
7843
7844		// Match hyphen, em dash, en dash
7845		return !/[^\-\u2014\u2013\s]/.test( item.text() );
7846	},
7847
7848	collapse: function( event ) {
7849		var newItem = this.active &&
7850			this.active.parent().closest( ".ui-menu-item", this.element );
7851		if ( newItem && newItem.length ) {
7852			this._close();
7853			this.focus( event, newItem );
7854		}
7855	},
7856
7857	expand: function( event ) {
7858		var newItem = this.active &&
7859			this.active
7860				.children( ".ui-menu " )
7861					.find( this.options.items )
7862						.first();
7863
7864		if ( newItem && newItem.length ) {
7865			this._open( newItem.parent() );
7866
7867			// Delay so Firefox will not hide activedescendant change in expanding submenu from AT
7868			this._delay( function() {
7869				this.focus( event, newItem );
7870			} );
7871		}
7872	},
7873
7874	next: function( event ) {
7875		this._move( "next", "first", event );
7876	},
7877
7878	previous: function( event ) {
7879		this._move( "prev", "last", event );
7880	},
7881
7882	isFirstItem: function() {
7883		return this.active && !this.active.prevAll( ".ui-menu-item" ).length;
7884	},
7885
7886	isLastItem: function() {
7887		return this.active && !this.active.nextAll( ".ui-menu-item" ).length;
7888	},
7889
7890	_move: function( direction, filter, event ) {
7891		var next;
7892		if ( this.active ) {
7893			if ( direction === "first" || direction === "last" ) {
7894				next = this.active
7895					[ direction === "first" ? "prevAll" : "nextAll" ]( ".ui-menu-item" )
7896					.eq( -1 );
7897			} else {
7898				next = this.active
7899					[ direction + "All" ]( ".ui-menu-item" )
7900					.eq( 0 );
7901			}
7902		}
7903		if ( !next || !next.length || !this.active ) {
7904			next = this.activeMenu.find( this.options.items )[ filter ]();
7905		}
7906
7907		this.focus( event, next );
7908	},
7909
7910	nextPage: function( event ) {
7911		var item, base, height;
7912
7913		if ( !this.active ) {
7914			this.next( event );
7915			return;
7916		}
7917		if ( this.isLastItem() ) {
7918			return;
7919		}
7920		if ( this._hasScroll() ) {
7921			base = this.active.offset().top;
7922			height = this.element.height();
7923			this.active.nextAll( ".ui-menu-item" ).each( function() {
7924				item = $( this );
7925				return item.offset().top - base - height < 0;
7926			} );
7927
7928			this.focus( event, item );
7929		} else {
7930			this.focus( event, this.activeMenu.find( this.options.items )
7931				[ !this.active ? "first" : "last" ]() );
7932		}
7933	},
7934
7935	previousPage: function( event ) {
7936		var item, base, height;
7937		if ( !this.active ) {
7938			this.next( event );
7939			return;
7940		}
7941		if ( this.isFirstItem() ) {
7942			return;
7943		}
7944		if ( this._hasScroll() ) {
7945			base = this.active.offset().top;
7946			height = this.element.height();
7947			this.active.prevAll( ".ui-menu-item" ).each( function() {
7948				item = $( this );
7949				return item.offset().top - base + height > 0;
7950			} );
7951
7952			this.focus( event, item );
7953		} else {
7954			this.focus( event, this.activeMenu.find( this.options.items ).first() );
7955		}
7956	},
7957
7958	_hasScroll: function() {
7959		return this.element.outerHeight() < this.element.prop( "scrollHeight" );
7960	},
7961
7962	select: function( event ) {
7963
7964		// TODO: It should never be possible to not have an active item at this
7965		// point, but the tests don't trigger mouseenter before click.
7966		this.active = this.active || $( event.target ).closest( ".ui-menu-item" );
7967		var ui = { item: this.active };
7968		if ( !this.active.has( ".ui-menu" ).length ) {
7969			this.collapseAll( event, true );
7970		}
7971		this._trigger( "select", event, ui );
7972	},
7973
7974	_filterMenuItems: function( character ) {
7975		var escapedCharacter = character.replace( /[\-\[\]{}()*+?.,\\\^$|#\s]/g, "\\$&" ),
7976			regex = new RegExp( "^" + escapedCharacter, "i" );
7977
7978		return this.activeMenu
7979			.find( this.options.items )
7980
7981				// Only match on items, not dividers or other content (#10571)
7982				.filter( ".ui-menu-item" )
7983					.filter( function() {
7984						return regex.test(
7985							$.trim( $( this ).children( ".ui-menu-item-wrapper" ).text() ) );
7986					} );
7987	}
7988} );
7989
7990
7991/*!
7992 * jQuery UI Autocomplete 1.12.1
7993 * http://jqueryui.com
7994 *
7995 * Copyright jQuery Foundation and other contributors
7996 * Released under the MIT license.
7997 * http://jquery.org/license
7998 */
7999
8000//>>label: Autocomplete
8001//>>group: Widgets
8002//>>description: Lists suggested words as the user is typing.
8003//>>docs: http://api.jqueryui.com/autocomplete/
8004//>>demos: http://jqueryui.com/autocomplete/
8005//>>css.structure: ../../themes/base/core.css
8006//>>css.structure: ../../themes/base/autocomplete.css
8007//>>css.theme: ../../themes/base/theme.css
8008
8009
8010
8011$.widget( "ui.autocomplete", {
8012	version: "1.12.1",
8013	defaultElement: "<input>",
8014	options: {
8015		appendTo: null,
8016		autoFocus: false,
8017		delay: 300,
8018		minLength: 1,
8019		position: {
8020			my: "left top",
8021			at: "left bottom",
8022			collision: "none"
8023		},
8024		source: null,
8025
8026		// Callbacks
8027		change: null,
8028		close: null,
8029		focus: null,
8030		open: null,
8031		response: null,
8032		search: null,
8033		select: null
8034	},
8035
8036	requestIndex: 0,
8037	pending: 0,
8038
8039	_create: function() {
8040
8041		// Some browsers only repeat keydown events, not keypress events,
8042		// so we use the suppressKeyPress flag to determine if we've already
8043		// handled the keydown event. #7269
8044		// Unfortunately the code for & in keypress is the same as the up arrow,
8045		// so we use the suppressKeyPressRepeat flag to avoid handling keypress
8046		// events when we know the keydown event was used to modify the
8047		// search term. #7799
8048		var suppressKeyPress, suppressKeyPressRepeat, suppressInput,
8049			nodeName = this.element[ 0 ].nodeName.toLowerCase(),
8050			isTextarea = nodeName === "textarea",
8051			isInput = nodeName === "input";
8052
8053		// Textareas are always multi-line
8054		// Inputs are always single-line, even if inside a contentEditable element
8055		// IE also treats inputs as contentEditable
8056		// All other element types are determined by whether or not they're contentEditable
8057		this.isMultiLine = isTextarea || !isInput && this._isContentEditable( this.element );
8058
8059		this.valueMethod = this.element[ isTextarea || isInput ? "val" : "text" ];
8060		this.isNewMenu = true;
8061
8062		this._addClass( "ui-autocomplete-input" );
8063		this.element.attr( "autocomplete", "off" );
8064
8065		this._on( this.element, {
8066			keydown: function( event ) {
8067				if ( this.element.prop( "readOnly" ) ) {
8068					suppressKeyPress = true;
8069					suppressInput = true;
8070					suppressKeyPressRepeat = true;
8071					return;
8072				}
8073
8074				suppressKeyPress = false;
8075				suppressInput = false;
8076				suppressKeyPressRepeat = false;
8077				var keyCode = $.ui.keyCode;
8078				switch ( event.keyCode ) {
8079				case keyCode.PAGE_UP:
8080					suppressKeyPress = true;
8081					this._move( "previousPage", event );
8082					break;
8083				case keyCode.PAGE_DOWN:
8084					suppressKeyPress = true;
8085					this._move( "nextPage", event );
8086					break;
8087				case keyCode.UP:
8088					suppressKeyPress = true;
8089					this._keyEvent( "previous", event );
8090					break;
8091				case keyCode.DOWN:
8092					suppressKeyPress = true;
8093					this._keyEvent( "next", event );
8094					break;
8095				case keyCode.ENTER:
8096
8097					// when menu is open and has focus
8098					if ( this.menu.active ) {
8099
8100						// #6055 - Opera still allows the keypress to occur
8101						// which causes forms to submit
8102						suppressKeyPress = true;
8103						event.preventDefault();
8104						this.menu.select( event );
8105					}
8106					break;
8107				case keyCode.TAB:
8108					if ( this.menu.active ) {
8109						this.menu.select( event );
8110					}
8111					break;
8112				case keyCode.ESCAPE:
8113					if ( this.menu.element.is( ":visible" ) ) {
8114						if ( !this.isMultiLine ) {
8115							this._value( this.term );
8116						}
8117						this.close( event );
8118
8119						// Different browsers have different default behavior for escape
8120						// Single press can mean undo or clear
8121						// Double press in IE means clear the whole form
8122						event.preventDefault();
8123					}
8124					break;
8125				default:
8126					suppressKeyPressRepeat = true;
8127
8128					// search timeout should be triggered before the input value is changed
8129					this._searchTimeout( event );
8130					break;
8131				}
8132			},
8133			keypress: function( event ) {
8134				if ( suppressKeyPress ) {
8135					suppressKeyPress = false;
8136					if ( !this.isMultiLine || this.menu.element.is( ":visible" ) ) {
8137						event.preventDefault();
8138					}
8139					return;
8140				}
8141				if ( suppressKeyPressRepeat ) {
8142					return;
8143				}
8144
8145				// Replicate some key handlers to allow them to repeat in Firefox and Opera
8146				var keyCode = $.ui.keyCode;
8147				switch ( event.keyCode ) {
8148				case keyCode.PAGE_UP:
8149					this._move( "previousPage", event );
8150					break;
8151				case keyCode.PAGE_DOWN:
8152					this._move( "nextPage", event );
8153					break;
8154				case keyCode.UP:
8155					this._keyEvent( "previous", event );
8156					break;
8157				case keyCode.DOWN:
8158					this._keyEvent( "next", event );
8159					break;
8160				}
8161			},
8162			input: function( event ) {
8163				if ( suppressInput ) {
8164					suppressInput = false;
8165					event.preventDefault();
8166					return;
8167				}
8168				this._searchTimeout( event );
8169			},
8170			focus: function() {
8171				this.selectedItem = null;
8172				this.previous = this._value();
8173			},
8174			blur: function( event ) {
8175				if ( this.cancelBlur ) {
8176					delete this.cancelBlur;
8177					return;
8178				}
8179
8180				clearTimeout( this.searching );
8181				this.close( event );
8182				this._change( event );
8183			}
8184		} );
8185
8186		this._initSource();
8187		this.menu = $( "<ul>" )
8188			.appendTo( this._appendTo() )
8189			.menu( {
8190
8191				// disable ARIA support, the live region takes care of that
8192				role: null
8193			} )
8194			.hide()
8195			.menu( "instance" );
8196
8197		this._addClass( this.menu.element, "ui-autocomplete", "ui-front" );
8198		this._on( this.menu.element, {
8199			mousedown: function( event ) {
8200
8201				// prevent moving focus out of the text field
8202				event.preventDefault();
8203
8204				// IE doesn't prevent moving focus even with event.preventDefault()
8205				// so we set a flag to know when we should ignore the blur event
8206				this.cancelBlur = true;
8207				this._delay( function() {
8208					delete this.cancelBlur;
8209
8210					// Support: IE 8 only
8211					// Right clicking a menu item or selecting text from the menu items will
8212					// result in focus moving out of the input. However, we've already received
8213					// and ignored the blur event because of the cancelBlur flag set above. So
8214					// we restore focus to ensure that the menu closes properly based on the user's
8215					// next actions.
8216					if ( this.element[ 0 ] !== $.ui.safeActiveElement( this.document[ 0 ] ) ) {
8217						this.element.trigger( "focus" );
8218					}
8219				} );
8220			},
8221			menufocus: function( event, ui ) {
8222				var label, item;
8223
8224				// support: Firefox
8225				// Prevent accidental activation of menu items in Firefox (#7024 #9118)
8226				if ( this.isNewMenu ) {
8227					this.isNewMenu = false;
8228					if ( event.originalEvent && /^mouse/.test( event.originalEvent.type ) ) {
8229						this.menu.blur();
8230
8231						this.document.one( "mousemove", function() {
8232							$( event.target ).trigger( event.originalEvent );
8233						} );
8234
8235						return;
8236					}
8237				}
8238
8239				item = ui.item.data( "ui-autocomplete-item" );
8240				if ( false !== this._trigger( "focus", event, { item: item } ) ) {
8241
8242					// use value to match what will end up in the input, if it was a key event
8243					if ( event.originalEvent && /^key/.test( event.originalEvent.type ) ) {
8244						this._value( item.value );
8245					}
8246				}
8247
8248				// Announce the value in the liveRegion
8249				label = ui.item.attr( "aria-label" ) || item.value;
8250				if ( label && $.trim( label ).length ) {
8251					this.liveRegion.children().hide();
8252					$( "<div>" ).text( label ).appendTo( this.liveRegion );
8253				}
8254			},
8255			menuselect: function( event, ui ) {
8256				var item = ui.item.data( "ui-autocomplete-item" ),
8257					previous = this.previous;
8258
8259				// Only trigger when focus was lost (click on menu)
8260				if ( this.element[ 0 ] !== $.ui.safeActiveElement( this.document[ 0 ] ) ) {
8261					this.element.trigger( "focus" );
8262					this.previous = previous;
8263
8264					// #6109 - IE triggers two focus events and the second
8265					// is asynchronous, so we need to reset the previous
8266					// term synchronously and asynchronously :-(
8267					this._delay( function() {
8268						this.previous = previous;
8269						this.selectedItem = item;
8270					} );
8271				}
8272
8273				if ( false !== this._trigger( "select", event, { item: item } ) ) {
8274					this._value( item.value );
8275				}
8276
8277				// reset the term after the select event
8278				// this allows custom select handling to work properly
8279				this.term = this._value();
8280
8281				this.close( event );
8282				this.selectedItem = item;
8283			}
8284		} );
8285
8286		this.liveRegion = $( "<div>", {
8287			role: "status",
8288			"aria-live": "assertive",
8289			"aria-relevant": "additions"
8290		} )
8291			.appendTo( this.document[ 0 ].body );
8292
8293		this._addClass( this.liveRegion, null, "ui-helper-hidden-accessible" );
8294
8295		// Turning off autocomplete prevents the browser from remembering the
8296		// value when navigating through history, so we re-enable autocomplete
8297		// if the page is unloaded before the widget is destroyed. #7790
8298		this._on( this.window, {
8299			beforeunload: function() {
8300				this.element.removeAttr( "autocomplete" );
8301			}
8302		} );
8303	},
8304
8305	_destroy: function() {
8306		clearTimeout( this.searching );
8307		this.element.removeAttr( "autocomplete" );
8308		this.menu.element.remove();
8309		this.liveRegion.remove();
8310	},
8311
8312	_setOption: function( key, value ) {
8313		this._super( key, value );
8314		if ( key === "source" ) {
8315			this._initSource();
8316		}
8317		if ( key === "appendTo" ) {
8318			this.menu.element.appendTo( this._appendTo() );
8319		}
8320		if ( key === "disabled" && value && this.xhr ) {
8321			this.xhr.abort();
8322		}
8323	},
8324
8325	_isEventTargetInWidget: function( event ) {
8326		var menuElement = this.menu.element[ 0 ];
8327
8328		return event.target === this.element[ 0 ] ||
8329			event.target === menuElement ||
8330			$.contains( menuElement, event.target );
8331	},
8332
8333	_closeOnClickOutside: function( event ) {
8334		if ( !this._isEventTargetInWidget( event ) ) {
8335			this.close();
8336		}
8337	},
8338
8339	_appendTo: function() {
8340		var element = this.options.appendTo;
8341
8342		if ( element ) {
8343			element = element.jquery || element.nodeType ?
8344				$( element ) :
8345				this.document.find( element ).eq( 0 );
8346		}
8347
8348		if ( !element || !element[ 0 ] ) {
8349			element = this.element.closest( ".ui-front, dialog" );
8350		}
8351
8352		if ( !element.length ) {
8353			element = this.document[ 0 ].body;
8354		}
8355
8356		return element;
8357	},
8358
8359	_initSource: function() {
8360		var array, url,
8361			that = this;
8362		if ( $.isArray( this.options.source ) ) {
8363			array = this.options.source;
8364			this.source = function( request, response ) {
8365				response( $.ui.autocomplete.filter( array, request.term ) );
8366			};
8367		} else if ( typeof this.options.source === "string" ) {
8368			url = this.options.source;
8369			this.source = function( request, response ) {
8370				if ( that.xhr ) {
8371					that.xhr.abort();
8372				}
8373				that.xhr = $.ajax( {
8374					url: url,
8375					data: request,
8376					dataType: "json",
8377					success: function( data ) {
8378						response( data );
8379					},
8380					error: function() {
8381						response( [] );
8382					}
8383				} );
8384			};
8385		} else {
8386			this.source = this.options.source;
8387		}
8388	},
8389
8390	_searchTimeout: function( event ) {
8391		clearTimeout( this.searching );
8392		this.searching = this._delay( function() {
8393
8394			// Search if the value has changed, or if the user retypes the same value (see #7434)
8395			var equalValues = this.term === this._value(),
8396				menuVisible = this.menu.element.is( ":visible" ),
8397				modifierKey = event.altKey || event.ctrlKey || event.metaKey || event.shiftKey;
8398
8399			if ( !equalValues || ( equalValues && !menuVisible && !modifierKey ) ) {
8400				this.selectedItem = null;
8401				this.search( null, event );
8402			}
8403		}, this.options.delay );
8404	},
8405
8406	search: function( value, event ) {
8407		value = value != null ? value : this._value();
8408
8409		// Always save the actual value, not the one passed as an argument
8410		this.term = this._value();
8411
8412		if ( value.length < this.options.minLength ) {
8413			return this.close( event );
8414		}
8415
8416		if ( this._trigger( "search", event ) === false ) {
8417			return;
8418		}
8419
8420		return this._search( value );
8421	},
8422
8423	_search: function( value ) {
8424		this.pending++;
8425		this._addClass( "ui-autocomplete-loading" );
8426		this.cancelSearch = false;
8427
8428		this.source( { term: value }, this._response() );
8429	},
8430
8431	_response: function() {
8432		var index = ++this.requestIndex;
8433
8434		return $.proxy( function( content ) {
8435			if ( index === this.requestIndex ) {
8436				this.__response( content );
8437			}
8438
8439			this.pending--;
8440			if ( !this.pending ) {
8441				this._removeClass( "ui-autocomplete-loading" );
8442			}
8443		}, this );
8444	},
8445
8446	__response: function( content ) {
8447		if ( content ) {
8448			content = this._normalize( content );
8449		}
8450		this._trigger( "response", null, { content: content } );
8451		if ( !this.options.disabled && content && content.length && !this.cancelSearch ) {
8452			this._suggest( content );
8453			this._trigger( "open" );
8454		} else {
8455
8456			// use ._close() instead of .close() so we don't cancel future searches
8457			this._close();
8458		}
8459	},
8460
8461	close: function( event ) {
8462		this.cancelSearch = true;
8463		this._close( event );
8464	},
8465
8466	_close: function( event ) {
8467
8468		// Remove the handler that closes the menu on outside clicks
8469		this._off( this.document, "mousedown" );
8470
8471		if ( this.menu.element.is( ":visible" ) ) {
8472			this.menu.element.hide();
8473			this.menu.blur();
8474			this.isNewMenu = true;
8475			this._trigger( "close", event );
8476		}
8477	},
8478
8479	_change: function( event ) {
8480		if ( this.previous !== this._value() ) {
8481			this._trigger( "change", event, { item: this.selectedItem } );
8482		}
8483	},
8484
8485	_normalize: function( items ) {
8486
8487		// assume all items have the right format when the first item is complete
8488		if ( items.length && items[ 0 ].label && items[ 0 ].value ) {
8489			return items;
8490		}
8491		return $.map( items, function( item ) {
8492			if ( typeof item === "string" ) {
8493				return {
8494					label: item,
8495					value: item
8496				};
8497			}
8498			return $.extend( {}, item, {
8499				label: item.label || item.value,
8500				value: item.value || item.label
8501			} );
8502		} );
8503	},
8504
8505	_suggest: function( items ) {
8506		var ul = this.menu.element.empty();
8507		this._renderMenu( ul, items );
8508		this.isNewMenu = true;
8509		this.menu.refresh();
8510
8511		// Size and position menu
8512		ul.show();
8513		this._resizeMenu();
8514		ul.position( $.extend( {
8515			of: this.element
8516		}, this.options.position ) );
8517
8518		if ( this.options.autoFocus ) {
8519			this.menu.next();
8520		}
8521
8522		// Listen for interactions outside of the widget (#6642)
8523		this._on( this.document, {
8524			mousedown: "_closeOnClickOutside"
8525		} );
8526	},
8527
8528	_resizeMenu: function() {
8529		var ul = this.menu.element;
8530		ul.outerWidth( Math.max(
8531
8532			// Firefox wraps long text (possibly a rounding bug)
8533			// so we add 1px to avoid the wrapping (#7513)
8534			ul.width( "" ).outerWidth() + 1,
8535			this.element.outerWidth()
8536		) );
8537	},
8538
8539	_renderMenu: function( ul, items ) {
8540		var that = this;
8541		$.each( items, function( index, item ) {
8542			that._renderItemData( ul, item );
8543		} );
8544	},
8545
8546	_renderItemData: function( ul, item ) {
8547		return this._renderItem( ul, item ).data( "ui-autocomplete-item", item );
8548	},
8549
8550	_renderItem: function( ul, item ) {
8551		return $( "<li>" )
8552			.append( $( "<div>" ).text( item.label ) )
8553			.appendTo( ul );
8554	},
8555
8556	_move: function( direction, event ) {
8557		if ( !this.menu.element.is( ":visible" ) ) {
8558			this.search( null, event );
8559			return;
8560		}
8561		if ( this.menu.isFirstItem() && /^previous/.test( direction ) ||
8562				this.menu.isLastItem() && /^next/.test( direction ) ) {
8563
8564			if ( !this.isMultiLine ) {
8565				this._value( this.term );
8566			}
8567
8568			this.menu.blur();
8569			return;
8570		}
8571		this.menu[ direction ]( event );
8572	},
8573
8574	widget: function() {
8575		return this.menu.element;
8576	},
8577
8578	_value: function() {
8579		return this.valueMethod.apply( this.element, arguments );
8580	},
8581
8582	_keyEvent: function( keyEvent, event ) {
8583		if ( !this.isMultiLine || this.menu.element.is( ":visible" ) ) {
8584			this._move( keyEvent, event );
8585
8586			// Prevents moving cursor to beginning/end of the text field in some browsers
8587			event.preventDefault();
8588		}
8589	},
8590
8591	// Support: Chrome <=50
8592	// We should be able to just use this.element.prop( "isContentEditable" )
8593	// but hidden elements always report false in Chrome.
8594	// https://code.google.com/p/chromium/issues/detail?id=313082
8595	_isContentEditable: function( element ) {
8596		if ( !element.length ) {
8597			return false;
8598		}
8599
8600		var editable = element.prop( "contentEditable" );
8601
8602		if ( editable === "inherit" ) {
8603		  return this._isContentEditable( element.parent() );
8604		}
8605
8606		return editable === "true";
8607	}
8608} );
8609
8610$.extend( $.ui.autocomplete, {
8611	escapeRegex: function( value ) {
8612		return value.replace( /[\-\[\]{}()*+?.,\\\^$|#\s]/g, "\\$&" );
8613	},
8614	filter: function( array, term ) {
8615		var matcher = new RegExp( $.ui.autocomplete.escapeRegex( term ), "i" );
8616		return $.grep( array, function( value ) {
8617			return matcher.test( value.label || value.value || value );
8618		} );
8619	}
8620} );
8621
8622// Live region extension, adding a `messages` option
8623// NOTE: This is an experimental API. We are still investigating
8624// a full solution for string manipulation and internationalization.
8625$.widget( "ui.autocomplete", $.ui.autocomplete, {
8626	options: {
8627		messages: {
8628			noResults: "No search results.",
8629			results: function( amount ) {
8630				return amount + ( amount > 1 ? " results are" : " result is" ) +
8631					" available, use up and down arrow keys to navigate.";
8632			}
8633		}
8634	},
8635
8636	__response: function( content ) {
8637		var message;
8638		this._superApply( arguments );
8639		if ( this.options.disabled || this.cancelSearch ) {
8640			return;
8641		}
8642		if ( content && content.length ) {
8643			message = this.options.messages.results( content.length );
8644		} else {
8645			message = this.options.messages.noResults;
8646		}
8647		this.liveRegion.children().hide();
8648		$( "<div>" ).text( message ).appendTo( this.liveRegion );
8649	}
8650} );
8651
8652var widgetsAutocomplete = $.ui.autocomplete;
8653
8654
8655/*!
8656 * jQuery UI Controlgroup 1.12.1
8657 * http://jqueryui.com
8658 *
8659 * Copyright jQuery Foundation and other contributors
8660 * Released under the MIT license.
8661 * http://jquery.org/license
8662 */
8663
8664//>>label: Controlgroup
8665//>>group: Widgets
8666//>>description: Visually groups form control widgets
8667//>>docs: http://api.jqueryui.com/controlgroup/
8668//>>demos: http://jqueryui.com/controlgroup/
8669//>>css.structure: ../../themes/base/core.css
8670//>>css.structure: ../../themes/base/controlgroup.css
8671//>>css.theme: ../../themes/base/theme.css
8672
8673
8674var controlgroupCornerRegex = /ui-corner-([a-z]){2,6}/g;
8675
8676var widgetsControlgroup = $.widget( "ui.controlgroup", {
8677	version: "1.12.1",
8678	defaultElement: "<div>",
8679	options: {
8680		direction: "horizontal",
8681		disabled: null,
8682		onlyVisible: true,
8683		items: {
8684			"button": "input[type=button], input[type=submit], input[type=reset], button, a",
8685			"controlgroupLabel": ".ui-controlgroup-label",
8686			"checkboxradio": "input[type='checkbox'], input[type='radio']",
8687			"selectmenu": "select",
8688			"spinner": ".ui-spinner-input"
8689		}
8690	},
8691
8692	_create: function() {
8693		this._enhance();
8694	},
8695
8696	// To support the enhanced option in jQuery Mobile, we isolate DOM manipulation
8697	_enhance: function() {
8698		this.element.attr( "role", "toolbar" );
8699		this.refresh();
8700	},
8701
8702	_destroy: function() {
8703		this._callChildMethod( "destroy" );
8704		this.childWidgets.removeData( "ui-controlgroup-data" );
8705		this.element.removeAttr( "role" );
8706		if ( this.options.items.controlgroupLabel ) {
8707			this.element
8708				.find( this.options.items.controlgroupLabel )
8709				.find( ".ui-controlgroup-label-contents" )
8710				.contents().unwrap();
8711		}
8712	},
8713
8714	_initWidgets: function() {
8715		var that = this,
8716			childWidgets = [];
8717
8718		// First we iterate over each of the items options
8719		$.each( this.options.items, function( widget, selector ) {
8720			var labels;
8721			var options = {};
8722
8723			// Make sure the widget has a selector set
8724			if ( !selector ) {
8725				return;
8726			}
8727
8728			if ( widget === "controlgroupLabel" ) {
8729				labels = that.element.find( selector );
8730				labels.each( function() {
8731					var element = $( this );
8732
8733					if ( element.children( ".ui-controlgroup-label-contents" ).length ) {
8734						return;
8735					}
8736					element.contents()
8737						.wrapAll( "<span class='ui-controlgroup-label-contents'></span>" );
8738				} );
8739				that._addClass( labels, null, "ui-widget ui-widget-content ui-state-default" );
8740				childWidgets = childWidgets.concat( labels.get() );
8741				return;
8742			}
8743
8744			// Make sure the widget actually exists
8745			if ( !$.fn[ widget ] ) {
8746				return;
8747			}
8748
8749			// We assume everything is in the middle to start because we can't determine
8750			// first / last elements until all enhancments are done.
8751			if ( that[ "_" + widget + "Options" ] ) {
8752				options = that[ "_" + widget + "Options" ]( "middle" );
8753			} else {
8754				options = { classes: {} };
8755			}
8756
8757			// Find instances of this widget inside controlgroup and init them
8758			that.element
8759				.find( selector )
8760				.each( function() {
8761					var element = $( this );
8762					var instance = element[ widget ]( "instance" );
8763
8764					// We need to clone the default options for this type of widget to avoid
8765					// polluting the variable options which has a wider scope than a single widget.
8766					var instanceOptions = $.widget.extend( {}, options );
8767
8768					// If the button is the child of a spinner ignore it
8769					// TODO: Find a more generic solution
8770					if ( widget === "button" && element.parent( ".ui-spinner" ).length ) {
8771						return;
8772					}
8773
8774					// Create the widget if it doesn't exist
8775					if ( !instance ) {
8776						instance = element[ widget ]()[ widget ]( "instance" );
8777					}
8778					if ( instance ) {
8779						instanceOptions.classes =
8780							that._resolveClassesValues( instanceOptions.classes, instance );
8781					}
8782					element[ widget ]( instanceOptions );
8783
8784					// Store an instance of the controlgroup to be able to reference
8785					// from the outermost element for changing options and refresh
8786					var widgetElement = element[ widget ]( "widget" );
8787					$.data( widgetElement[ 0 ], "ui-controlgroup-data",
8788						instance ? instance : element[ widget ]( "instance" ) );
8789
8790					childWidgets.push( widgetElement[ 0 ] );
8791				} );
8792		} );
8793
8794		this.childWidgets = $( $.unique( childWidgets ) );
8795		this._addClass( this.childWidgets, "ui-controlgroup-item" );
8796	},
8797
8798	_callChildMethod: function( method ) {
8799		this.childWidgets.each( function() {
8800			var element = $( this ),
8801				data = element.data( "ui-controlgroup-data" );
8802			if ( data && data[ method ] ) {
8803				data[ method ]();
8804			}
8805		} );
8806	},
8807
8808	_updateCornerClass: function( element, position ) {
8809		var remove = "ui-corner-top ui-corner-bottom ui-corner-left ui-corner-right ui-corner-all";
8810		var add = this._buildSimpleOptions( position, "label" ).classes.label;
8811
8812		this._removeClass( element, null, remove );
8813		this._addClass( element, null, add );
8814	},
8815
8816	_buildSimpleOptions: function( position, key ) {
8817		var direction = this.options.direction === "vertical";
8818		var result = {
8819			classes: {}
8820		};
8821		result.classes[ key ] = {
8822			"middle": "",
8823			"first": "ui-corner-" + ( direction ? "top" : "left" ),
8824			"last": "ui-corner-" + ( direction ? "bottom" : "right" ),
8825			"only": "ui-corner-all"
8826		}[ position ];
8827
8828		return result;
8829	},
8830
8831	_spinnerOptions: function( position ) {
8832		var options = this._buildSimpleOptions( position, "ui-spinner" );
8833
8834		options.classes[ "ui-spinner-up" ] = "";
8835		options.classes[ "ui-spinner-down" ] = "";
8836
8837		return options;
8838	},
8839
8840	_buttonOptions: function( position ) {
8841		return this._buildSimpleOptions( position, "ui-button" );
8842	},
8843
8844	_checkboxradioOptions: function( position ) {
8845		return this._buildSimpleOptions( position, "ui-checkboxradio-label" );
8846	},
8847
8848	_selectmenuOptions: function( position ) {
8849		var direction = this.options.direction === "vertical";
8850		return {
8851			width: direction ? "auto" : false,
8852			classes: {
8853				middle: {
8854					"ui-selectmenu-button-open": "",
8855					"ui-selectmenu-button-closed": ""
8856				},
8857				first: {
8858					"ui-selectmenu-button-open": "ui-corner-" + ( direction ? "top" : "tl" ),
8859					"ui-selectmenu-button-closed": "ui-corner-" + ( direction ? "top" : "left" )
8860				},
8861				last: {
8862					"ui-selectmenu-button-open": direction ? "" : "ui-corner-tr",
8863					"ui-selectmenu-button-closed": "ui-corner-" + ( direction ? "bottom" : "right" )
8864				},
8865				only: {
8866					"ui-selectmenu-button-open": "ui-corner-top",
8867					"ui-selectmenu-button-closed": "ui-corner-all"
8868				}
8869
8870			}[ position ]
8871		};
8872	},
8873
8874	_resolveClassesValues: function( classes, instance ) {
8875		var result = {};
8876		$.each( classes, function( key ) {
8877			var current = instance.options.classes[ key ] || "";
8878			current = $.trim( current.replace( controlgroupCornerRegex, "" ) );
8879			result[ key ] = ( current + " " + classes[ key ] ).replace( /\s+/g, " " );
8880		} );
8881		return result;
8882	},
8883
8884	_setOption: function( key, value ) {
8885		if ( key === "direction" ) {
8886			this._removeClass( "ui-controlgroup-" + this.options.direction );
8887		}
8888
8889		this._super( key, value );
8890		if ( key === "disabled" ) {
8891			this._callChildMethod( value ? "disable" : "enable" );
8892			return;
8893		}
8894
8895		this.refresh();
8896	},
8897
8898	refresh: function() {
8899		var children,
8900			that = this;
8901
8902		this._addClass( "ui-controlgroup ui-controlgroup-" + this.options.direction );
8903
8904		if ( this.options.direction === "horizontal" ) {
8905			this._addClass( null, "ui-helper-clearfix" );
8906		}
8907		this._initWidgets();
8908
8909		children = this.childWidgets;
8910
8911		// We filter here because we need to track all childWidgets not just the visible ones
8912		if ( this.options.onlyVisible ) {
8913			children = children.filter( ":visible" );
8914		}
8915
8916		if ( children.length ) {
8917
8918			// We do this last because we need to make sure all enhancment is done
8919			// before determining first and last
8920			$.each( [ "first", "last" ], function( index, value ) {
8921				var instance = children[ value ]().data( "ui-controlgroup-data" );
8922
8923				if ( instance && that[ "_" + instance.widgetName + "Options" ] ) {
8924					var options = that[ "_" + instance.widgetName + "Options" ](
8925						children.length === 1 ? "only" : value
8926					);
8927					options.classes = that._resolveClassesValues( options.classes, instance );
8928					instance.element[ instance.widgetName ]( options );
8929				} else {
8930					that._updateCornerClass( children[ value ](), value );
8931				}
8932			} );
8933
8934			// Finally call the refresh method on each of the child widgets.
8935			this._callChildMethod( "refresh" );
8936		}
8937	}
8938} );
8939
8940/*!
8941 * jQuery UI Checkboxradio 1.12.1
8942 * http://jqueryui.com
8943 *
8944 * Copyright jQuery Foundation and other contributors
8945 * Released under the MIT license.
8946 * http://jquery.org/license
8947 */
8948
8949//>>label: Checkboxradio
8950//>>group: Widgets
8951//>>description: Enhances a form with multiple themeable checkboxes or radio buttons.
8952//>>docs: http://api.jqueryui.com/checkboxradio/
8953//>>demos: http://jqueryui.com/checkboxradio/
8954//>>css.structure: ../../themes/base/core.css
8955//>>css.structure: ../../themes/base/button.css
8956//>>css.structure: ../../themes/base/checkboxradio.css
8957//>>css.theme: ../../themes/base/theme.css
8958
8959
8960
8961$.widget( "ui.checkboxradio", [ $.ui.formResetMixin, {
8962	version: "1.12.1",
8963	options: {
8964		disabled: null,
8965		label: null,
8966		icon: true,
8967		classes: {
8968			"ui-checkboxradio-label": "ui-corner-all",
8969			"ui-checkboxradio-icon": "ui-corner-all"
8970		}
8971	},
8972
8973	_getCreateOptions: function() {
8974		var disabled, labels;
8975		var that = this;
8976		var options = this._super() || {};
8977
8978		// We read the type here, because it makes more sense to throw a element type error first,
8979		// rather then the error for lack of a label. Often if its the wrong type, it
8980		// won't have a label (e.g. calling on a div, btn, etc)
8981		this._readType();
8982
8983		labels = this.element.labels();
8984
8985		// If there are multiple labels, use the last one
8986		this.label = $( labels[ labels.length - 1 ] );
8987		if ( !this.label.length ) {
8988			$.error( "No label found for checkboxradio widget" );
8989		}
8990
8991		this.originalLabel = "";
8992
8993		// We need to get the label text but this may also need to make sure it does not contain the
8994		// input itself.
8995		this.label.contents().not( this.element[ 0 ] ).each( function() {
8996
8997			// The label contents could be text, html, or a mix. We concat each element to get a
8998			// string representation of the label, without the input as part of it.
8999			that.originalLabel += this.nodeType === 3 ? $( this ).text() : this.outerHTML;
9000		} );
9001
9002		// Set the label option if we found label text
9003		if ( this.originalLabel ) {
9004			options.label = this.originalLabel;
9005		}
9006
9007		disabled = this.element[ 0 ].disabled;
9008		if ( disabled != null ) {
9009			options.disabled = disabled;
9010		}
9011		return options;
9012	},
9013
9014	_create: function() {
9015		var checked = this.element[ 0 ].checked;
9016
9017		this._bindFormResetHandler();
9018
9019		if ( this.options.disabled == null ) {
9020			this.options.disabled = this.element[ 0 ].disabled;
9021		}
9022
9023		this._setOption( "disabled", this.options.disabled );
9024		this._addClass( "ui-checkboxradio", "ui-helper-hidden-accessible" );
9025		this._addClass( this.label, "ui-checkboxradio-label", "ui-button ui-widget" );
9026
9027		if ( this.type === "radio" ) {
9028			this._addClass( this.label, "ui-checkboxradio-radio-label" );
9029		}
9030
9031		if ( this.options.label && this.options.label !== this.originalLabel ) {
9032			this._updateLabel();
9033		} else if ( this.originalLabel ) {
9034			this.options.label = this.originalLabel;
9035		}
9036
9037		this._enhance();
9038
9039		if ( checked ) {
9040			this._addClass( this.label, "ui-checkboxradio-checked", "ui-state-active" );
9041			if ( this.icon ) {
9042				this._addClass( this.icon, null, "ui-state-hover" );
9043			}
9044		}
9045
9046		this._on( {
9047			change: "_toggleClasses",
9048			focus: function() {
9049				this._addClass( this.label, null, "ui-state-focus ui-visual-focus" );
9050			},
9051			blur: function() {
9052				this._removeClass( this.label, null, "ui-state-focus ui-visual-focus" );
9053			}
9054		} );
9055	},
9056
9057	_readType: function() {
9058		var nodeName = this.element[ 0 ].nodeName.toLowerCase();
9059		this.type = this.element[ 0 ].type;
9060		if ( nodeName !== "input" || !/radio|checkbox/.test( this.type ) ) {
9061			$.error( "Can't create checkboxradio on element.nodeName=" + nodeName +
9062				" and element.type=" + this.type );
9063		}
9064	},
9065
9066	// Support jQuery Mobile enhanced option
9067	_enhance: function() {
9068		this._updateIcon( this.element[ 0 ].checked );
9069	},
9070
9071	widget: function() {
9072		return this.label;
9073	},
9074
9075	_getRadioGroup: function() {
9076		var group;
9077		var name = this.element[ 0 ].name;
9078		var nameSelector = "input[name='" + $.ui.escapeSelector( name ) + "']";
9079
9080		if ( !name ) {
9081			return $( [] );
9082		}
9083
9084		if ( this.form.length ) {
9085			group = $( this.form[ 0 ].elements ).filter( nameSelector );
9086		} else {
9087
9088			// Not inside a form, check all inputs that also are not inside a form
9089			group = $( nameSelector ).filter( function() {
9090				return $( this ).form().length === 0;
9091			} );
9092		}
9093
9094		return group.not( this.element );
9095	},
9096
9097	_toggleClasses: function() {
9098		var checked = this.element[ 0 ].checked;
9099		this._toggleClass( this.label, "ui-checkboxradio-checked", "ui-state-active", checked );
9100
9101		if ( this.options.icon && this.type === "checkbox" ) {
9102			this._toggleClass( this.icon, null, "ui-icon-check ui-state-checked", checked )
9103				._toggleClass( this.icon, null, "ui-icon-blank", !checked );
9104		}
9105
9106		if ( this.type === "radio" ) {
9107			this._getRadioGroup()
9108				.each( function() {
9109					var instance = $( this ).checkboxradio( "instance" );
9110
9111					if ( instance ) {
9112						instance._removeClass( instance.label,
9113							"ui-checkboxradio-checked", "ui-state-active" );
9114					}
9115				} );
9116		}
9117	},
9118
9119	_destroy: function() {
9120		this._unbindFormResetHandler();
9121
9122		if ( this.icon ) {
9123			this.icon.remove();
vendor: 4,659 bytes, lines 9124-9297
9124			this.iconSpace.remove();
9125		}
9126	},
9127
9128	_setOption: function( key, value ) {
9129
9130		// We don't allow the value to be set to nothing
9131		if ( key === "label" && !value ) {
9132			return;
9133		}
9134
9135		this._super( key, value );
9136
9137		if ( key === "disabled" ) {
9138			this._toggleClass( this.label, null, "ui-state-disabled", value );
9139			this.element[ 0 ].disabled = value;
9140
9141			// Don't refresh when setting disabled
9142			return;
9143		}
9144		this.refresh();
9145	},
9146
9147	_updateIcon: function( checked ) {
9148		var toAdd = "ui-icon ui-icon-background ";
9149
9150		if ( this.options.icon ) {
9151			if ( !this.icon ) {
9152				this.icon = $( "<span>" );
9153				this.iconSpace = $( "<span> </span>" );
9154				this._addClass( this.iconSpace, "ui-checkboxradio-icon-space" );
9155			}
9156
9157			if ( this.type === "checkbox" ) {
9158				toAdd += checked ? "ui-icon-check ui-state-checked" : "ui-icon-blank";
9159				this._removeClass( this.icon, null, checked ? "ui-icon-blank" : "ui-icon-check" );
9160			} else {
9161				toAdd += "ui-icon-blank";
9162			}
9163			this._addClass( this.icon, "ui-checkboxradio-icon", toAdd );
9164			if ( !checked ) {
9165				this._removeClass( this.icon, null, "ui-icon-check ui-state-checked" );
9166			}
9167			this.icon.prependTo( this.label ).after( this.iconSpace );
9168		} else if ( this.icon !== undefined ) {
9169			this.icon.remove();
9170			this.iconSpace.remove();
9171			delete this.icon;
9172		}
9173	},
9174
9175	_updateLabel: function() {
9176
9177		// Remove the contents of the label ( minus the icon, icon space, and input )
9178		var contents = this.label.contents().not( this.element[ 0 ] );
9179		if ( this.icon ) {
9180			contents = contents.not( this.icon[ 0 ] );
9181		}
9182		if ( this.iconSpace ) {
9183			contents = contents.not( this.iconSpace[ 0 ] );
9184		}
9185		contents.remove();
9186
9187		this.label.append( this.options.label );
9188	},
9189
9190	refresh: function() {
9191		var checked = this.element[ 0 ].checked,
9192			isDisabled = this.element[ 0 ].disabled;
9193
9194		this._updateIcon( checked );
9195		this._toggleClass( this.label, "ui-checkboxradio-checked", "ui-state-active", checked );
9196		if ( this.options.label !== null ) {
9197			this._updateLabel();
9198		}
9199
9200		if ( isDisabled !== this.options.disabled ) {
9201			this._setOptions( { "disabled": isDisabled } );
9202		}
9203	}
9204
9205} ] );
9206
9207var widgetsCheckboxradio = $.ui.checkboxradio;
9208
9209
9210/*!
9211 * jQuery UI Button 1.12.1
9212 * http://jqueryui.com
9213 *
9214 * Copyright jQuery Foundation and other contributors
9215 * Released under the MIT license.
9216 * http://jquery.org/license
9217 */
9218
9219//>>label: Button
9220//>>group: Widgets
9221//>>description: Enhances a form with themeable buttons.
9222//>>docs: http://api.jqueryui.com/button/
9223//>>demos: http://jqueryui.com/button/
9224//>>css.structure: ../../themes/base/core.css
9225//>>css.structure: ../../themes/base/button.css
9226//>>css.theme: ../../themes/base/theme.css
9227
9228
9229
9230$.widget( "ui.button", {
9231	version: "1.12.1",
9232	defaultElement: "<button>",
9233	options: {
9234		classes: {
9235			"ui-button": "ui-corner-all"
9236		},
9237		disabled: null,
9238		icon: null,
9239		iconPosition: "beginning",
9240		label: null,
9241		showLabel: true
9242	},
9243
9244	_getCreateOptions: function() {
9245		var disabled,
9246
9247			// This is to support cases like in jQuery Mobile where the base widget does have
9248			// an implementation of _getCreateOptions
9249			options = this._super() || {};
9250
9251		this.isInput = this.element.is( "input" );
9252
9253		disabled = this.element[ 0 ].disabled;
9254		if ( disabled != null ) {
9255			options.disabled = disabled;
9256		}
9257
9258		this.originalLabel = this.isInput ? this.element.val() : this.element.html();
9259		if ( this.originalLabel ) {
9260			options.label = this.originalLabel;
9261		}
9262
9263		return options;
9264	},
9265
9266	_create: function() {
9267		if ( !this.option.showLabel & !this.options.icon ) {
9268			this.options.showLabel = true;
9269		}
9270
9271		// We have to check the option again here even though we did in _getCreateOptions,
9272		// because null may have been passed on init which would override what was set in
9273		// _getCreateOptions
9274		if ( this.options.disabled == null ) {
9275			this.options.disabled = this.element[ 0 ].disabled || false;
9276		}
9277
9278		this.hasTitle = !!this.element.attr( "title" );
9279
9280		// Check to see if the label needs to be set or if its already correct
9281		if ( this.options.label && this.options.label !== this.originalLabel ) {
9282			if ( this.isInput ) {
9283				this.element.val( this.options.label );
9284			} else {
9285				this.element.html( this.options.label );
9286			}
9287		}
9288		this._addClass( "ui-button", "ui-widget" );
9289		this._setOption( "disabled", this.options.disabled );
9290		this._enhance();
9291
9292		if ( this.element.is( "a" ) ) {
9293			this._on( {
9294				"keyup": function( event ) {
9295					if ( event.keyCode === $.ui.keyCode.SPACE ) {
9296						event.preventDefault();
9297
vendor: 7,743 bytes, lines 9298-9580
9298						// Support: PhantomJS <= 1.9, IE 8 Only
9299						// If a native click is available use it so we actually cause navigation
9300						// otherwise just trigger a click event
9301						if ( this.element[ 0 ].click ) {
9302							this.element[ 0 ].click();
9303						} else {
9304							this.element.trigger( "click" );
9305						}
9306					}
9307				}
9308			} );
9309		}
9310	},
9311
9312	_enhance: function() {
9313		if ( !this.element.is( "button" ) ) {
9314			this.element.attr( "role", "button" );
9315		}
9316
9317		if ( this.options.icon ) {
9318			this._updateIcon( "icon", this.options.icon );
9319			this._updateTooltip();
9320		}
9321	},
9322
9323	_updateTooltip: function() {
9324		this.title = this.element.attr( "title" );
9325
9326		if ( !this.options.showLabel && !this.title ) {
9327			this.element.attr( "title", this.options.label );
9328		}
9329	},
9330
9331	_updateIcon: function( option, value ) {
9332		var icon = option !== "iconPosition",
9333			position = icon ? this.options.iconPosition : value,
9334			displayBlock = position === "top" || position === "bottom";
9335
9336		// Create icon
9337		if ( !this.icon ) {
9338			this.icon = $( "<span>" );
9339
9340			this._addClass( this.icon, "ui-button-icon", "ui-icon" );
9341
9342			if ( !this.options.showLabel ) {
9343				this._addClass( "ui-button-icon-only" );
9344			}
9345		} else if ( icon ) {
9346
9347			// If we are updating the icon remove the old icon class
9348			this._removeClass( this.icon, null, this.options.icon );
9349		}
9350
9351		// If we are updating the icon add the new icon class
9352		if ( icon ) {
9353			this._addClass( this.icon, null, value );
9354		}
9355
9356		this._attachIcon( position );
9357
9358		// If the icon is on top or bottom we need to add the ui-widget-icon-block class and remove
9359		// the iconSpace if there is one.
9360		if ( displayBlock ) {
9361			this._addClass( this.icon, null, "ui-widget-icon-block" );
9362			if ( this.iconSpace ) {
9363				this.iconSpace.remove();
9364			}
9365		} else {
9366
9367			// Position is beginning or end so remove the ui-widget-icon-block class and add the
9368			// space if it does not exist
9369			if ( !this.iconSpace ) {
9370				this.iconSpace = $( "<span> </span>" );
9371				this._addClass( this.iconSpace, "ui-button-icon-space" );
9372			}
9373			this._removeClass( this.icon, null, "ui-wiget-icon-block" );
9374			this._attachIconSpace( position );
9375		}
9376	},
9377
9378	_destroy: function() {
9379		this.element.removeAttr( "role" );
9380
9381		if ( this.icon ) {
9382			this.icon.remove();
9383		}
9384		if ( this.iconSpace ) {
9385			this.iconSpace.remove();
9386		}
9387		if ( !this.hasTitle ) {
9388			this.element.removeAttr( "title" );
9389		}
9390	},
9391
9392	_attachIconSpace: function( iconPosition ) {
9393		this.icon[ /^(?:end|bottom)/.test( iconPosition ) ? "before" : "after" ]( this.iconSpace );
9394	},
9395
9396	_attachIcon: function( iconPosition ) {
9397		this.element[ /^(?:end|bottom)/.test( iconPosition ) ? "append" : "prepend" ]( this.icon );
9398	},
9399
9400	_setOptions: function( options ) {
9401		var newShowLabel = options.showLabel === undefined ?
9402				this.options.showLabel :
9403				options.showLabel,
9404			newIcon = options.icon === undefined ? this.options.icon : options.icon;
9405
9406		if ( !newShowLabel && !newIcon ) {
9407			options.showLabel = true;
9408		}
9409		this._super( options );
9410	},
9411
9412	_setOption: function( key, value ) {
9413		if ( key === "icon" ) {
9414			if ( value ) {
9415				this._updateIcon( key, value );
9416			} else if ( this.icon ) {
9417				this.icon.remove();
9418				if ( this.iconSpace ) {
9419					this.iconSpace.remove();
9420				}
9421			}
9422		}
9423
9424		if ( key === "iconPosition" ) {
9425			this._updateIcon( key, value );
9426		}
9427
9428		// Make sure we can't end up with a button that has neither text nor icon
9429		if ( key === "showLabel" ) {
9430				this._toggleClass( "ui-button-icon-only", null, !value );
9431				this._updateTooltip();
9432		}
9433
9434		if ( key === "label" ) {
9435			if ( this.isInput ) {
9436				this.element.val( value );
9437			} else {
9438
9439				// If there is an icon, append it, else nothing then append the value
9440				// this avoids removal of the icon when setting label text
9441				this.element.html( value );
9442				if ( this.icon ) {
9443					this._attachIcon( this.options.iconPosition );
9444					this._attachIconSpace( this.options.iconPosition );
9445				}
9446			}
9447		}
9448
9449		this._super( key, value );
9450
9451		if ( key === "disabled" ) {
9452			this._toggleClass( null, "ui-state-disabled", value );
9453			this.element[ 0 ].disabled = value;
9454			if ( value ) {
9455				this.element.blur();
9456			}
9457		}
9458	},
9459
9460	refresh: function() {
9461
9462		// Make sure to only check disabled if its an element that supports this otherwise
9463		// check for the disabled class to determine state
9464		var isDisabled = this.element.is( "input, button" ) ?
9465			this.element[ 0 ].disabled : this.element.hasClass( "ui-button-disabled" );
9466
9467		if ( isDisabled !== this.options.disabled ) {
9468			this._setOptions( { disabled: isDisabled } );
9469		}
9470
9471		this._updateTooltip();
9472	}
9473} );
9474
9475// DEPRECATED
9476if ( $.uiBackCompat !== false ) {
9477
9478	// Text and Icons options
9479	$.widget( "ui.button", $.ui.button, {
9480		options: {
9481			text: true,
9482			icons: {
9483				primary: null,
9484				secondary: null
9485			}
9486		},
9487
9488		_create: function() {
9489			if ( this.options.showLabel && !this.options.text ) {
9490				this.options.showLabel = this.options.text;
9491			}
9492			if ( !this.options.showLabel && this.options.text ) {
9493				this.options.text = this.options.showLabel;
9494			}
9495			if ( !this.options.icon && ( this.options.icons.primary ||
9496					this.options.icons.secondary ) ) {
9497				if ( this.options.icons.primary ) {
9498					this.options.icon = this.options.icons.primary;
9499				} else {
9500					this.options.icon = this.options.icons.secondary;
9501					this.options.iconPosition = "end";
9502				}
9503			} else if ( this.options.icon ) {
9504				this.options.icons.primary = this.options.icon;
9505			}
9506			this._super();
9507		},
9508
9509		_setOption: function( key, value ) {
9510			if ( key === "text" ) {
9511				this._super( "showLabel", value );
9512				return;
9513			}
9514			if ( key === "showLabel" ) {
9515				this.options.text = value;
9516			}
9517			if ( key === "icon" ) {
9518				this.options.icons.primary = value;
9519			}
9520			if ( key === "icons" ) {
9521				if ( value.primary ) {
9522					this._super( "icon", value.primary );
9523					this._super( "iconPosition", "beginning" );
9524				} else if ( value.secondary ) {
9525					this._super( "icon", value.secondary );
9526					this._super( "iconPosition", "end" );
9527				}
9528			}
9529			this._superApply( arguments );
9530		}
9531	} );
9532
9533	$.fn.button = ( function( orig ) {
9534		return function() {
9535			if ( !this.length || ( this.length && this[ 0 ].tagName !== "INPUT" ) ||
9536					( this.length && this[ 0 ].tagName === "INPUT" && (
9537						this.attr( "type" ) !== "checkbox" && this.attr( "type" ) !== "radio"
9538					) ) ) {
9539				return orig.apply( this, arguments );
9540			}
9541			if ( !$.ui.checkboxradio ) {
9542				$.error( "Checkboxradio widget missing" );
9543			}
9544			if ( arguments.length === 0 ) {
9545				return this.checkboxradio( {
9546					"icon": false
9547				} );
9548			}
9549			return this.checkboxradio.apply( this, arguments );
9550		};
9551	} )( $.fn.button );
9552
9553	$.fn.buttonset = function() {
9554		if ( !$.ui.controlgroup ) {
9555			$.error( "Controlgroup widget missing" );
9556		}
9557		if ( arguments[ 0 ] === "option" && arguments[ 1 ] === "items" && arguments[ 2 ] ) {
9558			return this.controlgroup.apply( this,
9559				[ arguments[ 0 ], "items.button", arguments[ 2 ] ] );
9560		}
9561		if ( arguments[ 0 ] === "option" && arguments[ 1 ] === "items" ) {
9562			return this.controlgroup.apply( this, [ arguments[ 0 ], "items.button" ] );
9563		}
9564		if ( typeof arguments[ 0 ] === "object" && arguments[ 0 ].items ) {
9565			arguments[ 0 ].items = {
9566				button: arguments[ 0 ].items
9567			};
9568		}
9569		return this.controlgroup.apply( this, arguments );
9570	};
9571}
9572
9573var widgetsButton = $.ui.button;
9574
9575
9576// jscs:disable maximumLineLength
9577/* jscs:disable requireCamelCaseOrUpperCaseIdentifiers */
9578/*!
9579 * jQuery UI Datepicker 1.12.1
9580 * http://jqueryui.com
vendor: 4,553 bytes, lines 9581-9667
9581 *
9582 * Copyright jQuery Foundation and other contributors
9583 * Released under the MIT license.
9584 * http://jquery.org/license
9585 */
9586
9587//>>label: Datepicker
9588//>>group: Widgets
9589//>>description: Displays a calendar from an input or inline for selecting dates.
9590//>>docs: http://api.jqueryui.com/datepicker/
9591//>>demos: http://jqueryui.com/datepicker/
9592//>>css.structure: ../../themes/base/core.css
9593//>>css.structure: ../../themes/base/datepicker.css
9594//>>css.theme: ../../themes/base/theme.css
9595
9596
9597
9598$.extend( $.ui, { datepicker: { version: "1.12.1" } } );
9599
9600var datepicker_instActive;
9601
9602function datepicker_getZindex( elem ) {
9603	var position, value;
9604	while ( elem.length && elem[ 0 ] !== document ) {
9605
9606		// Ignore z-index if position is set to a value where z-index is ignored by the browser
9607		// This makes behavior of this function consistent across browsers
9608		// WebKit always returns auto if the element is positioned
9609		position = elem.css( "position" );
9610		if ( position === "absolute" || position === "relative" || position === "fixed" ) {
9611
9612			// IE returns 0 when zIndex is not specified
9613			// other browsers return a string
9614			// we ignore the case of nested elements with an explicit value of 0
9615			// <div style="z-index: -10;"><div style="z-index: 0;"></div></div>
9616			value = parseInt( elem.css( "zIndex" ), 10 );
9617			if ( !isNaN( value ) && value !== 0 ) {
9618				return value;
9619			}
9620		}
9621		elem = elem.parent();
9622	}
9623
9624	return 0;
9625}
9626/* Date picker manager.
9627   Use the singleton instance of this class, $.datepicker, to interact with the date picker.
9628   Settings for (groups of) date pickers are maintained in an instance object,
9629   allowing multiple different settings on the same page. */
9630
9631function Datepicker() {
9632	this._curInst = null; // The current instance in use
9633	this._keyEvent = false; // If the last event was a key event
9634	this._disabledInputs = []; // List of date picker inputs that have been disabled
9635	this._datepickerShowing = false; // True if the popup picker is showing , false if not
9636	this._inDialog = false; // True if showing within a "dialog", false if not
9637	this._mainDivId = "ui-datepicker-div"; // The ID of the main datepicker division
9638	this._inlineClass = "ui-datepicker-inline"; // The name of the inline marker class
9639	this._appendClass = "ui-datepicker-append"; // The name of the append marker class
9640	this._triggerClass = "ui-datepicker-trigger"; // The name of the trigger marker class
9641	this._dialogClass = "ui-datepicker-dialog"; // The name of the dialog marker class
9642	this._disableClass = "ui-datepicker-disabled"; // The name of the disabled covering marker class
9643	this._unselectableClass = "ui-datepicker-unselectable"; // The name of the unselectable cell marker class
9644	this._currentClass = "ui-datepicker-current-day"; // The name of the current day marker class
9645	this._dayOverClass = "ui-datepicker-days-cell-over"; // The name of the day hover marker class
9646	this.regional = []; // Available regional settings, indexed by language code
9647	this.regional[ "" ] = { // Default regional settings
9648		closeText: "Done", // Display text for close link
9649		prevText: "Prev", // Display text for previous month link
9650		nextText: "Next", // Display text for next month link
9651		currentText: "Today", // Display text for current month link
9652		monthNames: [ "January","February","March","April","May","June",
9653			"July","August","September","October","November","December" ], // Names of months for drop-down and formatting
9654		monthNamesShort: [ "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" ], // For formatting
9655		dayNames: [ "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday" ], // For formatting
9656		dayNamesShort: [ "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" ], // For formatting
9657		dayNamesMin: [ "Su","Mo","Tu","We","Th","Fr","Sa" ], // Column headings for days starting at Sunday
9658		weekHeader: "Wk", // Column header for week of the year
9659		dateFormat: "mm/dd/yy", // See format options on parseDate
9660		firstDay: 0, // The first day of the week, Sun = 0, Mon = 1, ...
9661		isRTL: false, // True if right-to-left language, false if left-to-right
9662		showMonthAfterYear: false, // True if the year select precedes month, false for month then year
9663		yearSuffix: "" // Additional text to append to the year in the month headers
9664	};
9665	this._defaults = { // Global defaults for all the date picker instances
9666		showOn: "focus", // "focus" for popup on focus,
9667			// "button" for trigger button, or "both" for either
vendor: 6,761 bytes, lines 9668-9800
9668		showAnim: "fadeIn", // Name of jQuery animation for popup
9669		showOptions: {}, // Options for enhanced animations
9670		defaultDate: null, // Used when field is blank: actual date,
9671			// +/-number for offset from today, null for today
9672		appendText: "", // Display text following the input box, e.g. showing the format
9673		buttonText: "...", // Text for trigger button
9674		buttonImage: "", // URL for trigger button image
9675		buttonImageOnly: false, // True if the image appears alone, false if it appears on a button
9676		hideIfNoPrevNext: false, // True to hide next/previous month links
9677			// if not applicable, false to just disable them
9678		navigationAsDateFormat: false, // True if date formatting applied to prev/today/next links
9679		gotoCurrent: false, // True if today link goes back to current selection instead
9680		changeMonth: false, // True if month can be selected directly, false if only prev/next
9681		changeYear: false, // True if year can be selected directly, false if only prev/next
9682		yearRange: "c-10:c+10", // Range of years to display in drop-down,
9683			// either relative to today's year (-nn:+nn), relative to currently displayed year
9684			// (c-nn:c+nn), absolute (nnnn:nnnn), or a combination of the above (nnnn:-n)
9685		showOtherMonths: false, // True to show dates in other months, false to leave blank
9686		selectOtherMonths: false, // True to allow selection of dates in other months, false for unselectable
9687		showWeek: false, // True to show week of the year, false to not show it
9688		calculateWeek: this.iso8601Week, // How to calculate the week of the year,
9689			// takes a Date and returns the number of the week for it
9690		shortYearCutoff: "+10", // Short year values < this are in the current century,
9691			// > this are in the previous century,
9692			// string value starting with "+" for current year + value
9693		minDate: null, // The earliest selectable date, or null for no limit
9694		maxDate: null, // The latest selectable date, or null for no limit
9695		duration: "fast", // Duration of display/closure
9696		beforeShowDay: null, // Function that takes a date and returns an array with
9697			// [0] = true if selectable, false if not, [1] = custom CSS class name(s) or "",
9698			// [2] = cell title (optional), e.g. $.datepicker.noWeekends
9699		beforeShow: null, // Function that takes an input field and
9700			// returns a set of custom settings for the date picker
9701		onSelect: null, // Define a callback function when a date is selected
9702		onChangeMonthYear: null, // Define a callback function when the month or year is changed
9703		onClose: null, // Define a callback function when the datepicker is closed
9704		numberOfMonths: 1, // Number of months to show at a time
9705		showCurrentAtPos: 0, // The position in multipe months at which to show the current month (starting at 0)
9706		stepMonths: 1, // Number of months to step back/forward
9707		stepBigMonths: 12, // Number of months to step back/forward for the big links
9708		altField: "", // Selector for an alternate field to store selected dates into
9709		altFormat: "", // The date format to use for the alternate field
9710		constrainInput: true, // The input is constrained by the current date format
9711		showButtonPanel: false, // True to show button panel, false to not show it
9712		autoSize: false, // True to size the input for the date format, false to leave as is
9713		disabled: false // The initial disabled state
9714	};
9715	$.extend( this._defaults, this.regional[ "" ] );
9716	this.regional.en = $.extend( true, {}, this.regional[ "" ] );
9717	this.regional[ "en-US" ] = $.extend( true, {}, this.regional.en );
9718	this.dpDiv = datepicker_bindHover( $( "<div id='" + this._mainDivId + "' class='ui-datepicker ui-widget ui-widget-content ui-helper-clearfix ui-corner-all'></div>" ) );
9719}
9720
9721$.extend( Datepicker.prototype, {
9722	/* Class name added to elements to indicate already configured with a date picker. */
9723	markerClassName: "hasDatepicker",
9724
9725	//Keep track of the maximum number of rows displayed (see #7043)
9726	maxRows: 4,
9727
9728	// TODO rename to "widget" when switching to widget factory
9729	_widgetDatepicker: function() {
9730		return this.dpDiv;
9731	},
9732
9733	/* Override the default settings for all instances of the date picker.
9734	 * @param  settings  object - the new settings to use as defaults (anonymous object)
9735	 * @return the manager object
9736	 */
9737	setDefaults: function( settings ) {
9738		datepicker_extendRemove( this._defaults, settings || {} );
9739		return this;
9740	},
9741
9742	/* Attach the date picker to a jQuery selection.
9743	 * @param  target	element - the target input field or division or span
9744	 * @param  settings  object - the new settings to use for this date picker instance (anonymous)
9745	 */
9746	_attachDatepicker: function( target, settings ) {
9747		var nodeName, inline, inst;
9748		nodeName = target.nodeName.toLowerCase();
9749		inline = ( nodeName === "div" || nodeName === "span" );
9750		if ( !target.id ) {
9751			this.uuid += 1;
9752			target.id = "dp" + this.uuid;
9753		}
9754		inst = this._newInst( $( target ), inline );
9755		inst.settings = $.extend( {}, settings || {} );
9756		if ( nodeName === "input" ) {
9757			this._connectDatepicker( target, inst );
9758		} else if ( inline ) {
9759			this._inlineDatepicker( target, inst );
9760		}
9761	},
9762
9763	/* Create a new instance object. */
9764	_newInst: function( target, inline ) {
9765		var id = target[ 0 ].id.replace( /([^A-Za-z0-9_\-])/g, "\\\\$1" ); // escape jQuery meta chars
9766		return { id: id, input: target, // associated target
9767			selectedDay: 0, selectedMonth: 0, selectedYear: 0, // current selection
9768			drawMonth: 0, drawYear: 0, // month being drawn
9769			inline: inline, // is datepicker inline or not
9770			dpDiv: ( !inline ? this.dpDiv : // presentation div
9771			datepicker_bindHover( $( "<div class='" + this._inlineClass + " ui-datepicker ui-widget ui-widget-content ui-helper-clearfix ui-corner-all'></div>" ) ) ) };
9772	},
9773
9774	/* Attach the date picker to an input field. */
9775	_connectDatepicker: function( target, inst ) {
9776		var input = $( target );
9777		inst.append = $( [] );
9778		inst.trigger = $( [] );
9779		if ( input.hasClass( this.markerClassName ) ) {
9780			return;
9781		}
9782		this._attachments( input, inst );
9783		input.addClass( this.markerClassName ).on( "keydown", this._doKeyDown ).
9784			on( "keypress", this._doKeyPress ).on( "keyup", this._doKeyUp );
9785		this._autoSize( inst );
9786		$.data( target, "datepicker", inst );
9787
9788		//If disabled option is true, disable the datepicker once it has been attached to the input (see ticket #5665)
9789		if ( inst.settings.disabled ) {
9790			this._disableDatepicker( target );
9791		}
9792	},
9793
9794	/* Make attachments based on settings. */
9795	_attachments: function( input, inst ) {
9796		var showOn, buttonText, buttonImage,
9797			appendText = this._get( inst, "appendText" ),
9798			isRTL = this._get( inst, "isRTL" );
9799
9800		if ( inst.append ) {
vendor: 6,192 bytes, lines 9801-9958
9801			inst.append.remove();
9802		}
9803		if ( appendText ) {
9804			inst.append = $( "<span class='" + this._appendClass + "'>" + appendText + "</span>" );
9805			input[ isRTL ? "before" : "after" ]( inst.append );
9806		}
9807
9808		input.off( "focus", this._showDatepicker );
9809
9810		if ( inst.trigger ) {
9811			inst.trigger.remove();
9812		}
9813
9814		showOn = this._get( inst, "showOn" );
9815		if ( showOn === "focus" || showOn === "both" ) { // pop-up date picker when in the marked field
9816			input.on( "focus", this._showDatepicker );
9817		}
9818		if ( showOn === "button" || showOn === "both" ) { // pop-up date picker when button clicked
9819			buttonText = this._get( inst, "buttonText" );
9820			buttonImage = this._get( inst, "buttonImage" );
9821			inst.trigger = $( this._get( inst, "buttonImageOnly" ) ?
9822				$( "<img/>" ).addClass( this._triggerClass ).
9823					attr( { src: buttonImage, alt: buttonText, title: buttonText } ) :
9824				$( "<button type='button'></button>" ).addClass( this._triggerClass ).
9825					html( !buttonImage ? buttonText : $( "<img/>" ).attr(
9826					{ src:buttonImage, alt:buttonText, title:buttonText } ) ) );
9827			input[ isRTL ? "before" : "after" ]( inst.trigger );
9828			inst.trigger.on( "click", function() {
9829				if ( $.datepicker._datepickerShowing && $.datepicker._lastInput === input[ 0 ] ) {
9830					$.datepicker._hideDatepicker();
9831				} else if ( $.datepicker._datepickerShowing && $.datepicker._lastInput !== input[ 0 ] ) {
9832					$.datepicker._hideDatepicker();
9833					$.datepicker._showDatepicker( input[ 0 ] );
9834				} else {
9835					$.datepicker._showDatepicker( input[ 0 ] );
9836				}
9837				return false;
9838			} );
9839		}
9840	},
9841
9842	/* Apply the maximum length for the date format. */
9843	_autoSize: function( inst ) {
9844		if ( this._get( inst, "autoSize" ) && !inst.inline ) {
9845			var findMax, max, maxI, i,
9846				date = new Date( 2009, 12 - 1, 20 ), // Ensure double digits
9847				dateFormat = this._get( inst, "dateFormat" );
9848
9849			if ( dateFormat.match( /[DM]/ ) ) {
9850				findMax = function( names ) {
9851					max = 0;
9852					maxI = 0;
9853					for ( i = 0; i < names.length; i++ ) {
9854						if ( names[ i ].length > max ) {
9855							max = names[ i ].length;
9856							maxI = i;
9857						}
9858					}
9859					return maxI;
9860				};
9861				date.setMonth( findMax( this._get( inst, ( dateFormat.match( /MM/ ) ?
9862					"monthNames" : "monthNamesShort" ) ) ) );
9863				date.setDate( findMax( this._get( inst, ( dateFormat.match( /DD/ ) ?
9864					"dayNames" : "dayNamesShort" ) ) ) + 20 - date.getDay() );
9865			}
9866			inst.input.attr( "size", this._formatDate( inst, date ).length );
9867		}
9868	},
9869
9870	/* Attach an inline date picker to a div. */
9871	_inlineDatepicker: function( target, inst ) {
9872		var divSpan = $( target );
9873		if ( divSpan.hasClass( this.markerClassName ) ) {
9874			return;
9875		}
9876		divSpan.addClass( this.markerClassName ).append( inst.dpDiv );
9877		$.data( target, "datepicker", inst );
9878		this._setDate( inst, this._getDefaultDate( inst ), true );
9879		this._updateDatepicker( inst );
9880		this._updateAlternate( inst );
9881
9882		//If disabled option is true, disable the datepicker before showing it (see ticket #5665)
9883		if ( inst.settings.disabled ) {
9884			this._disableDatepicker( target );
9885		}
9886
9887		// Set display:block in place of inst.dpDiv.show() which won't work on disconnected elements
9888		// http://bugs.jqueryui.com/ticket/7552 - A Datepicker created on a detached div has zero height
9889		inst.dpDiv.css( "display", "block" );
9890	},
9891
9892	/* Pop-up the date picker in a "dialog" box.
9893	 * @param  input element - ignored
9894	 * @param  date	string or Date - the initial date to display
9895	 * @param  onSelect  function - the function to call when a date is selected
9896	 * @param  settings  object - update the dialog date picker instance's settings (anonymous object)
9897	 * @param  pos int[2] - coordinates for the dialog's position within the screen or
9898	 *					event - with x/y coordinates or
9899	 *					leave empty for default (screen centre)
9900	 * @return the manager object
9901	 */
9902	_dialogDatepicker: function( input, date, onSelect, settings, pos ) {
9903		var id, browserWidth, browserHeight, scrollX, scrollY,
9904			inst = this._dialogInst; // internal instance
9905
9906		if ( !inst ) {
9907			this.uuid += 1;
9908			id = "dp" + this.uuid;
9909			this._dialogInput = $( "<input type='text' id='" + id +
9910				"' style='position: absolute; top: -100px; width: 0px;'/>" );
9911			this._dialogInput.on( "keydown", this._doKeyDown );
9912			$( "body" ).append( this._dialogInput );
9913			inst = this._dialogInst = this._newInst( this._dialogInput, false );
9914			inst.settings = {};
9915			$.data( this._dialogInput[ 0 ], "datepicker", inst );
9916		}
9917		datepicker_extendRemove( inst.settings, settings || {} );
9918		date = ( date && date.constructor === Date ? this._formatDate( inst, date ) : date );
9919		this._dialogInput.val( date );
9920
9921		this._pos = ( pos ? ( pos.length ? pos : [ pos.pageX, pos.pageY ] ) : null );
9922		if ( !this._pos ) {
9923			browserWidth = document.documentElement.clientWidth;
9924			browserHeight = document.documentElement.clientHeight;
9925			scrollX = document.documentElement.scrollLeft || document.body.scrollLeft;
9926			scrollY = document.documentElement.scrollTop || document.body.scrollTop;
9927			this._pos = // should use actual width/height below
9928				[ ( browserWidth / 2 ) - 100 + scrollX, ( browserHeight / 2 ) - 150 + scrollY ];
9929		}
9930
9931		// Move input on screen for focus, but hidden behind dialog
9932		this._dialogInput.css( "left", ( this._pos[ 0 ] + 20 ) + "px" ).css( "top", this._pos[ 1 ] + "px" );
9933		inst.settings.onSelect = onSelect;
9934		this._inDialog = true;
9935		this.dpDiv.addClass( this._dialogClass );
9936		this._showDatepicker( this._dialogInput[ 0 ] );
9937		if ( $.blockUI ) {
9938			$.blockUI( this.dpDiv );
9939		}
9940		$.data( this._dialogInput[ 0 ], "datepicker", inst );
9941		return this;
9942	},
9943
9944	/* Detach a datepicker from its control.
9945	 * @param  target	element - the target input field or division or span
9946	 */
9947	_destroyDatepicker: function( target ) {
9948		var nodeName,
9949			$target = $( target ),
9950			inst = $.data( target, "datepicker" );
9951
9952		if ( !$target.hasClass( this.markerClassName ) ) {
9953			return;
9954		}
9955
9956		nodeName = target.nodeName.toLowerCase();
9957		$.removeData( target, "datepicker" );
9958		if ( nodeName === "input" ) {
vendor: 12,111 bytes, lines 9959-10299
9959			inst.append.remove();
9960			inst.trigger.remove();
9961			$target.removeClass( this.markerClassName ).
9962				off( "focus", this._showDatepicker ).
9963				off( "keydown", this._doKeyDown ).
9964				off( "keypress", this._doKeyPress ).
9965				off( "keyup", this._doKeyUp );
9966		} else if ( nodeName === "div" || nodeName === "span" ) {
9967			$target.removeClass( this.markerClassName ).empty();
9968		}
9969
9970		if ( datepicker_instActive === inst ) {
9971			datepicker_instActive = null;
9972		}
9973	},
9974
9975	/* Enable the date picker to a jQuery selection.
9976	 * @param  target	element - the target input field or division or span
9977	 */
9978	_enableDatepicker: function( target ) {
9979		var nodeName, inline,
9980			$target = $( target ),
9981			inst = $.data( target, "datepicker" );
9982
9983		if ( !$target.hasClass( this.markerClassName ) ) {
9984			return;
9985		}
9986
9987		nodeName = target.nodeName.toLowerCase();
9988		if ( nodeName === "input" ) {
9989			target.disabled = false;
9990			inst.trigger.filter( "button" ).
9991				each( function() { this.disabled = false; } ).end().
9992				filter( "img" ).css( { opacity: "1.0", cursor: "" } );
9993		} else if ( nodeName === "div" || nodeName === "span" ) {
9994			inline = $target.children( "." + this._inlineClass );
9995			inline.children().removeClass( "ui-state-disabled" );
9996			inline.find( "select.ui-datepicker-month, select.ui-datepicker-year" ).
9997				prop( "disabled", false );
9998		}
9999		this._disabledInputs = $.map( this._disabledInputs,
10000			function( value ) { return ( value === target ? null : value ); } ); // delete entry
10001	},
10002
10003	/* Disable the date picker to a jQuery selection.
10004	 * @param  target	element - the target input field or division or span
10005	 */
10006	_disableDatepicker: function( target ) {
10007		var nodeName, inline,
10008			$target = $( target ),
10009			inst = $.data( target, "datepicker" );
10010
10011		if ( !$target.hasClass( this.markerClassName ) ) {
10012			return;
10013		}
10014
10015		nodeName = target.nodeName.toLowerCase();
10016		if ( nodeName === "input" ) {
10017			target.disabled = true;
10018			inst.trigger.filter( "button" ).
10019				each( function() { this.disabled = true; } ).end().
10020				filter( "img" ).css( { opacity: "0.5", cursor: "default" } );
10021		} else if ( nodeName === "div" || nodeName === "span" ) {
10022			inline = $target.children( "." + this._inlineClass );
10023			inline.children().addClass( "ui-state-disabled" );
10024			inline.find( "select.ui-datepicker-month, select.ui-datepicker-year" ).
10025				prop( "disabled", true );
10026		}
10027		this._disabledInputs = $.map( this._disabledInputs,
10028			function( value ) { return ( value === target ? null : value ); } ); // delete entry
10029		this._disabledInputs[ this._disabledInputs.length ] = target;
10030	},
10031
10032	/* Is the first field in a jQuery collection disabled as a datepicker?
10033	 * @param  target	element - the target input field or division or span
10034	 * @return boolean - true if disabled, false if enabled
10035	 */
10036	_isDisabledDatepicker: function( target ) {
10037		if ( !target ) {
10038			return false;
10039		}
10040		for ( var i = 0; i < this._disabledInputs.length; i++ ) {
10041			if ( this._disabledInputs[ i ] === target ) {
10042				return true;
10043			}
10044		}
10045		return false;
10046	},
10047
10048	/* Retrieve the instance data for the target control.
10049	 * @param  target  element - the target input field or division or span
10050	 * @return  object - the associated instance data
10051	 * @throws  error if a jQuery problem getting data
10052	 */
10053	_getInst: function( target ) {
10054		try {
10055			return $.data( target, "datepicker" );
10056		}
10057		catch ( err ) {
10058			throw "Missing instance data for this datepicker";
10059		}
10060	},
10061
10062	/* Update or retrieve the settings for a date picker attached to an input field or division.
10063	 * @param  target  element - the target input field or division or span
10064	 * @param  name	object - the new settings to update or
10065	 *				string - the name of the setting to change or retrieve,
10066	 *				when retrieving also "all" for all instance settings or
10067	 *				"defaults" for all global defaults
10068	 * @param  value   any - the new value for the setting
10069	 *				(omit if above is an object or to retrieve a value)
10070	 */
10071	_optionDatepicker: function( target, name, value ) {
10072		var settings, date, minDate, maxDate,
10073			inst = this._getInst( target );
10074
10075		if ( arguments.length === 2 && typeof name === "string" ) {
10076			return ( name === "defaults" ? $.extend( {}, $.datepicker._defaults ) :
10077				( inst ? ( name === "all" ? $.extend( {}, inst.settings ) :
10078				this._get( inst, name ) ) : null ) );
10079		}
10080
10081		settings = name || {};
10082		if ( typeof name === "string" ) {
10083			settings = {};
10084			settings[ name ] = value;
10085		}
10086
10087		if ( inst ) {
10088			if ( this._curInst === inst ) {
10089				this._hideDatepicker();
10090			}
10091
10092			date = this._getDateDatepicker( target, true );
10093			minDate = this._getMinMaxDate( inst, "min" );
10094			maxDate = this._getMinMaxDate( inst, "max" );
10095			datepicker_extendRemove( inst.settings, settings );
10096
10097			// reformat the old minDate/maxDate values if dateFormat changes and a new minDate/maxDate isn't provided
10098			if ( minDate !== null && settings.dateFormat !== undefined && settings.minDate === undefined ) {
10099				inst.settings.minDate = this._formatDate( inst, minDate );
10100			}
10101			if ( maxDate !== null && settings.dateFormat !== undefined && settings.maxDate === undefined ) {
10102				inst.settings.maxDate = this._formatDate( inst, maxDate );
10103			}
10104			if ( "disabled" in settings ) {
10105				if ( settings.disabled ) {
10106					this._disableDatepicker( target );
10107				} else {
10108					this._enableDatepicker( target );
10109				}
10110			}
10111			this._attachments( $( target ), inst );
10112			this._autoSize( inst );
10113			this._setDate( inst, date );
10114			this._updateAlternate( inst );
10115			this._updateDatepicker( inst );
10116		}
10117	},
10118
10119	// Change method deprecated
10120	_changeDatepicker: function( target, name, value ) {
10121		this._optionDatepicker( target, name, value );
10122	},
10123
10124	/* Redraw the date picker attached to an input field or division.
10125	 * @param  target  element - the target input field or division or span
10126	 */
10127	_refreshDatepicker: function( target ) {
10128		var inst = this._getInst( target );
10129		if ( inst ) {
10130			this._updateDatepicker( inst );
10131		}
10132	},
10133
10134	/* Set the dates for a jQuery selection.
10135	 * @param  target element - the target input field or division or span
10136	 * @param  date	Date - the new date
10137	 */
10138	_setDateDatepicker: function( target, date ) {
10139		var inst = this._getInst( target );
10140		if ( inst ) {
10141			this._setDate( inst, date );
10142			this._updateDatepicker( inst );
10143			this._updateAlternate( inst );
10144		}
10145	},
10146
10147	/* Get the date(s) for the first entry in a jQuery selection.
10148	 * @param  target element - the target input field or division or span
10149	 * @param  noDefault boolean - true if no default date is to be used
10150	 * @return Date - the current date
10151	 */
10152	_getDateDatepicker: function( target, noDefault ) {
10153		var inst = this._getInst( target );
10154		if ( inst && !inst.inline ) {
10155			this._setDateFromField( inst, noDefault );
10156		}
10157		return ( inst ? this._getDate( inst ) : null );
10158	},
10159
10160	/* Handle keystrokes. */
10161	_doKeyDown: function( event ) {
10162		var onSelect, dateStr, sel,
10163			inst = $.datepicker._getInst( event.target ),
10164			handled = true,
10165			isRTL = inst.dpDiv.is( ".ui-datepicker-rtl" );
10166
10167		inst._keyEvent = true;
10168		if ( $.datepicker._datepickerShowing ) {
10169			switch ( event.keyCode ) {
10170				case 9: $.datepicker._hideDatepicker();
10171						handled = false;
10172						break; // hide on tab out
10173				case 13: sel = $( "td." + $.datepicker._dayOverClass + ":not(." +
10174									$.datepicker._currentClass + ")", inst.dpDiv );
10175						if ( sel[ 0 ] ) {
10176							$.datepicker._selectDay( event.target, inst.selectedMonth, inst.selectedYear, sel[ 0 ] );
10177						}
10178
10179						onSelect = $.datepicker._get( inst, "onSelect" );
10180						if ( onSelect ) {
10181							dateStr = $.datepicker._formatDate( inst );
10182
10183							// Trigger custom callback
10184							onSelect.apply( ( inst.input ? inst.input[ 0 ] : null ), [ dateStr, inst ] );
10185						} else {
10186							$.datepicker._hideDatepicker();
10187						}
10188
10189						return false; // don't submit the form
10190				case 27: $.datepicker._hideDatepicker();
10191						break; // hide on escape
10192				case 33: $.datepicker._adjustDate( event.target, ( event.ctrlKey ?
10193							-$.datepicker._get( inst, "stepBigMonths" ) :
10194							-$.datepicker._get( inst, "stepMonths" ) ), "M" );
10195						break; // previous month/year on page up/+ ctrl
10196				case 34: $.datepicker._adjustDate( event.target, ( event.ctrlKey ?
10197							+$.datepicker._get( inst, "stepBigMonths" ) :
10198							+$.datepicker._get( inst, "stepMonths" ) ), "M" );
10199						break; // next month/year on page down/+ ctrl
10200				case 35: if ( event.ctrlKey || event.metaKey ) {
10201							$.datepicker._clearDate( event.target );
10202						}
10203						handled = event.ctrlKey || event.metaKey;
10204						break; // clear on ctrl or command +end
10205				case 36: if ( event.ctrlKey || event.metaKey ) {
10206							$.datepicker._gotoToday( event.target );
10207						}
10208						handled = event.ctrlKey || event.metaKey;
10209						break; // current on ctrl or command +home
10210				case 37: if ( event.ctrlKey || event.metaKey ) {
10211							$.datepicker._adjustDate( event.target, ( isRTL ? +1 : -1 ), "D" );
10212						}
10213						handled = event.ctrlKey || event.metaKey;
10214
10215						// -1 day on ctrl or command +left
10216						if ( event.originalEvent.altKey ) {
10217							$.datepicker._adjustDate( event.target, ( event.ctrlKey ?
10218								-$.datepicker._get( inst, "stepBigMonths" ) :
10219								-$.datepicker._get( inst, "stepMonths" ) ), "M" );
10220						}
10221
10222						// next month/year on alt +left on Mac
10223						break;
10224				case 38: if ( event.ctrlKey || event.metaKey ) {
10225							$.datepicker._adjustDate( event.target, -7, "D" );
10226						}
10227						handled = event.ctrlKey || event.metaKey;
10228						break; // -1 week on ctrl or command +up
10229				case 39: if ( event.ctrlKey || event.metaKey ) {
10230							$.datepicker._adjustDate( event.target, ( isRTL ? -1 : +1 ), "D" );
10231						}
10232						handled = event.ctrlKey || event.metaKey;
10233
10234						// +1 day on ctrl or command +right
10235						if ( event.originalEvent.altKey ) {
10236							$.datepicker._adjustDate( event.target, ( event.ctrlKey ?
10237								+$.datepicker._get( inst, "stepBigMonths" ) :
10238								+$.datepicker._get( inst, "stepMonths" ) ), "M" );
10239						}
10240
10241						// next month/year on alt +right
10242						break;
10243				case 40: if ( event.ctrlKey || event.metaKey ) {
10244							$.datepicker._adjustDate( event.target, +7, "D" );
10245						}
10246						handled = event.ctrlKey || event.metaKey;
10247						break; // +1 week on ctrl or command +down
10248				default: handled = false;
10249			}
10250		} else if ( event.keyCode === 36 && event.ctrlKey ) { // display the date picker on ctrl+home
10251			$.datepicker._showDatepicker( this );
10252		} else {
10253			handled = false;
10254		}
10255
10256		if ( handled ) {
10257			event.preventDefault();
10258			event.stopPropagation();
10259		}
10260	},
10261
10262	/* Filter entered characters - based on date format. */
10263	_doKeyPress: function( event ) {
10264		var chars, chr,
10265			inst = $.datepicker._getInst( event.target );
10266
10267		if ( $.datepicker._get( inst, "constrainInput" ) ) {
10268			chars = $.datepicker._possibleChars( $.datepicker._get( inst, "dateFormat" ) );
10269			chr = String.fromCharCode( event.charCode == null ? event.keyCode : event.charCode );
10270			return event.ctrlKey || event.metaKey || ( chr < " " || !chars || chars.indexOf( chr ) > -1 );
10271		}
10272	},
10273
10274	/* Synchronise manual entry and field/alternate field. */
10275	_doKeyUp: function( event ) {
10276		var date,
10277			inst = $.datepicker._getInst( event.target );
10278
10279		if ( inst.input.val() !== inst.lastVal ) {
10280			try {
10281				date = $.datepicker.parseDate( $.datepicker._get( inst, "dateFormat" ),
10282					( inst.input ? inst.input.val() : null ),
10283					$.datepicker._getFormatConfig( inst ) );
10284
10285				if ( date ) { // only if valid
10286					$.datepicker._setDateFromField( inst );
10287					$.datepicker._updateAlternate( inst );
10288					$.datepicker._updateDatepicker( inst );
10289				}
10290			}
10291			catch ( err ) {
10292			}
10293		}
10294		return true;
10295	},
10296
10297	/* Pop-up the date picker for a given input field.
10298	 * If false returned from beforeShow event handler do not show.
10299	 * @param  input  element - the input field attached to the date picker or
vendor: 1,885 bytes, lines 10300-10357
10300	 *					event - if triggered by focus
10301	 */
10302	_showDatepicker: function( input ) {
10303		input = input.target || input;
10304		if ( input.nodeName.toLowerCase() !== "input" ) { // find from button/image trigger
10305			input = $( "input", input.parentNode )[ 0 ];
10306		}
10307
10308		if ( $.datepicker._isDisabledDatepicker( input ) || $.datepicker._lastInput === input ) { // already here
10309			return;
10310		}
10311
10312		var inst, beforeShow, beforeShowSettings, isFixed,
10313			offset, showAnim, duration;
10314
10315		inst = $.datepicker._getInst( input );
10316		if ( $.datepicker._curInst && $.datepicker._curInst !== inst ) {
10317			$.datepicker._curInst.dpDiv.stop( true, true );
10318			if ( inst && $.datepicker._datepickerShowing ) {
10319				$.datepicker._hideDatepicker( $.datepicker._curInst.input[ 0 ] );
10320			}
10321		}
10322
10323		beforeShow = $.datepicker._get( inst, "beforeShow" );
10324		beforeShowSettings = beforeShow ? beforeShow.apply( input, [ input, inst ] ) : {};
10325		if ( beforeShowSettings === false ) {
10326			return;
10327		}
10328		datepicker_extendRemove( inst.settings, beforeShowSettings );
10329
10330		inst.lastVal = null;
10331		$.datepicker._lastInput = input;
10332		$.datepicker._setDateFromField( inst );
10333
10334		if ( $.datepicker._inDialog ) { // hide cursor
10335			input.value = "";
10336		}
10337		if ( !$.datepicker._pos ) { // position below input
10338			$.datepicker._pos = $.datepicker._findPos( input );
10339			$.datepicker._pos[ 1 ] += input.offsetHeight; // add the height
10340		}
10341
10342		isFixed = false;
10343		$( input ).parents().each( function() {
10344			isFixed |= $( this ).css( "position" ) === "fixed";
10345			return !isFixed;
10346		} );
10347
10348		offset = { left: $.datepicker._pos[ 0 ], top: $.datepicker._pos[ 1 ] };
10349		$.datepicker._pos = null;
10350
10351		//to avoid flashes on Firefox
10352		inst.dpDiv.empty();
10353
10354		// determine sizing offscreen
10355		inst.dpDiv.css( { position: "absolute", display: "block", top: "-1000px" } );
10356		$.datepicker._updateDatepicker( inst );
10357
vendor: 12,837 bytes, lines 10358-10710
10358		// fix width for dynamic number of date pickers
10359		// and adjust position before showing
10360		offset = $.datepicker._checkOffset( inst, offset, isFixed );
10361		inst.dpDiv.css( { position: ( $.datepicker._inDialog && $.blockUI ?
10362			"static" : ( isFixed ? "fixed" : "absolute" ) ), display: "none",
10363			left: offset.left + "px", top: offset.top + "px" } );
10364
10365		if ( !inst.inline ) {
10366			showAnim = $.datepicker._get( inst, "showAnim" );
10367			duration = $.datepicker._get( inst, "duration" );
10368			inst.dpDiv.css( "z-index", datepicker_getZindex( $( input ) ) + 1 );
10369			$.datepicker._datepickerShowing = true;
10370
10371			if ( $.effects && $.effects.effect[ showAnim ] ) {
10372				inst.dpDiv.show( showAnim, $.datepicker._get( inst, "showOptions" ), duration );
10373			} else {
10374				inst.dpDiv[ showAnim || "show" ]( showAnim ? duration : null );
10375			}
10376
10377			if ( $.datepicker._shouldFocusInput( inst ) ) {
10378				inst.input.trigger( "focus" );
10379			}
10380
10381			$.datepicker._curInst = inst;
10382		}
10383	},
10384
10385	/* Generate the date picker content. */
10386	_updateDatepicker: function( inst ) {
10387		this.maxRows = 4; //Reset the max number of rows being displayed (see #7043)
10388		datepicker_instActive = inst; // for delegate hover events
10389		inst.dpDiv.empty().append( this._generateHTML( inst ) );
10390		this._attachHandlers( inst );
10391
10392		var origyearshtml,
10393			numMonths = this._getNumberOfMonths( inst ),
10394			cols = numMonths[ 1 ],
10395			width = 17,
10396			activeCell = inst.dpDiv.find( "." + this._dayOverClass + " a" );
10397
10398		if ( activeCell.length > 0 ) {
10399			datepicker_handleMouseover.apply( activeCell.get( 0 ) );
10400		}
10401
10402		inst.dpDiv.removeClass( "ui-datepicker-multi-2 ui-datepicker-multi-3 ui-datepicker-multi-4" ).width( "" );
10403		if ( cols > 1 ) {
10404			inst.dpDiv.addClass( "ui-datepicker-multi-" + cols ).css( "width", ( width * cols ) + "em" );
10405		}
10406		inst.dpDiv[ ( numMonths[ 0 ] !== 1 || numMonths[ 1 ] !== 1 ? "add" : "remove" ) +
10407			"Class" ]( "ui-datepicker-multi" );
10408		inst.dpDiv[ ( this._get( inst, "isRTL" ) ? "add" : "remove" ) +
10409			"Class" ]( "ui-datepicker-rtl" );
10410
10411		if ( inst === $.datepicker._curInst && $.datepicker._datepickerShowing && $.datepicker._shouldFocusInput( inst ) ) {
10412			inst.input.trigger( "focus" );
10413		}
10414
10415		// Deffered render of the years select (to avoid flashes on Firefox)
10416		if ( inst.yearshtml ) {
10417			origyearshtml = inst.yearshtml;
10418			setTimeout( function() {
10419
10420				//assure that inst.yearshtml didn't change.
10421				if ( origyearshtml === inst.yearshtml && inst.yearshtml ) {
10422					inst.dpDiv.find( "select.ui-datepicker-year:first" ).replaceWith( inst.yearshtml );
10423				}
10424				origyearshtml = inst.yearshtml = null;
10425			}, 0 );
10426		}
10427	},
10428
10429	// #6694 - don't focus the input if it's already focused
10430	// this breaks the change event in IE
10431	// Support: IE and jQuery <1.9
10432	_shouldFocusInput: function( inst ) {
10433		return inst.input && inst.input.is( ":visible" ) && !inst.input.is( ":disabled" ) && !inst.input.is( ":focus" );
10434	},
10435
10436	/* Check positioning to remain on screen. */
10437	_checkOffset: function( inst, offset, isFixed ) {
10438		var dpWidth = inst.dpDiv.outerWidth(),
10439			dpHeight = inst.dpDiv.outerHeight(),
10440			inputWidth = inst.input ? inst.input.outerWidth() : 0,
10441			inputHeight = inst.input ? inst.input.outerHeight() : 0,
10442			viewWidth = document.documentElement.clientWidth + ( isFixed ? 0 : $( document ).scrollLeft() ),
10443			viewHeight = document.documentElement.clientHeight + ( isFixed ? 0 : $( document ).scrollTop() );
10444
10445		offset.left -= ( this._get( inst, "isRTL" ) ? ( dpWidth - inputWidth ) : 0 );
10446		offset.left -= ( isFixed && offset.left === inst.input.offset().left ) ? $( document ).scrollLeft() : 0;
10447		offset.top -= ( isFixed && offset.top === ( inst.input.offset().top + inputHeight ) ) ? $( document ).scrollTop() : 0;
10448
10449		// Now check if datepicker is showing outside window viewport - move to a better place if so.
10450		offset.left -= Math.min( offset.left, ( offset.left + dpWidth > viewWidth && viewWidth > dpWidth ) ?
10451			Math.abs( offset.left + dpWidth - viewWidth ) : 0 );
10452		offset.top -= Math.min( offset.top, ( offset.top + dpHeight > viewHeight && viewHeight > dpHeight ) ?
10453			Math.abs( dpHeight + inputHeight ) : 0 );
10454
10455		return offset;
10456	},
10457
10458	/* Find an object's position on the screen. */
10459	_findPos: function( obj ) {
10460		var position,
10461			inst = this._getInst( obj ),
10462			isRTL = this._get( inst, "isRTL" );
10463
10464		while ( obj && ( obj.type === "hidden" || obj.nodeType !== 1 || $.expr.filters.hidden( obj ) ) ) {
10465			obj = obj[ isRTL ? "previousSibling" : "nextSibling" ];
10466		}
10467
10468		position = $( obj ).offset();
10469		return [ position.left, position.top ];
10470	},
10471
10472	/* Hide the date picker from view.
10473	 * @param  input  element - the input field attached to the date picker
10474	 */
10475	_hideDatepicker: function( input ) {
10476		var showAnim, duration, postProcess, onClose,
10477			inst = this._curInst;
10478
10479		if ( !inst || ( input && inst !== $.data( input, "datepicker" ) ) ) {
10480			return;
10481		}
10482
10483		if ( this._datepickerShowing ) {
10484			showAnim = this._get( inst, "showAnim" );
10485			duration = this._get( inst, "duration" );
10486			postProcess = function() {
10487				$.datepicker._tidyDialog( inst );
10488			};
10489
10490			// DEPRECATED: after BC for 1.8.x $.effects[ showAnim ] is not needed
10491			if ( $.effects && ( $.effects.effect[ showAnim ] || $.effects[ showAnim ] ) ) {
10492				inst.dpDiv.hide( showAnim, $.datepicker._get( inst, "showOptions" ), duration, postProcess );
10493			} else {
10494				inst.dpDiv[ ( showAnim === "slideDown" ? "slideUp" :
10495					( showAnim === "fadeIn" ? "fadeOut" : "hide" ) ) ]( ( showAnim ? duration : null ), postProcess );
10496			}
10497
10498			if ( !showAnim ) {
10499				postProcess();
10500			}
10501			this._datepickerShowing = false;
10502
10503			onClose = this._get( inst, "onClose" );
10504			if ( onClose ) {
10505				onClose.apply( ( inst.input ? inst.input[ 0 ] : null ), [ ( inst.input ? inst.input.val() : "" ), inst ] );
10506			}
10507
10508			this._lastInput = null;
10509			if ( this._inDialog ) {
10510				this._dialogInput.css( { position: "absolute", left: "0", top: "-100px" } );
10511				if ( $.blockUI ) {
10512					$.unblockUI();
10513					$( "body" ).append( this.dpDiv );
10514				}
10515			}
10516			this._inDialog = false;
10517		}
10518	},
10519
10520	/* Tidy up after a dialog display. */
10521	_tidyDialog: function( inst ) {
10522		inst.dpDiv.removeClass( this._dialogClass ).off( ".ui-datepicker-calendar" );
10523	},
10524
10525	/* Close date picker if clicked elsewhere. */
10526	_checkExternalClick: function( event ) {
10527		if ( !$.datepicker._curInst ) {
10528			return;
10529		}
10530
10531		var $target = $( event.target ),
10532			inst = $.datepicker._getInst( $target[ 0 ] );
10533
10534		if ( ( ( $target[ 0 ].id !== $.datepicker._mainDivId &&
10535				$target.parents( "#" + $.datepicker._mainDivId ).length === 0 &&
10536				!$target.hasClass( $.datepicker.markerClassName ) &&
10537				!$target.closest( "." + $.datepicker._triggerClass ).length &&
10538				$.datepicker._datepickerShowing && !( $.datepicker._inDialog && $.blockUI ) ) ) ||
10539			( $target.hasClass( $.datepicker.markerClassName ) && $.datepicker._curInst !== inst ) ) {
10540				$.datepicker._hideDatepicker();
10541		}
10542	},
10543
10544	/* Adjust one of the date sub-fields. */
10545	_adjustDate: function( id, offset, period ) {
10546		var target = $( id ),
10547			inst = this._getInst( target[ 0 ] );
10548
10549		if ( this._isDisabledDatepicker( target[ 0 ] ) ) {
10550			return;
10551		}
10552		this._adjustInstDate( inst, offset +
10553			( period === "M" ? this._get( inst, "showCurrentAtPos" ) : 0 ), // undo positioning
10554			period );
10555		this._updateDatepicker( inst );
10556	},
10557
10558	/* Action for current link. */
10559	_gotoToday: function( id ) {
10560		var date,
10561			target = $( id ),
10562			inst = this._getInst( target[ 0 ] );
10563
10564		if ( this._get( inst, "gotoCurrent" ) && inst.currentDay ) {
10565			inst.selectedDay = inst.currentDay;
10566			inst.drawMonth = inst.selectedMonth = inst.currentMonth;
10567			inst.drawYear = inst.selectedYear = inst.currentYear;
10568		} else {
10569			date = new Date();
10570			inst.selectedDay = date.getDate();
10571			inst.drawMonth = inst.selectedMonth = date.getMonth();
10572			inst.drawYear = inst.selectedYear = date.getFullYear();
10573		}
10574		this._notifyChange( inst );
10575		this._adjustDate( target );
10576	},
10577
10578	/* Action for selecting a new month/year. */
10579	_selectMonthYear: function( id, select, period ) {
10580		var target = $( id ),
10581			inst = this._getInst( target[ 0 ] );
10582
10583		inst[ "selected" + ( period === "M" ? "Month" : "Year" ) ] =
10584		inst[ "draw" + ( period === "M" ? "Month" : "Year" ) ] =
10585			parseInt( select.options[ select.selectedIndex ].value, 10 );
10586
10587		this._notifyChange( inst );
10588		this._adjustDate( target );
10589	},
10590
10591	/* Action for selecting a day. */
10592	_selectDay: function( id, month, year, td ) {
10593		var inst,
10594			target = $( id );
10595
10596		if ( $( td ).hasClass( this._unselectableClass ) || this._isDisabledDatepicker( target[ 0 ] ) ) {
10597			return;
10598		}
10599
10600		inst = this._getInst( target[ 0 ] );
10601		inst.selectedDay = inst.currentDay = $( "a", td ).html();
10602		inst.selectedMonth = inst.currentMonth = month;
10603		inst.selectedYear = inst.currentYear = year;
10604		this._selectDate( id, this._formatDate( inst,
10605			inst.currentDay, inst.currentMonth, inst.currentYear ) );
10606	},
10607
10608	/* Erase the input field and hide the date picker. */
10609	_clearDate: function( id ) {
10610		var target = $( id );
10611		this._selectDate( target, "" );
10612	},
10613
10614	/* Update the input field with the selected date. */
10615	_selectDate: function( id, dateStr ) {
10616		var onSelect,
10617			target = $( id ),
10618			inst = this._getInst( target[ 0 ] );
10619
10620		dateStr = ( dateStr != null ? dateStr : this._formatDate( inst ) );
10621		if ( inst.input ) {
10622			inst.input.val( dateStr );
10623		}
10624		this._updateAlternate( inst );
10625
10626		onSelect = this._get( inst, "onSelect" );
10627		if ( onSelect ) {
10628			onSelect.apply( ( inst.input ? inst.input[ 0 ] : null ), [ dateStr, inst ] );  // trigger custom callback
10629		} else if ( inst.input ) {
10630			inst.input.trigger( "change" ); // fire the change event
10631		}
10632
10633		if ( inst.inline ) {
10634			this._updateDatepicker( inst );
10635		} else {
10636			this._hideDatepicker();
10637			this._lastInput = inst.input[ 0 ];
10638			if ( typeof( inst.input[ 0 ] ) !== "object" ) {
10639				inst.input.trigger( "focus" ); // restore focus
10640			}
10641			this._lastInput = null;
10642		}
10643	},
10644
10645	/* Update any alternate field to synchronise with the main field. */
10646	_updateAlternate: function( inst ) {
10647		var altFormat, date, dateStr,
10648			altField = this._get( inst, "altField" );
10649
10650		if ( altField ) { // update alternate field too
10651			altFormat = this._get( inst, "altFormat" ) || this._get( inst, "dateFormat" );
10652			date = this._getDate( inst );
10653			dateStr = this.formatDate( altFormat, date, this._getFormatConfig( inst ) );
10654			$( altField ).val( dateStr );
10655		}
10656	},
10657
10658	/* Set as beforeShowDay function to prevent selection of weekends.
10659	 * @param  date  Date - the date to customise
10660	 * @return [boolean, string] - is this date selectable?, what is its CSS class?
10661	 */
10662	noWeekends: function( date ) {
10663		var day = date.getDay();
10664		return [ ( day > 0 && day < 6 ), "" ];
10665	},
10666
10667	/* Set as calculateWeek to determine the week of the year based on the ISO 8601 definition.
10668	 * @param  date  Date - the date to get the week for
10669	 * @return  number - the number of the week within the year that contains this date
10670	 */
10671	iso8601Week: function( date ) {
10672		var time,
10673			checkDate = new Date( date.getTime() );
10674
10675		// Find Thursday of this week starting on Monday
10676		checkDate.setDate( checkDate.getDate() + 4 - ( checkDate.getDay() || 7 ) );
10677
10678		time = checkDate.getTime();
10679		checkDate.setMonth( 0 ); // Compare with Jan 1
10680		checkDate.setDate( 1 );
10681		return Math.floor( Math.round( ( time - checkDate ) / 86400000 ) / 7 ) + 1;
10682	},
10683
10684	/* Parse a string value into a date object.
10685	 * See formatDate below for the possible formats.
10686	 *
10687	 * @param  format string - the expected format of the date
10688	 * @param  value string - the date in the above format
10689	 * @param  settings Object - attributes include:
10690	 *					shortYearCutoff  number - the cutoff year for determining the century (optional)
10691	 *					dayNamesShort	string[7] - abbreviated names of the days from Sunday (optional)
10692	 *					dayNames		string[7] - names of the days from Sunday (optional)
10693	 *					monthNamesShort string[12] - abbreviated names of the months (optional)
10694	 *					monthNames		string[12] - names of the months (optional)
10695	 * @return  Date - the extracted date value or null if value is blank
10696	 */
10697	parseDate: function( format, value, settings ) {
10698		if ( format == null || value == null ) {
10699			throw "Invalid arguments";
10700		}
10701
10702		value = ( typeof value === "object" ? value.toString() : value + "" );
10703		if ( value === "" ) {
10704			return null;
10705		}
10706
10707		var iFormat, dim, extra,
10708			iValue = 0,
10709			shortYearCutoffTemp = ( settings ? settings.shortYearCutoff : null ) || this._defaults.shortYearCutoff,
10710			shortYearCutoff = ( typeof shortYearCutoffTemp !== "string" ? shortYearCutoffTemp 
vendor: 15,177 bytes, lines 10710-11186
10710:
10711				new Date().getFullYear() % 100 + parseInt( shortYearCutoffTemp, 10 ) ),
10712			dayNamesShort = ( settings ? settings.dayNamesShort : null ) || this._defaults.dayNamesShort,
10713			dayNames = ( settings ? settings.dayNames : null ) || this._defaults.dayNames,
10714			monthNamesShort = ( settings ? settings.monthNamesShort : null ) || this._defaults.monthNamesShort,
10715			monthNames = ( settings ? settings.monthNames : null ) || this._defaults.monthNames,
10716			year = -1,
10717			month = -1,
10718			day = -1,
10719			doy = -1,
10720			literal = false,
10721			date,
10722
10723			// Check whether a format character is doubled
10724			lookAhead = function( match ) {
10725				var matches = ( iFormat + 1 < format.length && format.charAt( iFormat + 1 ) === match );
10726				if ( matches ) {
10727					iFormat++;
10728				}
10729				return matches;
10730			},
10731
10732			// Extract a number from the string value
10733			getNumber = function( match ) {
10734				var isDoubled = lookAhead( match ),
10735					size = ( match === "@" ? 14 : ( match === "!" ? 20 :
10736					( match === "y" && isDoubled ? 4 : ( match === "o" ? 3 : 2 ) ) ) ),
10737					minSize = ( match === "y" ? size : 1 ),
10738					digits = new RegExp( "^\\d{" + minSize + "," + size + "}" ),
10739					num = value.substring( iValue ).match( digits );
10740				if ( !num ) {
10741					throw "Missing number at position " + iValue;
10742				}
10743				iValue += num[ 0 ].length;
10744				return parseInt( num[ 0 ], 10 );
10745			},
10746
10747			// Extract a name from the string value and convert to an index
10748			getName = function( match, shortNames, longNames ) {
10749				var index = -1,
10750					names = $.map( lookAhead( match ) ? longNames : shortNames, function( v, k ) {
10751						return [ [ k, v ] ];
10752					} ).sort( function( a, b ) {
10753						return -( a[ 1 ].length - b[ 1 ].length );
10754					} );
10755
10756				$.each( names, function( i, pair ) {
10757					var name = pair[ 1 ];
10758					if ( value.substr( iValue, name.length ).toLowerCase() === name.toLowerCase() ) {
10759						index = pair[ 0 ];
10760						iValue += name.length;
10761						return false;
10762					}
10763				} );
10764				if ( index !== -1 ) {
10765					return index + 1;
10766				} else {
10767					throw "Unknown name at position " + iValue;
10768				}
10769			},
10770
10771			// Confirm that a literal character matches the string value
10772			checkLiteral = function() {
10773				if ( value.charAt( iValue ) !== format.charAt( iFormat ) ) {
10774					throw "Unexpected literal at position " + iValue;
10775				}
10776				iValue++;
10777			};
10778
10779		for ( iFormat = 0; iFormat < format.length; iFormat++ ) {
10780			if ( literal ) {
10781				if ( format.charAt( iFormat ) === "'" && !lookAhead( "'" ) ) {
10782					literal = false;
10783				} else {
10784					checkLiteral();
10785				}
10786			} else {
10787				switch ( format.charAt( iFormat ) ) {
10788					case "d":
10789						day = getNumber( "d" );
10790						break;
10791					case "D":
10792						getName( "D", dayNamesShort, dayNames );
10793						break;
10794					case "o":
10795						doy = getNumber( "o" );
10796						break;
10797					case "m":
10798						month = getNumber( "m" );
10799						break;
10800					case "M":
10801						month = getName( "M", monthNamesShort, monthNames );
10802						break;
10803					case "y":
10804						year = getNumber( "y" );
10805						break;
10806					case "@":
10807						date = new Date( getNumber( "@" ) );
10808						year = date.getFullYear();
10809						month = date.getMonth() + 1;
10810						day = date.getDate();
10811						break;
10812					case "!":
10813						date = new Date( ( getNumber( "!" ) - this._ticksTo1970 ) / 10000 );
10814						year = date.getFullYear();
10815						month = date.getMonth() + 1;
10816						day = date.getDate();
10817						break;
10818					case "'":
10819						if ( lookAhead( "'" ) ) {
10820							checkLiteral();
10821						} else {
10822							literal = true;
10823						}
10824						break;
10825					default:
10826						checkLiteral();
10827				}
10828			}
10829		}
10830
10831		if ( iValue < value.length ) {
10832			extra = value.substr( iValue );
10833			if ( !/^\s+/.test( extra ) ) {
10834				throw "Extra/unparsed characters found in date: " + extra;
10835			}
10836		}
10837
10838		if ( year === -1 ) {
10839			year = new Date().getFullYear();
10840		} else if ( year < 100 ) {
10841			year += new Date().getFullYear() - new Date().getFullYear() % 100 +
10842				( year <= shortYearCutoff ? 0 : -100 );
10843		}
10844
10845		if ( doy > -1 ) {
10846			month = 1;
10847			day = doy;
10848			do {
10849				dim = this._getDaysInMonth( year, month - 1 );
10850				if ( day <= dim ) {
10851					break;
10852				}
10853				month++;
10854				day -= dim;
10855			} while ( true );
10856		}
10857
10858		date = this._daylightSavingAdjust( new Date( year, month - 1, day ) );
10859		if ( date.getFullYear() !== year || date.getMonth() + 1 !== month || date.getDate() !== day ) {
10860			throw "Invalid date"; // E.g. 31/02/00
10861		}
10862		return date;
10863	},
10864
10865	/* Standard date formats. */
10866	ATOM: "yy-mm-dd", // RFC 3339 (ISO 8601)
10867	COOKIE: "D, dd M yy",
10868	ISO_8601: "yy-mm-dd",
10869	RFC_822: "D, d M y",
10870	RFC_850: "DD, dd-M-y",
10871	RFC_1036: "D, d M y",
10872	RFC_1123: "D, d M yy",
10873	RFC_2822: "D, d M yy",
10874	RSS: "D, d M y", // RFC 822
10875	TICKS: "!",
10876	TIMESTAMP: "@",
10877	W3C: "yy-mm-dd", // ISO 8601
10878
10879	_ticksTo1970: ( ( ( 1970 - 1 ) * 365 + Math.floor( 1970 / 4 ) - Math.floor( 1970 / 100 ) +
10880		Math.floor( 1970 / 400 ) ) * 24 * 60 * 60 * 10000000 ),
10881
10882	/* Format a date object into a string value.
10883	 * The format can be combinations of the following:
10884	 * d  - day of month (no leading zero)
10885	 * dd - day of month (two digit)
10886	 * o  - day of year (no leading zeros)
10887	 * oo - day of year (three digit)
10888	 * D  - day name short
10889	 * DD - day name long
10890	 * m  - month of year (no leading zero)
10891	 * mm - month of year (two digit)
10892	 * M  - month name short
10893	 * MM - month name long
10894	 * y  - year (two digit)
10895	 * yy - year (four digit)
10896	 * @ - Unix timestamp (ms since 01/01/1970)
10897	 * ! - Windows ticks (100ns since 01/01/0001)
10898	 * "..." - literal text
10899	 * '' - single quote
10900	 *
10901	 * @param  format string - the desired format of the date
10902	 * @param  date Date - the date value to format
10903	 * @param  settings Object - attributes include:
10904	 *					dayNamesShort	string[7] - abbreviated names of the days from Sunday (optional)
10905	 *					dayNames		string[7] - names of the days from Sunday (optional)
10906	 *					monthNamesShort string[12] - abbreviated names of the months (optional)
10907	 *					monthNames		string[12] - names of the months (optional)
10908	 * @return  string - the date in the above format
10909	 */
10910	formatDate: function( format, date, settings ) {
10911		if ( !date ) {
10912			return "";
10913		}
10914
10915		var iFormat,
10916			dayNamesShort = ( settings ? settings.dayNamesShort : null ) || this._defaults.dayNamesShort,
10917			dayNames = ( settings ? settings.dayNames : null ) || this._defaults.dayNames,
10918			monthNamesShort = ( settings ? settings.monthNamesShort : null ) || this._defaults.monthNamesShort,
10919			monthNames = ( settings ? settings.monthNames : null ) || this._defaults.monthNames,
10920
10921			// Check whether a format character is doubled
10922			lookAhead = function( match ) {
10923				var matches = ( iFormat + 1 < format.length && format.charAt( iFormat + 1 ) === match );
10924				if ( matches ) {
10925					iFormat++;
10926				}
10927				return matches;
10928			},
10929
10930			// Format a number, with leading zero if necessary
10931			formatNumber = function( match, value, len ) {
10932				var num = "" + value;
10933				if ( lookAhead( match ) ) {
10934					while ( num.length < len ) {
10935						num = "0" + num;
10936					}
10937				}
10938				return num;
10939			},
10940
10941			// Format a name, short or long as requested
10942			formatName = function( match, value, shortNames, longNames ) {
10943				return ( lookAhead( match ) ? longNames[ value ] : shortNames[ value ] );
10944			},
10945			output = "",
10946			literal = false;
10947
10948		if ( date ) {
10949			for ( iFormat = 0; iFormat < format.length; iFormat++ ) {
10950				if ( literal ) {
10951					if ( format.charAt( iFormat ) === "'" && !lookAhead( "'" ) ) {
10952						literal = false;
10953					} else {
10954						output += format.charAt( iFormat );
10955					}
10956				} else {
10957					switch ( format.charAt( iFormat ) ) {
10958						case "d":
10959							output += formatNumber( "d", date.getDate(), 2 );
10960							break;
10961						case "D":
10962							output += formatName( "D", date.getDay(), dayNamesShort, dayNames );
10963							break;
10964						case "o":
10965							output += formatNumber( "o",
10966								Math.round( ( new Date( date.getFullYear(), date.getMonth(), date.getDate() ).getTime() - new Date( date.getFullYear(), 0, 0 ).getTime() ) / 86400000 ), 3 );
10967							break;
10968						case "m":
10969							output += formatNumber( "m", date.getMonth() + 1, 2 );
10970							break;
10971						case "M":
10972							output += formatName( "M", date.getMonth(), monthNamesShort, monthNames );
10973							break;
10974						case "y":
10975							output += ( lookAhead( "y" ) ? date.getFullYear() :
10976								( date.getFullYear() % 100 < 10 ? "0" : "" ) + date.getFullYear() % 100 );
10977							break;
10978						case "@":
10979							output += date.getTime();
10980							break;
10981						case "!":
10982							output += date.getTime() * 10000 + this._ticksTo1970;
10983							break;
10984						case "'":
10985							if ( lookAhead( "'" ) ) {
10986								output += "'";
10987							} else {
10988								literal = true;
10989							}
10990							break;
10991						default:
10992							output += format.charAt( iFormat );
10993					}
10994				}
10995			}
10996		}
10997		return output;
10998	},
10999
11000	/* Extract all possible characters from the date format. */
11001	_possibleChars: function( format ) {
11002		var iFormat,
11003			chars = "",
11004			literal = false,
11005
11006			// Check whether a format character is doubled
11007			lookAhead = function( match ) {
11008				var matches = ( iFormat + 1 < format.length && format.charAt( iFormat + 1 ) === match );
11009				if ( matches ) {
11010					iFormat++;
11011				}
11012				return matches;
11013			};
11014
11015		for ( iFormat = 0; iFormat < format.length; iFormat++ ) {
11016			if ( literal ) {
11017				if ( format.charAt( iFormat ) === "'" && !lookAhead( "'" ) ) {
11018					literal = false;
11019				} else {
11020					chars += format.charAt( iFormat );
11021				}
11022			} else {
11023				switch ( format.charAt( iFormat ) ) {
11024					case "d": case "m": case "y": case "@":
11025						chars += "0123456789";
11026						break;
11027					case "D": case "M":
11028						return null; // Accept anything
11029					case "'":
11030						if ( lookAhead( "'" ) ) {
11031							chars += "'";
11032						} else {
11033							literal = true;
11034						}
11035						break;
11036					default:
11037						chars += format.charAt( iFormat );
11038				}
11039			}
11040		}
11041		return chars;
11042	},
11043
11044	/* Get a setting value, defaulting if necessary. */
11045	_get: function( inst, name ) {
11046		return inst.settings[ name ] !== undefined ?
11047			inst.settings[ name ] : this._defaults[ name ];
11048	},
11049
11050	/* Parse existing date and initialise date picker. */
11051	_setDateFromField: function( inst, noDefault ) {
11052		if ( inst.input.val() === inst.lastVal ) {
11053			return;
11054		}
11055
11056		var dateFormat = this._get( inst, "dateFormat" ),
11057			dates = inst.lastVal = inst.input ? inst.input.val() : null,
11058			defaultDate = this._getDefaultDate( inst ),
11059			date = defaultDate,
11060			settings = this._getFormatConfig( inst );
11061
11062		try {
11063			date = this.parseDate( dateFormat, dates, settings ) || defaultDate;
11064		} catch ( event ) {
11065			dates = ( noDefault ? "" : dates );
11066		}
11067		inst.selectedDay = date.getDate();
11068		inst.drawMonth = inst.selectedMonth = date.getMonth();
11069		inst.drawYear = inst.selectedYear = date.getFullYear();
11070		inst.currentDay = ( dates ? date.getDate() : 0 );
11071		inst.currentMonth = ( dates ? date.getMonth() : 0 );
11072		inst.currentYear = ( dates ? date.getFullYear() : 0 );
11073		this._adjustInstDate( inst );
11074	},
11075
11076	/* Retrieve the default date shown on opening. */
11077	_getDefaultDate: function( inst ) {
11078		return this._restrictMinMax( inst,
11079			this._determineDate( inst, this._get( inst, "defaultDate" ), new Date() ) );
11080	},
11081
11082	/* A date may be specified as an exact value or a relative one. */
11083	_determineDate: function( inst, date, defaultDate ) {
11084		var offsetNumeric = function( offset ) {
11085				var date = new Date();
11086				date.setDate( date.getDate() + offset );
11087				return date;
11088			},
11089			offsetString = function( offset ) {
11090				try {
11091					return $.datepicker.parseDate( $.datepicker._get( inst, "dateFormat" ),
11092						offset, $.datepicker._getFormatConfig( inst ) );
11093				}
11094				catch ( e ) {
11095
11096					// Ignore
11097				}
11098
11099				var date = ( offset.toLowerCase().match( /^c/ ) ?
11100					$.datepicker._getDate( inst ) : null ) || new Date(),
11101					year = date.getFullYear(),
11102					month = date.getMonth(),
11103					day = date.getDate(),
11104					pattern = /([+\-]?[0-9]+)\s*(d|D|w|W|m|M|y|Y)?/g,
11105					matches = pattern.exec( offset );
11106
11107				while ( matches ) {
11108					switch ( matches[ 2 ] || "d" ) {
11109						case "d" : case "D" :
11110							day += parseInt( matches[ 1 ], 10 ); break;
11111						case "w" : case "W" :
11112							day += parseInt( matches[ 1 ], 10 ) * 7; break;
11113						case "m" : case "M" :
11114							month += parseInt( matches[ 1 ], 10 );
11115							day = Math.min( day, $.datepicker._getDaysInMonth( year, month ) );
11116							break;
11117						case "y": case "Y" :
11118							year += parseInt( matches[ 1 ], 10 );
11119							day = Math.min( day, $.datepicker._getDaysInMonth( year, month ) );
11120							break;
11121					}
11122					matches = pattern.exec( offset );
11123				}
11124				return new Date( year, month, day );
11125			},
11126			newDate = ( date == null || date === "" ? defaultDate : ( typeof date === "string" ? offsetString( date ) :
11127				( typeof date === "number" ? ( isNaN( date ) ? defaultDate : offsetNumeric( date ) ) : new Date( date.getTime() ) ) ) );
11128
11129		newDate = ( newDate && newDate.toString() === "Invalid Date" ? defaultDate : newDate );
11130		if ( newDate ) {
11131			newDate.setHours( 0 );
11132			newDate.setMinutes( 0 );
11133			newDate.setSeconds( 0 );
11134			newDate.setMilliseconds( 0 );
11135		}
11136		return this._daylightSavingAdjust( newDate );
11137	},
11138
11139	/* Handle switch to/from daylight saving.
11140	 * Hours may be non-zero on daylight saving cut-over:
11141	 * > 12 when midnight changeover, but then cannot generate
11142	 * midnight datetime, so jump to 1AM, otherwise reset.
11143	 * @param  date  (Date) the date to check
11144	 * @return  (Date) the corrected date
11145	 */
11146	_daylightSavingAdjust: function( date ) {
11147		if ( !date ) {
11148			return null;
11149		}
11150		date.setHours( date.getHours() > 12 ? date.getHours() + 2 : 0 );
11151		return date;
11152	},
11153
11154	/* Set the date(s) directly. */
11155	_setDate: function( inst, date, noChange ) {
11156		var clear = !date,
11157			origMonth = inst.selectedMonth,
11158			origYear = inst.selectedYear,
11159			newDate = this._restrictMinMax( inst, this._determineDate( inst, date, new Date() ) );
11160
11161		inst.selectedDay = inst.currentDay = newDate.getDate();
11162		inst.drawMonth = inst.selectedMonth = inst.currentMonth = newDate.getMonth();
11163		inst.drawYear = inst.selectedYear = inst.currentYear = newDate.getFullYear();
11164		if ( ( origMonth !== inst.selectedMonth || origYear !== inst.selectedYear ) && !noChange ) {
11165			this._notifyChange( inst );
11166		}
11167		this._adjustInstDate( inst );
11168		if ( inst.input ) {
11169			inst.input.val( clear ? "" : this._formatDate( inst ) );
11170		}
11171	},
11172
11173	/* Retrieve the date(s) directly. */
11174	_getDate: function( inst ) {
11175		var startDate = ( !inst.currentYear || ( inst.input && inst.input.val() === "" ) ? null :
11176			this._daylightSavingAdjust( new Date(
11177			inst.currentYear, inst.currentMonth, inst.currentDay ) ) );
11178			return startDate;
11179	},
11180
11181	/* Attach the onxxx handlers.  These are declared statically so
11182	 * they work with static code transformers like Caja.
11183	 */
11184	_attachHandlers: function( inst ) {
11185		var stepMonths = this._get( inst, "stepMonths" ),
11186			id = "#" + inst.id.replace( /\\\\/g, "\\" );
vendor: 48,709 bytes, lines 11187-12677
11187		inst.dpDiv.find( "[data-handler]" ).map( function() {
11188			var handler = {
11189				prev: function() {
11190					$.datepicker._adjustDate( id, -stepMonths, "M" );
11191				},
11192				next: function() {
11193					$.datepicker._adjustDate( id, +stepMonths, "M" );
11194				},
11195				hide: function() {
11196					$.datepicker._hideDatepicker();
11197				},
11198				today: function() {
11199					$.datepicker._gotoToday( id );
11200				},
11201				selectDay: function() {
11202					$.datepicker._selectDay( id, +this.getAttribute( "data-month" ), +this.getAttribute( "data-year" ), this );
11203					return false;
11204				},
11205				selectMonth: function() {
11206					$.datepicker._selectMonthYear( id, this, "M" );
11207					return false;
11208				},
11209				selectYear: function() {
11210					$.datepicker._selectMonthYear( id, this, "Y" );
11211					return false;
11212				}
11213			};
11214			$( this ).on( this.getAttribute( "data-event" ), handler[ this.getAttribute( "data-handler" ) ] );
11215		} );
11216	},
11217
11218	/* Generate the HTML for the current state of the date picker. */
11219	_generateHTML: function( inst ) {
11220		var maxDraw, prevText, prev, nextText, next, currentText, gotoDate,
11221			controls, buttonPanel, firstDay, showWeek, dayNames, dayNamesMin,
11222			monthNames, monthNamesShort, beforeShowDay, showOtherMonths,
11223			selectOtherMonths, defaultDate, html, dow, row, group, col, selectedDate,
11224			cornerClass, calender, thead, day, daysInMonth, leadDays, curRows, numRows,
11225			printDate, dRow, tbody, daySettings, otherMonth, unselectable,
11226			tempDate = new Date(),
11227			today = this._daylightSavingAdjust(
11228				new Date( tempDate.getFullYear(), tempDate.getMonth(), tempDate.getDate() ) ), // clear time
11229			isRTL = this._get( inst, "isRTL" ),
11230			showButtonPanel = this._get( inst, "showButtonPanel" ),
11231			hideIfNoPrevNext = this._get( inst, "hideIfNoPrevNext" ),
11232			navigationAsDateFormat = this._get( inst, "navigationAsDateFormat" ),
11233			numMonths = this._getNumberOfMonths( inst ),
11234			showCurrentAtPos = this._get( inst, "showCurrentAtPos" ),
11235			stepMonths = this._get( inst, "stepMonths" ),
11236			isMultiMonth = ( numMonths[ 0 ] !== 1 || numMonths[ 1 ] !== 1 ),
11237			currentDate = this._daylightSavingAdjust( ( !inst.currentDay ? new Date( 9999, 9, 9 ) :
11238				new Date( inst.currentYear, inst.currentMonth, inst.currentDay ) ) ),
11239			minDate = this._getMinMaxDate( inst, "min" ),
11240			maxDate = this._getMinMaxDate( inst, "max" ),
11241			drawMonth = inst.drawMonth - showCurrentAtPos,
11242			drawYear = inst.drawYear;
11243
11244		if ( drawMonth < 0 ) {
11245			drawMonth += 12;
11246			drawYear--;
11247		}
11248		if ( maxDate ) {
11249			maxDraw = this._daylightSavingAdjust( new Date( maxDate.getFullYear(),
11250				maxDate.getMonth() - ( numMonths[ 0 ] * numMonths[ 1 ] ) + 1, maxDate.getDate() ) );
11251			maxDraw = ( minDate && maxDraw < minDate ? minDate : maxDraw );
11252			while ( this._daylightSavingAdjust( new Date( drawYear, drawMonth, 1 ) ) > maxDraw ) {
11253				drawMonth--;
11254				if ( drawMonth < 0 ) {
11255					drawMonth = 11;
11256					drawYear--;
11257				}
11258			}
11259		}
11260		inst.drawMonth = drawMonth;
11261		inst.drawYear = drawYear;
11262
11263		prevText = this._get( inst, "prevText" );
11264		prevText = ( !navigationAsDateFormat ? prevText : this.formatDate( prevText,
11265			this._daylightSavingAdjust( new Date( drawYear, drawMonth - stepMonths, 1 ) ),
11266			this._getFormatConfig( inst ) ) );
11267
11268		prev = ( this._canAdjustMonth( inst, -1, drawYear, drawMonth ) ?
11269			"<a class='ui-datepicker-prev ui-corner-all' data-handler='prev' data-event='click'" +
11270			" title='" + prevText + "'><span class='ui-icon ui-icon-circle-triangle-" + ( isRTL ? "e" : "w" ) + "'>" + prevText + "</span></a>" :
11271			( hideIfNoPrevNext ? "" : "<a class='ui-datepicker-prev ui-corner-all ui-state-disabled' title='" + prevText + "'><span class='ui-icon ui-icon-circle-triangle-" + ( isRTL ? "e" : "w" ) + "'>" + prevText + "</span></a>" ) );
11272
11273		nextText = this._get( inst, "nextText" );
11274		nextText = ( !navigationAsDateFormat ? nextText : this.formatDate( nextText,
11275			this._daylightSavingAdjust( new Date( drawYear, drawMonth + stepMonths, 1 ) ),
11276			this._getFormatConfig( inst ) ) );
11277
11278		next = ( this._canAdjustMonth( inst, +1, drawYear, drawMonth ) ?
11279			"<a class='ui-datepicker-next ui-corner-all' data-handler='next' data-event='click'" +
11280			" title='" + nextText + "'><span class='ui-icon ui-icon-circle-triangle-" + ( isRTL ? "w" : "e" ) + "'>" + nextText + "</span></a>" :
11281			( hideIfNoPrevNext ? "" : "<a class='ui-datepicker-next ui-corner-all ui-state-disabled' title='" + nextText + "'><span class='ui-icon ui-icon-circle-triangle-" + ( isRTL ? "w" : "e" ) + "'>" + nextText + "</span></a>" ) );
11282
11283		currentText = this._get( inst, "currentText" );
11284		gotoDate = ( this._get( inst, "gotoCurrent" ) && inst.currentDay ? currentDate : today );
11285		currentText = ( !navigationAsDateFormat ? currentText :
11286			this.formatDate( currentText, gotoDate, this._getFormatConfig( inst ) ) );
11287
11288		controls = ( !inst.inline ? "<button type='button' class='ui-datepicker-close ui-state-default ui-priority-primary ui-corner-all' data-handler='hide' data-event='click'>" +
11289			this._get( inst, "closeText" ) + "</button>" : "" );
11290
11291		buttonPanel = ( showButtonPanel ) ? "<div class='ui-datepicker-buttonpane ui-widget-content'>" + ( isRTL ? controls : "" ) +
11292			( this._isInRange( inst, gotoDate ) ? "<button type='button' class='ui-datepicker-current ui-state-default ui-priority-secondary ui-corner-all' data-handler='today' data-event='click'" +
11293			">" + currentText + "</button>" : "" ) + ( isRTL ? "" : controls ) + "</div>" : "";
11294
11295		firstDay = parseInt( this._get( inst, "firstDay" ), 10 );
11296		firstDay = ( isNaN( firstDay ) ? 0 : firstDay );
11297
11298		showWeek = this._get( inst, "showWeek" );
11299		dayNames = this._get( inst, "dayNames" );
11300		dayNamesMin = this._get( inst, "dayNamesMin" );
11301		monthNames = this._get( inst, "monthNames" );
11302		monthNamesShort = this._get( inst, "monthNamesShort" );
11303		beforeShowDay = this._get( inst, "beforeShowDay" );
11304		showOtherMonths = this._get( inst, "showOtherMonths" );
11305		selectOtherMonths = this._get( inst, "selectOtherMonths" );
11306		defaultDate = this._getDefaultDate( inst );
11307		html = "";
11308
11309		for ( row = 0; row < numMonths[ 0 ]; row++ ) {
11310			group = "";
11311			this.maxRows = 4;
11312			for ( col = 0; col < numMonths[ 1 ]; col++ ) {
11313				selectedDate = this._daylightSavingAdjust( new Date( drawYear, drawMonth, inst.selectedDay ) );
11314				cornerClass = " ui-corner-all";
11315				calender = "";
11316				if ( isMultiMonth ) {
11317					calender += "<div class='ui-datepicker-group";
11318					if ( numMonths[ 1 ] > 1 ) {
11319						switch ( col ) {
11320							case 0: calender += " ui-datepicker-group-first";
11321								cornerClass = " ui-corner-" + ( isRTL ? "right" : "left" ); break;
11322							case numMonths[ 1 ] - 1: calender += " ui-datepicker-group-last";
11323								cornerClass = " ui-corner-" + ( isRTL ? "left" : "right" ); break;
11324							default: calender += " ui-datepicker-group-middle"; cornerClass = ""; break;
11325						}
11326					}
11327					calender += "'>";
11328				}
11329				calender += "<div class='ui-datepicker-header ui-widget-header ui-helper-clearfix" + cornerClass + "'>" +
11330					( /all|left/.test( cornerClass ) && row === 0 ? ( isRTL ? next : prev ) : "" ) +
11331					( /all|right/.test( cornerClass ) && row === 0 ? ( isRTL ? prev : next ) : "" ) +
11332					this._generateMonthYearHeader( inst, drawMonth, drawYear, minDate, maxDate,
11333					row > 0 || col > 0, monthNames, monthNamesShort ) + // draw month headers
11334					"</div><table class='ui-datepicker-calendar'><thead>" +
11335					"<tr>";
11336				thead = ( showWeek ? "<th class='ui-datepicker-week-col'>" + this._get( inst, "weekHeader" ) + "</th>" : "" );
11337				for ( dow = 0; dow < 7; dow++ ) { // days of the week
11338					day = ( dow + firstDay ) % 7;
11339					thead += "<th scope='col'" + ( ( dow + firstDay + 6 ) % 7 >= 5 ? " class='ui-datepicker-week-end'" : "" ) + ">" +
11340						"<span title='" + dayNames[ day ] + "'>" + dayNamesMin[ day ] + "</span></th>";
11341				}
11342				calender += thead + "</tr></thead><tbody>";
11343				daysInMonth = this._getDaysInMonth( drawYear, drawMonth );
11344				if ( drawYear === inst.selectedYear && drawMonth === inst.selectedMonth ) {
11345					inst.selectedDay = Math.min( inst.selectedDay, daysInMonth );
11346				}
11347				leadDays = ( this._getFirstDayOfMonth( drawYear, drawMonth ) - firstDay + 7 ) % 7;
11348				curRows = Math.ceil( ( leadDays + daysInMonth ) / 7 ); // calculate the number of rows to generate
11349				numRows = ( isMultiMonth ? this.maxRows > curRows ? this.maxRows : curRows : curRows ); //If multiple months, use the higher number of rows (see #7043)
11350				this.maxRows = numRows;
11351				printDate = this._daylightSavingAdjust( new Date( drawYear, drawMonth, 1 - leadDays ) );
11352				for ( dRow = 0; dRow < numRows; dRow++ ) { // create date picker rows
11353					calender += "<tr>";
11354					tbody = ( !showWeek ? "" : "<td class='ui-datepicker-week-col'>" +
11355						this._get( inst, "calculateWeek" )( printDate ) + "</td>" );
11356					for ( dow = 0; dow < 7; dow++ ) { // create date picker days
11357						daySettings = ( beforeShowDay ?
11358							beforeShowDay.apply( ( inst.input ? inst.input[ 0 ] : null ), [ printDate ] ) : [ true, "" ] );
11359						otherMonth = ( printDate.getMonth() !== drawMonth );
11360						unselectable = ( otherMonth && !selectOtherMonths ) || !daySettings[ 0 ] ||
11361							( minDate && printDate < minDate ) || ( maxDate && printDate > maxDate );
11362						tbody += "<td class='" +
11363							( ( dow + firstDay + 6 ) % 7 >= 5 ? " ui-datepicker-week-end" : "" ) + // highlight weekends
11364							( otherMonth ? " ui-datepicker-other-month" : "" ) + // highlight days from other months
11365							( ( printDate.getTime() === selectedDate.getTime() && drawMonth === inst.selectedMonth && inst._keyEvent ) || // user pressed key
11366							( defaultDate.getTime() === printDate.getTime() && defaultDate.getTime() === selectedDate.getTime() ) ?
11367
11368							// or defaultDate is current printedDate and defaultDate is selectedDate
11369							" " + this._dayOverClass : "" ) + // highlight selected day
11370							( unselectable ? " " + this._unselectableClass + " ui-state-disabled" : "" ) +  // highlight unselectable days
11371							( otherMonth && !showOtherMonths ? "" : " " + daySettings[ 1 ] + // highlight custom dates
11372							( printDate.getTime() === currentDate.getTime() ? " " + this._currentClass : "" ) + // highlight selected day
11373							( printDate.getTime() === today.getTime() ? " ui-datepicker-today" : "" ) ) + "'" + // highlight today (if different)
11374							( ( !otherMonth || showOtherMonths ) && daySettings[ 2 ] ? " title='" + daySettings[ 2 ].replace( /'/g, "&#39;" ) + "'" : "" ) + // cell title
11375							( unselectable ? "" : " data-handler='selectDay' data-event='click' data-month='" + printDate.getMonth() + "' data-year='" + printDate.getFullYear() + "'" ) + ">" + // actions
11376							( otherMonth && !showOtherMonths ? "&#xa0;" : // display for other months
11377							( unselectable ? "<span class='ui-state-default'>" + printDate.getDate() + "</span>" : "<a class='ui-state-default" +
11378							( printDate.getTime() === today.getTime() ? " ui-state-highlight" : "" ) +
11379							( printDate.getTime() === currentDate.getTime() ? " ui-state-active" : "" ) + // highlight selected day
11380							( otherMonth ? " ui-priority-secondary" : "" ) + // distinguish dates from other months
11381							"' href='#'>" + printDate.getDate() + "</a>" ) ) + "</td>"; // display selectable date
11382						printDate.setDate( printDate.getDate() + 1 );
11383						printDate = this._daylightSavingAdjust( printDate );
11384					}
11385					calender += tbody + "</tr>";
11386				}
11387				drawMonth++;
11388				if ( drawMonth > 11 ) {
11389					drawMonth = 0;
11390					drawYear++;
11391				}
11392				calender += "</tbody></table>" + ( isMultiMonth ? "</div>" +
11393							( ( numMonths[ 0 ] > 0 && col === numMonths[ 1 ] - 1 ) ? "<div class='ui-datepicker-row-break'></div>" : "" ) : "" );
11394				group += calender;
11395			}
11396			html += group;
11397		}
11398		html += buttonPanel;
11399		inst._keyEvent = false;
11400		return html;
11401	},
11402
11403	/* Generate the month and year header. */
11404	_generateMonthYearHeader: function( inst, drawMonth, drawYear, minDate, maxDate,
11405			secondary, monthNames, monthNamesShort ) {
11406
11407		var inMinYear, inMaxYear, month, years, thisYear, determineYear, year, endYear,
11408			changeMonth = this._get( inst, "changeMonth" ),
11409			changeYear = this._get( inst, "changeYear" ),
11410			showMonthAfterYear = this._get( inst, "showMonthAfterYear" ),
11411			html = "<div class='ui-datepicker-title'>",
11412			monthHtml = "";
11413
11414		// Month selection
11415		if ( secondary || !changeMonth ) {
11416			monthHtml += "<span class='ui-datepicker-month'>" + monthNames[ drawMonth ] + "</span>";
11417		} else {
11418			inMinYear = ( minDate && minDate.getFullYear() === drawYear );
11419			inMaxYear = ( maxDate && maxDate.getFullYear() === drawYear );
11420			monthHtml += "<select class='ui-datepicker-month' data-handler='selectMonth' data-event='change'>";
11421			for ( month = 0; month < 12; month++ ) {
11422				if ( ( !inMinYear || month >= minDate.getMonth() ) && ( !inMaxYear || month <= maxDate.getMonth() ) ) {
11423					monthHtml += "<option value='" + month + "'" +
11424						( month === drawMonth ? " selected='selected'" : "" ) +
11425						">" + monthNamesShort[ month ] + "</option>";
11426				}
11427			}
11428			monthHtml += "</select>";
11429		}
11430
11431		if ( !showMonthAfterYear ) {
11432			html += monthHtml + ( secondary || !( changeMonth && changeYear ) ? "&#xa0;" : "" );
11433		}
11434
11435		// Year selection
11436		if ( !inst.yearshtml ) {
11437			inst.yearshtml = "";
11438			if ( secondary || !changeYear ) {
11439				html += "<span class='ui-datepicker-year'>" + drawYear + "</span>";
11440			} else {
11441
11442				// determine range of years to display
11443				years = this._get( inst, "yearRange" ).split( ":" );
11444				thisYear = new Date().getFullYear();
11445				determineYear = function( value ) {
11446					var year = ( value.match( /c[+\-].*/ ) ? drawYear + parseInt( value.substring( 1 ), 10 ) :
11447						( value.match( /[+\-].*/ ) ? thisYear + parseInt( value, 10 ) :
11448						parseInt( value, 10 ) ) );
11449					return ( isNaN( year ) ? thisYear : year );
11450				};
11451				year = determineYear( years[ 0 ] );
11452				endYear = Math.max( year, determineYear( years[ 1 ] || "" ) );
11453				year = ( minDate ? Math.max( year, minDate.getFullYear() ) : year );
11454				endYear = ( maxDate ? Math.min( endYear, maxDate.getFullYear() ) : endYear );
11455				inst.yearshtml += "<select class='ui-datepicker-year' data-handler='selectYear' data-event='change'>";
11456				for ( ; year <= endYear; year++ ) {
11457					inst.yearshtml += "<option value='" + year + "'" +
11458						( year === drawYear ? " selected='selected'" : "" ) +
11459						">" + year + "</option>";
11460				}
11461				inst.yearshtml += "</select>";
11462
11463				html += inst.yearshtml;
11464				inst.yearshtml = null;
11465			}
11466		}
11467
11468		html += this._get( inst, "yearSuffix" );
11469		if ( showMonthAfterYear ) {
11470			html += ( secondary || !( changeMonth && changeYear ) ? "&#xa0;" : "" ) + monthHtml;
11471		}
11472		html += "</div>"; // Close datepicker_header
11473		return html;
11474	},
11475
11476	/* Adjust one of the date sub-fields. */
11477	_adjustInstDate: function( inst, offset, period ) {
11478		var year = inst.selectedYear + ( period === "Y" ? offset : 0 ),
11479			month = inst.selectedMonth + ( period === "M" ? offset : 0 ),
11480			day = Math.min( inst.selectedDay, this._getDaysInMonth( year, month ) ) + ( period === "D" ? offset : 0 ),
11481			date = this._restrictMinMax( inst, this._daylightSavingAdjust( new Date( year, month, day ) ) );
11482
11483		inst.selectedDay = date.getDate();
11484		inst.drawMonth = inst.selectedMonth = date.getMonth();
11485		inst.drawYear = inst.selectedYear = date.getFullYear();
11486		if ( period === "M" || period === "Y" ) {
11487			this._notifyChange( inst );
11488		}
11489	},
11490
11491	/* Ensure a date is within any min/max bounds. */
11492	_restrictMinMax: function( inst, date ) {
11493		var minDate = this._getMinMaxDate( inst, "min" ),
11494			maxDate = this._getMinMaxDate( inst, "max" ),
11495			newDate = ( minDate && date < minDate ? minDate : date );
11496		return ( maxDate && newDate > maxDate ? maxDate : newDate );
11497	},
11498
11499	/* Notify change of month/year. */
11500	_notifyChange: function( inst ) {
11501		var onChange = this._get( inst, "onChangeMonthYear" );
11502		if ( onChange ) {
11503			onChange.apply( ( inst.input ? inst.input[ 0 ] : null ),
11504				[ inst.selectedYear, inst.selectedMonth + 1, inst ] );
11505		}
11506	},
11507
11508	/* Determine the number of months to show. */
11509	_getNumberOfMonths: function( inst ) {
11510		var numMonths = this._get( inst, "numberOfMonths" );
11511		return ( numMonths == null ? [ 1, 1 ] : ( typeof numMonths === "number" ? [ 1, numMonths ] : numMonths ) );
11512	},
11513
11514	/* Determine the current maximum date - ensure no time components are set. */
11515	_getMinMaxDate: function( inst, minMax ) {
11516		return this._determineDate( inst, this._get( inst, minMax + "Date" ), null );
11517	},
11518
11519	/* Find the number of days in a given month. */
11520	_getDaysInMonth: function( year, month ) {
11521		return 32 - this._daylightSavingAdjust( new Date( year, month, 32 ) ).getDate();
11522	},
11523
11524	/* Find the day of the week of the first of a month. */
11525	_getFirstDayOfMonth: function( year, month ) {
11526		return new Date( year, month, 1 ).getDay();
11527	},
11528
11529	/* Determines if we should allow a "next/prev" month display change. */
11530	_canAdjustMonth: function( inst, offset, curYear, curMonth ) {
11531		var numMonths = this._getNumberOfMonths( inst ),
11532			date = this._daylightSavingAdjust( new Date( curYear,
11533			curMonth + ( offset < 0 ? offset : numMonths[ 0 ] * numMonths[ 1 ] ), 1 ) );
11534
11535		if ( offset < 0 ) {
11536			date.setDate( this._getDaysInMonth( date.getFullYear(), date.getMonth() ) );
11537		}
11538		return this._isInRange( inst, date );
11539	},
11540
11541	/* Is the given date in the accepted range? */
11542	_isInRange: function( inst, date ) {
11543		var yearSplit, currentYear,
11544			minDate = this._getMinMaxDate( inst, "min" ),
11545			maxDate = this._getMinMaxDate( inst, "max" ),
11546			minYear = null,
11547			maxYear = null,
11548			years = this._get( inst, "yearRange" );
11549			if ( years ) {
11550				yearSplit = years.split( ":" );
11551				currentYear = new Date().getFullYear();
11552				minYear = parseInt( yearSplit[ 0 ], 10 );
11553				maxYear = parseInt( yearSplit[ 1 ], 10 );
11554				if ( yearSplit[ 0 ].match( /[+\-].*/ ) ) {
11555					minYear += currentYear;
11556				}
11557				if ( yearSplit[ 1 ].match( /[+\-].*/ ) ) {
11558					maxYear += currentYear;
11559				}
11560			}
11561
11562		return ( ( !minDate || date.getTime() >= minDate.getTime() ) &&
11563			( !maxDate || date.getTime() <= maxDate.getTime() ) &&
11564			( !minYear || date.getFullYear() >= minYear ) &&
11565			( !maxYear || date.getFullYear() <= maxYear ) );
11566	},
11567
11568	/* Provide the configuration settings for formatting/parsing. */
11569	_getFormatConfig: function( inst ) {
11570		var shortYearCutoff = this._get( inst, "shortYearCutoff" );
11571		shortYearCutoff = ( typeof shortYearCutoff !== "string" ? shortYearCutoff :
11572			new Date().getFullYear() % 100 + parseInt( shortYearCutoff, 10 ) );
11573		return { shortYearCutoff: shortYearCutoff,
11574			dayNamesShort: this._get( inst, "dayNamesShort" ), dayNames: this._get( inst, "dayNames" ),
11575			monthNamesShort: this._get( inst, "monthNamesShort" ), monthNames: this._get( inst, "monthNames" ) };
11576	},
11577
11578	/* Format the given date for display. */
11579	_formatDate: function( inst, day, month, year ) {
11580		if ( !day ) {
11581			inst.currentDay = inst.selectedDay;
11582			inst.currentMonth = inst.selectedMonth;
11583			inst.currentYear = inst.selectedYear;
11584		}
11585		var date = ( day ? ( typeof day === "object" ? day :
11586			this._daylightSavingAdjust( new Date( year, month, day ) ) ) :
11587			this._daylightSavingAdjust( new Date( inst.currentYear, inst.currentMonth, inst.currentDay ) ) );
11588		return this.formatDate( this._get( inst, "dateFormat" ), date, this._getFormatConfig( inst ) );
11589	}
11590} );
11591
11592/*
11593 * Bind hover events for datepicker elements.
11594 * Done via delegate so the binding only occurs once in the lifetime of the parent div.
11595 * Global datepicker_instActive, set by _updateDatepicker allows the handlers to find their way back to the active picker.
11596 */
11597function datepicker_bindHover( dpDiv ) {
11598	var selector = "button, .ui-datepicker-prev, .ui-datepicker-next, .ui-datepicker-calendar td a";
11599	return dpDiv.on( "mouseout", selector, function() {
11600			$( this ).removeClass( "ui-state-hover" );
11601			if ( this.className.indexOf( "ui-datepicker-prev" ) !== -1 ) {
11602				$( this ).removeClass( "ui-datepicker-prev-hover" );
11603			}
11604			if ( this.className.indexOf( "ui-datepicker-next" ) !== -1 ) {
11605				$( this ).removeClass( "ui-datepicker-next-hover" );
11606			}
11607		} )
11608		.on( "mouseover", selector, datepicker_handleMouseover );
11609}
11610
11611function datepicker_handleMouseover() {
11612	if ( !$.datepicker._isDisabledDatepicker( datepicker_instActive.inline ? datepicker_instActive.dpDiv.parent()[ 0 ] : datepicker_instActive.input[ 0 ] ) ) {
11613		$( this ).parents( ".ui-datepicker-calendar" ).find( "a" ).removeClass( "ui-state-hover" );
11614		$( this ).addClass( "ui-state-hover" );
11615		if ( this.className.indexOf( "ui-datepicker-prev" ) !== -1 ) {
11616			$( this ).addClass( "ui-datepicker-prev-hover" );
11617		}
11618		if ( this.className.indexOf( "ui-datepicker-next" ) !== -1 ) {
11619			$( this ).addClass( "ui-datepicker-next-hover" );
11620		}
11621	}
11622}
11623
11624/* jQuery extend now ignores nulls! */
11625function datepicker_extendRemove( target, props ) {
11626	$.extend( target, props );
11627	for ( var name in props ) {
11628		if ( props[ name ] == null ) {
11629			target[ name ] = props[ name ];
11630		}
11631	}
11632	return target;
11633}
11634
11635/* Invoke the datepicker functionality.
11636   @param  options  string - a command, optionally followed by additional parameters or
11637					Object - settings for attaching new datepicker functionality
11638   @return  jQuery object */
11639$.fn.datepicker = function( options ) {
11640
11641	/* Verify an empty collection wasn't passed - Fixes #6976 */
11642	if ( !this.length ) {
11643		return this;
11644	}
11645
11646	/* Initialise the date picker. */
11647	if ( !$.datepicker.initialized ) {
11648		$( document ).on( "mousedown", $.datepicker._checkExternalClick );
11649		$.datepicker.initialized = true;
11650	}
11651
11652	/* Append datepicker main container to body if not exist. */
11653	if ( $( "#" + $.datepicker._mainDivId ).length === 0 ) {
11654		$( "body" ).append( $.datepicker.dpDiv );
11655	}
11656
11657	var otherArgs = Array.prototype.slice.call( arguments, 1 );
11658	if ( typeof options === "string" && ( options === "isDisabled" || options === "getDate" || options === "widget" ) ) {
11659		return $.datepicker[ "_" + options + "Datepicker" ].
11660			apply( $.datepicker, [ this[ 0 ] ].concat( otherArgs ) );
11661	}
11662	if ( options === "option" && arguments.length === 2 && typeof arguments[ 1 ] === "string" ) {
11663		return $.datepicker[ "_" + options + "Datepicker" ].
11664			apply( $.datepicker, [ this[ 0 ] ].concat( otherArgs ) );
11665	}
11666	return this.each( function() {
11667		typeof options === "string" ?
11668			$.datepicker[ "_" + options + "Datepicker" ].
11669				apply( $.datepicker, [ this ].concat( otherArgs ) ) :
11670			$.datepicker._attachDatepicker( this, options );
11671	} );
11672};
11673
11674$.datepicker = new Datepicker(); // singleton instance
11675$.datepicker.initialized = false;
11676$.datepicker.uuid = new Date().getTime();
11677$.datepicker.version = "1.12.1";
11678
11679var widgetsDatepicker = $.datepicker;
11680
11681
11682/*!
11683 * jQuery UI Dialog 1.12.1
11684 * http://jqueryui.com
11685 *
11686 * Copyright jQuery Foundation and other contributors
11687 * Released under the MIT license.
11688 * http://jquery.org/license
11689 */
11690
11691//>>label: Dialog
11692//>>group: Widgets
11693//>>description: Displays customizable dialog windows.
11694//>>docs: http://api.jqueryui.com/dialog/
11695//>>demos: http://jqueryui.com/dialog/
11696//>>css.structure: ../../themes/base/core.css
11697//>>css.structure: ../../themes/base/dialog.css
11698//>>css.theme: ../../themes/base/theme.css
11699
11700
11701
11702$.widget( "ui.dialog", {
11703	version: "1.12.1",
11704	options: {
11705		appendTo: "body",
11706		autoOpen: true,
11707		buttons: [],
11708		classes: {
11709			"ui-dialog": "ui-corner-all",
11710			"ui-dialog-titlebar": "ui-corner-all"
11711		},
11712		closeOnEscape: true,
11713		closeText: "Close",
11714		draggable: true,
11715		hide: null,
11716		height: "auto",
11717		maxHeight: null,
11718		maxWidth: null,
11719		minHeight: 150,
11720		minWidth: 150,
11721		modal: false,
11722		position: {
11723			my: "center",
11724			at: "center",
11725			of: window,
11726			collision: "fit",
11727
11728			// Ensure the titlebar is always visible
11729			using: function( pos ) {
11730				var topOffset = $( this ).css( pos ).offset().top;
11731				if ( topOffset < 0 ) {
11732					$( this ).css( "top", pos.top - topOffset );
11733				}
11734			}
11735		},
11736		resizable: true,
11737		show: null,
11738		title: null,
11739		width: 300,
11740
11741		// Callbacks
11742		beforeClose: null,
11743		close: null,
11744		drag: null,
11745		dragStart: null,
11746		dragStop: null,
11747		focus: null,
11748		open: null,
11749		resize: null,
11750		resizeStart: null,
11751		resizeStop: null
11752	},
11753
11754	sizeRelatedOptions: {
11755		buttons: true,
11756		height: true,
11757		maxHeight: true,
11758		maxWidth: true,
11759		minHeight: true,
11760		minWidth: true,
11761		width: true
11762	},
11763
11764	resizableRelatedOptions: {
11765		maxHeight: true,
11766		maxWidth: true,
11767		minHeight: true,
11768		minWidth: true
11769	},
11770
11771	_create: function() {
11772		this.originalCss = {
11773			display: this.element[ 0 ].style.display,
11774			width: this.element[ 0 ].style.width,
11775			minHeight: this.element[ 0 ].style.minHeight,
11776			maxHeight: this.element[ 0 ].style.maxHeight,
11777			height: this.element[ 0 ].style.height
11778		};
11779		this.originalPosition = {
11780			parent: this.element.parent(),
11781			index: this.element.parent().children().index( this.element )
11782		};
11783		this.originalTitle = this.element.attr( "title" );
11784		if ( this.options.title == null && this.originalTitle != null ) {
11785			this.options.title = this.originalTitle;
11786		}
11787
11788		// Dialogs can't be disabled
11789		if ( this.options.disabled ) {
11790			this.options.disabled = false;
11791		}
11792
11793		this._createWrapper();
11794
11795		this.element
11796			.show()
11797			.removeAttr( "title" )
11798			.appendTo( this.uiDialog );
11799
11800		this._addClass( "ui-dialog-content", "ui-widget-content" );
11801
11802		this._createTitlebar();
11803		this._createButtonPane();
11804
11805		if ( this.options.draggable && $.fn.draggable ) {
11806			this._makeDraggable();
11807		}
11808		if ( this.options.resizable && $.fn.resizable ) {
11809			this._makeResizable();
11810		}
11811
11812		this._isOpen = false;
11813
11814		this._trackFocus();
11815	},
11816
11817	_init: function() {
11818		if ( this.options.autoOpen ) {
11819			this.open();
11820		}
11821	},
11822
11823	_appendTo: function() {
11824		var element = this.options.appendTo;
11825		if ( element && ( element.jquery || element.nodeType ) ) {
11826			return $( element );
11827		}
11828		return this.document.find( element || "body" ).eq( 0 );
11829	},
11830
11831	_destroy: function() {
11832		var next,
11833			originalPosition = this.originalPosition;
11834
11835		this._untrackInstance();
11836		this._destroyOverlay();
11837
11838		this.element
11839			.removeUniqueId()
11840			.css( this.originalCss )
11841
11842			// Without detaching first, the following becomes really slow
11843			.detach();
11844
11845		this.uiDialog.remove();
11846
11847		if ( this.originalTitle ) {
11848			this.element.attr( "title", this.originalTitle );
11849		}
11850
11851		next = originalPosition.parent.children().eq( originalPosition.index );
11852
11853		// Don't try to place the dialog next to itself (#8613)
11854		if ( next.length && next[ 0 ] !== this.element[ 0 ] ) {
11855			next.before( this.element );
11856		} else {
11857			originalPosition.parent.append( this.element );
11858		}
11859	},
11860
11861	widget: function() {
11862		return this.uiDialog;
11863	},
11864
11865	disable: $.noop,
11866	enable: $.noop,
11867
11868	close: function( event ) {
11869		var that = this;
11870
11871		if ( !this._isOpen || this._trigger( "beforeClose", event ) === false ) {
11872			return;
11873		}
11874
11875		this._isOpen = false;
11876		this._focusedElement = null;
11877		this._destroyOverlay();
11878		this._untrackInstance();
11879
11880		if ( !this.opener.filter( ":focusable" ).trigger( "focus" ).length ) {
11881
11882			// Hiding a focused element doesn't trigger blur in WebKit
11883			// so in case we have nothing to focus on, explicitly blur the active element
11884			// https://bugs.webkit.org/show_bug.cgi?id=47182
11885			$.ui.safeBlur( $.ui.safeActiveElement( this.document[ 0 ] ) );
11886		}
11887
11888		this._hide( this.uiDialog, this.options.hide, function() {
11889			that._trigger( "close", event );
11890		} );
11891	},
11892
11893	isOpen: function() {
11894		return this._isOpen;
11895	},
11896
11897	moveToTop: function() {
11898		this._moveToTop();
11899	},
11900
11901	_moveToTop: function( event, silent ) {
11902		var moved = false,
11903			zIndices = this.uiDialog.siblings( ".ui-front:visible" ).map( function() {
11904				return +$( this ).css( "z-index" );
11905			} ).get(),
11906			zIndexMax = Math.max.apply( null, zIndices );
11907
11908		if ( zIndexMax >= +this.uiDialog.css( "z-index" ) ) {
11909			this.uiDialog.css( "z-index", zIndexMax + 1 );
11910			moved = true;
11911		}
11912
11913		if ( moved && !silent ) {
11914			this._trigger( "focus", event );
11915		}
11916		return moved;
11917	},
11918
11919	open: function() {
11920		var that = this;
11921		if ( this._isOpen ) {
11922			if ( this._moveToTop() ) {
11923				this._focusTabbable();
11924			}
11925			return;
11926		}
11927
11928		this._isOpen = true;
11929		this.opener = $( $.ui.safeActiveElement( this.document[ 0 ] ) );
11930
11931		this._size();
11932		this._position();
11933		this._createOverlay();
11934		this._moveToTop( null, true );
11935
11936		// Ensure the overlay is moved to the top with the dialog, but only when
11937		// opening. The overlay shouldn't move after the dialog is open so that
11938		// modeless dialogs opened after the modal dialog stack properly.
11939		if ( this.overlay ) {
11940			this.overlay.css( "z-index", this.uiDialog.css( "z-index" ) - 1 );
11941		}
11942
11943		this._show( this.uiDialog, this.options.show, function() {
11944			that._focusTabbable();
11945			that._trigger( "focus" );
11946		} );
11947
11948		// Track the dialog immediately upon openening in case a focus event
11949		// somehow occurs outside of the dialog before an element inside the
11950		// dialog is focused (#10152)
11951		this._makeFocusTarget();
11952
11953		this._trigger( "open" );
11954	},
11955
11956	_focusTabbable: function() {
11957
11958		// Set focus to the first match:
11959		// 1. An element that was focused previously
11960		// 2. First element inside the dialog matching [autofocus]
11961		// 3. Tabbable element inside the content element
11962		// 4. Tabbable element inside the buttonpane
11963		// 5. The close button
11964		// 6. The dialog itself
11965		var hasFocus = this._focusedElement;
11966		if ( !hasFocus ) {
11967			hasFocus = this.element.find( "[autofocus]" );
11968		}
11969		if ( !hasFocus.length ) {
11970			hasFocus = this.element.find( ":tabbable" );
11971		}
11972		if ( !hasFocus.length ) {
11973			hasFocus = this.uiDialogButtonPane.find( ":tabbable" );
11974		}
11975		if ( !hasFocus.length ) {
11976			hasFocus = this.uiDialogTitlebarClose.filter( ":tabbable" );
11977		}
11978		if ( !hasFocus.length ) {
11979			hasFocus = this.uiDialog;
11980		}
11981		hasFocus.eq( 0 ).trigger( "focus" );
11982	},
11983
11984	_keepFocus: function( event ) {
11985		function checkFocus() {
11986			var activeElement = $.ui.safeActiveElement( this.document[ 0 ] ),
11987				isActive = this.uiDialog[ 0 ] === activeElement ||
11988					$.contains( this.uiDialog[ 0 ], activeElement );
11989			if ( !isActive ) {
11990				this._focusTabbable();
11991			}
11992		}
11993		event.preventDefault();
11994		checkFocus.call( this );
11995
11996		// support: IE
11997		// IE <= 8 doesn't prevent moving focus even with event.preventDefault()
11998		// so we check again later
11999		this._delay( checkFocus );
12000	},
12001
12002	_createWrapper: function() {
12003		this.uiDialog = $( "<div>" )
12004			.hide()
12005			.attr( {
12006
12007				// Setting tabIndex makes the div focusable
12008				tabIndex: -1,
12009				role: "dialog"
12010			} )
12011			.appendTo( this._appendTo() );
12012
12013		this._addClass( this.uiDialog, "ui-dialog", "ui-widget ui-widget-content ui-front" );
12014		this._on( this.uiDialog, {
12015			keydown: function( event ) {
12016				if ( this.options.closeOnEscape && !event.isDefaultPrevented() && event.keyCode &&
12017						event.keyCode === $.ui.keyCode.ESCAPE ) {
12018					event.preventDefault();
12019					this.close( event );
12020					return;
12021				}
12022
12023				// Prevent tabbing out of dialogs
12024				if ( event.keyCode !== $.ui.keyCode.TAB || event.isDefaultPrevented() ) {
12025					return;
12026				}
12027				var tabbables = this.uiDialog.find( ":tabbable" ),
12028					first = tabbables.filter( ":first" ),
12029					last = tabbables.filter( ":last" );
12030
12031				if ( ( event.target === last[ 0 ] || event.target === this.uiDialog[ 0 ] ) &&
12032						!event.shiftKey ) {
12033					this._delay( function() {
12034						first.trigger( "focus" );
12035					} );
12036					event.preventDefault();
12037				} else if ( ( event.target === first[ 0 ] ||
12038						event.target === this.uiDialog[ 0 ] ) && event.shiftKey ) {
12039					this._delay( function() {
12040						last.trigger( "focus" );
12041					} );
12042					event.preventDefault();
12043				}
12044			},
12045			mousedown: function( event ) {
12046				if ( this._moveToTop( event ) ) {
12047					this._focusTabbable();
12048				}
12049			}
12050		} );
12051
12052		// We assume that any existing aria-describedby attribute means
12053		// that the dialog content is marked up properly
12054		// otherwise we brute force the content as the description
12055		if ( !this.element.find( "[aria-describedby]" ).length ) {
12056			this.uiDialog.attr( {
12057				"aria-describedby": this.element.uniqueId().attr( "id" )
12058			} );
12059		}
12060	},
12061
12062	_createTitlebar: function() {
12063		var uiDialogTitle;
12064
12065		this.uiDialogTitlebar = $( "<div>" );
12066		this._addClass( this.uiDialogTitlebar,
12067			"ui-dialog-titlebar", "ui-widget-header ui-helper-clearfix" );
12068		this._on( this.uiDialogTitlebar, {
12069			mousedown: function( event ) {
12070
12071				// Don't prevent click on close button (#8838)
12072				// Focusing a dialog that is partially scrolled out of view
12073				// causes the browser to scroll it into view, preventing the click event
12074				if ( !$( event.target ).closest( ".ui-dialog-titlebar-close" ) ) {
12075
12076					// Dialog isn't getting focus when dragging (#8063)
12077					this.uiDialog.trigger( "focus" );
12078				}
12079			}
12080		} );
12081
12082		// Support: IE
12083		// Use type="button" to prevent enter keypresses in textboxes from closing the
12084		// dialog in IE (#9312)
12085		this.uiDialogTitlebarClose = $( "<button type='button'></button>" )
12086			.button( {
12087				label: $( "<a>" ).text( this.options.closeText ).html(),
12088				icon: "ui-icon-closethick",
12089				showLabel: false
12090			} )
12091			.appendTo( this.uiDialogTitlebar );
12092
12093		this._addClass( this.uiDialogTitlebarClose, "ui-dialog-titlebar-close" );
12094		this._on( this.uiDialogTitlebarClose, {
12095			click: function( event ) {
12096				event.preventDefault();
12097				this.close( event );
12098			}
12099		} );
12100
12101		uiDialogTitle = $( "<span>" ).uniqueId().prependTo( this.uiDialogTitlebar );
12102		this._addClass( uiDialogTitle, "ui-dialog-title" );
12103		this._title( uiDialogTitle );
12104
12105		this.uiDialogTitlebar.prependTo( this.uiDialog );
12106
12107		this.uiDialog.attr( {
12108			"aria-labelledby": uiDialogTitle.attr( "id" )
12109		} );
12110	},
12111
12112	_title: function( title ) {
12113		if ( this.options.title ) {
12114			title.text( this.options.title );
12115		} else {
12116			title.html( "&#160;" );
12117		}
12118	},
12119
12120	_createButtonPane: function() {
12121		this.uiDialogButtonPane = $( "<div>" );
12122		this._addClass( this.uiDialogButtonPane, "ui-dialog-buttonpane",
12123			"ui-widget-content ui-helper-clearfix" );
12124
12125		this.uiButtonSet = $( "<div>" )
12126			.appendTo( this.uiDialogButtonPane );
12127		this._addClass( this.uiButtonSet, "ui-dialog-buttonset" );
12128
12129		this._createButtons();
12130	},
12131
12132	_createButtons: function() {
12133		var that = this,
12134			buttons = this.options.buttons;
12135
12136		// If we already have a button pane, remove it
12137		this.uiDialogButtonPane.remove();
12138		this.uiButtonSet.empty();
12139
12140		if ( $.isEmptyObject( buttons ) || ( $.isArray( buttons ) && !buttons.length ) ) {
12141			this._removeClass( this.uiDialog, "ui-dialog-buttons" );
12142			return;
12143		}
12144
12145		$.each( buttons, function( name, props ) {
12146			var click, buttonOptions;
12147			props = $.isFunction( props ) ?
12148				{ click: props, text: name } :
12149				props;
12150
12151			// Default to a non-submitting button
12152			props = $.extend( { type: "button" }, props );
12153
12154			// Change the context for the click callback to be the main element
12155			click = props.click;
12156			buttonOptions = {
12157				icon: props.icon,
12158				iconPosition: props.iconPosition,
12159				showLabel: props.showLabel,
12160
12161				// Deprecated options
12162				icons: props.icons,
12163				text: props.text
12164			};
12165
12166			delete props.click;
12167			delete props.icon;
12168			delete props.iconPosition;
12169			delete props.showLabel;
12170
12171			// Deprecated options
12172			delete props.icons;
12173			if ( typeof props.text === "boolean" ) {
12174				delete props.text;
12175			}
12176
12177			$( "<button></button>", props )
12178				.button( buttonOptions )
12179				.appendTo( that.uiButtonSet )
12180				.on( "click", function() {
12181					click.apply( that.element[ 0 ], arguments );
12182				} );
12183		} );
12184		this._addClass( this.uiDialog, "ui-dialog-buttons" );
12185		this.uiDialogButtonPane.appendTo( this.uiDialog );
12186	},
12187
12188	_makeDraggable: function() {
12189		var that = this,
12190			options = this.options;
12191
12192		function filteredUi( ui ) {
12193			return {
12194				position: ui.position,
12195				offset: ui.offset
12196			};
12197		}
12198
12199		this.uiDialog.draggable( {
12200			cancel: ".ui-dialog-content, .ui-dialog-titlebar-close",
12201			handle: ".ui-dialog-titlebar",
12202			containment: "document",
12203			start: function( event, ui ) {
12204				that._addClass( $( this ), "ui-dialog-dragging" );
12205				that._blockFrames();
12206				that._trigger( "dragStart", event, filteredUi( ui ) );
12207			},
12208			drag: function( event, ui ) {
12209				that._trigger( "drag", event, filteredUi( ui ) );
12210			},
12211			stop: function( event, ui ) {
12212				var left = ui.offset.left - that.document.scrollLeft(),
12213					top = ui.offset.top - that.document.scrollTop();
12214
12215				options.position = {
12216					my: "left top",
12217					at: "left" + ( left >= 0 ? "+" : "" ) + left + " " +
12218						"top" + ( top >= 0 ? "+" : "" ) + top,
12219					of: that.window
12220				};
12221				that._removeClass( $( this ), "ui-dialog-dragging" );
12222				that._unblockFrames();
12223				that._trigger( "dragStop", event, filteredUi( ui ) );
12224			}
12225		} );
12226	},
12227
12228	_makeResizable: function() {
12229		var that = this,
12230			options = this.options,
12231			handles = options.resizable,
12232
12233			// .ui-resizable has position: relative defined in the stylesheet
12234			// but dialogs have to use absolute or fixed positioning
12235			position = this.uiDialog.css( "position" ),
12236			resizeHandles = typeof handles === "string" ?
12237				handles :
12238				"n,e,s,w,se,sw,ne,nw";
12239
12240		function filteredUi( ui ) {
12241			return {
12242				originalPosition: ui.originalPosition,
12243				originalSize: ui.originalSize,
12244				position: ui.position,
12245				size: ui.size
12246			};
12247		}
12248
12249		this.uiDialog.resizable( {
12250			cancel: ".ui-dialog-content",
12251			containment: "document",
12252			alsoResize: this.element,
12253			maxWidth: options.maxWidth,
12254			maxHeight: options.maxHeight,
12255			minWidth: options.minWidth,
12256			minHeight: this._minHeight(),
12257			handles: resizeHandles,
12258			start: function( event, ui ) {
12259				that._addClass( $( this ), "ui-dialog-resizing" );
12260				that._blockFrames();
12261				that._trigger( "resizeStart", event, filteredUi( ui ) );
12262			},
12263			resize: function( event, ui ) {
12264				that._trigger( "resize", event, filteredUi( ui ) );
12265			},
12266			stop: function( event, ui ) {
12267				var offset = that.uiDialog.offset(),
12268					left = offset.left - that.document.scrollLeft(),
12269					top = offset.top - that.document.scrollTop();
12270
12271				options.height = that.uiDialog.height();
12272				options.width = that.uiDialog.width();
12273				options.position = {
12274					my: "left top",
12275					at: "left" + ( left >= 0 ? "+" : "" ) + left + " " +
12276						"top" + ( top >= 0 ? "+" : "" ) + top,
12277					of: that.window
12278				};
12279				that._removeClass( $( this ), "ui-dialog-resizing" );
12280				that._unblockFrames();
12281				that._trigger( "resizeStop", event, filteredUi( ui ) );
12282			}
12283		} )
12284			.css( "position", position );
12285	},
12286
12287	_trackFocus: function() {
12288		this._on( this.widget(), {
12289			focusin: function( event ) {
12290				this._makeFocusTarget();
12291				this._focusedElement = $( event.target );
12292			}
12293		} );
12294	},
12295
12296	_makeFocusTarget: function() {
12297		this._untrackInstance();
12298		this._trackingInstances().unshift( this );
12299	},
12300
12301	_untrackInstance: function() {
12302		var instances = this._trackingInstances(),
12303			exists = $.inArray( this, instances );
12304		if ( exists !== -1 ) {
12305			instances.splice( exists, 1 );
12306		}
12307	},
12308
12309	_trackingInstances: function() {
12310		var instances = this.document.data( "ui-dialog-instances" );
12311		if ( !instances ) {
12312			instances = [];
12313			this.document.data( "ui-dialog-instances", instances );
12314		}
12315		return instances;
12316	},
12317
12318	_minHeight: function() {
12319		var options = this.options;
12320
12321		return options.height === "auto" ?
12322			options.minHeight :
12323			Math.min( options.minHeight, options.height );
12324	},
12325
12326	_position: function() {
12327
12328		// Need to show the dialog to get the actual offset in the position plugin
12329		var isVisible = this.uiDialog.is( ":visible" );
12330		if ( !isVisible ) {
12331			this.uiDialog.show();
12332		}
12333		this.uiDialog.position( this.options.position );
12334		if ( !isVisible ) {
12335			this.uiDialog.hide();
12336		}
12337	},
12338
12339	_setOptions: function( options ) {
12340		var that = this,
12341			resize = false,
12342			resizableOptions = {};
12343
12344		$.each( options, function( key, value ) {
12345			that._setOption( key, value );
12346
12347			if ( key in that.sizeRelatedOptions ) {
12348				resize = true;
12349			}
12350			if ( key in that.resizableRelatedOptions ) {
12351				resizableOptions[ key ] = value;
12352			}
12353		} );
12354
12355		if ( resize ) {
12356			this._size();
12357			this._position();
12358		}
12359		if ( this.uiDialog.is( ":data(ui-resizable)" ) ) {
12360			this.uiDialog.resizable( "option", resizableOptions );
12361		}
12362	},
12363
12364	_setOption: function( key, value ) {
12365		var isDraggable, isResizable,
12366			uiDialog = this.uiDialog;
12367
12368		if ( key === "disabled" ) {
12369			return;
12370		}
12371
12372		this._super( key, value );
12373
12374		if ( key === "appendTo" ) {
12375			this.uiDialog.appendTo( this._appendTo() );
12376		}
12377
12378		if ( key === "buttons" ) {
12379			this._createButtons();
12380		}
12381
12382		if ( key === "closeText" ) {
12383			this.uiDialogTitlebarClose.button( {
12384
12385				// Ensure that we always pass a string
12386				label: $( "<a>" ).text( "" + this.options.closeText ).html()
12387			} );
12388		}
12389
12390		if ( key === "draggable" ) {
12391			isDraggable = uiDialog.is( ":data(ui-draggable)" );
12392			if ( isDraggable && !value ) {
12393				uiDialog.draggable( "destroy" );
12394			}
12395
12396			if ( !isDraggable && value ) {
12397				this._makeDraggable();
12398			}
12399		}
12400
12401		if ( key === "position" ) {
12402			this._position();
12403		}
12404
12405		if ( key === "resizable" ) {
12406
12407			// currently resizable, becoming non-resizable
12408			isResizable = uiDialog.is( ":data(ui-resizable)" );
12409			if ( isResizable && !value ) {
12410				uiDialog.resizable( "destroy" );
12411			}
12412
12413			// Currently resizable, changing handles
12414			if ( isResizable && typeof value === "string" ) {
12415				uiDialog.resizable( "option", "handles", value );
12416			}
12417
12418			// Currently non-resizable, becoming resizable
12419			if ( !isResizable && value !== false ) {
12420				this._makeResizable();
12421			}
12422		}
12423
12424		if ( key === "title" ) {
12425			this._title( this.uiDialogTitlebar.find( ".ui-dialog-title" ) );
12426		}
12427	},
12428
12429	_size: function() {
12430
12431		// If the user has resized the dialog, the .ui-dialog and .ui-dialog-content
12432		// divs will both have width and height set, so we need to reset them
12433		var nonContentHeight, minContentHeight, maxContentHeight,
12434			options = this.options;
12435
12436		// Reset content sizing
12437		this.element.show().css( {
12438			width: "auto",
12439			minHeight: 0,
12440			maxHeight: "none",
12441			height: 0
12442		} );
12443
12444		if ( options.minWidth > options.width ) {
12445			options.width = options.minWidth;
12446		}
12447
12448		// Reset wrapper sizing
12449		// determine the height of all the non-content elements
12450		nonContentHeight = this.uiDialog.css( {
12451			height: "auto",
12452			width: options.width
12453		} )
12454			.outerHeight();
12455		minContentHeight = Math.max( 0, options.minHeight - nonContentHeight );
12456		maxContentHeight = typeof options.maxHeight === "number" ?
12457			Math.max( 0, options.maxHeight - nonContentHeight ) :
12458			"none";
12459
12460		if ( options.height === "auto" ) {
12461			this.element.css( {
12462				minHeight: minContentHeight,
12463				maxHeight: maxContentHeight,
12464				height: "auto"
12465			} );
12466		} else {
12467			this.element.height( Math.max( 0, options.height - nonContentHeight ) );
12468		}
12469
12470		if ( this.uiDialog.is( ":data(ui-resizable)" ) ) {
12471			this.uiDialog.resizable( "option", "minHeight", this._minHeight() );
12472		}
12473	},
12474
12475	_blockFrames: function() {
12476		this.iframeBlocks = this.document.find( "iframe" ).map( function() {
12477			var iframe = $( this );
12478
12479			return $( "<div>" )
12480				.css( {
12481					position: "absolute",
12482					width: iframe.outerWidth(),
12483					height: iframe.outerHeight()
12484				} )
12485				.appendTo( iframe.parent() )
12486				.offset( iframe.offset() )[ 0 ];
12487		} );
12488	},
12489
12490	_unblockFrames: function() {
12491		if ( this.iframeBlocks ) {
12492			this.iframeBlocks.remove();
12493			delete this.iframeBlocks;
12494		}
12495	},
12496
12497	_allowInteraction: function( event ) {
12498		if ( $( event.target ).closest( ".ui-dialog" ).length ) {
12499			return true;
12500		}
12501
12502		// TODO: Remove hack when datepicker implements
12503		// the .ui-front logic (#8989)
12504		return !!$( event.target ).closest( ".ui-datepicker" ).length;
12505	},
12506
12507	_createOverlay: function() {
12508		if ( !this.options.modal ) {
12509			return;
12510		}
12511
12512		// We use a delay in case the overlay is created from an
12513		// event that we're going to be cancelling (#2804)
12514		var isOpening = true;
12515		this._delay( function() {
12516			isOpening = false;
12517		} );
12518
12519		if ( !this.document.data( "ui-dialog-overlays" ) ) {
12520
12521			// Prevent use of anchors and inputs
12522			// Using _on() for an event handler shared across many instances is
12523			// safe because the dialogs stack and must be closed in reverse order
12524			this._on( this.document, {
12525				focusin: function( event ) {
12526					if ( isOpening ) {
12527						return;
12528					}
12529
12530					if ( !this._allowInteraction( event ) ) {
12531						event.preventDefault();
12532						this._trackingInstances()[ 0 ]._focusTabbable();
12533					}
12534				}
12535			} );
12536		}
12537
12538		this.overlay = $( "<div>" )
12539			.appendTo( this._appendTo() );
12540
12541		this._addClass( this.overlay, null, "ui-widget-overlay ui-front" );
12542		this._on( this.overlay, {
12543			mousedown: "_keepFocus"
12544		} );
12545		this.document.data( "ui-dialog-overlays",
12546			( this.document.data( "ui-dialog-overlays" ) || 0 ) + 1 );
12547	},
12548
12549	_destroyOverlay: function() {
12550		if ( !this.options.modal ) {
12551			return;
12552		}
12553
12554		if ( this.overlay ) {
12555			var overlays = this.document.data( "ui-dialog-overlays" ) - 1;
12556
12557			if ( !overlays ) {
12558				this._off( this.document, "focusin" );
12559				this.document.removeData( "ui-dialog-overlays" );
12560			} else {
12561				this.document.data( "ui-dialog-overlays", overlays );
12562			}
12563
12564			this.overlay.remove();
12565			this.overlay = null;
12566		}
12567	}
12568} );
12569
12570// DEPRECATED
12571// TODO: switch return back to widget declaration at top of file when this is removed
12572if ( $.uiBackCompat !== false ) {
12573
12574	// Backcompat for dialogClass option
12575	$.widget( "ui.dialog", $.ui.dialog, {
12576		options: {
12577			dialogClass: ""
12578		},
12579		_createWrapper: function() {
12580			this._super();
12581			this.uiDialog.addClass( this.options.dialogClass );
12582		},
12583		_setOption: function( key, value ) {
12584			if ( key === "dialogClass" ) {
12585				this.uiDialog
12586					.removeClass( this.options.dialogClass )
12587					.addClass( value );
12588			}
12589			this._superApply( arguments );
12590		}
12591	} );
12592}
12593
12594var widgetsDialog = $.ui.dialog;
12595
12596
12597/*!
12598 * jQuery UI Progressbar 1.12.1
12599 * http://jqueryui.com
12600 *
12601 * Copyright jQuery Foundation and other contributors
12602 * Released under the MIT license.
12603 * http://jquery.org/license
12604 */
12605
12606//>>label: Progressbar
12607//>>group: Widgets
12608// jscs:disable maximumLineLength
12609//>>description: Displays a status indicator for loading state, standard percentage, and other progress indicators.
12610// jscs:enable maximumLineLength
12611//>>docs: http://api.jqueryui.com/progressbar/
12612//>>demos: http://jqueryui.com/progressbar/
12613//>>css.structure: ../../themes/base/core.css
12614//>>css.structure: ../../themes/base/progressbar.css
12615//>>css.theme: ../../themes/base/theme.css
12616
12617
12618
12619var widgetsProgressbar = $.widget( "ui.progressbar", {
12620	version: "1.12.1",
12621	options: {
12622		classes: {
12623			"ui-progressbar": "ui-corner-all",
12624			"ui-progressbar-value": "ui-corner-left",
12625			"ui-progressbar-complete": "ui-corner-right"
12626		},
12627		max: 100,
12628		value: 0,
12629
12630		change: null,
12631		complete: null
12632	},
12633
12634	min: 0,
12635
12636	_create: function() {
12637
12638		// Constrain initial value
12639		this.oldValue = this.options.value = this._constrainedValue();
12640
12641		this.element.attr( {
12642
12643			// Only set static values; aria-valuenow and aria-valuemax are
12644			// set inside _refreshValue()
12645			role: "progressbar",
12646			"aria-valuemin": this.min
12647		} );
12648		this._addClass( "ui-progressbar", "ui-widget ui-widget-content" );
12649
12650		this.valueDiv = $( "<div>" ).appendTo( this.element );
12651		this._addClass( this.valueDiv, "ui-progressbar-value", "ui-widget-header" );
12652		this._refreshValue();
12653	},
12654
12655	_destroy: function() {
12656		this.element.removeAttr( "role aria-valuemin aria-valuemax aria-valuenow" );
12657
12658		this.valueDiv.remove();
12659	},
12660
12661	value: function( newValue ) {
12662		if ( newValue === undefined ) {
12663			return this.options.value;
12664		}
12665
12666		this.options.value = this._constrainedValue( newValue );
12667		this._refreshValue();
12668	},
12669
12670	_constrainedValue: function( newValue ) {
12671		if ( newValue === undefined ) {
12672			newValue = this.options.value;
12673		}
12674
12675		this.indeterminate = newValue === false;
12676
12677		// Sanitize value
vendor: 5,900 bytes, lines 12678-12907
12678		if ( typeof newValue !== "number" ) {
12679			newValue = 0;
12680		}
12681
12682		return this.indeterminate ? false :
12683			Math.min( this.options.max, Math.max( this.min, newValue ) );
12684	},
12685
12686	_setOptions: function( options ) {
12687
12688		// Ensure "value" option is set after other values (like max)
12689		var value = options.value;
12690		delete options.value;
12691
12692		this._super( options );
12693
12694		this.options.value = this._constrainedValue( value );
12695		this._refreshValue();
12696	},
12697
12698	_setOption: function( key, value ) {
12699		if ( key === "max" ) {
12700
12701			// Don't allow a max less than min
12702			value = Math.max( this.min, value );
12703		}
12704		this._super( key, value );
12705	},
12706
12707	_setOptionDisabled: function( value ) {
12708		this._super( value );
12709
12710		this.element.attr( "aria-disabled", value );
12711		this._toggleClass( null, "ui-state-disabled", !!value );
12712	},
12713
12714	_percentage: function() {
12715		return this.indeterminate ?
12716			100 :
12717			100 * ( this.options.value - this.min ) / ( this.options.max - this.min );
12718	},
12719
12720	_refreshValue: function() {
12721		var value = this.options.value,
12722			percentage = this._percentage();
12723
12724		this.valueDiv
12725			.toggle( this.indeterminate || value > this.min )
12726			.width( percentage.toFixed( 0 ) + "%" );
12727
12728		this
12729			._toggleClass( this.valueDiv, "ui-progressbar-complete", null,
12730				value === this.options.max )
12731			._toggleClass( "ui-progressbar-indeterminate", null, this.indeterminate );
12732
12733		if ( this.indeterminate ) {
12734			this.element.removeAttr( "aria-valuenow" );
12735			if ( !this.overlayDiv ) {
12736				this.overlayDiv = $( "<div>" ).appendTo( this.valueDiv );
12737				this._addClass( this.overlayDiv, "ui-progressbar-overlay" );
12738			}
12739		} else {
12740			this.element.attr( {
12741				"aria-valuemax": this.options.max,
12742				"aria-valuenow": value
12743			} );
12744			if ( this.overlayDiv ) {
12745				this.overlayDiv.remove();
12746				this.overlayDiv = null;
12747			}
12748		}
12749
12750		if ( this.oldValue !== value ) {
12751			this.oldValue = value;
12752			this._trigger( "change" );
12753		}
12754		if ( value === this.options.max ) {
12755			this._trigger( "complete" );
12756		}
12757	}
12758} );
12759
12760
12761/*!
12762 * jQuery UI Selectmenu 1.12.1
12763 * http://jqueryui.com
12764 *
12765 * Copyright jQuery Foundation and other contributors
12766 * Released under the MIT license.
12767 * http://jquery.org/license
12768 */
12769
12770//>>label: Selectmenu
12771//>>group: Widgets
12772// jscs:disable maximumLineLength
12773//>>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.
12774// jscs:enable maximumLineLength
12775//>>docs: http://api.jqueryui.com/selectmenu/
12776//>>demos: http://jqueryui.com/selectmenu/
12777//>>css.structure: ../../themes/base/core.css
12778//>>css.structure: ../../themes/base/selectmenu.css, ../../themes/base/button.css
12779//>>css.theme: ../../themes/base/theme.css
12780
12781
12782
12783var widgetsSelectmenu = $.widget( "ui.selectmenu", [ $.ui.formResetMixin, {
12784	version: "1.12.1",
12785	defaultElement: "<select>",
12786	options: {
12787		appendTo: null,
12788		classes: {
12789			"ui-selectmenu-button-open": "ui-corner-top",
12790			"ui-selectmenu-button-closed": "ui-corner-all"
12791		},
12792		disabled: null,
12793		icons: {
12794			button: "ui-icon-triangle-1-s"
12795		},
12796		position: {
12797			my: "left top",
12798			at: "left bottom",
12799			collision: "none"
12800		},
12801		width: false,
12802
12803		// Callbacks
12804		change: null,
12805		close: null,
12806		focus: null,
12807		open: null,
12808		select: null
12809	},
12810
12811	_create: function() {
12812		var selectmenuId = this.element.uniqueId().attr( "id" );
12813		this.ids = {
12814			element: selectmenuId,
12815			button: selectmenuId + "-button",
12816			menu: selectmenuId + "-menu"
12817		};
12818
12819		this._drawButton();
12820		this._drawMenu();
12821		this._bindFormResetHandler();
12822
12823		this._rendered = false;
12824		this.menuItems = $();
12825	},
12826
12827	_drawButton: function() {
12828		var icon,
12829			that = this,
12830			item = this._parseOption(
12831				this.element.find( "option:selected" ),
12832				this.element[ 0 ].selectedIndex
12833			);
12834
12835		// Associate existing label with the new button
12836		this.labels = this.element.labels().attr( "for", this.ids.button );
12837		this._on( this.labels, {
12838			click: function( event ) {
12839				this.button.focus();
12840				event.preventDefault();
12841			}
12842		} );
12843
12844		// Hide original select element
12845		this.element.hide();
12846
12847		// Create button
12848		this.button = $( "<span>", {
12849			tabindex: this.options.disabled ? -1 : 0,
12850			id: this.ids.button,
12851			role: "combobox",
12852			"aria-expanded": "false",
12853			"aria-autocomplete": "list",
12854			"aria-owns": this.ids.menu,
12855			"aria-haspopup": "true",
12856			title: this.element.attr( "title" )
12857		} )
12858			.insertAfter( this.element );
12859
12860		this._addClass( this.button, "ui-selectmenu-button ui-selectmenu-button-closed",
12861			"ui-button ui-widget" );
12862
12863		icon = $( "<span>" ).appendTo( this.button );
12864		this._addClass( icon, "ui-selectmenu-icon", "ui-icon " + this.options.icons.button );
12865		this.buttonItem = this._renderButtonItem( item )
12866			.appendTo( this.button );
12867
12868		if ( this.options.width !== false ) {
12869			this._resizeButton();
12870		}
12871
12872		this._on( this.button, this._buttonEvents );
12873		this.button.one( "focusin", function() {
12874
12875			// Delay rendering the menu items until the button receives focus.
12876			// The menu may have already been rendered via a programmatic open.
12877			if ( !that._rendered ) {
12878				that._refreshMenu();
12879			}
12880		} );
12881	},
12882
12883	_drawMenu: function() {
12884		var that = this;
12885
12886		// Create menu
12887		this.menu = $( "<ul>", {
12888			"aria-hidden": "true",
12889			"aria-labelledby": this.ids.button,
12890			id: this.ids.menu
12891		} );
12892
12893		// Wrap menu
12894		this.menuWrap = $( "<div>" ).append( this.menu );
12895		this._addClass( this.menuWrap, "ui-selectmenu-menu", "ui-front" );
12896		this.menuWrap.appendTo( this._appendTo() );
12897
12898		// Initialize menu widget
12899		this.menuInstance = this.menu
12900			.menu( {
12901				classes: {
12902					"ui-menu": "ui-corner-bottom"
12903				},
12904				role: "listbox",
12905				select: function( event, ui ) {
12906					event.preventDefault();
12907
vendor: 11,520 bytes, lines 12908-13378
12908					// Support: IE8
12909					// If the item was selected via a click, the text selection
12910					// will be destroyed in IE
12911					that._setSelection();
12912
12913					that._select( ui.item.data( "ui-selectmenu-item" ), event );
12914				},
12915				focus: function( event, ui ) {
12916					var item = ui.item.data( "ui-selectmenu-item" );
12917
12918					// Prevent inital focus from firing and check if its a newly focused item
12919					if ( that.focusIndex != null && item.index !== that.focusIndex ) {
12920						that._trigger( "focus", event, { item: item } );
12921						if ( !that.isOpen ) {
12922							that._select( item, event );
12923						}
12924					}
12925					that.focusIndex = item.index;
12926
12927					that.button.attr( "aria-activedescendant",
12928						that.menuItems.eq( item.index ).attr( "id" ) );
12929				}
12930			} )
12931			.menu( "instance" );
12932
12933		// Don't close the menu on mouseleave
12934		this.menuInstance._off( this.menu, "mouseleave" );
12935
12936		// Cancel the menu's collapseAll on document click
12937		this.menuInstance._closeOnDocumentClick = function() {
12938			return false;
12939		};
12940
12941		// Selects often contain empty items, but never contain dividers
12942		this.menuInstance._isDivider = function() {
12943			return false;
12944		};
12945	},
12946
12947	refresh: function() {
12948		this._refreshMenu();
12949		this.buttonItem.replaceWith(
12950			this.buttonItem = this._renderButtonItem(
12951
12952				// Fall back to an empty object in case there are no options
12953				this._getSelectedItem().data( "ui-selectmenu-item" ) || {}
12954			)
12955		);
12956		if ( this.options.width === null ) {
12957			this._resizeButton();
12958		}
12959	},
12960
12961	_refreshMenu: function() {
12962		var item,
12963			options = this.element.find( "option" );
12964
12965		this.menu.empty();
12966
12967		this._parseOptions( options );
12968		this._renderMenu( this.menu, this.items );
12969
12970		this.menuInstance.refresh();
12971		this.menuItems = this.menu.find( "li" )
12972			.not( ".ui-selectmenu-optgroup" )
12973				.find( ".ui-menu-item-wrapper" );
12974
12975		this._rendered = true;
12976
12977		if ( !options.length ) {
12978			return;
12979		}
12980
12981		item = this._getSelectedItem();
12982
12983		// Update the menu to have the correct item focused
12984		this.menuInstance.focus( null, item );
12985		this._setAria( item.data( "ui-selectmenu-item" ) );
12986
12987		// Set disabled state
12988		this._setOption( "disabled", this.element.prop( "disabled" ) );
12989	},
12990
12991	open: function( event ) {
12992		if ( this.options.disabled ) {
12993			return;
12994		}
12995
12996		// If this is the first time the menu is being opened, render the items
12997		if ( !this._rendered ) {
12998			this._refreshMenu();
12999		} else {
13000
13001			// Menu clears focus on close, reset focus to selected item
13002			this._removeClass( this.menu.find( ".ui-state-active" ), null, "ui-state-active" );
13003			this.menuInstance.focus( null, this._getSelectedItem() );
13004		}
13005
13006		// If there are no options, don't open the menu
13007		if ( !this.menuItems.length ) {
13008			return;
13009		}
13010
13011		this.isOpen = true;
13012		this._toggleAttr();
13013		this._resizeMenu();
13014		this._position();
13015
13016		this._on( this.document, this._documentClick );
13017
13018		this._trigger( "open", event );
13019	},
13020
13021	_position: function() {
13022		this.menuWrap.position( $.extend( { of: this.button }, this.options.position ) );
13023	},
13024
13025	close: function( event ) {
13026		if ( !this.isOpen ) {
13027			return;
13028		}
13029
13030		this.isOpen = false;
13031		this._toggleAttr();
13032
13033		this.range = null;
13034		this._off( this.document );
13035
13036		this._trigger( "close", event );
13037	},
13038
13039	widget: function() {
13040		return this.button;
13041	},
13042
13043	menuWidget: function() {
13044		return this.menu;
13045	},
13046
13047	_renderButtonItem: function( item ) {
13048		var buttonItem = $( "<span>" );
13049
13050		this._setText( buttonItem, item.label );
13051		this._addClass( buttonItem, "ui-selectmenu-text" );
13052
13053		return buttonItem;
13054	},
13055
13056	_renderMenu: function( ul, items ) {
13057		var that = this,
13058			currentOptgroup = "";
13059
13060		$.each( items, function( index, item ) {
13061			var li;
13062
13063			if ( item.optgroup !== currentOptgroup ) {
13064				li = $( "<li>", {
13065					text: item.optgroup
13066				} );
13067				that._addClass( li, "ui-selectmenu-optgroup", "ui-menu-divider" +
13068					( item.element.parent( "optgroup" ).prop( "disabled" ) ?
13069						" ui-state-disabled" :
13070						"" ) );
13071
13072				li.appendTo( ul );
13073
13074				currentOptgroup = item.optgroup;
13075			}
13076
13077			that._renderItemData( ul, item );
13078		} );
13079	},
13080
13081	_renderItemData: function( ul, item ) {
13082		return this._renderItem( ul, item ).data( "ui-selectmenu-item", item );
13083	},
13084
13085	_renderItem: function( ul, item ) {
13086		var li = $( "<li>" ),
13087			wrapper = $( "<div>", {
13088				title: item.element.attr( "title" )
13089			} );
13090
13091		if ( item.disabled ) {
13092			this._addClass( li, null, "ui-state-disabled" );
13093		}
13094		this._setText( wrapper, item.label );
13095
13096		return li.append( wrapper ).appendTo( ul );
13097	},
13098
13099	_setText: function( element, value ) {
13100		if ( value ) {
13101			element.text( value );
13102		} else {
13103			element.html( "&#160;" );
13104		}
13105	},
13106
13107	_move: function( direction, event ) {
13108		var item, next,
13109			filter = ".ui-menu-item";
13110
13111		if ( this.isOpen ) {
13112			item = this.menuItems.eq( this.focusIndex ).parent( "li" );
13113		} else {
13114			item = this.menuItems.eq( this.element[ 0 ].selectedIndex ).parent( "li" );
13115			filter += ":not(.ui-state-disabled)";
13116		}
13117
13118		if ( direction === "first" || direction === "last" ) {
13119			next = item[ direction === "first" ? "prevAll" : "nextAll" ]( filter ).eq( -1 );
13120		} else {
13121			next = item[ direction + "All" ]( filter ).eq( 0 );
13122		}
13123
13124		if ( next.length ) {
13125			this.menuInstance.focus( event, next );
13126		}
13127	},
13128
13129	_getSelectedItem: function() {
13130		return this.menuItems.eq( this.element[ 0 ].selectedIndex ).parent( "li" );
13131	},
13132
13133	_toggle: function( event ) {
13134		this[ this.isOpen ? "close" : "open" ]( event );
13135	},
13136
13137	_setSelection: function() {
13138		var selection;
13139
13140		if ( !this.range ) {
13141			return;
13142		}
13143
13144		if ( window.getSelection ) {
13145			selection = window.getSelection();
13146			selection.removeAllRanges();
13147			selection.addRange( this.range );
13148
13149		// Support: IE8
13150		} else {
13151			this.range.select();
13152		}
13153
13154		// Support: IE
13155		// Setting the text selection kills the button focus in IE, but
13156		// restoring the focus doesn't kill the selection.
13157		this.button.focus();
13158	},
13159
13160	_documentClick: {
13161		mousedown: function( event ) {
13162			if ( !this.isOpen ) {
13163				return;
13164			}
13165
13166			if ( !$( event.target ).closest( ".ui-selectmenu-menu, #" +
13167					$.ui.escapeSelector( this.ids.button ) ).length ) {
13168				this.close( event );
13169			}
13170		}
13171	},
13172
13173	_buttonEvents: {
13174
13175		// Prevent text selection from being reset when interacting with the selectmenu (#10144)
13176		mousedown: function() {
13177			var selection;
13178
13179			if ( window.getSelection ) {
13180				selection = window.getSelection();
13181				if ( selection.rangeCount ) {
13182					this.range = selection.getRangeAt( 0 );
13183				}
13184
13185			// Support: IE8
13186			} else {
13187				this.range = document.selection.createRange();
13188			}
13189		},
13190
13191		click: function( event ) {
13192			this._setSelection();
13193			this._toggle( event );
13194		},
13195
13196		keydown: function( event ) {
13197			var preventDefault = true;
13198			switch ( event.keyCode ) {
13199			case $.ui.keyCode.TAB:
13200			case $.ui.keyCode.ESCAPE:
13201				this.close( event );
13202				preventDefault = false;
13203				break;
13204			case $.ui.keyCode.ENTER:
13205				if ( this.isOpen ) {
13206					this._selectFocusedItem( event );
13207				}
13208				break;
13209			case $.ui.keyCode.UP:
13210				if ( event.altKey ) {
13211					this._toggle( event );
13212				} else {
13213					this._move( "prev", event );
13214				}
13215				break;
13216			case $.ui.keyCode.DOWN:
13217				if ( event.altKey ) {
13218					this._toggle( event );
13219				} else {
13220					this._move( "next", event );
13221				}
13222				break;
13223			case $.ui.keyCode.SPACE:
13224				if ( this.isOpen ) {
13225					this._selectFocusedItem( event );
13226				} else {
13227					this._toggle( event );
13228				}
13229				break;
13230			case $.ui.keyCode.LEFT:
13231				this._move( "prev", event );
13232				break;
13233			case $.ui.keyCode.RIGHT:
13234				this._move( "next", event );
13235				break;
13236			case $.ui.keyCode.HOME:
13237			case $.ui.keyCode.PAGE_UP:
13238				this._move( "first", event );
13239				break;
13240			case $.ui.keyCode.END:
13241			case $.ui.keyCode.PAGE_DOWN:
13242				this._move( "last", event );
13243				break;
13244			default:
13245				this.menu.trigger( event );
13246				preventDefault = false;
13247			}
13248
13249			if ( preventDefault ) {
13250				event.preventDefault();
13251			}
13252		}
13253	},
13254
13255	_selectFocusedItem: function( event ) {
13256		var item = this.menuItems.eq( this.focusIndex ).parent( "li" );
13257		if ( !item.hasClass( "ui-state-disabled" ) ) {
13258			this._select( item.data( "ui-selectmenu-item" ), event );
13259		}
13260	},
13261
13262	_select: function( item, event ) {
13263		var oldIndex = this.element[ 0 ].selectedIndex;
13264
13265		// Change native select element
13266		this.element[ 0 ].selectedIndex = item.index;
13267		this.buttonItem.replaceWith( this.buttonItem = this._renderButtonItem( item ) );
13268		this._setAria( item );
13269		this._trigger( "select", event, { item: item } );
13270
13271		if ( item.index !== oldIndex ) {
13272			this._trigger( "change", event, { item: item } );
13273		}
13274
13275		this.close( event );
13276	},
13277
13278	_setAria: function( item ) {
13279		var id = this.menuItems.eq( item.index ).attr( "id" );
13280
13281		this.button.attr( {
13282			"aria-labelledby": id,
13283			"aria-activedescendant": id
13284		} );
13285		this.menu.attr( "aria-activedescendant", id );
13286	},
13287
13288	_setOption: function( key, value ) {
13289		if ( key === "icons" ) {
13290			var icon = this.button.find( "span.ui-icon" );
13291			this._removeClass( icon, null, this.options.icons.button )
13292				._addClass( icon, null, value.button );
13293		}
13294
13295		this._super( key, value );
13296
13297		if ( key === "appendTo" ) {
13298			this.menuWrap.appendTo( this._appendTo() );
13299		}
13300
13301		if ( key === "width" ) {
13302			this._resizeButton();
13303		}
13304	},
13305
13306	_setOptionDisabled: function( value ) {
13307		this._super( value );
13308
13309		this.menuInstance.option( "disabled", value );
13310		this.button.attr( "aria-disabled", value );
13311		this._toggleClass( this.button, null, "ui-state-disabled", value );
13312
13313		this.element.prop( "disabled", value );
13314		if ( value ) {
13315			this.button.attr( "tabindex", -1 );
13316			this.close();
13317		} else {
13318			this.button.attr( "tabindex", 0 );
13319		}
13320	},
13321
13322	_appendTo: function() {
13323		var element = this.options.appendTo;
13324
13325		if ( element ) {
13326			element = element.jquery || element.nodeType ?
13327				$( element ) :
13328				this.document.find( element ).eq( 0 );
13329		}
13330
13331		if ( !element || !element[ 0 ] ) {
13332			element = this.element.closest( ".ui-front, dialog" );
13333		}
13334
13335		if ( !element.length ) {
13336			element = this.document[ 0 ].body;
13337		}
13338
13339		return element;
13340	},
13341
13342	_toggleAttr: function() {
13343		this.button.attr( "aria-expanded", this.isOpen );
13344
13345		// We can't use two _toggleClass() calls here, because we need to make sure
13346		// we always remove classes first and add them second, otherwise if both classes have the
13347		// same theme class, it will be removed after we add it.
13348		this._removeClass( this.button, "ui-selectmenu-button-" +
13349			( this.isOpen ? "closed" : "open" ) )
13350			._addClass( this.button, "ui-selectmenu-button-" +
13351				( this.isOpen ? "open" : "closed" ) )
13352			._toggleClass( this.menuWrap, "ui-selectmenu-open", null, this.isOpen );
13353
13354		this.menu.attr( "aria-hidden", !this.isOpen );
13355	},
13356
13357	_resizeButton: function() {
13358		var width = this.options.width;
13359
13360		// For `width: false`, just remove inline style and stop
13361		if ( width === false ) {
13362			this.button.css( "width", "" );
13363			return;
13364		}
13365
13366		// For `width: null`, match the width of the original element
13367		if ( width === null ) {
13368			width = this.element.show().outerWidth();
13369			this.element.hide();
13370		}
13371
13372		this.button.outerWidth( width );
13373	},
13374
13375	_resizeMenu: function() {
13376		this.menu.outerWidth( Math.max(
13377			this.button.outerWidth(),
13378
vendor: 5,390 bytes, lines 13379-13592
13379			// Support: IE10
13380			// IE10 wraps long text (possibly a rounding bug)
13381			// so we add 1px to avoid the wrapping
13382			this.menu.width( "" ).outerWidth() + 1
13383		) );
13384	},
13385
13386	_getCreateOptions: function() {
13387		var options = this._super();
13388
13389		options.disabled = this.element.prop( "disabled" );
13390
13391		return options;
13392	},
13393
13394	_parseOptions: function( options ) {
13395		var that = this,
13396			data = [];
13397		options.each( function( index, item ) {
13398			data.push( that._parseOption( $( item ), index ) );
13399		} );
13400		this.items = data;
13401	},
13402
13403	_parseOption: function( option, index ) {
13404		var optgroup = option.parent( "optgroup" );
13405
13406		return {
13407			element: option,
13408			index: index,
13409			value: option.val(),
13410			label: option.text(),
13411			optgroup: optgroup.attr( "label" ) || "",
13412			disabled: optgroup.prop( "disabled" ) || option.prop( "disabled" )
13413		};
13414	},
13415
13416	_destroy: function() {
13417		this._unbindFormResetHandler();
13418		this.menuWrap.remove();
13419		this.button.remove();
13420		this.element.show();
13421		this.element.removeUniqueId();
13422		this.labels.attr( "for", this.ids.element );
13423	}
13424} ] );
13425
13426
13427/*!
13428 * jQuery UI Slider 1.12.1
13429 * http://jqueryui.com
13430 *
13431 * Copyright jQuery Foundation and other contributors
13432 * Released under the MIT license.
13433 * http://jquery.org/license
13434 */
13435
13436//>>label: Slider
13437//>>group: Widgets
13438//>>description: Displays a flexible slider with ranges and accessibility via keyboard.
13439//>>docs: http://api.jqueryui.com/slider/
13440//>>demos: http://jqueryui.com/slider/
13441//>>css.structure: ../../themes/base/core.css
13442//>>css.structure: ../../themes/base/slider.css
13443//>>css.theme: ../../themes/base/theme.css
13444
13445
13446
13447var widgetsSlider = $.widget( "ui.slider", $.ui.mouse, {
13448	version: "1.12.1",
13449	widgetEventPrefix: "slide",
13450
13451	options: {
13452		animate: false,
13453		classes: {
13454			"ui-slider": "ui-corner-all",
13455			"ui-slider-handle": "ui-corner-all",
13456
13457			// Note: ui-widget-header isn't the most fittingly semantic framework class for this
13458			// element, but worked best visually with a variety of themes
13459			"ui-slider-range": "ui-corner-all ui-widget-header"
13460		},
13461		distance: 0,
13462		max: 100,
13463		min: 0,
13464		orientation: "horizontal",
13465		range: false,
13466		step: 1,
13467		value: 0,
13468		values: null,
13469
13470		// Callbacks
13471		change: null,
13472		slide: null,
13473		start: null,
13474		stop: null
13475	},
13476
13477	// Number of pages in a slider
13478	// (how many times can you page up/down to go through the whole range)
13479	numPages: 5,
13480
13481	_create: function() {
13482		this._keySliding = false;
13483		this._mouseSliding = false;
13484		this._animateOff = true;
13485		this._handleIndex = null;
13486		this._detectOrientation();
13487		this._mouseInit();
13488		this._calculateNewMax();
13489
13490		this._addClass( "ui-slider ui-slider-" + this.orientation,
13491			"ui-widget ui-widget-content" );
13492
13493		this._refresh();
13494
13495		this._animateOff = false;
13496	},
13497
13498	_refresh: function() {
13499		this._createRange();
13500		this._createHandles();
13501		this._setupEvents();
13502		this._refreshValue();
13503	},
13504
13505	_createHandles: function() {
13506		var i, handleCount,
13507			options = this.options,
13508			existingHandles = this.element.find( ".ui-slider-handle" ),
13509			handle = "<span tabindex='0'></span>",
13510			handles = [];
13511
13512		handleCount = ( options.values && options.values.length ) || 1;
13513
13514		if ( existingHandles.length > handleCount ) {
13515			existingHandles.slice( handleCount ).remove();
13516			existingHandles = existingHandles.slice( 0, handleCount );
13517		}
13518
13519		for ( i = existingHandles.length; i < handleCount; i++ ) {
13520			handles.push( handle );
13521		}
13522
13523		this.handles = existingHandles.add( $( handles.join( "" ) ).appendTo( this.element ) );
13524
13525		this._addClass( this.handles, "ui-slider-handle", "ui-state-default" );
13526
13527		this.handle = this.handles.eq( 0 );
13528
13529		this.handles.each( function( i ) {
13530			$( this )
13531				.data( "ui-slider-handle-index", i )
13532				.attr( "tabIndex", 0 );
13533		} );
13534	},
13535
13536	_createRange: function() {
13537		var options = this.options;
13538
13539		if ( options.range ) {
13540			if ( options.range === true ) {
13541				if ( !options.values ) {
13542					options.values = [ this._valueMin(), this._valueMin() ];
13543				} else if ( options.values.length && options.values.length !== 2 ) {
13544					options.values = [ options.values[ 0 ], options.values[ 0 ] ];
13545				} else if ( $.isArray( options.values ) ) {
13546					options.values = options.values.slice( 0 );
13547				}
13548			}
13549
13550			if ( !this.range || !this.range.length ) {
13551				this.range = $( "<div>" )
13552					.appendTo( this.element );
13553
13554				this._addClass( this.range, "ui-slider-range" );
13555			} else {
13556				this._removeClass( this.range, "ui-slider-range-min ui-slider-range-max" );
13557
13558				// Handle range switching from true to min/max
13559				this.range.css( {
13560					"left": "",
13561					"bottom": ""
13562				} );
13563			}
13564			if ( options.range === "min" || options.range === "max" ) {
13565				this._addClass( this.range, "ui-slider-range-" + options.range );
13566			}
13567		} else {
13568			if ( this.range ) {
13569				this.range.remove();
13570			}
13571			this.range = null;
13572		}
13573	},
13574
13575	_setupEvents: function() {
13576		this._off( this.handles );
13577		this._on( this.handles, this._handleEvents );
13578		this._hoverable( this.handles );
13579		this._focusable( this.handles );
13580	},
13581
13582	_destroy: function() {
13583		this.handles.remove();
13584		if ( this.range ) {
13585			this.range.remove();
13586		}
13587
13588		this._mouseDestroy();
13589	},
13590
13591	_mouseCapture: function( event ) {
13592		var position, normValue, distance, closestHandle, index, allowed, offset, mou
vendor: 15,708 bytes, lines 13592-14163
13592seOverHandle,
13593			that = this,
13594			o = this.options;
13595
13596		if ( o.disabled ) {
13597			return false;
13598		}
13599
13600		this.elementSize = {
13601			width: this.element.outerWidth(),
13602			height: this.element.outerHeight()
13603		};
13604		this.elementOffset = this.element.offset();
13605
13606		position = { x: event.pageX, y: event.pageY };
13607		normValue = this._normValueFromMouse( position );
13608		distance = this._valueMax() - this._valueMin() + 1;
13609		this.handles.each( function( i ) {
13610			var thisDistance = Math.abs( normValue - that.values( i ) );
13611			if ( ( distance > thisDistance ) ||
13612				( distance === thisDistance &&
13613					( i === that._lastChangedValue || that.values( i ) === o.min ) ) ) {
13614				distance = thisDistance;
13615				closestHandle = $( this );
13616				index = i;
13617			}
13618		} );
13619
13620		allowed = this._start( event, index );
13621		if ( allowed === false ) {
13622			return false;
13623		}
13624		this._mouseSliding = true;
13625
13626		this._handleIndex = index;
13627
13628		this._addClass( closestHandle, null, "ui-state-active" );
13629		closestHandle.trigger( "focus" );
13630
13631		offset = closestHandle.offset();
13632		mouseOverHandle = !$( event.target ).parents().addBack().is( ".ui-slider-handle" );
13633		this._clickOffset = mouseOverHandle ? { left: 0, top: 0 } : {
13634			left: event.pageX - offset.left - ( closestHandle.width() / 2 ),
13635			top: event.pageY - offset.top -
13636				( closestHandle.height() / 2 ) -
13637				( parseInt( closestHandle.css( "borderTopWidth" ), 10 ) || 0 ) -
13638				( parseInt( closestHandle.css( "borderBottomWidth" ), 10 ) || 0 ) +
13639				( parseInt( closestHandle.css( "marginTop" ), 10 ) || 0 )
13640		};
13641
13642		if ( !this.handles.hasClass( "ui-state-hover" ) ) {
13643			this._slide( event, index, normValue );
13644		}
13645		this._animateOff = true;
13646		return true;
13647	},
13648
13649	_mouseStart: function() {
13650		return true;
13651	},
13652
13653	_mouseDrag: function( event ) {
13654		var position = { x: event.pageX, y: event.pageY },
13655			normValue = this._normValueFromMouse( position );
13656
13657		this._slide( event, this._handleIndex, normValue );
13658
13659		return false;
13660	},
13661
13662	_mouseStop: function( event ) {
13663		this._removeClass( this.handles, null, "ui-state-active" );
13664		this._mouseSliding = false;
13665
13666		this._stop( event, this._handleIndex );
13667		this._change( event, this._handleIndex );
13668
13669		this._handleIndex = null;
13670		this._clickOffset = null;
13671		this._animateOff = false;
13672
13673		return false;
13674	},
13675
13676	_detectOrientation: function() {
13677		this.orientation = ( this.options.orientation === "vertical" ) ? "vertical" : "horizontal";
13678	},
13679
13680	_normValueFromMouse: function( position ) {
13681		var pixelTotal,
13682			pixelMouse,
13683			percentMouse,
13684			valueTotal,
13685			valueMouse;
13686
13687		if ( this.orientation === "horizontal" ) {
13688			pixelTotal = this.elementSize.width;
13689			pixelMouse = position.x - this.elementOffset.left -
13690				( this._clickOffset ? this._clickOffset.left : 0 );
13691		} else {
13692			pixelTotal = this.elementSize.height;
13693			pixelMouse = position.y - this.elementOffset.top -
13694				( this._clickOffset ? this._clickOffset.top : 0 );
13695		}
13696
13697		percentMouse = ( pixelMouse / pixelTotal );
13698		if ( percentMouse > 1 ) {
13699			percentMouse = 1;
13700		}
13701		if ( percentMouse < 0 ) {
13702			percentMouse = 0;
13703		}
13704		if ( this.orientation === "vertical" ) {
13705			percentMouse = 1 - percentMouse;
13706		}
13707
13708		valueTotal = this._valueMax() - this._valueMin();
13709		valueMouse = this._valueMin() + percentMouse * valueTotal;
13710
13711		return this._trimAlignValue( valueMouse );
13712	},
13713
13714	_uiHash: function( index, value, values ) {
13715		var uiHash = {
13716			handle: this.handles[ index ],
13717			handleIndex: index,
13718			value: value !== undefined ? value : this.value()
13719		};
13720
13721		if ( this._hasMultipleValues() ) {
13722			uiHash.value = value !== undefined ? value : this.values( index );
13723			uiHash.values = values || this.values();
13724		}
13725
13726		return uiHash;
13727	},
13728
13729	_hasMultipleValues: function() {
13730		return this.options.values && this.options.values.length;
13731	},
13732
13733	_start: function( event, index ) {
13734		return this._trigger( "start", event, this._uiHash( index ) );
13735	},
13736
13737	_slide: function( event, index, newVal ) {
13738		var allowed, otherVal,
13739			currentValue = this.value(),
13740			newValues = this.values();
13741
13742		if ( this._hasMultipleValues() ) {
13743			otherVal = this.values( index ? 0 : 1 );
13744			currentValue = this.values( index );
13745
13746			if ( this.options.values.length === 2 && this.options.range === true ) {
13747				newVal =  index === 0 ? Math.min( otherVal, newVal ) : Math.max( otherVal, newVal );
13748			}
13749
13750			newValues[ index ] = newVal;
13751		}
13752
13753		if ( newVal === currentValue ) {
13754			return;
13755		}
13756
13757		allowed = this._trigger( "slide", event, this._uiHash( index, newVal, newValues ) );
13758
13759		// A slide can be canceled by returning false from the slide callback
13760		if ( allowed === false ) {
13761			return;
13762		}
13763
13764		if ( this._hasMultipleValues() ) {
13765			this.values( index, newVal );
13766		} else {
13767			this.value( newVal );
13768		}
13769	},
13770
13771	_stop: function( event, index ) {
13772		this._trigger( "stop", event, this._uiHash( index ) );
13773	},
13774
13775	_change: function( event, index ) {
13776		if ( !this._keySliding && !this._mouseSliding ) {
13777
13778			//store the last changed value index for reference when handles overlap
13779			this._lastChangedValue = index;
13780			this._trigger( "change", event, this._uiHash( index ) );
13781		}
13782	},
13783
13784	value: function( newValue ) {
13785		if ( arguments.length ) {
13786			this.options.value = this._trimAlignValue( newValue );
13787			this._refreshValue();
13788			this._change( null, 0 );
13789			return;
13790		}
13791
13792		return this._value();
13793	},
13794
13795	values: function( index, newValue ) {
13796		var vals,
13797			newValues,
13798			i;
13799
13800		if ( arguments.length > 1 ) {
13801			this.options.values[ index ] = this._trimAlignValue( newValue );
13802			this._refreshValue();
13803			this._change( null, index );
13804			return;
13805		}
13806
13807		if ( arguments.length ) {
13808			if ( $.isArray( arguments[ 0 ] ) ) {
13809				vals = this.options.values;
13810				newValues = arguments[ 0 ];
13811				for ( i = 0; i < vals.length; i += 1 ) {
13812					vals[ i ] = this._trimAlignValue( newValues[ i ] );
13813					this._change( null, i );
13814				}
13815				this._refreshValue();
13816			} else {
13817				if ( this._hasMultipleValues() ) {
13818					return this._values( index );
13819				} else {
13820					return this.value();
13821				}
13822			}
13823		} else {
13824			return this._values();
13825		}
13826	},
13827
13828	_setOption: function( key, value ) {
13829		var i,
13830			valsLength = 0;
13831
13832		if ( key === "range" && this.options.range === true ) {
13833			if ( value === "min" ) {
13834				this.options.value = this._values( 0 );
13835				this.options.values = null;
13836			} else if ( value === "max" ) {
13837				this.options.value = this._values( this.options.values.length - 1 );
13838				this.options.values = null;
13839			}
13840		}
13841
13842		if ( $.isArray( this.options.values ) ) {
13843			valsLength = this.options.values.length;
13844		}
13845
13846		this._super( key, value );
13847
13848		switch ( key ) {
13849			case "orientation":
13850				this._detectOrientation();
13851				this._removeClass( "ui-slider-horizontal ui-slider-vertical" )
13852					._addClass( "ui-slider-" + this.orientation );
13853				this._refreshValue();
13854				if ( this.options.range ) {
13855					this._refreshRange( value );
13856				}
13857
13858				// Reset positioning from previous orientation
13859				this.handles.css( value === "horizontal" ? "bottom" : "left", "" );
13860				break;
13861			case "value":
13862				this._animateOff = true;
13863				this._refreshValue();
13864				this._change( null, 0 );
13865				this._animateOff = false;
13866				break;
13867			case "values":
13868				this._animateOff = true;
13869				this._refreshValue();
13870
13871				// Start from the last handle to prevent unreachable handles (#9046)
13872				for ( i = valsLength - 1; i >= 0; i-- ) {
13873					this._change( null, i );
13874				}
13875				this._animateOff = false;
13876				break;
13877			case "step":
13878			case "min":
13879			case "max":
13880				this._animateOff = true;
13881				this._calculateNewMax();
13882				this._refreshValue();
13883				this._animateOff = false;
13884				break;
13885			case "range":
13886				this._animateOff = true;
13887				this._refresh();
13888				this._animateOff = false;
13889				break;
13890		}
13891	},
13892
13893	_setOptionDisabled: function( value ) {
13894		this._super( value );
13895
13896		this._toggleClass( null, "ui-state-disabled", !!value );
13897	},
13898
13899	//internal value getter
13900	// _value() returns value trimmed by min and max, aligned by step
13901	_value: function() {
13902		var val = this.options.value;
13903		val = this._trimAlignValue( val );
13904
13905		return val;
13906	},
13907
13908	//internal values getter
13909	// _values() returns array of values trimmed by min and max, aligned by step
13910	// _values( index ) returns single value trimmed by min and max, aligned by step
13911	_values: function( index ) {
13912		var val,
13913			vals,
13914			i;
13915
13916		if ( arguments.length ) {
13917			val = this.options.values[ index ];
13918			val = this._trimAlignValue( val );
13919
13920			return val;
13921		} else if ( this._hasMultipleValues() ) {
13922
13923			// .slice() creates a copy of the array
13924			// this copy gets trimmed by min and max and then returned
13925			vals = this.options.values.slice();
13926			for ( i = 0; i < vals.length; i += 1 ) {
13927				vals[ i ] = this._trimAlignValue( vals[ i ] );
13928			}
13929
13930			return vals;
13931		} else {
13932			return [];
13933		}
13934	},
13935
13936	// Returns the step-aligned value that val is closest to, between (inclusive) min and max
13937	_trimAlignValue: function( val ) {
13938		if ( val <= this._valueMin() ) {
13939			return this._valueMin();
13940		}
13941		if ( val >= this._valueMax() ) {
13942			return this._valueMax();
13943		}
13944		var step = ( this.options.step > 0 ) ? this.options.step : 1,
13945			valModStep = ( val - this._valueMin() ) % step,
13946			alignValue = val - valModStep;
13947
13948		if ( Math.abs( valModStep ) * 2 >= step ) {
13949			alignValue += ( valModStep > 0 ) ? step : ( -step );
13950		}
13951
13952		// Since JavaScript has problems with large floats, round
13953		// the final value to 5 digits after the decimal point (see #4124)
13954		return parseFloat( alignValue.toFixed( 5 ) );
13955	},
13956
13957	_calculateNewMax: function() {
13958		var max = this.options.max,
13959			min = this._valueMin(),
13960			step = this.options.step,
13961			aboveMin = Math.round( ( max - min ) / step ) * step;
13962		max = aboveMin + min;
13963		if ( max > this.options.max ) {
13964
13965			//If max is not divisible by step, rounding off may increase its value
13966			max -= step;
13967		}
13968		this.max = parseFloat( max.toFixed( this._precision() ) );
13969	},
13970
13971	_precision: function() {
13972		var precision = this._precisionOf( this.options.step );
13973		if ( this.options.min !== null ) {
13974			precision = Math.max( precision, this._precisionOf( this.options.min ) );
13975		}
13976		return precision;
13977	},
13978
13979	_precisionOf: function( num ) {
13980		var str = num.toString(),
13981			decimal = str.indexOf( "." );
13982		return decimal === -1 ? 0 : str.length - decimal - 1;
13983	},
13984
13985	_valueMin: function() {
13986		return this.options.min;
13987	},
13988
13989	_valueMax: function() {
13990		return this.max;
13991	},
13992
13993	_refreshRange: function( orientation ) {
13994		if ( orientation === "vertical" ) {
13995			this.range.css( { "width": "", "left": "" } );
13996		}
13997		if ( orientation === "horizontal" ) {
13998			this.range.css( { "height": "", "bottom": "" } );
13999		}
14000	},
14001
14002	_refreshValue: function() {
14003		var lastValPercent, valPercent, value, valueMin, valueMax,
14004			oRange = this.options.range,
14005			o = this.options,
14006			that = this,
14007			animate = ( !this._animateOff ) ? o.animate : false,
14008			_set = {};
14009
14010		if ( this._hasMultipleValues() ) {
14011			this.handles.each( function( i ) {
14012				valPercent = ( that.values( i ) - that._valueMin() ) / ( that._valueMax() -
14013					that._valueMin() ) * 100;
14014				_set[ that.orientation === "horizontal" ? "left" : "bottom" ] = valPercent + "%";
14015				$( this ).stop( 1, 1 )[ animate ? "animate" : "css" ]( _set, o.animate );
14016				if ( that.options.range === true ) {
14017					if ( that.orientation === "horizontal" ) {
14018						if ( i === 0 ) {
14019							that.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( {
14020								left: valPercent + "%"
14021							}, o.animate );
14022						}
14023						if ( i === 1 ) {
14024							that.range[ animate ? "animate" : "css" ]( {
14025								width: ( valPercent - lastValPercent ) + "%"
14026							}, {
14027								queue: false,
14028								duration: o.animate
14029							} );
14030						}
14031					} else {
14032						if ( i === 0 ) {
14033							that.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( {
14034								bottom: ( valPercent ) + "%"
14035							}, o.animate );
14036						}
14037						if ( i === 1 ) {
14038							that.range[ animate ? "animate" : "css" ]( {
14039								height: ( valPercent - lastValPercent ) + "%"
14040							}, {
14041								queue: false,
14042								duration: o.animate
14043							} );
14044						}
14045					}
14046				}
14047				lastValPercent = valPercent;
14048			} );
14049		} else {
14050			value = this.value();
14051			valueMin = this._valueMin();
14052			valueMax = this._valueMax();
14053			valPercent = ( valueMax !== valueMin ) ?
14054					( value - valueMin ) / ( valueMax - valueMin ) * 100 :
14055					0;
14056			_set[ this.orientation === "horizontal" ? "left" : "bottom" ] = valPercent + "%";
14057			this.handle.stop( 1, 1 )[ animate ? "animate" : "css" ]( _set, o.animate );
14058
14059			if ( oRange === "min" && this.orientation === "horizontal" ) {
14060				this.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( {
14061					width: valPercent + "%"
14062				}, o.animate );
14063			}
14064			if ( oRange === "max" && this.orientation === "horizontal" ) {
14065				this.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( {
14066					width: ( 100 - valPercent ) + "%"
14067				}, o.animate );
14068			}
14069			if ( oRange === "min" && this.orientation === "vertical" ) {
14070				this.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( {
14071					height: valPercent + "%"
14072				}, o.animate );
14073			}
14074			if ( oRange === "max" && this.orientation === "vertical" ) {
14075				this.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( {
14076					height: ( 100 - valPercent ) + "%"
14077				}, o.animate );
14078			}
14079		}
14080	},
14081
14082	_handleEvents: {
14083		keydown: function( event ) {
14084			var allowed, curVal, newVal, step,
14085				index = $( event.target ).data( "ui-slider-handle-index" );
14086
14087			switch ( event.keyCode ) {
14088				case $.ui.keyCode.HOME:
14089				case $.ui.keyCode.END:
14090				case $.ui.keyCode.PAGE_UP:
14091				case $.ui.keyCode.PAGE_DOWN:
14092				case $.ui.keyCode.UP:
14093				case $.ui.keyCode.RIGHT:
14094				case $.ui.keyCode.DOWN:
14095				case $.ui.keyCode.LEFT:
14096					event.preventDefault();
14097					if ( !this._keySliding ) {
14098						this._keySliding = true;
14099						this._addClass( $( event.target ), null, "ui-state-active" );
14100						allowed = this._start( event, index );
14101						if ( allowed === false ) {
14102							return;
14103						}
14104					}
14105					break;
14106			}
14107
14108			step = this.options.step;
14109			if ( this._hasMultipleValues() ) {
14110				curVal = newVal = this.values( index );
14111			} else {
14112				curVal = newVal = this.value();
14113			}
14114
14115			switch ( event.keyCode ) {
14116				case $.ui.keyCode.HOME:
14117					newVal = this._valueMin();
14118					break;
14119				case $.ui.keyCode.END:
14120					newVal = this._valueMax();
14121					break;
14122				case $.ui.keyCode.PAGE_UP:
14123					newVal = this._trimAlignValue(
14124						curVal + ( ( this._valueMax() - this._valueMin() ) / this.numPages )
14125					);
14126					break;
14127				case $.ui.keyCode.PAGE_DOWN:
14128					newVal = this._trimAlignValue(
14129						curVal - ( ( this._valueMax() - this._valueMin() ) / this.numPages ) );
14130					break;
14131				case $.ui.keyCode.UP:
14132				case $.ui.keyCode.RIGHT:
14133					if ( curVal === this._valueMax() ) {
14134						return;
14135					}
14136					newVal = this._trimAlignValue( curVal + step );
14137					break;
14138				case $.ui.keyCode.DOWN:
14139				case $.ui.keyCode.LEFT:
14140					if ( curVal === this._valueMin() ) {
14141						return;
14142					}
14143					newVal = this._trimAlignValue( curVal - step );
14144					break;
14145			}
14146
14147			this._slide( event, index, newVal );
14148		},
14149		keyup: function( event ) {
14150			var index = $( event.target ).data( "ui-slider-handle-index" );
14151
14152			if ( this._keySliding ) {
14153				this._keySliding = false;
14154				this._stop( event, index );
14155				this._change( event, index );
14156				this._removeClass( $( event.target ), null, "ui-state-active" );
14157			}
14158		}
14159	}
14160} );
14161
14162
14163/*!
vendor: 4,519 bytes, lines 14164-14330
14164 * jQuery UI Spinner 1.12.1
14165 * http://jqueryui.com
14166 *
14167 * Copyright jQuery Foundation and other contributors
14168 * Released under the MIT license.
14169 * http://jquery.org/license
14170 */
14171
14172//>>label: Spinner
14173//>>group: Widgets
14174//>>description: Displays buttons to easily input numbers via the keyboard or mouse.
14175//>>docs: http://api.jqueryui.com/spinner/
14176//>>demos: http://jqueryui.com/spinner/
14177//>>css.structure: ../../themes/base/core.css
14178//>>css.structure: ../../themes/base/spinner.css
14179//>>css.theme: ../../themes/base/theme.css
14180
14181
14182
14183function spinnerModifer( fn ) {
14184	return function() {
14185		var previous = this.element.val();
14186		fn.apply( this, arguments );
14187		this._refresh();
14188		if ( previous !== this.element.val() ) {
14189			this._trigger( "change" );
14190		}
14191	};
14192}
14193
14194$.widget( "ui.spinner", {
14195	version: "1.12.1",
14196	defaultElement: "<input>",
14197	widgetEventPrefix: "spin",
14198	options: {
14199		classes: {
14200			"ui-spinner": "ui-corner-all",
14201			"ui-spinner-down": "ui-corner-br",
14202			"ui-spinner-up": "ui-corner-tr"
14203		},
14204		culture: null,
14205		icons: {
14206			down: "ui-icon-triangle-1-s",
14207			up: "ui-icon-triangle-1-n"
14208		},
14209		incremental: true,
14210		max: null,
14211		min: null,
14212		numberFormat: null,
14213		page: 10,
14214		step: 1,
14215
14216		change: null,
14217		spin: null,
14218		start: null,
14219		stop: null
14220	},
14221
14222	_create: function() {
14223
14224		// handle string values that need to be parsed
14225		this._setOption( "max", this.options.max );
14226		this._setOption( "min", this.options.min );
14227		this._setOption( "step", this.options.step );
14228
14229		// Only format if there is a value, prevents the field from being marked
14230		// as invalid in Firefox, see #9573.
14231		if ( this.value() !== "" ) {
14232
14233			// Format the value, but don't constrain.
14234			this._value( this.element.val(), true );
14235		}
14236
14237		this._draw();
14238		this._on( this._events );
14239		this._refresh();
14240
14241		// Turning off autocomplete prevents the browser from remembering the
14242		// value when navigating through history, so we re-enable autocomplete
14243		// if the page is unloaded before the widget is destroyed. #7790
14244		this._on( this.window, {
14245			beforeunload: function() {
14246				this.element.removeAttr( "autocomplete" );
14247			}
14248		} );
14249	},
14250
14251	_getCreateOptions: function() {
14252		var options = this._super();
14253		var element = this.element;
14254
14255		$.each( [ "min", "max", "step" ], function( i, option ) {
14256			var value = element.attr( option );
14257			if ( value != null && value.length ) {
14258				options[ option ] = value;
14259			}
14260		} );
14261
14262		return options;
14263	},
14264
14265	_events: {
14266		keydown: function( event ) {
14267			if ( this._start( event ) && this._keydown( event ) ) {
14268				event.preventDefault();
14269			}
14270		},
14271		keyup: "_stop",
14272		focus: function() {
14273			this.previous = this.element.val();
14274		},
14275		blur: function( event ) {
14276			if ( this.cancelBlur ) {
14277				delete this.cancelBlur;
14278				return;
14279			}
14280
14281			this._stop();
14282			this._refresh();
14283			if ( this.previous !== this.element.val() ) {
14284				this._trigger( "change", event );
14285			}
14286		},
14287		mousewheel: function( event, delta ) {
14288			if ( !delta ) {
14289				return;
14290			}
14291			if ( !this.spinning && !this._start( event ) ) {
14292				return false;
14293			}
14294
14295			this._spin( ( delta > 0 ? 1 : -1 ) * this.options.step, event );
14296			clearTimeout( this.mousewheelTimer );
14297			this.mousewheelTimer = this._delay( function() {
14298				if ( this.spinning ) {
14299					this._stop( event );
14300				}
14301			}, 100 );
14302			event.preventDefault();
14303		},
14304		"mousedown .ui-spinner-button": function( event ) {
14305			var previous;
14306
14307			// We never want the buttons to have focus; whenever the user is
14308			// interacting with the spinner, the focus should be on the input.
14309			// If the input is focused then this.previous is properly set from
14310			// when the input first received focus. If the input is not focused
14311			// then we need to set this.previous based on the value before spinning.
14312			previous = this.element[ 0 ] === $.ui.safeActiveElement( this.document[ 0 ] ) ?
14313				this.previous : this.element.val();
14314			function checkFocus() {
14315				var isActive = this.element[ 0 ] === $.ui.safeActiveElement( this.document[ 0 ] );
14316				if ( !isActive ) {
14317					this.element.trigger( "focus" );
14318					this.previous = previous;
14319
14320					// support: IE
14321					// IE sets focus asynchronously, so we need to check if focus
14322					// moved off of the input because the user clicked on the button.
14323					this._delay( function() {
14324						this.previous = previous;
14325					} );
14326				}
14327			}
14328
14329			// Ensure focus is on (or stays on) the text field
14330			event.preventDefault();
vendor: 5,986 bytes, lines 14331-14560
14331			checkFocus.call( this );
14332
14333			// Support: IE
14334			// IE doesn't prevent moving focus even with event.preventDefault()
14335			// so we set a flag to know when we should ignore the blur event
14336			// and check (again) if focus moved off of the input.
14337			this.cancelBlur = true;
14338			this._delay( function() {
14339				delete this.cancelBlur;
14340				checkFocus.call( this );
14341			} );
14342
14343			if ( this._start( event ) === false ) {
14344				return;
14345			}
14346
14347			this._repeat( null, $( event.currentTarget )
14348				.hasClass( "ui-spinner-up" ) ? 1 : -1, event );
14349		},
14350		"mouseup .ui-spinner-button": "_stop",
14351		"mouseenter .ui-spinner-button": function( event ) {
14352
14353			// button will add ui-state-active if mouse was down while mouseleave and kept down
14354			if ( !$( event.currentTarget ).hasClass( "ui-state-active" ) ) {
14355				return;
14356			}
14357
14358			if ( this._start( event ) === false ) {
14359				return false;
14360			}
14361			this._repeat( null, $( event.currentTarget )
14362				.hasClass( "ui-spinner-up" ) ? 1 : -1, event );
14363		},
14364
14365		// TODO: do we really want to consider this a stop?
14366		// shouldn't we just stop the repeater and wait until mouseup before
14367		// we trigger the stop event?
14368		"mouseleave .ui-spinner-button": "_stop"
14369	},
14370
14371	// Support mobile enhanced option and make backcompat more sane
14372	_enhance: function() {
14373		this.uiSpinner = this.element
14374			.attr( "autocomplete", "off" )
14375			.wrap( "<span>" )
14376			.parent()
14377
14378				// Add buttons
14379				.append(
14380					"<a></a><a></a>"
14381				);
14382	},
14383
14384	_draw: function() {
14385		this._enhance();
14386
14387		this._addClass( this.uiSpinner, "ui-spinner", "ui-widget ui-widget-content" );
14388		this._addClass( "ui-spinner-input" );
14389
14390		this.element.attr( "role", "spinbutton" );
14391
14392		// Button bindings
14393		this.buttons = this.uiSpinner.children( "a" )
14394			.attr( "tabIndex", -1 )
14395			.attr( "aria-hidden", true )
14396			.button( {
14397				classes: {
14398					"ui-button": ""
14399				}
14400			} );
14401
14402		// TODO: Right now button does not support classes this is already updated in button PR
14403		this._removeClass( this.buttons, "ui-corner-all" );
14404
14405		this._addClass( this.buttons.first(), "ui-spinner-button ui-spinner-up" );
14406		this._addClass( this.buttons.last(), "ui-spinner-button ui-spinner-down" );
14407		this.buttons.first().button( {
14408			"icon": this.options.icons.up,
14409			"showLabel": false
14410		} );
14411		this.buttons.last().button( {
14412			"icon": this.options.icons.down,
14413			"showLabel": false
14414		} );
14415
14416		// IE 6 doesn't understand height: 50% for the buttons
14417		// unless the wrapper has an explicit height
14418		if ( this.buttons.height() > Math.ceil( this.uiSpinner.height() * 0.5 ) &&
14419				this.uiSpinner.height() > 0 ) {
14420			this.uiSpinner.height( this.uiSpinner.height() );
14421		}
14422	},
14423
14424	_keydown: function( event ) {
14425		var options = this.options,
14426			keyCode = $.ui.keyCode;
14427
14428		switch ( event.keyCode ) {
14429		case keyCode.UP:
14430			this._repeat( null, 1, event );
14431			return true;
14432		case keyCode.DOWN:
14433			this._repeat( null, -1, event );
14434			return true;
14435		case keyCode.PAGE_UP:
14436			this._repeat( null, options.page, event );
14437			return true;
14438		case keyCode.PAGE_DOWN:
14439			this._repeat( null, -options.page, event );
14440			return true;
14441		}
14442
14443		return false;
14444	},
14445
14446	_start: function( event ) {
14447		if ( !this.spinning && this._trigger( "start", event ) === false ) {
14448			return false;
14449		}
14450
14451		if ( !this.counter ) {
14452			this.counter = 1;
14453		}
14454		this.spinning = true;
14455		return true;
14456	},
14457
14458	_repeat: function( i, steps, event ) {
14459		i = i || 500;
14460
14461		clearTimeout( this.timer );
14462		this.timer = this._delay( function() {
14463			this._repeat( 40, steps, event );
14464		}, i );
14465
14466		this._spin( steps * this.options.step, event );
14467	},
14468
14469	_spin: function( step, event ) {
14470		var value = this.value() || 0;
14471
14472		if ( !this.counter ) {
14473			this.counter = 1;
14474		}
14475
14476		value = this._adjustValue( value + step * this._increment( this.counter ) );
14477
14478		if ( !this.spinning || this._trigger( "spin", event, { value: value } ) !== false ) {
14479			this._value( value );
14480			this.counter++;
14481		}
14482	},
14483
14484	_increment: function( i ) {
14485		var incremental = this.options.incremental;
14486
14487		if ( incremental ) {
14488			return $.isFunction( incremental ) ?
14489				incremental( i ) :
14490				Math.floor( i * i * i / 50000 - i * i / 500 + 17 * i / 200 + 1 );
14491		}
14492
14493		return 1;
14494	},
14495
14496	_precision: function() {
14497		var precision = this._precisionOf( this.options.step );
14498		if ( this.options.min !== null ) {
14499			precision = Math.max( precision, this._precisionOf( this.options.min ) );
14500		}
14501		return precision;
14502	},
14503
14504	_precisionOf: function( num ) {
14505		var str = num.toString(),
14506			decimal = str.indexOf( "." );
14507		return decimal === -1 ? 0 : str.length - decimal - 1;
14508	},
14509
14510	_adjustValue: function( value ) {
14511		var base, aboveMin,
14512			options = this.options;
14513
14514		// Make sure we're at a valid step
14515		// - find out where we are relative to the base (min or 0)
14516		base = options.min !== null ? options.min : 0;
14517		aboveMin = value - base;
14518
14519		// - round to the nearest step
14520		aboveMin = Math.round( aboveMin / options.step ) * options.step;
14521
14522		// - rounding is based on 0, so adjust back to our base
14523		value = base + aboveMin;
14524
14525		// Fix precision from bad JS floating point math
14526		value = parseFloat( value.toFixed( this._precision() ) );
14527
14528		// Clamp the value
14529		if ( options.max !== null && value > options.max ) {
14530			return options.max;
14531		}
14532		if ( options.min !== null && value < options.min ) {
14533			return options.min;
14534		}
14535
14536		return value;
14537	},
14538
14539	_stop: function( event ) {
14540		if ( !this.spinning ) {
14541			return;
14542		}
14543
14544		clearTimeout( this.timer );
14545		clearTimeout( this.mousewheelTimer );
14546		this.counter = 0;
14547		this.spinning = false;
14548		this._trigger( "stop", event );
14549	},
14550
14551	_setOption: function( key, value ) {
14552		var prevValue, first, last;
14553
14554		if ( key === "culture" || key === "numberFormat" ) {
14555			prevValue = this._parse( this.element.val() );
14556			this.options[ key ] = value;
14557			this.element.val( this._format( prevValue ) );
14558			return;
14559		}
14560
vendor: 12,920 bytes, lines 14561-15057
14561		if ( key === "max" || key === "min" || key === "step" ) {
14562			if ( typeof value === "string" ) {
14563				value = this._parse( value );
14564			}
14565		}
14566		if ( key === "icons" ) {
14567			first = this.buttons.first().find( ".ui-icon" );
14568			this._removeClass( first, null, this.options.icons.up );
14569			this._addClass( first, null, value.up );
14570			last = this.buttons.last().find( ".ui-icon" );
14571			this._removeClass( last, null, this.options.icons.down );
14572			this._addClass( last, null, value.down );
14573		}
14574
14575		this._super( key, value );
14576	},
14577
14578	_setOptionDisabled: function( value ) {
14579		this._super( value );
14580
14581		this._toggleClass( this.uiSpinner, null, "ui-state-disabled", !!value );
14582		this.element.prop( "disabled", !!value );
14583		this.buttons.button( value ? "disable" : "enable" );
14584	},
14585
14586	_setOptions: spinnerModifer( function( options ) {
14587		this._super( options );
14588	} ),
14589
14590	_parse: function( val ) {
14591		if ( typeof val === "string" && val !== "" ) {
14592			val = window.Globalize && this.options.numberFormat ?
14593				Globalize.parseFloat( val, 10, this.options.culture ) : +val;
14594		}
14595		return val === "" || isNaN( val ) ? null : val;
14596	},
14597
14598	_format: function( value ) {
14599		if ( value === "" ) {
14600			return "";
14601		}
14602		return window.Globalize && this.options.numberFormat ?
14603			Globalize.format( value, this.options.numberFormat, this.options.culture ) :
14604			value;
14605	},
14606
14607	_refresh: function() {
14608		this.element.attr( {
14609			"aria-valuemin": this.options.min,
14610			"aria-valuemax": this.options.max,
14611
14612			// TODO: what should we do with values that can't be parsed?
14613			"aria-valuenow": this._parse( this.element.val() )
14614		} );
14615	},
14616
14617	isValid: function() {
14618		var value = this.value();
14619
14620		// Null is invalid
14621		if ( value === null ) {
14622			return false;
14623		}
14624
14625		// If value gets adjusted, it's invalid
14626		return value === this._adjustValue( value );
14627	},
14628
14629	// Update the value without triggering change
14630	_value: function( value, allowAny ) {
14631		var parsed;
14632		if ( value !== "" ) {
14633			parsed = this._parse( value );
14634			if ( parsed !== null ) {
14635				if ( !allowAny ) {
14636					parsed = this._adjustValue( parsed );
14637				}
14638				value = this._format( parsed );
14639			}
14640		}
14641		this.element.val( value );
14642		this._refresh();
14643	},
14644
14645	_destroy: function() {
14646		this.element
14647			.prop( "disabled", false )
14648			.removeAttr( "autocomplete role aria-valuemin aria-valuemax aria-valuenow" );
14649
14650		this.uiSpinner.replaceWith( this.element );
14651	},
14652
14653	stepUp: spinnerModifer( function( steps ) {
14654		this._stepUp( steps );
14655	} ),
14656	_stepUp: function( steps ) {
14657		if ( this._start() ) {
14658			this._spin( ( steps || 1 ) * this.options.step );
14659			this._stop();
14660		}
14661	},
14662
14663	stepDown: spinnerModifer( function( steps ) {
14664		this._stepDown( steps );
14665	} ),
14666	_stepDown: function( steps ) {
14667		if ( this._start() ) {
14668			this._spin( ( steps || 1 ) * -this.options.step );
14669			this._stop();
14670		}
14671	},
14672
14673	pageUp: spinnerModifer( function( pages ) {
14674		this._stepUp( ( pages || 1 ) * this.options.page );
14675	} ),
14676
14677	pageDown: spinnerModifer( function( pages ) {
14678		this._stepDown( ( pages || 1 ) * this.options.page );
14679	} ),
14680
14681	value: function( newVal ) {
14682		if ( !arguments.length ) {
14683			return this._parse( this.element.val() );
14684		}
14685		spinnerModifer( this._value ).call( this, newVal );
14686	},
14687
14688	widget: function() {
14689		return this.uiSpinner;
14690	}
14691} );
14692
14693// DEPRECATED
14694// TODO: switch return back to widget declaration at top of file when this is removed
14695if ( $.uiBackCompat !== false ) {
14696
14697	// Backcompat for spinner html extension points
14698	$.widget( "ui.spinner", $.ui.spinner, {
14699		_enhance: function() {
14700			this.uiSpinner = this.element
14701				.attr( "autocomplete", "off" )
14702				.wrap( this._uiSpinnerHtml() )
14703				.parent()
14704
14705					// Add buttons
14706					.append( this._buttonHtml() );
14707		},
14708		_uiSpinnerHtml: function() {
14709			return "<span>";
14710		},
14711
14712		_buttonHtml: function() {
14713			return "<a></a><a></a>";
14714		}
14715	} );
14716}
14717
14718var widgetsSpinner = $.ui.spinner;
14719
14720
14721/*!
14722 * jQuery UI Tabs 1.12.1
14723 * http://jqueryui.com
14724 *
14725 * Copyright jQuery Foundation and other contributors
14726 * Released under the MIT license.
14727 * http://jquery.org/license
14728 */
14729
14730//>>label: Tabs
14731//>>group: Widgets
14732//>>description: Transforms a set of container elements into a tab structure.
14733//>>docs: http://api.jqueryui.com/tabs/
14734//>>demos: http://jqueryui.com/tabs/
14735//>>css.structure: ../../themes/base/core.css
14736//>>css.structure: ../../themes/base/tabs.css
14737//>>css.theme: ../../themes/base/theme.css
14738
14739
14740
14741$.widget( "ui.tabs", {
14742	version: "1.12.1",
14743	delay: 300,
14744	options: {
14745		active: null,
14746		classes: {
14747			"ui-tabs": "ui-corner-all",
14748			"ui-tabs-nav": "ui-corner-all",
14749			"ui-tabs-panel": "ui-corner-bottom",
14750			"ui-tabs-tab": "ui-corner-top"
14751		},
14752		collapsible: false,
14753		event: "click",
14754		heightStyle: "content",
14755		hide: null,
14756		show: null,
14757
14758		// Callbacks
14759		activate: null,
14760		beforeActivate: null,
14761		beforeLoad: null,
14762		load: null
14763	},
14764
14765	_isLocal: ( function() {
14766		var rhash = /#.*$/;
14767
14768		return function( anchor ) {
14769			var anchorUrl, locationUrl;
14770
14771			anchorUrl = anchor.href.replace( rhash, "" );
14772			locationUrl = location.href.replace( rhash, "" );
14773
14774			// Decoding may throw an error if the URL isn't UTF-8 (#9518)
14775			try {
14776				anchorUrl = decodeURIComponent( anchorUrl );
14777			} catch ( error ) {}
14778			try {
14779				locationUrl = decodeURIComponent( locationUrl );
14780			} catch ( error ) {}
14781
14782			return anchor.hash.length > 1 && anchorUrl === locationUrl;
14783		};
14784	} )(),
14785
14786	_create: function() {
14787		var that = this,
14788			options = this.options;
14789
14790		this.running = false;
14791
14792		this._addClass( "ui-tabs", "ui-widget ui-widget-content" );
14793		this._toggleClass( "ui-tabs-collapsible", null, options.collapsible );
14794
14795		this._processTabs();
14796		options.active = this._initialActive();
14797
14798		// Take disabling tabs via class attribute from HTML
14799		// into account and update option properly.
14800		if ( $.isArray( options.disabled ) ) {
14801			options.disabled = $.unique( options.disabled.concat(
14802				$.map( this.tabs.filter( ".ui-state-disabled" ), function( li ) {
14803					return that.tabs.index( li );
14804				} )
14805			) ).sort();
14806		}
14807
14808		// Check for length avoids error when initializing empty list
14809		if ( this.options.active !== false && this.anchors.length ) {
14810			this.active = this._findActive( options.active );
14811		} else {
14812			this.active = $();
14813		}
14814
14815		this._refresh();
14816
14817		if ( this.active.length ) {
14818			this.load( options.active );
14819		}
14820	},
14821
14822	_initialActive: function() {
14823		var active = this.options.active,
14824			collapsible = this.options.collapsible,
14825			locationHash = location.hash.substring( 1 );
14826
14827		if ( active === null ) {
14828
14829			// check the fragment identifier in the URL
14830			if ( locationHash ) {
14831				this.tabs.each( function( i, tab ) {
14832					if ( $( tab ).attr( "aria-controls" ) === locationHash ) {
14833						active = i;
14834						return false;
14835					}
14836				} );
14837			}
14838
14839			// Check for a tab marked active via a class
14840			if ( active === null ) {
14841				active = this.tabs.index( this.tabs.filter( ".ui-tabs-active" ) );
14842			}
14843
14844			// No active tab, set to false
14845			if ( active === null || active === -1 ) {
14846				active = this.tabs.length ? 0 : false;
14847			}
14848		}
14849
14850		// Handle numbers: negative, out of range
14851		if ( active !== false ) {
14852			active = this.tabs.index( this.tabs.eq( active ) );
14853			if ( active === -1 ) {
14854				active = collapsible ? false : 0;
14855			}
14856		}
14857
14858		// Don't allow collapsible: false and active: false
14859		if ( !collapsible && active === false && this.anchors.length ) {
14860			active = 0;
14861		}
14862
14863		return active;
14864	},
14865
14866	_getCreateEventData: function() {
14867		return {
14868			tab: this.active,
14869			panel: !this.active.length ? $() : this._getPanelForTab( this.active )
14870		};
14871	},
14872
14873	_tabKeydown: function( event ) {
14874		var focusedTab = $( $.ui.safeActiveElement( this.document[ 0 ] ) ).closest( "li" ),
14875			selectedIndex = this.tabs.index( focusedTab ),
14876			goingForward = true;
14877
14878		if ( this._handlePageNav( event ) ) {
14879			return;
14880		}
14881
14882		switch ( event.keyCode ) {
14883		case $.ui.keyCode.RIGHT:
14884		case $.ui.keyCode.DOWN:
14885			selectedIndex++;
14886			break;
14887		case $.ui.keyCode.UP:
14888		case $.ui.keyCode.LEFT:
14889			goingForward = false;
14890			selectedIndex--;
14891			break;
14892		case $.ui.keyCode.END:
14893			selectedIndex = this.anchors.length - 1;
14894			break;
14895		case $.ui.keyCode.HOME:
14896			selectedIndex = 0;
14897			break;
14898		case $.ui.keyCode.SPACE:
14899
14900			// Activate only, no collapsing
14901			event.preventDefault();
14902			clearTimeout( this.activating );
14903			this._activate( selectedIndex );
14904			return;
14905		case $.ui.keyCode.ENTER:
14906
14907			// Toggle (cancel delayed activation, allow collapsing)
14908			event.preventDefault();
14909			clearTimeout( this.activating );
14910
14911			// Determine if we should collapse or activate
14912			this._activate( selectedIndex === this.options.active ? false : selectedIndex );
14913			return;
14914		default:
14915			return;
14916		}
14917
14918		// Focus the appropriate tab, based on which key was pressed
14919		event.preventDefault();
14920		clearTimeout( this.activating );
14921		selectedIndex = this._focusNextTab( selectedIndex, goingForward );
14922
14923		// Navigating with control/command key will prevent automatic activation
14924		if ( !event.ctrlKey && !event.metaKey ) {
14925
14926			// Update aria-selected immediately so that AT think the tab is already selected.
14927			// Otherwise AT may confuse the user by stating that they need to activate the tab,
14928			// but the tab will already be activated by the time the announcement finishes.
14929			focusedTab.attr( "aria-selected", "false" );
14930			this.tabs.eq( selectedIndex ).attr( "aria-selected", "true" );
14931
14932			this.activating = this._delay( function() {
14933				this.option( "active", selectedIndex );
14934			}, this.delay );
14935		}
14936	},
14937
14938	_panelKeydown: function( event ) {
14939		if ( this._handlePageNav( event ) ) {
14940			return;
14941		}
14942
14943		// Ctrl+up moves focus to the current tab
14944		if ( event.ctrlKey && event.keyCode === $.ui.keyCode.UP ) {
14945			event.preventDefault();
14946			this.active.trigger( "focus" );
14947		}
14948	},
14949
14950	// Alt+page up/down moves focus to the previous/next tab (and activates)
14951	_handlePageNav: function( event ) {
14952		if ( event.altKey && event.keyCode === $.ui.keyCode.PAGE_UP ) {
14953			this._activate( this._focusNextTab( this.options.active - 1, false ) );
14954			return true;
14955		}
14956		if ( event.altKey && event.keyCode === $.ui.keyCode.PAGE_DOWN ) {
14957			this._activate( this._focusNextTab( this.options.active + 1, true ) );
14958			return true;
14959		}
14960	},
14961
14962	_findNextTab: function( index, goingForward ) {
14963		var lastTabIndex = this.tabs.length - 1;
14964
14965		function constrain() {
14966			if ( index > lastTabIndex ) {
14967				index = 0;
14968			}
14969			if ( index < 0 ) {
14970				index = lastTabIndex;
14971			}
14972			return index;
14973		}
14974
14975		while ( $.inArray( constrain(), this.options.disabled ) !== -1 ) {
14976			index = goingForward ? index + 1 : index - 1;
14977		}
14978
14979		return index;
14980	},
14981
14982	_focusNextTab: function( index, goingForward ) {
14983		index = this._findNextTab( index, goingForward );
14984		this.tabs.eq( index ).trigger( "focus" );
14985		return index;
14986	},
14987
14988	_setOption: function( key, value ) {
14989		if ( key === "active" ) {
14990
14991			// _activate() will handle invalid values and update this.options
14992			this._activate( value );
14993			return;
14994		}
14995
14996		this._super( key, value );
14997
14998		if ( key === "collapsible" ) {
14999			this._toggleClass( "ui-tabs-collapsible", null, value );
15000
15001			// Setting collapsible: false while collapsed; open first panel
15002			if ( !value && this.options.active === false ) {
15003				this._activate( 0 );
15004			}
15005		}
15006
15007		if ( key === "event" ) {
15008			this._setupEvents( value );
15009		}
15010
15011		if ( key === "heightStyle" ) {
15012			this._setupHeightStyle( value );
15013		}
15014	},
15015
15016	_sanitizeSelector: function( hash ) {
15017		return hash ? hash.replace( /[!"$%&'()*+,.\/:;<=>?@\[\]\^`{|}~]/g, "\\$&" ) : "";
15018	},
15019
15020	refresh: function() {
15021		var options = this.options,
15022			lis = this.tablist.children( ":has(a[href])" );
15023
15024		// Get disabled tabs from class attribute from HTML
15025		// this will get converted to a boolean if needed in _refresh()
15026		options.disabled = $.map( lis.filter( ".ui-state-disabled" ), function( tab ) {
15027			return lis.index( tab );
15028		} );
15029
15030		this._processTabs();
15031
15032		// Was collapsed or no tabs
15033		if ( options.active === false || !this.anchors.length ) {
15034			options.active = false;
15035			this.active = $();
15036
15037		// was active, but active tab is gone
15038		} else if ( this.active.length && !$.contains( this.tablist[ 0 ], this.active[ 0 ] ) ) {
15039
15040			// all remaining tabs are disabled
15041			if ( this.tabs.length === options.disabled.length ) {
15042				options.active = false;
15043				this.active = $();
15044
15045			// activate previous tab
15046			} else {
15047				this._activate( this._findNextTab( Math.max( 0, options.active - 1 ), false ) );
15048			}
15049
15050		// was active, active tab still exists
15051		} else {
15052
15053			// make sure active index is correct
15054			options.active = this.tabs.index( this.active );
15055		}
15056
15057		this._refresh();
vendor: 18,906 bytes, lines 15058-15763
15058	},
15059
15060	_refresh: function() {
15061		this._setOptionDisabled( this.options.disabled );
15062		this._setupEvents( this.options.event );
15063		this._setupHeightStyle( this.options.heightStyle );
15064
15065		this.tabs.not( this.active ).attr( {
15066			"aria-selected": "false",
15067			"aria-expanded": "false",
15068			tabIndex: -1
15069		} );
15070		this.panels.not( this._getPanelForTab( this.active ) )
15071			.hide()
15072			.attr( {
15073				"aria-hidden": "true"
15074			} );
15075
15076		// Make sure one tab is in the tab order
15077		if ( !this.active.length ) {
15078			this.tabs.eq( 0 ).attr( "tabIndex", 0 );
15079		} else {
15080			this.active
15081				.attr( {
15082					"aria-selected": "true",
15083					"aria-expanded": "true",
15084					tabIndex: 0
15085				} );
15086			this._addClass( this.active, "ui-tabs-active", "ui-state-active" );
15087			this._getPanelForTab( this.active )
15088				.show()
15089				.attr( {
15090					"aria-hidden": "false"
15091				} );
15092		}
15093	},
15094
15095	_processTabs: function() {
15096		var that = this,
15097			prevTabs = this.tabs,
15098			prevAnchors = this.anchors,
15099			prevPanels = this.panels;
15100
15101		this.tablist = this._getList().attr( "role", "tablist" );
15102		this._addClass( this.tablist, "ui-tabs-nav",
15103			"ui-helper-reset ui-helper-clearfix ui-widget-header" );
15104
15105		// Prevent users from focusing disabled tabs via click
15106		this.tablist
15107			.on( "mousedown" + this.eventNamespace, "> li", function( event ) {
15108				if ( $( this ).is( ".ui-state-disabled" ) ) {
15109					event.preventDefault();
15110				}
15111			} )
15112
15113			// Support: IE <9
15114			// Preventing the default action in mousedown doesn't prevent IE
15115			// from focusing the element, so if the anchor gets focused, blur.
15116			// We don't have to worry about focusing the previously focused
15117			// element since clicking on a non-focusable element should focus
15118			// the body anyway.
15119			.on( "focus" + this.eventNamespace, ".ui-tabs-anchor", function() {
15120				if ( $( this ).closest( "li" ).is( ".ui-state-disabled" ) ) {
15121					this.blur();
15122				}
15123			} );
15124
15125		this.tabs = this.tablist.find( "> li:has(a[href])" )
15126			.attr( {
15127				role: "tab",
15128				tabIndex: -1
15129			} );
15130		this._addClass( this.tabs, "ui-tabs-tab", "ui-state-default" );
15131
15132		this.anchors = this.tabs.map( function() {
15133			return $( "a", this )[ 0 ];
15134		} )
15135			.attr( {
15136				role: "presentation",
15137				tabIndex: -1
15138			} );
15139		this._addClass( this.anchors, "ui-tabs-anchor" );
15140
15141		this.panels = $();
15142
15143		this.anchors.each( function( i, anchor ) {
15144			var selector, panel, panelId,
15145				anchorId = $( anchor ).uniqueId().attr( "id" ),
15146				tab = $( anchor ).closest( "li" ),
15147				originalAriaControls = tab.attr( "aria-controls" );
15148
15149			// Inline tab
15150			if ( that._isLocal( anchor ) ) {
15151				selector = anchor.hash;
15152				panelId = selector.substring( 1 );
15153				panel = that.element.find( that._sanitizeSelector( selector ) );
15154
15155			// remote tab
15156			} else {
15157
15158				// If the tab doesn't already have aria-controls,
15159				// generate an id by using a throw-away element
15160				panelId = tab.attr( "aria-controls" ) || $( {} ).uniqueId()[ 0 ].id;
15161				selector = "#" + panelId;
15162				panel = that.element.find( selector );
15163				if ( !panel.length ) {
15164					panel = that._createPanel( panelId );
15165					panel.insertAfter( that.panels[ i - 1 ] || that.tablist );
15166				}
15167				panel.attr( "aria-live", "polite" );
15168			}
15169
15170			if ( panel.length ) {
15171				that.panels = that.panels.add( panel );
15172			}
15173			if ( originalAriaControls ) {
15174				tab.data( "ui-tabs-aria-controls", originalAriaControls );
15175			}
15176			tab.attr( {
15177				"aria-controls": panelId,
15178				"aria-labelledby": anchorId
15179			} );
15180			panel.attr( "aria-labelledby", anchorId );
15181		} );
15182
15183		this.panels.attr( "role", "tabpanel" );
15184		this._addClass( this.panels, "ui-tabs-panel", "ui-widget-content" );
15185
15186		// Avoid memory leaks (#10056)
15187		if ( prevTabs ) {
15188			this._off( prevTabs.not( this.tabs ) );
15189			this._off( prevAnchors.not( this.anchors ) );
15190			this._off( prevPanels.not( this.panels ) );
15191		}
15192	},
15193
15194	// Allow overriding how to find the list for rare usage scenarios (#7715)
15195	_getList: function() {
15196		return this.tablist || this.element.find( "ol, ul" ).eq( 0 );
15197	},
15198
15199	_createPanel: function( id ) {
15200		return $( "<div>" )
15201			.attr( "id", id )
15202			.data( "ui-tabs-destroy", true );
15203	},
15204
15205	_setOptionDisabled: function( disabled ) {
15206		var currentItem, li, i;
15207
15208		if ( $.isArray( disabled ) ) {
15209			if ( !disabled.length ) {
15210				disabled = false;
15211			} else if ( disabled.length === this.anchors.length ) {
15212				disabled = true;
15213			}
15214		}
15215
15216		// Disable tabs
15217		for ( i = 0; ( li = this.tabs[ i ] ); i++ ) {
15218			currentItem = $( li );
15219			if ( disabled === true || $.inArray( i, disabled ) !== -1 ) {
15220				currentItem.attr( "aria-disabled", "true" );
15221				this._addClass( currentItem, null, "ui-state-disabled" );
15222			} else {
15223				currentItem.removeAttr( "aria-disabled" );
15224				this._removeClass( currentItem, null, "ui-state-disabled" );
15225			}
15226		}
15227
15228		this.options.disabled = disabled;
15229
15230		this._toggleClass( this.widget(), this.widgetFullName + "-disabled", null,
15231			disabled === true );
15232	},
15233
15234	_setupEvents: function( event ) {
15235		var events = {};
15236		if ( event ) {
15237			$.each( event.split( " " ), function( index, eventName ) {
15238				events[ eventName ] = "_eventHandler";
15239			} );
15240		}
15241
15242		this._off( this.anchors.add( this.tabs ).add( this.panels ) );
15243
15244		// Always prevent the default action, even when disabled
15245		this._on( true, this.anchors, {
15246			click: function( event ) {
15247				event.preventDefault();
15248			}
15249		} );
15250		this._on( this.anchors, events );
15251		this._on( this.tabs, { keydown: "_tabKeydown" } );
15252		this._on( this.panels, { keydown: "_panelKeydown" } );
15253
15254		this._focusable( this.tabs );
15255		this._hoverable( this.tabs );
15256	},
15257
15258	_setupHeightStyle: function( heightStyle ) {
15259		var maxHeight,
15260			parent = this.element.parent();
15261
15262		if ( heightStyle === "fill" ) {
15263			maxHeight = parent.height();
15264			maxHeight -= this.element.outerHeight() - this.element.height();
15265
15266			this.element.siblings( ":visible" ).each( function() {
15267				var elem = $( this ),
15268					position = elem.css( "position" );
15269
15270				if ( position === "absolute" || position === "fixed" ) {
15271					return;
15272				}
15273				maxHeight -= elem.outerHeight( true );
15274			} );
15275
15276			this.element.children().not( this.panels ).each( function() {
15277				maxHeight -= $( this ).outerHeight( true );
15278			} );
15279
15280			this.panels.each( function() {
15281				$( this ).height( Math.max( 0, maxHeight -
15282					$( this ).innerHeight() + $( this ).height() ) );
15283			} )
15284				.css( "overflow", "auto" );
15285		} else if ( heightStyle === "auto" ) {
15286			maxHeight = 0;
15287			this.panels.each( function() {
15288				maxHeight = Math.max( maxHeight, $( this ).height( "" ).height() );
15289			} ).height( maxHeight );
15290		}
15291	},
15292
15293	_eventHandler: function( event ) {
15294		var options = this.options,
15295			active = this.active,
15296			anchor = $( event.currentTarget ),
15297			tab = anchor.closest( "li" ),
15298			clickedIsActive = tab[ 0 ] === active[ 0 ],
15299			collapsing = clickedIsActive && options.collapsible,
15300			toShow = collapsing ? $() : this._getPanelForTab( tab ),
15301			toHide = !active.length ? $() : this._getPanelForTab( active ),
15302			eventData = {
15303				oldTab: active,
15304				oldPanel: toHide,
15305				newTab: collapsing ? $() : tab,
15306				newPanel: toShow
15307			};
15308
15309		event.preventDefault();
15310
15311		if ( tab.hasClass( "ui-state-disabled" ) ||
15312
15313				// tab is already loading
15314				tab.hasClass( "ui-tabs-loading" ) ||
15315
15316				// can't switch durning an animation
15317				this.running ||
15318
15319				// click on active header, but not collapsible
15320				( clickedIsActive && !options.collapsible ) ||
15321
15322				// allow canceling activation
15323				( this._trigger( "beforeActivate", event, eventData ) === false ) ) {
15324			return;
15325		}
15326
15327		options.active = collapsing ? false : this.tabs.index( tab );
15328
15329		this.active = clickedIsActive ? $() : tab;
15330		if ( this.xhr ) {
15331			this.xhr.abort();
15332		}
15333
15334		if ( !toHide.length && !toShow.length ) {
15335			$.error( "jQuery UI Tabs: Mismatching fragment identifier." );
15336		}
15337
15338		if ( toShow.length ) {
15339			this.load( this.tabs.index( tab ), event );
15340		}
15341		this._toggle( event, eventData );
15342	},
15343
15344	// Handles show/hide for selecting tabs
15345	_toggle: function( event, eventData ) {
15346		var that = this,
15347			toShow = eventData.newPanel,
15348			toHide = eventData.oldPanel;
15349
15350		this.running = true;
15351
15352		function complete() {
15353			that.running = false;
15354			that._trigger( "activate", event, eventData );
15355		}
15356
15357		function show() {
15358			that._addClass( eventData.newTab.closest( "li" ), "ui-tabs-active", "ui-state-active" );
15359
15360			if ( toShow.length && that.options.show ) {
15361				that._show( toShow, that.options.show, complete );
15362			} else {
15363				toShow.show();
15364				complete();
15365			}
15366		}
15367
15368		// Start out by hiding, then showing, then completing
15369		if ( toHide.length && this.options.hide ) {
15370			this._hide( toHide, this.options.hide, function() {
15371				that._removeClass( eventData.oldTab.closest( "li" ),
15372					"ui-tabs-active", "ui-state-active" );
15373				show();
15374			} );
15375		} else {
15376			this._removeClass( eventData.oldTab.closest( "li" ),
15377				"ui-tabs-active", "ui-state-active" );
15378			toHide.hide();
15379			show();
15380		}
15381
15382		toHide.attr( "aria-hidden", "true" );
15383		eventData.oldTab.attr( {
15384			"aria-selected": "false",
15385			"aria-expanded": "false"
15386		} );
15387
15388		// If we're switching tabs, remove the old tab from the tab order.
15389		// If we're opening from collapsed state, remove the previous tab from the tab order.
15390		// If we're collapsing, then keep the collapsing tab in the tab order.
15391		if ( toShow.length && toHide.length ) {
15392			eventData.oldTab.attr( "tabIndex", -1 );
15393		} else if ( toShow.length ) {
15394			this.tabs.filter( function() {
15395				return $( this ).attr( "tabIndex" ) === 0;
15396			} )
15397				.attr( "tabIndex", -1 );
15398		}
15399
15400		toShow.attr( "aria-hidden", "false" );
15401		eventData.newTab.attr( {
15402			"aria-selected": "true",
15403			"aria-expanded": "true",
15404			tabIndex: 0
15405		} );
15406	},
15407
15408	_activate: function( index ) {
15409		var anchor,
15410			active = this._findActive( index );
15411
15412		// Trying to activate the already active panel
15413		if ( active[ 0 ] === this.active[ 0 ] ) {
15414			return;
15415		}
15416
15417		// Trying to collapse, simulate a click on the current active header
15418		if ( !active.length ) {
15419			active = this.active;
15420		}
15421
15422		anchor = active.find( ".ui-tabs-anchor" )[ 0 ];
15423		this._eventHandler( {
15424			target: anchor,
15425			currentTarget: anchor,
15426			preventDefault: $.noop
15427		} );
15428	},
15429
15430	_findActive: function( index ) {
15431		return index === false ? $() : this.tabs.eq( index );
15432	},
15433
15434	_getIndex: function( index ) {
15435
15436		// meta-function to give users option to provide a href string instead of a numerical index.
15437		if ( typeof index === "string" ) {
15438			index = this.anchors.index( this.anchors.filter( "[href$='" +
15439				$.ui.escapeSelector( index ) + "']" ) );
15440		}
15441
15442		return index;
15443	},
15444
15445	_destroy: function() {
15446		if ( this.xhr ) {
15447			this.xhr.abort();
15448		}
15449
15450		this.tablist
15451			.removeAttr( "role" )
15452			.off( this.eventNamespace );
15453
15454		this.anchors
15455			.removeAttr( "role tabIndex" )
15456			.removeUniqueId();
15457
15458		this.tabs.add( this.panels ).each( function() {
15459			if ( $.data( this, "ui-tabs-destroy" ) ) {
15460				$( this ).remove();
15461			} else {
15462				$( this ).removeAttr( "role tabIndex " +
15463					"aria-live aria-busy aria-selected aria-labelledby aria-hidden aria-expanded" );
15464			}
15465		} );
15466
15467		this.tabs.each( function() {
15468			var li = $( this ),
15469				prev = li.data( "ui-tabs-aria-controls" );
15470			if ( prev ) {
15471				li
15472					.attr( "aria-controls", prev )
15473					.removeData( "ui-tabs-aria-controls" );
15474			} else {
15475				li.removeAttr( "aria-controls" );
15476			}
15477		} );
15478
15479		this.panels.show();
15480
15481		if ( this.options.heightStyle !== "content" ) {
15482			this.panels.css( "height", "" );
15483		}
15484	},
15485
15486	enable: function( index ) {
15487		var disabled = this.options.disabled;
15488		if ( disabled === false ) {
15489			return;
15490		}
15491
15492		if ( index === undefined ) {
15493			disabled = false;
15494		} else {
15495			index = this._getIndex( index );
15496			if ( $.isArray( disabled ) ) {
15497				disabled = $.map( disabled, function( num ) {
15498					return num !== index ? num : null;
15499				} );
15500			} else {
15501				disabled = $.map( this.tabs, function( li, num ) {
15502					return num !== index ? num : null;
15503				} );
15504			}
15505		}
15506		this._setOptionDisabled( disabled );
15507	},
15508
15509	disable: function( index ) {
15510		var disabled = this.options.disabled;
15511		if ( disabled === true ) {
15512			return;
15513		}
15514
15515		if ( index === undefined ) {
15516			disabled = true;
15517		} else {
15518			index = this._getIndex( index );
15519			if ( $.inArray( index, disabled ) !== -1 ) {
15520				return;
15521			}
15522			if ( $.isArray( disabled ) ) {
15523				disabled = $.merge( [ index ], disabled ).sort();
15524			} else {
15525				disabled = [ index ];
15526			}
15527		}
15528		this._setOptionDisabled( disabled );
15529	},
15530
15531	load: function( index, event ) {
15532		index = this._getIndex( index );
15533		var that = this,
15534			tab = this.tabs.eq( index ),
15535			anchor = tab.find( ".ui-tabs-anchor" ),
15536			panel = this._getPanelForTab( tab ),
15537			eventData = {
15538				tab: tab,
15539				panel: panel
15540			},
15541			complete = function( jqXHR, status ) {
15542				if ( status === "abort" ) {
15543					that.panels.stop( false, true );
15544				}
15545
15546				that._removeClass( tab, "ui-tabs-loading" );
15547				panel.removeAttr( "aria-busy" );
15548
15549				if ( jqXHR === that.xhr ) {
15550					delete that.xhr;
15551				}
15552			};
15553
15554		// Not remote
15555		if ( this._isLocal( anchor[ 0 ] ) ) {
15556			return;
15557		}
15558
15559		this.xhr = $.ajax( this._ajaxSettings( anchor, event, eventData ) );
15560
15561		// Support: jQuery <1.8
15562		// jQuery <1.8 returns false if the request is canceled in beforeSend,
15563		// but as of 1.8, $.ajax() always returns a jqXHR object.
15564		if ( this.xhr && this.xhr.statusText !== "canceled" ) {
15565			this._addClass( tab, "ui-tabs-loading" );
15566			panel.attr( "aria-busy", "true" );
15567
15568			this.xhr
15569				.done( function( response, status, jqXHR ) {
15570
15571					// support: jQuery <1.8
15572					// http://bugs.jquery.com/ticket/11778
15573					setTimeout( function() {
15574						panel.html( response );
15575						that._trigger( "load", event, eventData );
15576
15577						complete( jqXHR, status );
15578					}, 1 );
15579				} )
15580				.fail( function( jqXHR, status ) {
15581
15582					// support: jQuery <1.8
15583					// http://bugs.jquery.com/ticket/11778
15584					setTimeout( function() {
15585						complete( jqXHR, status );
15586					}, 1 );
15587				} );
15588		}
15589	},
15590
15591	_ajaxSettings: function( anchor, event, eventData ) {
15592		var that = this;
15593		return {
15594
15595			// Support: IE <11 only
15596			// Strip any hash that exists to prevent errors with the Ajax request
15597			url: anchor.attr( "href" ).replace( /#.*$/, "" ),
15598			beforeSend: function( jqXHR, settings ) {
15599				return that._trigger( "beforeLoad", event,
15600					$.extend( { jqXHR: jqXHR, ajaxSettings: settings }, eventData ) );
15601			}
15602		};
15603	},
15604
15605	_getPanelForTab: function( tab ) {
15606		var id = $( tab ).attr( "aria-controls" );
15607		return this.element.find( this._sanitizeSelector( "#" + id ) );
15608	}
15609} );
15610
15611// DEPRECATED
15612// TODO: Switch return back to widget declaration at top of file when this is removed
15613if ( $.uiBackCompat !== false ) {
15614
15615	// Backcompat for ui-tab class (now ui-tabs-tab)
15616	$.widget( "ui.tabs", $.ui.tabs, {
15617		_processTabs: function() {
15618			this._superApply( arguments );
15619			this._addClass( this.tabs, "ui-tab" );
15620		}
15621	} );
15622}
15623
15624var widgetsTabs = $.ui.tabs;
15625
15626
15627/*!
15628 * jQuery UI Tooltip 1.12.1
15629 * http://jqueryui.com
15630 *
15631 * Copyright jQuery Foundation and other contributors
15632 * Released under the MIT license.
15633 * http://jquery.org/license
15634 */
15635
15636//>>label: Tooltip
15637//>>group: Widgets
15638//>>description: Shows additional information for any element on hover or focus.
15639//>>docs: http://api.jqueryui.com/tooltip/
15640//>>demos: http://jqueryui.com/tooltip/
15641//>>css.structure: ../../themes/base/core.css
15642//>>css.structure: ../../themes/base/tooltip.css
15643//>>css.theme: ../../themes/base/theme.css
15644
15645
15646
15647$.widget( "ui.tooltip", {
15648	version: "1.12.1",
15649	options: {
15650		classes: {
15651			"ui-tooltip": "ui-corner-all ui-widget-shadow"
15652		},
15653		content: function() {
15654
15655			// support: IE<9, Opera in jQuery <1.7
15656			// .text() can't accept undefined, so coerce to a string
15657			var title = $( this ).attr( "title" ) || "";
15658
15659			// Escape title, since we're going from an attribute to raw HTML
15660			return $( "<a>" ).text( title ).html();
15661		},
15662		hide: true,
15663
15664		// Disabled elements have inconsistent behavior across browsers (#8661)
15665		items: "[title]:not([disabled])",
15666		position: {
15667			my: "left top+15",
15668			at: "left bottom",
15669			collision: "flipfit flip"
15670		},
15671		show: true,
15672		track: false,
15673
15674		// Callbacks
15675		close: null,
15676		open: null
15677	},
15678
15679	_addDescribedBy: function( elem, id ) {
15680		var describedby = ( elem.attr( "aria-describedby" ) || "" ).split( /\s+/ );
15681		describedby.push( id );
15682		elem
15683			.data( "ui-tooltip-id", id )
15684			.attr( "aria-describedby", $.trim( describedby.join( " " ) ) );
15685	},
15686
15687	_removeDescribedBy: function( elem ) {
15688		var id = elem.data( "ui-tooltip-id" ),
15689			describedby = ( elem.attr( "aria-describedby" ) || "" ).split( /\s+/ ),
15690			index = $.inArray( id, describedby );
15691
15692		if ( index !== -1 ) {
15693			describedby.splice( index, 1 );
15694		}
15695
15696		elem.removeData( "ui-tooltip-id" );
15697		describedby = $.trim( describedby.join( " " ) );
15698		if ( describedby ) {
15699			elem.attr( "aria-describedby", describedby );
15700		} else {
15701			elem.removeAttr( "aria-describedby" );
15702		}
15703	},
15704
15705	_create: function() {
15706		this._on( {
15707			mouseover: "open",
15708			focusin: "open"
15709		} );
15710
15711		// IDs of generated tooltips, needed for destroy
15712		this.tooltips = {};
15713
15714		// IDs of parent tooltips where we removed the title attribute
15715		this.parents = {};
15716
15717		// Append the aria-live region so tooltips announce correctly
15718		this.liveRegion = $( "<div>" )
15719			.attr( {
15720				role: "log",
15721				"aria-live": "assertive",
15722				"aria-relevant": "additions"
15723			} )
15724			.appendTo( this.document[ 0 ].body );
15725		this._addClass( this.liveRegion, null, "ui-helper-hidden-accessible" );
15726
15727		this.disabledTitles = $( [] );
15728	},
15729
15730	_setOption: function( key, value ) {
15731		var that = this;
15732
15733		this._super( key, value );
15734
15735		if ( key === "content" ) {
15736			$.each( this.tooltips, function( id, tooltipData ) {
15737				that._updateContent( tooltipData.element );
15738			} );
15739		}
15740	},
15741
15742	_setOptionDisabled: function( value ) {
15743		this[ value ? "_disable" : "_enable" ]();
15744	},
15745
15746	_disable: function() {
15747		var that = this;
15748
15749		// Close open tooltips
15750		$.each( this.tooltips, function( id, tooltipData ) {
15751			var event = $.Event( "blur" );
15752			event.target = event.currentTarget = tooltipData.element[ 0 ];
15753			that.close( event, true );
15754		} );
15755
15756		// Remove title attributes to prevent native tooltips
15757		this.disabledTitles = this.disabledTitles.add(
15758			this.element.find( this.options.items ).addBack()
15759				.filter( function() {
15760					var element = $( this );
15761					if ( element.is( "[title]" ) ) {
15762						return element
15763							.data( "ui-tooltip-title", element.attr( "title" ) )
vendor: 4,119 bytes, lines 15764-15899
15764							.removeAttr( "title" );
15765					}
15766				} )
15767		);
15768	},
15769
15770	_enable: function() {
15771
15772		// restore title attributes
15773		this.disabledTitles.each( function() {
15774			var element = $( this );
15775			if ( element.data( "ui-tooltip-title" ) ) {
15776				element.attr( "title", element.data( "ui-tooltip-title" ) );
15777			}
15778		} );
15779		this.disabledTitles = $( [] );
15780	},
15781
15782	open: function( event ) {
15783		var that = this,
15784			target = $( event ? event.target : this.element )
15785
15786				// we need closest here due to mouseover bubbling,
15787				// but always pointing at the same event target
15788				.closest( this.options.items );
15789
15790		// No element to show a tooltip for or the tooltip is already open
15791		if ( !target.length || target.data( "ui-tooltip-id" ) ) {
15792			return;
15793		}
15794
15795		if ( target.attr( "title" ) ) {
15796			target.data( "ui-tooltip-title", target.attr( "title" ) );
15797		}
15798
15799		target.data( "ui-tooltip-open", true );
15800
15801		// Kill parent tooltips, custom or native, for hover
15802		if ( event && event.type === "mouseover" ) {
15803			target.parents().each( function() {
15804				var parent = $( this ),
15805					blurEvent;
15806				if ( parent.data( "ui-tooltip-open" ) ) {
15807					blurEvent = $.Event( "blur" );
15808					blurEvent.target = blurEvent.currentTarget = this;
15809					that.close( blurEvent, true );
15810				}
15811				if ( parent.attr( "title" ) ) {
15812					parent.uniqueId();
15813					that.parents[ this.id ] = {
15814						element: this,
15815						title: parent.attr( "title" )
15816					};
15817					parent.attr( "title", "" );
15818				}
15819			} );
15820		}
15821
15822		this._registerCloseHandlers( event, target );
15823		this._updateContent( target, event );
15824	},
15825
15826	_updateContent: function( target, event ) {
15827		var content,
15828			contentOption = this.options.content,
15829			that = this,
15830			eventType = event ? event.type : null;
15831
15832		if ( typeof contentOption === "string" || contentOption.nodeType ||
15833				contentOption.jquery ) {
15834			return this._open( event, target, contentOption );
15835		}
15836
15837		content = contentOption.call( target[ 0 ], function( response ) {
15838
15839			// IE may instantly serve a cached response for ajax requests
15840			// delay this call to _open so the other call to _open runs first
15841			that._delay( function() {
15842
15843				// Ignore async response if tooltip was closed already
15844				if ( !target.data( "ui-tooltip-open" ) ) {
15845					return;
15846				}
15847
15848				// JQuery creates a special event for focusin when it doesn't
15849				// exist natively. To improve performance, the native event
15850				// object is reused and the type is changed. Therefore, we can't
15851				// rely on the type being correct after the event finished
15852				// bubbling, so we set it back to the previous value. (#8740)
15853				if ( event ) {
15854					event.type = eventType;
15855				}
15856				this._open( event, target, response );
15857			} );
15858		} );
15859		if ( content ) {
15860			this._open( event, target, content );
15861		}
15862	},
15863
15864	_open: function( event, target, content ) {
15865		var tooltipData, tooltip, delayedShow, a11yContent,
15866			positionOption = $.extend( {}, this.options.position );
15867
15868		if ( !content ) {
15869			return;
15870		}
15871
15872		// Content can be updated multiple times. If the tooltip already
15873		// exists, then just update the content and bail.
15874		tooltipData = this._find( target );
15875		if ( tooltipData ) {
15876			tooltipData.tooltip.find( ".ui-tooltip-content" ).html( content );
15877			return;
15878		}
15879
15880		// If we have a title, clear it to prevent the native tooltip
15881		// we have to check first to avoid defining a title if none exists
15882		// (we don't want to cause an element to start matching [title])
15883		//
15884		// We use removeAttr only for key events, to allow IE to export the correct
15885		// accessible attributes. For mouse events, set to empty string to avoid
15886		// native tooltip showing up (happens only when removing inside mouseover).
15887		if ( target.is( "[title]" ) ) {
15888			if ( event && event.type === "mouseover" ) {
15889				target.attr( "title", "" );
15890			} else {
15891				target.removeAttr( "title" );
15892			}
15893		}
15894
15895		tooltipData = this._tooltip( target );
15896		tooltip = tooltipData.tooltip;
15897		this._addDescribedBy( target, tooltip.attr( "id" ) );
15898		tooltip.find( ".ui-tooltip-content" ).html( content );
15899
vendor: 12,020 bytes, lines 15900-16341
15900		// Support: Voiceover on OS X, JAWS on IE <= 9
15901		// JAWS announces deletions even when aria-relevant="additions"
15902		// Voiceover will sometimes re-read the entire log region's contents from the beginning
15903		this.liveRegion.children().hide();
15904		a11yContent = $( "<div>" ).html( tooltip.find( ".ui-tooltip-content" ).html() );
15905		a11yContent.removeAttr( "name" ).find( "[name]" ).removeAttr( "name" );
15906		a11yContent.removeAttr( "id" ).find( "[id]" ).removeAttr( "id" );
15907		a11yContent.appendTo( this.liveRegion );
15908
15909		function position( event ) {
15910			positionOption.of = event;
15911			if ( tooltip.is( ":hidden" ) ) {
15912				return;
15913			}
15914			tooltip.position( positionOption );
15915		}
15916		if ( this.options.track && event && /^mouse/.test( event.type ) ) {
15917			this._on( this.document, {
15918				mousemove: position
15919			} );
15920
15921			// trigger once to override element-relative positioning
15922			position( event );
15923		} else {
15924			tooltip.position( $.extend( {
15925				of: target
15926			}, this.options.position ) );
15927		}
15928
15929		tooltip.hide();
15930
15931		this._show( tooltip, this.options.show );
15932
15933		// Handle tracking tooltips that are shown with a delay (#8644). As soon
15934		// as the tooltip is visible, position the tooltip using the most recent
15935		// event.
15936		// Adds the check to add the timers only when both delay and track options are set (#14682)
15937		if ( this.options.track && this.options.show && this.options.show.delay ) {
15938			delayedShow = this.delayedShow = setInterval( function() {
15939				if ( tooltip.is( ":visible" ) ) {
15940					position( positionOption.of );
15941					clearInterval( delayedShow );
15942				}
15943			}, $.fx.interval );
15944		}
15945
15946		this._trigger( "open", event, { tooltip: tooltip } );
15947	},
15948
15949	_registerCloseHandlers: function( event, target ) {
15950		var events = {
15951			keyup: function( event ) {
15952				if ( event.keyCode === $.ui.keyCode.ESCAPE ) {
15953					var fakeEvent = $.Event( event );
15954					fakeEvent.currentTarget = target[ 0 ];
15955					this.close( fakeEvent, true );
15956				}
15957			}
15958		};
15959
15960		// Only bind remove handler for delegated targets. Non-delegated
15961		// tooltips will handle this in destroy.
15962		if ( target[ 0 ] !== this.element[ 0 ] ) {
15963			events.remove = function() {
15964				this._removeTooltip( this._find( target ).tooltip );
15965			};
15966		}
15967
15968		if ( !event || event.type === "mouseover" ) {
15969			events.mouseleave = "close";
15970		}
15971		if ( !event || event.type === "focusin" ) {
15972			events.focusout = "close";
15973		}
15974		this._on( true, target, events );
15975	},
15976
15977	close: function( event ) {
15978		var tooltip,
15979			that = this,
15980			target = $( event ? event.currentTarget : this.element ),
15981			tooltipData = this._find( target );
15982
15983		// The tooltip may already be closed
15984		if ( !tooltipData ) {
15985
15986			// We set ui-tooltip-open immediately upon open (in open()), but only set the
15987			// additional data once there's actually content to show (in _open()). So even if the
15988			// tooltip doesn't have full data, we always remove ui-tooltip-open in case we're in
15989			// the period between open() and _open().
15990			target.removeData( "ui-tooltip-open" );
15991			return;
15992		}
15993
15994		tooltip = tooltipData.tooltip;
15995
15996		// Disabling closes the tooltip, so we need to track when we're closing
15997		// to avoid an infinite loop in case the tooltip becomes disabled on close
15998		if ( tooltipData.closing ) {
15999			return;
16000		}
16001
16002		// Clear the interval for delayed tracking tooltips
16003		clearInterval( this.delayedShow );
16004
16005		// Only set title if we had one before (see comment in _open())
16006		// If the title attribute has changed since open(), don't restore
16007		if ( target.data( "ui-tooltip-title" ) && !target.attr( "title" ) ) {
16008			target.attr( "title", target.data( "ui-tooltip-title" ) );
16009		}
16010
16011		this._removeDescribedBy( target );
16012
16013		tooltipData.hiding = true;
16014		tooltip.stop( true );
16015		this._hide( tooltip, this.options.hide, function() {
16016			that._removeTooltip( $( this ) );
16017		} );
16018
16019		target.removeData( "ui-tooltip-open" );
16020		this._off( target, "mouseleave focusout keyup" );
16021
16022		// Remove 'remove' binding only on delegated targets
16023		if ( target[ 0 ] !== this.element[ 0 ] ) {
16024			this._off( target, "remove" );
16025		}
16026		this._off( this.document, "mousemove" );
16027
16028		if ( event && event.type === "mouseleave" ) {
16029			$.each( this.parents, function( id, parent ) {
16030				$( parent.element ).attr( "title", parent.title );
16031				delete that.parents[ id ];
16032			} );
16033		}
16034
16035		tooltipData.closing = true;
16036		this._trigger( "close", event, { tooltip: tooltip } );
16037		if ( !tooltipData.hiding ) {
16038			tooltipData.closing = false;
16039		}
16040	},
16041
16042	_tooltip: function( element ) {
16043		var tooltip = $( "<div>" ).attr( "role", "tooltip" ),
16044			content = $( "<div>" ).appendTo( tooltip ),
16045			id = tooltip.uniqueId().attr( "id" );
16046
16047		this._addClass( content, "ui-tooltip-content" );
16048		this._addClass( tooltip, "ui-tooltip", "ui-widget ui-widget-content" );
16049
16050		tooltip.appendTo( this._appendTo( element ) );
16051
16052		return this.tooltips[ id ] = {
16053			element: element,
16054			tooltip: tooltip
16055		};
16056	},
16057
16058	_find: function( target ) {
16059		var id = target.data( "ui-tooltip-id" );
16060		return id ? this.tooltips[ id ] : null;
16061	},
16062
16063	_removeTooltip: function( tooltip ) {
16064		tooltip.remove();
16065		delete this.tooltips[ tooltip.attr( "id" ) ];
16066	},
16067
16068	_appendTo: function( target ) {
16069		var element = target.closest( ".ui-front, dialog" );
16070
16071		if ( !element.length ) {
16072			element = this.document[ 0 ].body;
16073		}
16074
16075		return element;
16076	},
16077
16078	_destroy: function() {
16079		var that = this;
16080
16081		// Close open tooltips
16082		$.each( this.tooltips, function( id, tooltipData ) {
16083
16084			// Delegate to close method to handle common cleanup
16085			var event = $.Event( "blur" ),
16086				element = tooltipData.element;
16087			event.target = event.currentTarget = element[ 0 ];
16088			that.close( event, true );
16089
16090			// Remove immediately; destroying an open tooltip doesn't use the
16091			// hide animation
16092			$( "#" + id ).remove();
16093
16094			// Restore the title
16095			if ( element.data( "ui-tooltip-title" ) ) {
16096
16097				// If the title attribute has changed since open(), don't restore
16098				if ( !element.attr( "title" ) ) {
16099					element.attr( "title", element.data( "ui-tooltip-title" ) );
16100				}
16101				element.removeData( "ui-tooltip-title" );
16102			}
16103		} );
16104		this.liveRegion.remove();
16105	}
16106} );
16107
16108// DEPRECATED
16109// TODO: Switch return back to widget declaration at top of file when this is removed
16110if ( $.uiBackCompat !== false ) {
16111
16112	// Backcompat for tooltipClass option
16113	$.widget( "ui.tooltip", $.ui.tooltip, {
16114		options: {
16115			tooltipClass: null
16116		},
16117		_tooltip: function() {
16118			var tooltipData = this._superApply( arguments );
16119			if ( this.options.tooltipClass ) {
16120				tooltipData.tooltip.addClass( this.options.tooltipClass );
16121			}
16122			return tooltipData;
16123		}
16124	} );
16125}
16126
16127var widgetsTooltip = $.ui.tooltip;
16128
16129
16130/*!
16131 * jQuery UI Effects 1.12.1
16132 * http://jqueryui.com
16133 *
16134 * Copyright jQuery Foundation and other contributors
16135 * Released under the MIT license.
16136 * http://jquery.org/license
16137 */
16138
16139//>>label: Effects Core
16140//>>group: Effects
16141// jscs:disable maximumLineLength
16142//>>description: Extends the internal jQuery effects. Includes morphing and easing. Required by all other effects.
16143// jscs:enable maximumLineLength
16144//>>docs: http://api.jqueryui.com/category/effects-core/
16145//>>demos: http://jqueryui.com/effect/
16146
16147
16148
16149var dataSpace = "ui-effects-",
16150	dataSpaceStyle = "ui-effects-style",
16151	dataSpaceAnimated = "ui-effects-animated",
16152
16153	// Create a local jQuery because jQuery Color relies on it and the
16154	// global may not exist with AMD and a custom build (#10199)
16155	jQuery = $;
16156
16157$.effects = {
16158	effect: {}
16159};
16160
16161/*!
16162 * jQuery Color Animations v2.1.2
16163 * https://github.com/jquery/jquery-color
16164 *
16165 * Copyright 2014 jQuery Foundation and other contributors
16166 * Released under the MIT license.
16167 * http://jquery.org/license
16168 *
16169 * Date: Wed Jan 16 08:47:09 2013 -0600
16170 */
16171( function( jQuery, undefined ) {
16172
16173	var stepHooks = "backgroundColor borderBottomColor borderLeftColor borderRightColor " +
16174		"borderTopColor color columnRuleColor outlineColor textDecorationColor textEmphasisColor",
16175
16176	// Plusequals test for += 100 -= 100
16177	rplusequals = /^([\-+])=\s*(\d+\.?\d*)/,
16178
16179	// A set of RE's that can match strings and generate color tuples.
16180	stringParsers = [ {
16181			re: /rgba?\(\s*(\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(\d{1,3})\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/,
16182			parse: function( execResult ) {
16183				return [
16184					execResult[ 1 ],
16185					execResult[ 2 ],
16186					execResult[ 3 ],
16187					execResult[ 4 ]
16188				];
16189			}
16190		}, {
16191			re: /rgba?\(\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/,
16192			parse: function( execResult ) {
16193				return [
16194					execResult[ 1 ] * 2.55,
16195					execResult[ 2 ] * 2.55,
16196					execResult[ 3 ] * 2.55,
16197					execResult[ 4 ]
16198				];
16199			}
16200		}, {
16201
16202			// This regex ignores A-F because it's compared against an already lowercased string
16203			re: /#([a-f0-9]{2})([a-f0-9]{2})([a-f0-9]{2})/,
16204			parse: function( execResult ) {
16205				return [
16206					parseInt( execResult[ 1 ], 16 ),
16207					parseInt( execResult[ 2 ], 16 ),
16208					parseInt( execResult[ 3 ], 16 )
16209				];
16210			}
16211		}, {
16212
16213			// This regex ignores A-F because it's compared against an already lowercased string
16214			re: /#([a-f0-9])([a-f0-9])([a-f0-9])/,
16215			parse: function( execResult ) {
16216				return [
16217					parseInt( execResult[ 1 ] + execResult[ 1 ], 16 ),
16218					parseInt( execResult[ 2 ] + execResult[ 2 ], 16 ),
16219					parseInt( execResult[ 3 ] + execResult[ 3 ], 16 )
16220				];
16221			}
16222		}, {
16223			re: /hsla?\(\s*(\d+(?:\.\d+)?)\s*,\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/,
16224			space: "hsla",
16225			parse: function( execResult ) {
16226				return [
16227					execResult[ 1 ],
16228					execResult[ 2 ] / 100,
16229					execResult[ 3 ] / 100,
16230					execResult[ 4 ]
16231				];
16232			}
16233		} ],
16234
16235	// JQuery.Color( )
16236	color = jQuery.Color = function( color, green, blue, alpha ) {
16237		return new jQuery.Color.fn.parse( color, green, blue, alpha );
16238	},
16239	spaces = {
16240		rgba: {
16241			props: {
16242				red: {
16243					idx: 0,
16244					type: "byte"
16245				},
16246				green: {
16247					idx: 1,
16248					type: "byte"
16249				},
16250				blue: {
16251					idx: 2,
16252					type: "byte"
16253				}
16254			}
16255		},
16256
16257		hsla: {
16258			props: {
16259				hue: {
16260					idx: 0,
16261					type: "degrees"
16262				},
16263				saturation: {
16264					idx: 1,
16265					type: "percent"
16266				},
16267				lightness: {
16268					idx: 2,
16269					type: "percent"
16270				}
16271			}
16272		}
16273	},
16274	propTypes = {
16275		"byte": {
16276			floor: true,
16277			max: 255
16278		},
16279		"percent": {
16280			max: 1
16281		},
16282		"degrees": {
16283			mod: 360,
16284			floor: true
16285		}
16286	},
16287	support = color.support = {},
16288
16289	// Element for support tests
16290	supportElem = jQuery( "<p>" )[ 0 ],
16291
16292	// Colors = jQuery.Color.names
16293	colors,
16294
16295	// Local aliases of functions called often
16296	each = jQuery.each;
16297
16298// Determine rgba support immediately
16299supportElem.style.cssText = "background-color:rgba(1,1,1,.5)";
16300support.rgba = supportElem.style.backgroundColor.indexOf( "rgba" ) > -1;
16301
16302// Define cache name and alpha properties
16303// for rgba and hsla spaces
16304each( spaces, function( spaceName, space ) {
16305	space.cache = "_" + spaceName;
16306	space.props.alpha = {
16307		idx: 3,
16308		type: "percent",
16309		def: 1
16310	};
16311} );
16312
16313function clamp( value, prop, allowEmpty ) {
16314	var type = propTypes[ prop.type ] || {};
16315
16316	if ( value == null ) {
16317		return ( allowEmpty || !prop.def ) ? null : prop.def;
16318	}
16319
16320	// ~~ is an short way of doing floor for positive numbers
16321	value = type.floor ? ~~value : parseFloat( value );
16322
16323	// IE will pass in empty strings as value for alpha,
16324	// which will hit this case
16325	if ( isNaN( value ) ) {
16326		return prop.def;
16327	}
16328
16329	if ( type.mod ) {
16330
16331		// We add mod before modding to make sure that negatives values
16332		// get converted properly: -10 -> 350
16333		return ( value + type.mod ) % type.mod;
16334	}
16335
16336	// For now all property types without mod have min and max
16337	return 0 > value ? 0 : type.max < value ? type.max : value;
16338}
16339
16340function stringParse( string ) {
16341	var inst = color(),
vendor: 16,726 bytes, lines 16342-16996
16342		rgba = inst._rgba = [];
16343
16344	string = string.toLowerCase();
16345
16346	each( stringParsers, function( i, parser ) {
16347		var parsed,
16348			match = parser.re.exec( string ),
16349			values = match && parser.parse( match ),
16350			spaceName = parser.space || "rgba";
16351
16352		if ( values ) {
16353			parsed = inst[ spaceName ]( values );
16354
16355			// If this was an rgba parse the assignment might happen twice
16356			// oh well....
16357			inst[ spaces[ spaceName ].cache ] = parsed[ spaces[ spaceName ].cache ];
16358			rgba = inst._rgba = parsed._rgba;
16359
16360			// Exit each( stringParsers ) here because we matched
16361			return false;
16362		}
16363	} );
16364
16365	// Found a stringParser that handled it
16366	if ( rgba.length ) {
16367
16368		// If this came from a parsed string, force "transparent" when alpha is 0
16369		// chrome, (and maybe others) return "transparent" as rgba(0,0,0,0)
16370		if ( rgba.join() === "0,0,0,0" ) {
16371			jQuery.extend( rgba, colors.transparent );
16372		}
16373		return inst;
16374	}
16375
16376	// Named colors
16377	return colors[ string ];
16378}
16379
16380color.fn = jQuery.extend( color.prototype, {
16381	parse: function( red, green, blue, alpha ) {
16382		if ( red === undefined ) {
16383			this._rgba = [ null, null, null, null ];
16384			return this;
16385		}
16386		if ( red.jquery || red.nodeType ) {
16387			red = jQuery( red ).css( green );
16388			green = undefined;
16389		}
16390
16391		var inst = this,
16392			type = jQuery.type( red ),
16393			rgba = this._rgba = [];
16394
16395		// More than 1 argument specified - assume ( red, green, blue, alpha )
16396		if ( green !== undefined ) {
16397			red = [ red, green, blue, alpha ];
16398			type = "array";
16399		}
16400
16401		if ( type === "string" ) {
16402			return this.parse( stringParse( red ) || colors._default );
16403		}
16404
16405		if ( type === "array" ) {
16406			each( spaces.rgba.props, function( key, prop ) {
16407				rgba[ prop.idx ] = clamp( red[ prop.idx ], prop );
16408			} );
16409			return this;
16410		}
16411
16412		if ( type === "object" ) {
16413			if ( red instanceof color ) {
16414				each( spaces, function( spaceName, space ) {
16415					if ( red[ space.cache ] ) {
16416						inst[ space.cache ] = red[ space.cache ].slice();
16417					}
16418				} );
16419			} else {
16420				each( spaces, function( spaceName, space ) {
16421					var cache = space.cache;
16422					each( space.props, function( key, prop ) {
16423
16424						// If the cache doesn't exist, and we know how to convert
16425						if ( !inst[ cache ] && space.to ) {
16426
16427							// If the value was null, we don't need to copy it
16428							// if the key was alpha, we don't need to copy it either
16429							if ( key === "alpha" || red[ key ] == null ) {
16430								return;
16431							}
16432							inst[ cache ] = space.to( inst._rgba );
16433						}
16434
16435						// This is the only case where we allow nulls for ALL properties.
16436						// call clamp with alwaysAllowEmpty
16437						inst[ cache ][ prop.idx ] = clamp( red[ key ], prop, true );
16438					} );
16439
16440					// Everything defined but alpha?
16441					if ( inst[ cache ] &&
16442							jQuery.inArray( null, inst[ cache ].slice( 0, 3 ) ) < 0 ) {
16443
16444						// Use the default of 1
16445						inst[ cache ][ 3 ] = 1;
16446						if ( space.from ) {
16447							inst._rgba = space.from( inst[ cache ] );
16448						}
16449					}
16450				} );
16451			}
16452			return this;
16453		}
16454	},
16455	is: function( compare ) {
16456		var is = color( compare ),
16457			same = true,
16458			inst = this;
16459
16460		each( spaces, function( _, space ) {
16461			var localCache,
16462				isCache = is[ space.cache ];
16463			if ( isCache ) {
16464				localCache = inst[ space.cache ] || space.to && space.to( inst._rgba ) || [];
16465				each( space.props, function( _, prop ) {
16466					if ( isCache[ prop.idx ] != null ) {
16467						same = ( isCache[ prop.idx ] === localCache[ prop.idx ] );
16468						return same;
16469					}
16470				} );
16471			}
16472			return same;
16473		} );
16474		return same;
16475	},
16476	_space: function() {
16477		var used = [],
16478			inst = this;
16479		each( spaces, function( spaceName, space ) {
16480			if ( inst[ space.cache ] ) {
16481				used.push( spaceName );
16482			}
16483		} );
16484		return used.pop();
16485	},
16486	transition: function( other, distance ) {
16487		var end = color( other ),
16488			spaceName = end._space(),
16489			space = spaces[ spaceName ],
16490			startColor = this.alpha() === 0 ? color( "transparent" ) : this,
16491			start = startColor[ space.cache ] || space.to( startColor._rgba ),
16492			result = start.slice();
16493
16494		end = end[ space.cache ];
16495		each( space.props, function( key, prop ) {
16496			var index = prop.idx,
16497				startValue = start[ index ],
16498				endValue = end[ index ],
16499				type = propTypes[ prop.type ] || {};
16500
16501			// If null, don't override start value
16502			if ( endValue === null ) {
16503				return;
16504			}
16505
16506			// If null - use end
16507			if ( startValue === null ) {
16508				result[ index ] = endValue;
16509			} else {
16510				if ( type.mod ) {
16511					if ( endValue - startValue > type.mod / 2 ) {
16512						startValue += type.mod;
16513					} else if ( startValue - endValue > type.mod / 2 ) {
16514						startValue -= type.mod;
16515					}
16516				}
16517				result[ index ] = clamp( ( endValue - startValue ) * distance + startValue, prop );
16518			}
16519		} );
16520		return this[ spaceName ]( result );
16521	},
16522	blend: function( opaque ) {
16523
16524		// If we are already opaque - return ourself
16525		if ( this._rgba[ 3 ] === 1 ) {
16526			return this;
16527		}
16528
16529		var rgb = this._rgba.slice(),
16530			a = rgb.pop(),
16531			blend = color( opaque )._rgba;
16532
16533		return color( jQuery.map( rgb, function( v, i ) {
16534			return ( 1 - a ) * blend[ i ] + a * v;
16535		} ) );
16536	},
16537	toRgbaString: function() {
16538		var prefix = "rgba(",
16539			rgba = jQuery.map( this._rgba, function( v, i ) {
16540				return v == null ? ( i > 2 ? 1 : 0 ) : v;
16541			} );
16542
16543		if ( rgba[ 3 ] === 1 ) {
16544			rgba.pop();
16545			prefix = "rgb(";
16546		}
16547
16548		return prefix + rgba.join() + ")";
16549	},
16550	toHslaString: function() {
16551		var prefix = "hsla(",
16552			hsla = jQuery.map( this.hsla(), function( v, i ) {
16553				if ( v == null ) {
16554					v = i > 2 ? 1 : 0;
16555				}
16556
16557				// Catch 1 and 2
16558				if ( i && i < 3 ) {
16559					v = Math.round( v * 100 ) + "%";
16560				}
16561				return v;
16562			} );
16563
16564		if ( hsla[ 3 ] === 1 ) {
16565			hsla.pop();
16566			prefix = "hsl(";
16567		}
16568		return prefix + hsla.join() + ")";
16569	},
16570	toHexString: function( includeAlpha ) {
16571		var rgba = this._rgba.slice(),
16572			alpha = rgba.pop();
16573
16574		if ( includeAlpha ) {
16575			rgba.push( ~~( alpha * 255 ) );
16576		}
16577
16578		return "#" + jQuery.map( rgba, function( v ) {
16579
16580			// Default to 0 when nulls exist
16581			v = ( v || 0 ).toString( 16 );
16582			return v.length === 1 ? "0" + v : v;
16583		} ).join( "" );
16584	},
16585	toString: function() {
16586		return this._rgba[ 3 ] === 0 ? "transparent" : this.toRgbaString();
16587	}
16588} );
16589color.fn.parse.prototype = color.fn;
16590
16591// Hsla conversions adapted from:
16592// https://code.google.com/p/maashaack/source/browse/packages/graphics/trunk/src/graphics/colors/HUE2RGB.as?r=5021
16593
16594function hue2rgb( p, q, h ) {
16595	h = ( h + 1 ) % 1;
16596	if ( h * 6 < 1 ) {
16597		return p + ( q - p ) * h * 6;
16598	}
16599	if ( h * 2 < 1 ) {
16600		return q;
16601	}
16602	if ( h * 3 < 2 ) {
16603		return p + ( q - p ) * ( ( 2 / 3 ) - h ) * 6;
16604	}
16605	return p;
16606}
16607
16608spaces.hsla.to = function( rgba ) {
16609	if ( rgba[ 0 ] == null || rgba[ 1 ] == null || rgba[ 2 ] == null ) {
16610		return [ null, null, null, rgba[ 3 ] ];
16611	}
16612	var r = rgba[ 0 ] / 255,
16613		g = rgba[ 1 ] / 255,
16614		b = rgba[ 2 ] / 255,
16615		a = rgba[ 3 ],
16616		max = Math.max( r, g, b ),
16617		min = Math.min( r, g, b ),
16618		diff = max - min,
16619		add = max + min,
16620		l = add * 0.5,
16621		h, s;
16622
16623	if ( min === max ) {
16624		h = 0;
16625	} else if ( r === max ) {
16626		h = ( 60 * ( g - b ) / diff ) + 360;
16627	} else if ( g === max ) {
16628		h = ( 60 * ( b - r ) / diff ) + 120;
16629	} else {
16630		h = ( 60 * ( r - g ) / diff ) + 240;
16631	}
16632
16633	// Chroma (diff) == 0 means greyscale which, by definition, saturation = 0%
16634	// otherwise, saturation is based on the ratio of chroma (diff) to lightness (add)
16635	if ( diff === 0 ) {
16636		s = 0;
16637	} else if ( l <= 0.5 ) {
16638		s = diff / add;
16639	} else {
16640		s = diff / ( 2 - add );
16641	}
16642	return [ Math.round( h ) % 360, s, l, a == null ? 1 : a ];
16643};
16644
16645spaces.hsla.from = function( hsla ) {
16646	if ( hsla[ 0 ] == null || hsla[ 1 ] == null || hsla[ 2 ] == null ) {
16647		return [ null, null, null, hsla[ 3 ] ];
16648	}
16649	var h = hsla[ 0 ] / 360,
16650		s = hsla[ 1 ],
16651		l = hsla[ 2 ],
16652		a = hsla[ 3 ],
16653		q = l <= 0.5 ? l * ( 1 + s ) : l + s - l * s,
16654		p = 2 * l - q;
16655
16656	return [
16657		Math.round( hue2rgb( p, q, h + ( 1 / 3 ) ) * 255 ),
16658		Math.round( hue2rgb( p, q, h ) * 255 ),
16659		Math.round( hue2rgb( p, q, h - ( 1 / 3 ) ) * 255 ),
16660		a
16661	];
16662};
16663
16664each( spaces, function( spaceName, space ) {
16665	var props = space.props,
16666		cache = space.cache,
16667		to = space.to,
16668		from = space.from;
16669
16670	// Makes rgba() and hsla()
16671	color.fn[ spaceName ] = function( value ) {
16672
16673		// Generate a cache for this space if it doesn't exist
16674		if ( to && !this[ cache ] ) {
16675			this[ cache ] = to( this._rgba );
16676		}
16677		if ( value === undefined ) {
16678			return this[ cache ].slice();
16679		}
16680
16681		var ret,
16682			type = jQuery.type( value ),
16683			arr = ( type === "array" || type === "object" ) ? value : arguments,
16684			local = this[ cache ].slice();
16685
16686		each( props, function( key, prop ) {
16687			var val = arr[ type === "object" ? key : prop.idx ];
16688			if ( val == null ) {
16689				val = local[ prop.idx ];
16690			}
16691			local[ prop.idx ] = clamp( val, prop );
16692		} );
16693
16694		if ( from ) {
16695			ret = color( from( local ) );
16696			ret[ cache ] = local;
16697			return ret;
16698		} else {
16699			return color( local );
16700		}
16701	};
16702
16703	// Makes red() green() blue() alpha() hue() saturation() lightness()
16704	each( props, function( key, prop ) {
16705
16706		// Alpha is included in more than one space
16707		if ( color.fn[ key ] ) {
16708			return;
16709		}
16710		color.fn[ key ] = function( value ) {
16711			var vtype = jQuery.type( value ),
16712				fn = ( key === "alpha" ? ( this._hsla ? "hsla" : "rgba" ) : spaceName ),
16713				local = this[ fn ](),
16714				cur = local[ prop.idx ],
16715				match;
16716
16717			if ( vtype === "undefined" ) {
16718				return cur;
16719			}
16720
16721			if ( vtype === "function" ) {
16722				value = value.call( this, cur );
16723				vtype = jQuery.type( value );
16724			}
16725			if ( value == null && prop.empty ) {
16726				return this;
16727			}
16728			if ( vtype === "string" ) {
16729				match = rplusequals.exec( value );
16730				if ( match ) {
16731					value = cur + parseFloat( match[ 2 ] ) * ( match[ 1 ] === "+" ? 1 : -1 );
16732				}
16733			}
16734			local[ prop.idx ] = value;
16735			return this[ fn ]( local );
16736		};
16737	} );
16738} );
16739
16740// Add cssHook and .fx.step function for each named hook.
16741// accept a space separated string of properties
16742color.hook = function( hook ) {
16743	var hooks = hook.split( " " );
16744	each( hooks, function( i, hook ) {
16745		jQuery.cssHooks[ hook ] = {
16746			set: function( elem, value ) {
16747				var parsed, curElem,
16748					backgroundColor = "";
16749
16750				if ( value !== "transparent" && ( jQuery.type( value ) !== "string" ||
16751						( parsed = stringParse( value ) ) ) ) {
16752					value = color( parsed || value );
16753					if ( !support.rgba && value._rgba[ 3 ] !== 1 ) {
16754						curElem = hook === "backgroundColor" ? elem.parentNode : elem;
16755						while (
16756							( backgroundColor === "" || backgroundColor === "transparent" ) &&
16757							curElem && curElem.style
16758						) {
16759							try {
16760								backgroundColor = jQuery.css( curElem, "backgroundColor" );
16761								curElem = curElem.parentNode;
16762							} catch ( e ) {
16763							}
16764						}
16765
16766						value = value.blend( backgroundColor && backgroundColor !== "transparent" ?
16767							backgroundColor :
16768							"_default" );
16769					}
16770
16771					value = value.toRgbaString();
16772				}
16773				try {
16774					elem.style[ hook ] = value;
16775				} catch ( e ) {
16776
16777					// Wrapped to prevent IE from throwing errors on "invalid" values like
16778					// 'auto' or 'inherit'
16779				}
16780			}
16781		};
16782		jQuery.fx.step[ hook ] = function( fx ) {
16783			if ( !fx.colorInit ) {
16784				fx.start = color( fx.elem, hook );
16785				fx.end = color( fx.end );
16786				fx.colorInit = true;
16787			}
16788			jQuery.cssHooks[ hook ].set( fx.elem, fx.start.transition( fx.end, fx.pos ) );
16789		};
16790	} );
16791
16792};
16793
16794color.hook( stepHooks );
16795
16796jQuery.cssHooks.borderColor = {
16797	expand: function( value ) {
16798		var expanded = {};
16799
16800		each( [ "Top", "Right", "Bottom", "Left" ], function( i, part ) {
16801			expanded[ "border" + part + "Color" ] = value;
16802		} );
16803		return expanded;
16804	}
16805};
16806
16807// Basic color names only.
16808// Usage of any of the other color names requires adding yourself or including
16809// jquery.color.svg-names.js.
16810colors = jQuery.Color.names = {
16811
16812	// 4.1. Basic color keywords
16813	aqua: "#00ffff",
16814	black: "#000000",
16815	blue: "#0000ff",
16816	fuchsia: "#ff00ff",
16817	gray: "#808080",
16818	green: "#008000",
16819	lime: "#00ff00",
16820	maroon: "#800000",
16821	navy: "#000080",
16822	olive: "#808000",
16823	purple: "#800080",
16824	red: "#ff0000",
16825	silver: "#c0c0c0",
16826	teal: "#008080",
16827	white: "#ffffff",
16828	yellow: "#ffff00",
16829
16830	// 4.2.3. "transparent" color keyword
16831	transparent: [ null, null, null, 0 ],
16832
16833	_default: "#ffffff"
16834};
16835
16836} )( jQuery );
16837
16838/******************************************************************************/
16839/****************************** CLASS ANIMATIONS ******************************/
16840/******************************************************************************/
16841( function() {
16842
16843var classAnimationActions = [ "add", "remove", "toggle" ],
16844	shorthandStyles = {
16845		border: 1,
16846		borderBottom: 1,
16847		borderColor: 1,
16848		borderLeft: 1,
16849		borderRight: 1,
16850		borderTop: 1,
16851		borderWidth: 1,
16852		margin: 1,
16853		padding: 1
16854	};
16855
16856$.each(
16857	[ "borderLeftStyle", "borderRightStyle", "borderBottomStyle", "borderTopStyle" ],
16858	function( _, prop ) {
16859		$.fx.step[ prop ] = function( fx ) {
16860			if ( fx.end !== "none" && !fx.setAttr || fx.pos === 1 && !fx.setAttr ) {
16861				jQuery.style( fx.elem, prop, fx.end );
16862				fx.setAttr = true;
16863			}
16864		};
16865	}
16866);
16867
16868function getElementStyles( elem ) {
16869	var key, len,
16870		style = elem.ownerDocument.defaultView ?
16871			elem.ownerDocument.defaultView.getComputedStyle( elem, null ) :
16872			elem.currentStyle,
16873		styles = {};
16874
16875	if ( style && style.length && style[ 0 ] && style[ style[ 0 ] ] ) {
16876		len = style.length;
16877		while ( len-- ) {
16878			key = style[ len ];
16879			if ( typeof style[ key ] === "string" ) {
16880				styles[ $.camelCase( key ) ] = style[ key ];
16881			}
16882		}
16883
16884	// Support: Opera, IE <9
16885	} else {
16886		for ( key in style ) {
16887			if ( typeof style[ key ] === "string" ) {
16888				styles[ key ] = style[ key ];
16889			}
16890		}
16891	}
16892
16893	return styles;
16894}
16895
16896function styleDifference( oldStyle, newStyle ) {
16897	var diff = {},
16898		name, value;
16899
16900	for ( name in newStyle ) {
16901		value = newStyle[ name ];
16902		if ( oldStyle[ name ] !== value ) {
16903			if ( !shorthandStyles[ name ] ) {
16904				if ( $.fx.step[ name ] || !isNaN( parseFloat( value ) ) ) {
16905					diff[ name ] = value;
16906				}
16907			}
16908		}
16909	}
16910
16911	return diff;
16912}
16913
16914// Support: jQuery <1.8
16915if ( !$.fn.addBack ) {
16916	$.fn.addBack = function( selector ) {
16917		return this.add( selector == null ?
16918			this.prevObject : this.prevObject.filter( selector )
16919		);
16920	};
16921}
16922
16923$.effects.animateClass = function( value, duration, easing, callback ) {
16924	var o = $.speed( duration, easing, callback );
16925
16926	return this.queue( function() {
16927		var animated = $( this ),
16928			baseClass = animated.attr( "class" ) || "",
16929			applyClassChange,
16930			allAnimations = o.children ? animated.find( "*" ).addBack() : animated;
16931
16932		// Map the animated objects to store the original styles.
16933		allAnimations = allAnimations.map( function() {
16934			var el = $( this );
16935			return {
16936				el: el,
16937				start: getElementStyles( this )
16938			};
16939		} );
16940
16941		// Apply class change
16942		applyClassChange = function() {
16943			$.each( classAnimationActions, function( i, action ) {
16944				if ( value[ action ] ) {
16945					animated[ action + "Class" ]( value[ action ] );
16946				}
16947			} );
16948		};
16949		applyClassChange();
16950
16951		// Map all animated objects again - calculate new styles and diff
16952		allAnimations = allAnimations.map( function() {
16953			this.end = getElementStyles( this.el[ 0 ] );
16954			this.diff = styleDifference( this.start, this.end );
16955			return this;
16956		} );
16957
16958		// Apply original class
16959		animated.attr( "class", baseClass );
16960
16961		// Map all animated objects again - this time collecting a promise
16962		allAnimations = allAnimations.map( function() {
16963			var styleInfo = this,
16964				dfd = $.Deferred(),
16965				opts = $.extend( {}, o, {
16966					queue: false,
16967					complete: function() {
16968						dfd.resolve( styleInfo );
16969					}
16970				} );
16971
16972			this.el.animate( this.diff, opts );
16973			return dfd.promise();
16974		} );
16975
16976		// Once all animations have completed:
16977		$.when.apply( $, allAnimations.get() ).done( function() {
16978
16979			// Set the final class
16980			applyClassChange();
16981
16982			// For each animated element,
16983			// clear all css properties that were animated
16984			$.each( arguments, function() {
16985				var el = this.el;
16986				$.each( this.diff, function( key ) {
16987					el.css( key, "" );
16988				} );
16989			} );
16990
16991			// This is guarnteed to be there if you use jQuery.speed()
16992			// it also handles dequeuing the next anim...
16993			o.complete.call( animated[ 0 ] );
16994		} );
16995	} );
16996};
vendor: 5,123 bytes, lines 16997-17177
16997
16998$.fn.extend( {
16999	addClass: ( function( orig ) {
17000		return function( classNames, speed, easing, callback ) {
17001			return speed ?
17002				$.effects.animateClass.call( this,
17003					{ add: classNames }, speed, easing, callback ) :
17004				orig.apply( this, arguments );
17005		};
17006	} )( $.fn.addClass ),
17007
17008	removeClass: ( function( orig ) {
17009		return function( classNames, speed, easing, callback ) {
17010			return arguments.length > 1 ?
17011				$.effects.animateClass.call( this,
17012					{ remove: classNames }, speed, easing, callback ) :
17013				orig.apply( this, arguments );
17014		};
17015	} )( $.fn.removeClass ),
17016
17017	toggleClass: ( function( orig ) {
17018		return function( classNames, force, speed, easing, callback ) {
17019			if ( typeof force === "boolean" || force === undefined ) {
17020				if ( !speed ) {
17021
17022					// Without speed parameter
17023					return orig.apply( this, arguments );
17024				} else {
17025					return $.effects.animateClass.call( this,
17026						( force ? { add: classNames } : { remove: classNames } ),
17027						speed, easing, callback );
17028				}
17029			} else {
17030
17031				// Without force parameter
17032				return $.effects.animateClass.call( this,
17033					{ toggle: classNames }, force, speed, easing );
17034			}
17035		};
17036	} )( $.fn.toggleClass ),
17037
17038	switchClass: function( remove, add, speed, easing, callback ) {
17039		return $.effects.animateClass.call( this, {
17040			add: add,
17041			remove: remove
17042		}, speed, easing, callback );
17043	}
17044} );
17045
17046} )();
17047
17048/******************************************************************************/
17049/*********************************** EFFECTS **********************************/
17050/******************************************************************************/
17051
17052( function() {
17053
17054if ( $.expr && $.expr.filters && $.expr.filters.animated ) {
17055	$.expr.filters.animated = ( function( orig ) {
17056		return function( elem ) {
17057			return !!$( elem ).data( dataSpaceAnimated ) || orig( elem );
17058		};
17059	} )( $.expr.filters.animated );
17060}
17061
17062if ( $.uiBackCompat !== false ) {
17063	$.extend( $.effects, {
17064
17065		// Saves a set of properties in a data storage
17066		save: function( element, set ) {
17067			var i = 0, length = set.length;
17068			for ( ; i < length; i++ ) {
17069				if ( set[ i ] !== null ) {
17070					element.data( dataSpace + set[ i ], element[ 0 ].style[ set[ i ] ] );
17071				}
17072			}
17073		},
17074
17075		// Restores a set of previously saved properties from a data storage
17076		restore: function( element, set ) {
17077			var val, i = 0, length = set.length;
17078			for ( ; i < length; i++ ) {
17079				if ( set[ i ] !== null ) {
17080					val = element.data( dataSpace + set[ i ] );
17081					element.css( set[ i ], val );
17082				}
17083			}
17084		},
17085
17086		setMode: function( el, mode ) {
17087			if ( mode === "toggle" ) {
17088				mode = el.is( ":hidden" ) ? "show" : "hide";
17089			}
17090			return mode;
17091		},
17092
17093		// Wraps the element around a wrapper that copies position properties
17094		createWrapper: function( element ) {
17095
17096			// If the element is already wrapped, return it
17097			if ( element.parent().is( ".ui-effects-wrapper" ) ) {
17098				return element.parent();
17099			}
17100
17101			// Wrap the element
17102			var props = {
17103					width: element.outerWidth( true ),
17104					height: element.outerHeight( true ),
17105					"float": element.css( "float" )
17106				},
17107				wrapper = $( "<div></div>" )
17108					.addClass( "ui-effects-wrapper" )
17109					.css( {
17110						fontSize: "100%",
17111						background: "transparent",
17112						border: "none",
17113						margin: 0,
17114						padding: 0
17115					} ),
17116
17117				// Store the size in case width/height are defined in % - Fixes #5245
17118				size = {
17119					width: element.width(),
17120					height: element.height()
17121				},
17122				active = document.activeElement;
17123
17124			// Support: Firefox
17125			// Firefox incorrectly exposes anonymous content
17126			// https://bugzilla.mozilla.org/show_bug.cgi?id=561664
17127			try {
17128				active.id;
17129			} catch ( e ) {
17130				active = document.body;
17131			}
17132
17133			element.wrap( wrapper );
17134
17135			// Fixes #7595 - Elements lose focus when wrapped.
17136			if ( element[ 0 ] === active || $.contains( element[ 0 ], active ) ) {
17137				$( active ).trigger( "focus" );
17138			}
17139
17140			// Hotfix for jQuery 1.4 since some change in wrap() seems to actually
17141			// lose the reference to the wrapped element
17142			wrapper = element.parent();
17143
17144			// Transfer positioning properties to the wrapper
17145			if ( element.css( "position" ) === "static" ) {
17146				wrapper.css( { position: "relative" } );
17147				element.css( { position: "relative" } );
17148			} else {
17149				$.extend( props, {
17150					position: element.css( "position" ),
17151					zIndex: element.css( "z-index" )
17152				} );
17153				$.each( [ "top", "left", "bottom", "right" ], function( i, pos ) {
17154					props[ pos ] = element.css( pos );
17155					if ( isNaN( parseInt( props[ pos ], 10 ) ) ) {
17156						props[ pos ] = "auto";
17157					}
17158				} );
17159				element.css( {
17160					position: "relative",
17161					top: 0,
17162					left: 0,
17163					right: "auto",
17164					bottom: "auto"
17165				} );
17166			}
17167			element.css( size );
17168
17169			return wrapper.css( props ).show();
17170		},
17171
17172		removeWrapper: function( element ) {
17173			var active = document.activeElement;
17174
17175			if ( element.parent().is( ".ui-effects-wrapper" ) ) {
17176				element.parent().replaceWith( element );
17177
vendor: 16,570 bytes, lines 17178-17813
17178				// Fixes #7595 - Elements lose focus when wrapped.
17179				if ( element[ 0 ] === active || $.contains( element[ 0 ], active ) ) {
17180					$( active ).trigger( "focus" );
17181				}
17182			}
17183
17184			return element;
17185		}
17186	} );
17187}
17188
17189$.extend( $.effects, {
17190	version: "1.12.1",
17191
17192	define: function( name, mode, effect ) {
17193		if ( !effect ) {
17194			effect = mode;
17195			mode = "effect";
17196		}
17197
17198		$.effects.effect[ name ] = effect;
17199		$.effects.effect[ name ].mode = mode;
17200
17201		return effect;
17202	},
17203
17204	scaledDimensions: function( element, percent, direction ) {
17205		if ( percent === 0 ) {
17206			return {
17207				height: 0,
17208				width: 0,
17209				outerHeight: 0,
17210				outerWidth: 0
17211			};
17212		}
17213
17214		var x = direction !== "horizontal" ? ( ( percent || 100 ) / 100 ) : 1,
17215			y = direction !== "vertical" ? ( ( percent || 100 ) / 100 ) : 1;
17216
17217		return {
17218			height: element.height() * y,
17219			width: element.width() * x,
17220			outerHeight: element.outerHeight() * y,
17221			outerWidth: element.outerWidth() * x
17222		};
17223
17224	},
17225
17226	clipToBox: function( animation ) {
17227		return {
17228			width: animation.clip.right - animation.clip.left,
17229			height: animation.clip.bottom - animation.clip.top,
17230			left: animation.clip.left,
17231			top: animation.clip.top
17232		};
17233	},
17234
17235	// Injects recently queued functions to be first in line (after "inprogress")
17236	unshift: function( element, queueLength, count ) {
17237		var queue = element.queue();
17238
17239		if ( queueLength > 1 ) {
17240			queue.splice.apply( queue,
17241				[ 1, 0 ].concat( queue.splice( queueLength, count ) ) );
17242		}
17243		element.dequeue();
17244	},
17245
17246	saveStyle: function( element ) {
17247		element.data( dataSpaceStyle, element[ 0 ].style.cssText );
17248	},
17249
17250	restoreStyle: function( element ) {
17251		element[ 0 ].style.cssText = element.data( dataSpaceStyle ) || "";
17252		element.removeData( dataSpaceStyle );
17253	},
17254
17255	mode: function( element, mode ) {
17256		var hidden = element.is( ":hidden" );
17257
17258		if ( mode === "toggle" ) {
17259			mode = hidden ? "show" : "hide";
17260		}
17261		if ( hidden ? mode === "hide" : mode === "show" ) {
17262			mode = "none";
17263		}
17264		return mode;
17265	},
17266
17267	// Translates a [top,left] array into a baseline value
17268	getBaseline: function( origin, original ) {
17269		var y, x;
17270
17271		switch ( origin[ 0 ] ) {
17272		case "top":
17273			y = 0;
17274			break;
17275		case "middle":
17276			y = 0.5;
17277			break;
17278		case "bottom":
17279			y = 1;
17280			break;
17281		default:
17282			y = origin[ 0 ] / original.height;
17283		}
17284
17285		switch ( origin[ 1 ] ) {
17286		case "left":
17287			x = 0;
17288			break;
17289		case "center":
17290			x = 0.5;
17291			break;
17292		case "right":
17293			x = 1;
17294			break;
17295		default:
17296			x = origin[ 1 ] / original.width;
17297		}
17298
17299		return {
17300			x: x,
17301			y: y
17302		};
17303	},
17304
17305	// Creates a placeholder element so that the original element can be made absolute
17306	createPlaceholder: function( element ) {
17307		var placeholder,
17308			cssPosition = element.css( "position" ),
17309			position = element.position();
17310
17311		// Lock in margins first to account for form elements, which
17312		// will change margin if you explicitly set height
17313		// see: http://jsfiddle.net/JZSMt/3/ https://bugs.webkit.org/show_bug.cgi?id=107380
17314		// Support: Safari
17315		element.css( {
17316			marginTop: element.css( "marginTop" ),
17317			marginBottom: element.css( "marginBottom" ),
17318			marginLeft: element.css( "marginLeft" ),
17319			marginRight: element.css( "marginRight" )
17320		} )
17321		.outerWidth( element.outerWidth() )
17322		.outerHeight( element.outerHeight() );
17323
17324		if ( /^(static|relative)/.test( cssPosition ) ) {
17325			cssPosition = "absolute";
17326
17327			placeholder = $( "<" + element[ 0 ].nodeName + ">" ).insertAfter( element ).css( {
17328
17329				// Convert inline to inline block to account for inline elements
17330				// that turn to inline block based on content (like img)
17331				display: /^(inline|ruby)/.test( element.css( "display" ) ) ?
17332					"inline-block" :
17333					"block",
17334				visibility: "hidden",
17335
17336				// Margins need to be set to account for margin collapse
17337				marginTop: element.css( "marginTop" ),
17338				marginBottom: element.css( "marginBottom" ),
17339				marginLeft: element.css( "marginLeft" ),
17340				marginRight: element.css( "marginRight" ),
17341				"float": element.css( "float" )
17342			} )
17343			.outerWidth( element.outerWidth() )
17344			.outerHeight( element.outerHeight() )
17345			.addClass( "ui-effects-placeholder" );
17346
17347			element.data( dataSpace + "placeholder", placeholder );
17348		}
17349
17350		element.css( {
17351			position: cssPosition,
17352			left: position.left,
17353			top: position.top
17354		} );
17355
17356		return placeholder;
17357	},
17358
17359	removePlaceholder: function( element ) {
17360		var dataKey = dataSpace + "placeholder",
17361				placeholder = element.data( dataKey );
17362
17363		if ( placeholder ) {
17364			placeholder.remove();
17365			element.removeData( dataKey );
17366		}
17367	},
17368
17369	// Removes a placeholder if it exists and restores
17370	// properties that were modified during placeholder creation
17371	cleanUp: function( element ) {
17372		$.effects.restoreStyle( element );
17373		$.effects.removePlaceholder( element );
17374	},
17375
17376	setTransition: function( element, list, factor, value ) {
17377		value = value || {};
17378		$.each( list, function( i, x ) {
17379			var unit = element.cssUnit( x );
17380			if ( unit[ 0 ] > 0 ) {
17381				value[ x ] = unit[ 0 ] * factor + unit[ 1 ];
17382			}
17383		} );
17384		return value;
17385	}
17386} );
17387
17388// Return an effect options object for the given parameters:
17389function _normalizeArguments( effect, options, speed, callback ) {
17390
17391	// Allow passing all options as the first parameter
17392	if ( $.isPlainObject( effect ) ) {
17393		options = effect;
17394		effect = effect.effect;
17395	}
17396
17397	// Convert to an object
17398	effect = { effect: effect };
17399
17400	// Catch (effect, null, ...)
17401	if ( options == null ) {
17402		options = {};
17403	}
17404
17405	// Catch (effect, callback)
17406	if ( $.isFunction( options ) ) {
17407		callback = options;
17408		speed = null;
17409		options = {};
17410	}
17411
17412	// Catch (effect, speed, ?)
17413	if ( typeof options === "number" || $.fx.speeds[ options ] ) {
17414		callback = speed;
17415		speed = options;
17416		options = {};
17417	}
17418
17419	// Catch (effect, options, callback)
17420	if ( $.isFunction( speed ) ) {
17421		callback = speed;
17422		speed = null;
17423	}
17424
17425	// Add options to effect
17426	if ( options ) {
17427		$.extend( effect, options );
17428	}
17429
17430	speed = speed || options.duration;
17431	effect.duration = $.fx.off ? 0 :
17432		typeof speed === "number" ? speed :
17433		speed in $.fx.speeds ? $.fx.speeds[ speed ] :
17434		$.fx.speeds._default;
17435
17436	effect.complete = callback || options.complete;
17437
17438	return effect;
17439}
17440
17441function standardAnimationOption( option ) {
17442
17443	// Valid standard speeds (nothing, number, named speed)
17444	if ( !option || typeof option === "number" || $.fx.speeds[ option ] ) {
17445		return true;
17446	}
17447
17448	// Invalid strings - treat as "normal" speed
17449	if ( typeof option === "string" && !$.effects.effect[ option ] ) {
17450		return true;
17451	}
17452
17453	// Complete callback
17454	if ( $.isFunction( option ) ) {
17455		return true;
17456	}
17457
17458	// Options hash (but not naming an effect)
17459	if ( typeof option === "object" && !option.effect ) {
17460		return true;
17461	}
17462
17463	// Didn't match any standard API
17464	return false;
17465}
17466
17467$.fn.extend( {
17468	effect: function( /* effect, options, speed, callback */ ) {
17469		var args = _normalizeArguments.apply( this, arguments ),
17470			effectMethod = $.effects.effect[ args.effect ],
17471			defaultMode = effectMethod.mode,
17472			queue = args.queue,
17473			queueName = queue || "fx",
17474			complete = args.complete,
17475			mode = args.mode,
17476			modes = [],
17477			prefilter = function( next ) {
17478				var el = $( this ),
17479					normalizedMode = $.effects.mode( el, mode ) || defaultMode;
17480
17481				// Sentinel for duck-punching the :animated psuedo-selector
17482				el.data( dataSpaceAnimated, true );
17483
17484				// Save effect mode for later use,
17485				// we can't just call $.effects.mode again later,
17486				// as the .show() below destroys the initial state
17487				modes.push( normalizedMode );
17488
17489				// See $.uiBackCompat inside of run() for removal of defaultMode in 1.13
17490				if ( defaultMode && ( normalizedMode === "show" ||
17491						( normalizedMode === defaultMode && normalizedMode === "hide" ) ) ) {
17492					el.show();
17493				}
17494
17495				if ( !defaultMode || normalizedMode !== "none" ) {
17496					$.effects.saveStyle( el );
17497				}
17498
17499				if ( $.isFunction( next ) ) {
17500					next();
17501				}
17502			};
17503
17504		if ( $.fx.off || !effectMethod ) {
17505
17506			// Delegate to the original method (e.g., .show()) if possible
17507			if ( mode ) {
17508				return this[ mode ]( args.duration, complete );
17509			} else {
17510				return this.each( function() {
17511					if ( complete ) {
17512						complete.call( this );
17513					}
17514				} );
17515			}
17516		}
17517
17518		function run( next ) {
17519			var elem = $( this );
17520
17521			function cleanup() {
17522				elem.removeData( dataSpaceAnimated );
17523
17524				$.effects.cleanUp( elem );
17525
17526				if ( args.mode === "hide" ) {
17527					elem.hide();
17528				}
17529
17530				done();
17531			}
17532
17533			function done() {
17534				if ( $.isFunction( complete ) ) {
17535					complete.call( elem[ 0 ] );
17536				}
17537
17538				if ( $.isFunction( next ) ) {
17539					next();
17540				}
17541			}
17542
17543			// Override mode option on a per element basis,
17544			// as toggle can be either show or hide depending on element state
17545			args.mode = modes.shift();
17546
17547			if ( $.uiBackCompat !== false && !defaultMode ) {
17548				if ( elem.is( ":hidden" ) ? mode === "hide" : mode === "show" ) {
17549
17550					// Call the core method to track "olddisplay" properly
17551					elem[ mode ]();
17552					done();
17553				} else {
17554					effectMethod.call( elem[ 0 ], args, done );
17555				}
17556			} else {
17557				if ( args.mode === "none" ) {
17558
17559					// Call the core method to track "olddisplay" properly
17560					elem[ mode ]();
17561					done();
17562				} else {
17563					effectMethod.call( elem[ 0 ], args, cleanup );
17564				}
17565			}
17566		}
17567
17568		// Run prefilter on all elements first to ensure that
17569		// any showing or hiding happens before placeholder creation,
17570		// which ensures that any layout changes are correctly captured.
17571		return queue === false ?
17572			this.each( prefilter ).each( run ) :
17573			this.queue( queueName, prefilter ).queue( queueName, run );
17574	},
17575
17576	show: ( function( orig ) {
17577		return function( option ) {
17578			if ( standardAnimationOption( option ) ) {
17579				return orig.apply( this, arguments );
17580			} else {
17581				var args = _normalizeArguments.apply( this, arguments );
17582				args.mode = "show";
17583				return this.effect.call( this, args );
17584			}
17585		};
17586	} )( $.fn.show ),
17587
17588	hide: ( function( orig ) {
17589		return function( option ) {
17590			if ( standardAnimationOption( option ) ) {
17591				return orig.apply( this, arguments );
17592			} else {
17593				var args = _normalizeArguments.apply( this, arguments );
17594				args.mode = "hide";
17595				return this.effect.call( this, args );
17596			}
17597		};
17598	} )( $.fn.hide ),
17599
17600	toggle: ( function( orig ) {
17601		return function( option ) {
17602			if ( standardAnimationOption( option ) || typeof option === "boolean" ) {
17603				return orig.apply( this, arguments );
17604			} else {
17605				var args = _normalizeArguments.apply( this, arguments );
17606				args.mode = "toggle";
17607				return this.effect.call( this, args );
17608			}
17609		};
17610	} )( $.fn.toggle ),
17611
17612	cssUnit: function( key ) {
17613		var style = this.css( key ),
17614			val = [];
17615
17616		$.each( [ "em", "px", "%", "pt" ], function( i, unit ) {
17617			if ( style.indexOf( unit ) > 0 ) {
17618				val = [ parseFloat( style ), unit ];
17619			}
17620		} );
17621		return val;
17622	},
17623
17624	cssClip: function( clipObj ) {
17625		if ( clipObj ) {
17626			return this.css( "clip", "rect(" + clipObj.top + "px " + clipObj.right + "px " +
17627				clipObj.bottom + "px " + clipObj.left + "px)" );
17628		}
17629		return parseClip( this.css( "clip" ), this );
17630	},
17631
17632	transfer: function( options, done ) {
17633		var element = $( this ),
17634			target = $( options.to ),
17635			targetFixed = target.css( "position" ) === "fixed",
17636			body = $( "body" ),
17637			fixTop = targetFixed ? body.scrollTop() : 0,
17638			fixLeft = targetFixed ? body.scrollLeft() : 0,
17639			endPosition = target.offset(),
17640			animation = {
17641				top: endPosition.top - fixTop,
17642				left: endPosition.left - fixLeft,
17643				height: target.innerHeight(),
17644				width: target.innerWidth()
17645			},
17646			startPosition = element.offset(),
17647			transfer = $( "<div class='ui-effects-transfer'></div>" )
17648				.appendTo( "body" )
17649				.addClass( options.className )
17650				.css( {
17651					top: startPosition.top - fixTop,
17652					left: startPosition.left - fixLeft,
17653					height: element.innerHeight(),
17654					width: element.innerWidth(),
17655					position: targetFixed ? "fixed" : "absolute"
17656				} )
17657				.animate( animation, options.duration, options.easing, function() {
17658					transfer.remove();
17659					if ( $.isFunction( done ) ) {
17660						done();
17661					}
17662				} );
17663	}
17664} );
17665
17666function parseClip( str, element ) {
17667		var outerWidth = element.outerWidth(),
17668			outerHeight = element.outerHeight(),
17669			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)\)$/,
17670			values = clipRegex.exec( str ) || [ "", 0, outerWidth, outerHeight, 0 ];
17671
17672		return {
17673			top: parseFloat( values[ 1 ] ) || 0,
17674			right: values[ 2 ] === "auto" ? outerWidth : parseFloat( values[ 2 ] ),
17675			bottom: values[ 3 ] === "auto" ? outerHeight : parseFloat( values[ 3 ] ),
17676			left: parseFloat( values[ 4 ] ) || 0
17677		};
17678}
17679
17680$.fx.step.clip = function( fx ) {
17681	if ( !fx.clipInit ) {
17682		fx.start = $( fx.elem ).cssClip();
17683		if ( typeof fx.end === "string" ) {
17684			fx.end = parseClip( fx.end, fx.elem );
17685		}
17686		fx.clipInit = true;
17687	}
17688
17689	$( fx.elem ).cssClip( {
17690		top: fx.pos * ( fx.end.top - fx.start.top ) + fx.start.top,
17691		right: fx.pos * ( fx.end.right - fx.start.right ) + fx.start.right,
17692		bottom: fx.pos * ( fx.end.bottom - fx.start.bottom ) + fx.start.bottom,
17693		left: fx.pos * ( fx.end.left - fx.start.left ) + fx.start.left
17694	} );
17695};
17696
17697} )();
17698
17699/******************************************************************************/
17700/*********************************** EASING ***********************************/
17701/******************************************************************************/
17702
17703( function() {
17704
17705// Based on easing equations from Robert Penner (http://www.robertpenner.com/easing)
17706
17707var baseEasings = {};
17708
17709$.each( [ "Quad", "Cubic", "Quart", "Quint", "Expo" ], function( i, name ) {
17710	baseEasings[ name ] = function( p ) {
17711		return Math.pow( p, i + 2 );
17712	};
17713} );
17714
17715$.extend( baseEasings, {
17716	Sine: function( p ) {
17717		return 1 - Math.cos( p * Math.PI / 2 );
17718	},
17719	Circ: function( p ) {
17720		return 1 - Math.sqrt( 1 - p * p );
17721	},
17722	Elastic: function( p ) {
17723		return p === 0 || p === 1 ? p :
17724			-Math.pow( 2, 8 * ( p - 1 ) ) * Math.sin( ( ( p - 1 ) * 80 - 7.5 ) * Math.PI / 15 );
17725	},
17726	Back: function( p ) {
17727		return p * p * ( 3 * p - 2 );
17728	},
17729	Bounce: function( p ) {
17730		var pow2,
17731			bounce = 4;
17732
17733		while ( p < ( ( pow2 = Math.pow( 2, --bounce ) ) - 1 ) / 11 ) {}
17734		return 1 / Math.pow( 4, 3 - bounce ) - 7.5625 * Math.pow( ( pow2 * 3 - 2 ) / 22 - p, 2 );
17735	}
17736} );
17737
17738$.each( baseEasings, function( name, easeIn ) {
17739	$.easing[ "easeIn" + name ] = easeIn;
17740	$.easing[ "easeOut" + name ] = function( p ) {
17741		return 1 - easeIn( 1 - p );
17742	};
17743	$.easing[ "easeInOut" + name ] = function( p ) {
17744		return p < 0.5 ?
17745			easeIn( p * 2 ) / 2 :
17746			1 - easeIn( p * -2 + 2 ) / 2;
17747	};
17748} );
17749
17750} )();
17751
17752var effect = $.effects;
17753
17754
17755/*!
17756 * jQuery UI Effects Blind 1.12.1
17757 * http://jqueryui.com
17758 *
17759 * Copyright jQuery Foundation and other contributors
17760 * Released under the MIT license.
17761 * http://jquery.org/license
17762 */
17763
17764//>>label: Blind Effect
17765//>>group: Effects
17766//>>description: Blinds the element.
17767//>>docs: http://api.jqueryui.com/blind-effect/
17768//>>demos: http://jqueryui.com/effect/
17769
17770
17771
17772var effectsEffectBlind = $.effects.define( "blind", "hide", function( options, done ) {
17773	var map = {
17774			up: [ "bottom", "top" ],
17775			vertical: [ "bottom", "top" ],
17776			down: [ "top", "bottom" ],
17777			left: [ "right", "left" ],
17778			horizontal: [ "right", "left" ],
17779			right: [ "left", "right" ]
17780		},
17781		element = $( this ),
17782		direction = options.direction || "up",
17783		start = element.cssClip(),
17784		animate = { clip: $.extend( {}, start ) },
17785		placeholder = $.effects.createPlaceholder( element );
17786
17787	animate.clip[ map[ direction ][ 0 ] ] = animate.clip[ map[ direction ][ 1 ] ];
17788
17789	if ( options.mode === "show" ) {
17790		element.cssClip( animate.clip );
17791		if ( placeholder ) {
17792			placeholder.css( $.effects.clipToBox( animate ) );
17793		}
17794
17795		animate.clip = start;
17796	}
17797
17798	if ( placeholder ) {
17799		placeholder.animate( $.effects.clipToBox( animate ), options.duration, options.easing );
17800	}
17801
17802	element.animate( animate, {
17803		queue: false,
17804		duration: options.duration,
17805		easing: options.easing,
17806		complete: done
17807	} );
17808} );
17809
17810
17811/*!
17812 * jQuery UI Effects Bounce 1.12.1
17813 * http://jqueryui.com
vendor: 10,588 bytes, lines 17814-18220
17814 *
17815 * Copyright jQuery Foundation and other contributors
17816 * Released under the MIT license.
17817 * http://jquery.org/license
17818 */
17819
17820//>>label: Bounce Effect
17821//>>group: Effects
17822//>>description: Bounces an element horizontally or vertically n times.
17823//>>docs: http://api.jqueryui.com/bounce-effect/
17824//>>demos: http://jqueryui.com/effect/
17825
17826
17827
17828var effectsEffectBounce = $.effects.define( "bounce", function( options, done ) {
17829	var upAnim, downAnim, refValue,
17830		element = $( this ),
17831
17832		// Defaults:
17833		mode = options.mode,
17834		hide = mode === "hide",
17835		show = mode === "show",
17836		direction = options.direction || "up",
17837		distance = options.distance,
17838		times = options.times || 5,
17839
17840		// Number of internal animations
17841		anims = times * 2 + ( show || hide ? 1 : 0 ),
17842		speed = options.duration / anims,
17843		easing = options.easing,
17844
17845		// Utility:
17846		ref = ( direction === "up" || direction === "down" ) ? "top" : "left",
17847		motion = ( direction === "up" || direction === "left" ),
17848		i = 0,
17849
17850		queuelen = element.queue().length;
17851
17852	$.effects.createPlaceholder( element );
17853
17854	refValue = element.css( ref );
17855
17856	// Default distance for the BIGGEST bounce is the outer Distance / 3
17857	if ( !distance ) {
17858		distance = element[ ref === "top" ? "outerHeight" : "outerWidth" ]() / 3;
17859	}
17860
17861	if ( show ) {
17862		downAnim = { opacity: 1 };
17863		downAnim[ ref ] = refValue;
17864
17865		// If we are showing, force opacity 0 and set the initial position
17866		// then do the "first" animation
17867		element
17868			.css( "opacity", 0 )
17869			.css( ref, motion ? -distance * 2 : distance * 2 )
17870			.animate( downAnim, speed, easing );
17871	}
17872
17873	// Start at the smallest distance if we are hiding
17874	if ( hide ) {
17875		distance = distance / Math.pow( 2, times - 1 );
17876	}
17877
17878	downAnim = {};
17879	downAnim[ ref ] = refValue;
17880
17881	// Bounces up/down/left/right then back to 0 -- times * 2 animations happen here
17882	for ( ; i < times; i++ ) {
17883		upAnim = {};
17884		upAnim[ ref ] = ( motion ? "-=" : "+=" ) + distance;
17885
17886		element
17887			.animate( upAnim, speed, easing )
17888			.animate( downAnim, speed, easing );
17889
17890		distance = hide ? distance * 2 : distance / 2;
17891	}
17892
17893	// Last Bounce when Hiding
17894	if ( hide ) {
17895		upAnim = { opacity: 0 };
17896		upAnim[ ref ] = ( motion ? "-=" : "+=" ) + distance;
17897
17898		element.animate( upAnim, speed, easing );
17899	}
17900
17901	element.queue( done );
17902
17903	$.effects.unshift( element, queuelen, anims + 1 );
17904} );
17905
17906
17907/*!
17908 * jQuery UI Effects Clip 1.12.1
17909 * http://jqueryui.com
17910 *
17911 * Copyright jQuery Foundation and other contributors
17912 * Released under the MIT license.
17913 * http://jquery.org/license
17914 */
17915
17916//>>label: Clip Effect
17917//>>group: Effects
17918//>>description: Clips the element on and off like an old TV.
17919//>>docs: http://api.jqueryui.com/clip-effect/
17920//>>demos: http://jqueryui.com/effect/
17921
17922
17923
17924var effectsEffectClip = $.effects.define( "clip", "hide", function( options, done ) {
17925	var start,
17926		animate = {},
17927		element = $( this ),
17928		direction = options.direction || "vertical",
17929		both = direction === "both",
17930		horizontal = both || direction === "horizontal",
17931		vertical = both || direction === "vertical";
17932
17933	start = element.cssClip();
17934	animate.clip = {
17935		top: vertical ? ( start.bottom - start.top ) / 2 : start.top,
17936		right: horizontal ? ( start.right - start.left ) / 2 : start.right,
17937		bottom: vertical ? ( start.bottom - start.top ) / 2 : start.bottom,
17938		left: horizontal ? ( start.right - start.left ) / 2 : start.left
17939	};
17940
17941	$.effects.createPlaceholder( element );
17942
17943	if ( options.mode === "show" ) {
17944		element.cssClip( animate.clip );
17945		animate.clip = start;
17946	}
17947
17948	element.animate( animate, {
17949		queue: false,
17950		duration: options.duration,
17951		easing: options.easing,
17952		complete: done
17953	} );
17954
17955} );
17956
17957
17958/*!
17959 * jQuery UI Effects Drop 1.12.1
17960 * http://jqueryui.com
17961 *
17962 * Copyright jQuery Foundation and other contributors
17963 * Released under the MIT license.
17964 * http://jquery.org/license
17965 */
17966
17967//>>label: Drop Effect
17968//>>group: Effects
17969//>>description: Moves an element in one direction and hides it at the same time.
17970//>>docs: http://api.jqueryui.com/drop-effect/
17971//>>demos: http://jqueryui.com/effect/
17972
17973
17974
17975var effectsEffectDrop = $.effects.define( "drop", "hide", function( options, done ) {
17976
17977	var distance,
17978		element = $( this ),
17979		mode = options.mode,
17980		show = mode === "show",
17981		direction = options.direction || "left",
17982		ref = ( direction === "up" || direction === "down" ) ? "top" : "left",
17983		motion = ( direction === "up" || direction === "left" ) ? "-=" : "+=",
17984		oppositeMotion = ( motion === "+=" ) ? "-=" : "+=",
17985		animation = {
17986			opacity: 0
17987		};
17988
17989	$.effects.createPlaceholder( element );
17990
17991	distance = options.distance ||
17992		element[ ref === "top" ? "outerHeight" : "outerWidth" ]( true ) / 2;
17993
17994	animation[ ref ] = motion + distance;
17995
17996	if ( show ) {
17997		element.css( animation );
17998
17999		animation[ ref ] = oppositeMotion + distance;
18000		animation.opacity = 1;
18001	}
18002
18003	// Animate
18004	element.animate( animation, {
18005		queue: false,
18006		duration: options.duration,
18007		easing: options.easing,
18008		complete: done
18009	} );
18010} );
18011
18012
18013/*!
18014 * jQuery UI Effects Explode 1.12.1
18015 * http://jqueryui.com
18016 *
18017 * Copyright jQuery Foundation and other contributors
18018 * Released under the MIT license.
18019 * http://jquery.org/license
18020 */
18021
18022//>>label: Explode Effect
18023//>>group: Effects
18024// jscs:disable maximumLineLength
18025//>>description: Explodes an element in all directions into n pieces. Implodes an element to its original wholeness.
18026// jscs:enable maximumLineLength
18027//>>docs: http://api.jqueryui.com/explode-effect/
18028//>>demos: http://jqueryui.com/effect/
18029
18030
18031
18032var effectsEffectExplode = $.effects.define( "explode", "hide", function( options, done ) {
18033
18034	var i, j, left, top, mx, my,
18035		rows = options.pieces ? Math.round( Math.sqrt( options.pieces ) ) : 3,
18036		cells = rows,
18037		element = $( this ),
18038		mode = options.mode,
18039		show = mode === "show",
18040
18041		// Show and then visibility:hidden the element before calculating offset
18042		offset = element.show().css( "visibility", "hidden" ).offset(),
18043
18044		// Width and height of a piece
18045		width = Math.ceil( element.outerWidth() / cells ),
18046		height = Math.ceil( element.outerHeight() / rows ),
18047		pieces = [];
18048
18049	// Children animate complete:
18050	function childComplete() {
18051		pieces.push( this );
18052		if ( pieces.length === rows * cells ) {
18053			animComplete();
18054		}
18055	}
18056
18057	// Clone the element for each row and cell.
18058	for ( i = 0; i < rows; i++ ) { // ===>
18059		top = offset.top + i * height;
18060		my = i - ( rows - 1 ) / 2;
18061
18062		for ( j = 0; j < cells; j++ ) { // |||
18063			left = offset.left + j * width;
18064			mx = j - ( cells - 1 ) / 2;
18065
18066			// Create a clone of the now hidden main element that will be absolute positioned
18067			// within a wrapper div off the -left and -top equal to size of our pieces
18068			element
18069				.clone()
18070				.appendTo( "body" )
18071				.wrap( "<div></div>" )
18072				.css( {
18073					position: "absolute",
18074					visibility: "visible",
18075					left: -j * width,
18076					top: -i * height
18077				} )
18078
18079				// Select the wrapper - make it overflow: hidden and absolute positioned based on
18080				// where the original was located +left and +top equal to the size of pieces
18081				.parent()
18082					.addClass( "ui-effects-explode" )
18083					.css( {
18084						position: "absolute",
18085						overflow: "hidden",
18086						width: width,
18087						height: height,
18088						left: left + ( show ? mx * width : 0 ),
18089						top: top + ( show ? my * height : 0 ),
18090						opacity: show ? 0 : 1
18091					} )
18092					.animate( {
18093						left: left + ( show ? 0 : mx * width ),
18094						top: top + ( show ? 0 : my * height ),
18095						opacity: show ? 1 : 0
18096					}, options.duration || 500, options.easing, childComplete );
18097		}
18098	}
18099
18100	function animComplete() {
18101		element.css( {
18102			visibility: "visible"
18103		} );
18104		$( pieces ).remove();
18105		done();
18106	}
18107} );
18108
18109
18110/*!
18111 * jQuery UI Effects Fade 1.12.1
18112 * http://jqueryui.com
18113 *
18114 * Copyright jQuery Foundation and other contributors
18115 * Released under the MIT license.
18116 * http://jquery.org/license
18117 */
18118
18119//>>label: Fade Effect
18120//>>group: Effects
18121//>>description: Fades the element.
18122//>>docs: http://api.jqueryui.com/fade-effect/
18123//>>demos: http://jqueryui.com/effect/
18124
18125
18126
18127var effectsEffectFade = $.effects.define( "fade", "toggle", function( options, done ) {
18128	var show = options.mode === "show";
18129
18130	$( this )
18131		.css( "opacity", show ? 0 : 1 )
18132		.animate( {
18133			opacity: show ? 1 : 0
18134		}, {
18135			queue: false,
18136			duration: options.duration,
18137			easing: options.easing,
18138			complete: done
18139		} );
18140} );
18141
18142
18143/*!
18144 * jQuery UI Effects Fold 1.12.1
18145 * http://jqueryui.com
18146 *
18147 * Copyright jQuery Foundation and other contributors
18148 * Released under the MIT license.
18149 * http://jquery.org/license
18150 */
18151
18152//>>label: Fold Effect
18153//>>group: Effects
18154//>>description: Folds an element first horizontally and then vertically.
18155//>>docs: http://api.jqueryui.com/fold-effect/
18156//>>demos: http://jqueryui.com/effect/
18157
18158
18159
18160var effectsEffectFold = $.effects.define( "fold", "hide", function( options, done ) {
18161
18162	// Create element
18163	var element = $( this ),
18164		mode = options.mode,
18165		show = mode === "show",
18166		hide = mode === "hide",
18167		size = options.size || 15,
18168		percent = /([0-9]+)%/.exec( size ),
18169		horizFirst = !!options.horizFirst,
18170		ref = horizFirst ? [ "right", "bottom" ] : [ "bottom", "right" ],
18171		duration = options.duration / 2,
18172
18173		placeholder = $.effects.createPlaceholder( element ),
18174
18175		start = element.cssClip(),
18176		animation1 = { clip: $.extend( {}, start ) },
18177		animation2 = { clip: $.extend( {}, start ) },
18178
18179		distance = [ start[ ref[ 0 ] ], start[ ref[ 1 ] ] ],
18180
18181		queuelen = element.queue().length;
18182
18183	if ( percent ) {
18184		size = parseInt( percent[ 1 ], 10 ) / 100 * distance[ hide ? 0 : 1 ];
18185	}
18186	animation1.clip[ ref[ 0 ] ] = size;
18187	animation2.clip[ ref[ 0 ] ] = size;
18188	animation2.clip[ ref[ 1 ] ] = 0;
18189
18190	if ( show ) {
18191		element.cssClip( animation2.clip );
18192		if ( placeholder ) {
18193			placeholder.css( $.effects.clipToBox( animation2 ) );
18194		}
18195
18196		animation2.clip = start;
18197	}
18198
18199	// Animate
18200	element
18201		.queue( function( next ) {
18202			if ( placeholder ) {
18203				placeholder
18204					.animate( $.effects.clipToBox( animation1 ), duration, options.easing )
18205					.animate( $.effects.clipToBox( animation2 ), duration, options.easing );
18206			}
18207
18208			next();
18209		} )
18210		.animate( animation1, duration, options.easing )
18211		.animate( animation2, duration, options.easing )
18212		.queue( done );
18213
18214	$.effects.unshift( element, queuelen, 4 );
18215} );
18216
18217
18218/*!
18219 * jQuery UI Effects Highlight 1.12.1
18220 * http://jqueryui.com
vendor: 6,249 bytes, lines 18221-18440
18221 *
18222 * Copyright jQuery Foundation and other contributors
18223 * Released under the MIT license.
18224 * http://jquery.org/license
18225 */
18226
18227//>>label: Highlight Effect
18228//>>group: Effects
18229//>>description: Highlights the background of an element in a defined color for a custom duration.
18230//>>docs: http://api.jqueryui.com/highlight-effect/
18231//>>demos: http://jqueryui.com/effect/
18232
18233
18234
18235var effectsEffectHighlight = $.effects.define( "highlight", "show", function( options, done ) {
18236	var element = $( this ),
18237		animation = {
18238			backgroundColor: element.css( "backgroundColor" )
18239		};
18240
18241	if ( options.mode === "hide" ) {
18242		animation.opacity = 0;
18243	}
18244
18245	$.effects.saveStyle( element );
18246
18247	element
18248		.css( {
18249			backgroundImage: "none",
18250			backgroundColor: options.color || "#ffff99"
18251		} )
18252		.animate( animation, {
18253			queue: false,
18254			duration: options.duration,
18255			easing: options.easing,
18256			complete: done
18257		} );
18258} );
18259
18260
18261/*!
18262 * jQuery UI Effects Size 1.12.1
18263 * http://jqueryui.com
18264 *
18265 * Copyright jQuery Foundation and other contributors
18266 * Released under the MIT license.
18267 * http://jquery.org/license
18268 */
18269
18270//>>label: Size Effect
18271//>>group: Effects
18272//>>description: Resize an element to a specified width and height.
18273//>>docs: http://api.jqueryui.com/size-effect/
18274//>>demos: http://jqueryui.com/effect/
18275
18276
18277
18278var effectsEffectSize = $.effects.define( "size", function( options, done ) {
18279
18280	// Create element
18281	var baseline, factor, temp,
18282		element = $( this ),
18283
18284		// Copy for children
18285		cProps = [ "fontSize" ],
18286		vProps = [ "borderTopWidth", "borderBottomWidth", "paddingTop", "paddingBottom" ],
18287		hProps = [ "borderLeftWidth", "borderRightWidth", "paddingLeft", "paddingRight" ],
18288
18289		// Set options
18290		mode = options.mode,
18291		restore = mode !== "effect",
18292		scale = options.scale || "both",
18293		origin = options.origin || [ "middle", "center" ],
18294		position = element.css( "position" ),
18295		pos = element.position(),
18296		original = $.effects.scaledDimensions( element ),
18297		from = options.from || original,
18298		to = options.to || $.effects.scaledDimensions( element, 0 );
18299
18300	$.effects.createPlaceholder( element );
18301
18302	if ( mode === "show" ) {
18303		temp = from;
18304		from = to;
18305		to = temp;
18306	}
18307
18308	// Set scaling factor
18309	factor = {
18310		from: {
18311			y: from.height / original.height,
18312			x: from.width / original.width
18313		},
18314		to: {
18315			y: to.height / original.height,
18316			x: to.width / original.width
18317		}
18318	};
18319
18320	// Scale the css box
18321	if ( scale === "box" || scale === "both" ) {
18322
18323		// Vertical props scaling
18324		if ( factor.from.y !== factor.to.y ) {
18325			from = $.effects.setTransition( element, vProps, factor.from.y, from );
18326			to = $.effects.setTransition( element, vProps, factor.to.y, to );
18327		}
18328
18329		// Horizontal props scaling
18330		if ( factor.from.x !== factor.to.x ) {
18331			from = $.effects.setTransition( element, hProps, factor.from.x, from );
18332			to = $.effects.setTransition( element, hProps, factor.to.x, to );
18333		}
18334	}
18335
18336	// Scale the content
18337	if ( scale === "content" || scale === "both" ) {
18338
18339		// Vertical props scaling
18340		if ( factor.from.y !== factor.to.y ) {
18341			from = $.effects.setTransition( element, cProps, factor.from.y, from );
18342			to = $.effects.setTransition( element, cProps, factor.to.y, to );
18343		}
18344	}
18345
18346	// Adjust the position properties based on the provided origin points
18347	if ( origin ) {
18348		baseline = $.effects.getBaseline( origin, original );
18349		from.top = ( original.outerHeight - from.outerHeight ) * baseline.y + pos.top;
18350		from.left = ( original.outerWidth - from.outerWidth ) * baseline.x + pos.left;
18351		to.top = ( original.outerHeight - to.outerHeight ) * baseline.y + pos.top;
18352		to.left = ( original.outerWidth - to.outerWidth ) * baseline.x + pos.left;
18353	}
18354	element.css( from );
18355
18356	// Animate the children if desired
18357	if ( scale === "content" || scale === "both" ) {
18358
18359		vProps = vProps.concat( [ "marginTop", "marginBottom" ] ).concat( cProps );
18360		hProps = hProps.concat( [ "marginLeft", "marginRight" ] );
18361
18362		// Only animate children with width attributes specified
18363		// TODO: is this right? should we include anything with css width specified as well
18364		element.find( "*[width]" ).each( function() {
18365			var child = $( this ),
18366				childOriginal = $.effects.scaledDimensions( child ),
18367				childFrom = {
18368					height: childOriginal.height * factor.from.y,
18369					width: childOriginal.width * factor.from.x,
18370					outerHeight: childOriginal.outerHeight * factor.from.y,
18371					outerWidth: childOriginal.outerWidth * factor.from.x
18372				},
18373				childTo = {
18374					height: childOriginal.height * factor.to.y,
18375					width: childOriginal.width * factor.to.x,
18376					outerHeight: childOriginal.height * factor.to.y,
18377					outerWidth: childOriginal.width * factor.to.x
18378				};
18379
18380			// Vertical props scaling
18381			if ( factor.from.y !== factor.to.y ) {
18382				childFrom = $.effects.setTransition( child, vProps, factor.from.y, childFrom );
18383				childTo = $.effects.setTransition( child, vProps, factor.to.y, childTo );
18384			}
18385
18386			// Horizontal props scaling
18387			if ( factor.from.x !== factor.to.x ) {
18388				childFrom = $.effects.setTransition( child, hProps, factor.from.x, childFrom );
18389				childTo = $.effects.setTransition( child, hProps, factor.to.x, childTo );
18390			}
18391
18392			if ( restore ) {
18393				$.effects.saveStyle( child );
18394			}
18395
18396			// Animate children
18397			child.css( childFrom );
18398			child.animate( childTo, options.duration, options.easing, function() {
18399
18400				// Restore children
18401				if ( restore ) {
18402					$.effects.restoreStyle( child );
18403				}
18404			} );
18405		} );
18406	}
18407
18408	// Animate
18409	element.animate( to, {
18410		queue: false,
18411		duration: options.duration,
18412		easing: options.easing,
18413		complete: function() {
18414
18415			var offset = element.offset();
18416
18417			if ( to.opacity === 0 ) {
18418				element.css( "opacity", from.opacity );
18419			}
18420
18421			if ( !restore ) {
18422				element
18423					.css( "position", position === "static" ? "relative" : position )
18424					.offset( offset );
18425
18426				// Need to save style here so that automatic style restoration
18427				// doesn't restore to the original styles from before the animation.
18428				$.effects.saveStyle( element );
18429			}
18430
18431			done();
18432		}
18433	} );
18434
18435} );
18436
18437
18438/*!
18439 * jQuery UI Effects Scale 1.12.1
18440 * http://jqueryui.com
vendor: 4,797 bytes, lines 18441-18618
18441 *
18442 * Copyright jQuery Foundation and other contributors
18443 * Released under the MIT license.
18444 * http://jquery.org/license
18445 */
18446
18447//>>label: Scale Effect
18448//>>group: Effects
18449//>>description: Grows or shrinks an element and its content.
18450//>>docs: http://api.jqueryui.com/scale-effect/
18451//>>demos: http://jqueryui.com/effect/
18452
18453
18454
18455var effectsEffectScale = $.effects.define( "scale", function( options, done ) {
18456
18457	// Create element
18458	var el = $( this ),
18459		mode = options.mode,
18460		percent = parseInt( options.percent, 10 ) ||
18461			( parseInt( options.percent, 10 ) === 0 ? 0 : ( mode !== "effect" ? 0 : 100 ) ),
18462
18463		newOptions = $.extend( true, {
18464			from: $.effects.scaledDimensions( el ),
18465			to: $.effects.scaledDimensions( el, percent, options.direction || "both" ),
18466			origin: options.origin || [ "middle", "center" ]
18467		}, options );
18468
18469	// Fade option to support puff
18470	if ( options.fade ) {
18471		newOptions.from.opacity = 1;
18472		newOptions.to.opacity = 0;
18473	}
18474
18475	$.effects.effect.size.call( this, newOptions, done );
18476} );
18477
18478
18479/*!
18480 * jQuery UI Effects Puff 1.12.1
18481 * http://jqueryui.com
18482 *
18483 * Copyright jQuery Foundation and other contributors
18484 * Released under the MIT license.
18485 * http://jquery.org/license
18486 */
18487
18488//>>label: Puff Effect
18489//>>group: Effects
18490//>>description: Creates a puff effect by scaling the element up and hiding it at the same time.
18491//>>docs: http://api.jqueryui.com/puff-effect/
18492//>>demos: http://jqueryui.com/effect/
18493
18494
18495
18496var effectsEffectPuff = $.effects.define( "puff", "hide", function( options, done ) {
18497	var newOptions = $.extend( true, {}, options, {
18498		fade: true,
18499		percent: parseInt( options.percent, 10 ) || 150
18500	} );
18501
18502	$.effects.effect.scale.call( this, newOptions, done );
18503} );
18504
18505
18506/*!
18507 * jQuery UI Effects Pulsate 1.12.1
18508 * http://jqueryui.com
18509 *
18510 * Copyright jQuery Foundation and other contributors
18511 * Released under the MIT license.
18512 * http://jquery.org/license
18513 */
18514
18515//>>label: Pulsate Effect
18516//>>group: Effects
18517//>>description: Pulsates an element n times by changing the opacity to zero and back.
18518//>>docs: http://api.jqueryui.com/pulsate-effect/
18519//>>demos: http://jqueryui.com/effect/
18520
18521
18522
18523var effectsEffectPulsate = $.effects.define( "pulsate", "show", function( options, done ) {
18524	var element = $( this ),
18525		mode = options.mode,
18526		show = mode === "show",
18527		hide = mode === "hide",
18528		showhide = show || hide,
18529
18530		// Showing or hiding leaves off the "last" animation
18531		anims = ( ( options.times || 5 ) * 2 ) + ( showhide ? 1 : 0 ),
18532		duration = options.duration / anims,
18533		animateTo = 0,
18534		i = 1,
18535		queuelen = element.queue().length;
18536
18537	if ( show || !element.is( ":visible" ) ) {
18538		element.css( "opacity", 0 ).show();
18539		animateTo = 1;
18540	}
18541
18542	// Anims - 1 opacity "toggles"
18543	for ( ; i < anims; i++ ) {
18544		element.animate( { opacity: animateTo }, duration, options.easing );
18545		animateTo = 1 - animateTo;
18546	}
18547
18548	element.animate( { opacity: animateTo }, duration, options.easing );
18549
18550	element.queue( done );
18551
18552	$.effects.unshift( element, queuelen, anims + 1 );
18553} );
18554
18555
18556/*!
18557 * jQuery UI Effects Shake 1.12.1
18558 * http://jqueryui.com
18559 *
18560 * Copyright jQuery Foundation and other contributors
18561 * Released under the MIT license.
18562 * http://jquery.org/license
18563 */
18564
18565//>>label: Shake Effect
18566//>>group: Effects
18567//>>description: Shakes an element horizontally or vertically n times.
18568//>>docs: http://api.jqueryui.com/shake-effect/
18569//>>demos: http://jqueryui.com/effect/
18570
18571
18572
18573var effectsEffectShake = $.effects.define( "shake", function( options, done ) {
18574
18575	var i = 1,
18576		element = $( this ),
18577		direction = options.direction || "left",
18578		distance = options.distance || 20,
18579		times = options.times || 3,
18580		anims = times * 2 + 1,
18581		speed = Math.round( options.duration / anims ),
18582		ref = ( direction === "up" || direction === "down" ) ? "top" : "left",
18583		positiveMotion = ( direction === "up" || direction === "left" ),
18584		animation = {},
18585		animation1 = {},
18586		animation2 = {},
18587
18588		queuelen = element.queue().length;
18589
18590	$.effects.createPlaceholder( element );
18591
18592	// Animation
18593	animation[ ref ] = ( positiveMotion ? "-=" : "+=" ) + distance;
18594	animation1[ ref ] = ( positiveMotion ? "+=" : "-=" ) + distance * 2;
18595	animation2[ ref ] = ( positiveMotion ? "-=" : "+=" ) + distance * 2;
18596
18597	// Animate
18598	element.animate( animation, speed, options.easing );
18599
18600	// Shakes
18601	for ( ; i < times; i++ ) {
18602		element
18603			.animate( animation1, speed, options.easing )
18604			.animate( animation2, speed, options.easing );
18605	}
18606
18607	element
18608		.animate( animation1, speed, options.easing )
18609		.animate( animation, speed / 2, options.easing )
18610		.queue( done );
18611
18612	$.effects.unshift( element, queuelen, anims + 1 );
18613} );
18614
18615
18616/*!
18617 * jQuery UI Effects Slide 1.12.1
18618 * http://jqueryui.com
vendor: 2,310 bytes, lines 18619-18706
18619 *
18620 * Copyright jQuery Foundation and other contributors
18621 * Released under the MIT license.
18622 * http://jquery.org/license
18623 */
18624
18625//>>label: Slide Effect
18626//>>group: Effects
18627//>>description: Slides an element in and out of the viewport.
18628//>>docs: http://api.jqueryui.com/slide-effect/
18629//>>demos: http://jqueryui.com/effect/
18630
18631
18632
18633var effectsEffectSlide = $.effects.define( "slide", "show", function( options, done ) {
18634	var startClip, startRef,
18635		element = $( this ),
18636		map = {
18637			up: [ "bottom", "top" ],
18638			down: [ "top", "bottom" ],
18639			left: [ "right", "left" ],
18640			right: [ "left", "right" ]
18641		},
18642		mode = options.mode,
18643		direction = options.direction || "left",
18644		ref = ( direction === "up" || direction === "down" ) ? "top" : "left",
18645		positiveMotion = ( direction === "up" || direction === "left" ),
18646		distance = options.distance ||
18647			element[ ref === "top" ? "outerHeight" : "outerWidth" ]( true ),
18648		animation = {};
18649
18650	$.effects.createPlaceholder( element );
18651
18652	startClip = element.cssClip();
18653	startRef = element.position()[ ref ];
18654
18655	// Define hide animation
18656	animation[ ref ] = ( positiveMotion ? -1 : 1 ) * distance + startRef;
18657	animation.clip = element.cssClip();
18658	animation.clip[ map[ direction ][ 1 ] ] = animation.clip[ map[ direction ][ 0 ] ];
18659
18660	// Reverse the animation if we're showing
18661	if ( mode === "show" ) {
18662		element.cssClip( animation.clip );
18663		element.css( ref, animation[ ref ] );
18664		animation.clip = startClip;
18665		animation[ ref ] = startRef;
18666	}
18667
18668	// Actually animate
18669	element.animate( animation, {
18670		queue: false,
18671		duration: options.duration,
18672		easing: options.easing,
18673		complete: done
18674	} );
18675} );
18676
18677
18678/*!
18679 * jQuery UI Effects Transfer 1.12.1
18680 * http://jqueryui.com
18681 *
18682 * Copyright jQuery Foundation and other contributors
18683 * Released under the MIT license.
18684 * http://jquery.org/license
18685 */
18686
18687//>>label: Transfer Effect
18688//>>group: Effects
18689//>>description: Displays a transfer effect from one element to another.
18690//>>docs: http://api.jqueryui.com/transfer-effect/
18691//>>demos: http://jqueryui.com/effect/
18692
18693
18694
18695var effect;
18696if ( $.uiBackCompat !== false ) {
18697	effect = $.effects.define( "transfer", function( options, done ) {
18698		$( this ).transfer( options, done );
18699	} );
18700}
18701var effectsEffectTransfer = effect;
18702
18703
18704
18705
18706}));

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.