PageSourceSearch

https://www.snh.cm/wp-content/plugins/industrie-addons/assets/js/jquery-ui.js?ver=201513434

js snh.cm collected 2026-10-02 19:11:00 UTC 520,329 bytes, 18,696 lines download raw bytes

1/*! jQuery UI - v1.12.1 - 2020-11-26
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
vendor: 46,668 bytes, lines 3-1721
3.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 ] ) {
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 ] ) ?
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
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();
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
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
vendor: 46,453 bytes, lines 1722-3408
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	},
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
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
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;
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
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
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
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;
vendor: 4,744 bytes, lines 3409-3581
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;
vendor: 5,516 bytes, lines 3582-3787
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;
vendor: 26,006 bytes, lines 3788-4816
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",
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
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",
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
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,
vendor: 13,664 bytes, lines 4817-5361
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,
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
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;
vendor: 42,276 bytes, lines 5362-6740
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 ];
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 :
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 
vendor: 2,177 bytes, lines 6740-6831
6740Accordion 1.12.1
6741 * http://jqueryui.com
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;
vendor: 8,005 bytes, lines 6831-7148
6831
6832	},
6833
6834	_destroyIcons: function() {
6835		this._removeClass( this.headers, "ui-accordion-icons" );
6836		this.headers.children( ".ui-accordion-header-icon" ).remove();
6837	},
6838
6839	_destroy: function() {
6840		var contents;
6841
6842		// Clean up main element
6843		this.element.removeAttr( "role" );
6844
6845		// Clean up headers
6846		this.headers
6847			.removeAttr( "role aria-expanded aria-selected aria-controls tabIndex" )
6848			.removeUniqueId();
6849
6850		this._destroyIcons();
6851
6852		// Clean up content panels
6853		contents = this.headers.next()
6854			.css( "display", "" )
6855			.removeAttr( "role aria-hidden aria-labelledby" )
6856			.removeUniqueId();
6857
6858		if ( this.options.heightStyle !== "content" ) {
6859			contents.css( "height", "" );
6860		}
6861	},
6862
6863	_setOption: function( key, value ) {
6864		if ( key === "active" ) {
6865
6866			// _activate() will handle invalid values and update this.options
6867			this._activate( value );
6868			return;
6869		}
6870
6871		if ( key === "event" ) {
6872			if ( this.options.event ) {
6873				this._off( this.headers, this.options.event );
6874			}
6875			this._setupEvents( value );
6876		}
6877
6878		this._super( key, value );
6879
6880		// Setting collapsible: false while collapsed; open first panel
6881		if ( key === "collapsible" && !value && this.options.active === false ) {
6882			this._activate( 0 );
6883		}
6884
6885		if ( key === "icons" ) {
6886			this._destroyIcons();
6887			if ( value ) {
6888				this._createIcons();
6889			}
6890		}
6891	},
6892
6893	_setOptionDisabled: function( value ) {
6894		this._super( value );
6895
6896		this.element.attr( "aria-disabled", value );
6897
6898		// Support: IE8 Only
6899		// #5332 / #6059 - opacity doesn't cascade to positioned elements in IE
6900		// so we need to add the disabled class to the headers and panels
6901		this._toggleClass( null, "ui-state-disabled", !!value );
6902		this._toggleClass( this.headers.add( this.headers.next() ), null, "ui-state-disabled",
6903			!!value );
6904	},
6905
6906	_keydown: function( event ) {
6907		if ( event.altKey || event.ctrlKey ) {
6908			return;
6909		}
6910
6911		var keyCode = $.ui.keyCode,
6912			length = this.headers.length,
6913			currentIndex = this.headers.index( event.target ),
6914			toFocus = false;
6915
6916		switch ( event.keyCode ) {
6917		case keyCode.RIGHT:
6918		case keyCode.DOWN:
6919			toFocus = this.headers[ ( currentIndex + 1 ) % length ];
6920			break;
6921		case keyCode.LEFT:
6922		case keyCode.UP:
6923			toFocus = this.headers[ ( currentIndex - 1 + length ) % length ];
6924			break;
6925		case keyCode.SPACE:
6926		case keyCode.ENTER:
6927			this._eventHandler( event );
6928			break;
6929		case keyCode.HOME:
6930			toFocus = this.headers[ 0 ];
6931			break;
6932		case keyCode.END:
6933			toFocus = this.headers[ length - 1 ];
6934			break;
6935		}
6936
6937		if ( toFocus ) {
6938			$( event.target ).attr( "tabIndex", -1 );
6939			$( toFocus ).attr( "tabIndex", 0 );
6940			$( toFocus ).trigger( "focus" );
6941			event.preventDefault();
6942		}
6943	},
6944
6945	_panelKeyDown: function( event ) {
6946		if ( event.keyCode === $.ui.keyCode.UP && event.ctrlKey ) {
6947			$( event.currentTarget ).prev().trigger( "focus" );
6948		}
6949	},
6950
6951	refresh: function() {
6952		var options = this.options;
6953		this._processPanels();
6954
6955		// Was collapsed or no panel
6956		if ( ( options.active === false && options.collapsible === true ) ||
6957				!this.headers.length ) {
6958			options.active = false;
6959			this.active = $();
6960
6961		// active false only when collapsible is true
6962		} else if ( options.active === false ) {
6963			this._activate( 0 );
6964
6965		// was active, but active panel is gone
6966		} else if ( this.active.length && !$.contains( this.element[ 0 ], this.active[ 0 ] ) ) {
6967
6968			// all remaining panel are disabled
6969			if ( this.headers.length === this.headers.find( ".ui-state-disabled" ).length ) {
6970				options.active = false;
6971				this.active = $();
6972
6973			// activate previous panel
6974			} else {
6975				this._activate( Math.max( 0, options.active - 1 ) );
6976			}
6977
6978		// was active, active panel still exists
6979		} else {
6980
6981			// make sure active index is correct
6982			options.active = this.headers.index( this.active );
6983		}
6984
6985		this._destroyIcons();
6986
6987		this._refresh();
6988	},
6989
6990	_processPanels: function() {
6991		var prevHeaders = this.headers,
6992			prevPanels = this.panels;
6993
6994		this.headers = this.element.find( this.options.header );
6995		this._addClass( this.headers, "ui-accordion-header ui-accordion-header-collapsed",
6996			"ui-state-default" );
6997
6998		this.panels = this.headers.next().filter( ":not(.ui-accordion-content-active)" ).hide();
6999		this._addClass( this.panels, "ui-accordion-content", "ui-helper-reset ui-widget-content" );
7000
7001		// Avoid memory leaks (#10056)
7002		if ( prevPanels ) {
7003			this._off( prevHeaders.not( this.headers ) );
7004			this._off( prevPanels.not( this.panels ) );
7005		}
7006	},
7007
7008	_refresh: function() {
7009		var maxHeight,
7010			options = this.options,
7011			heightStyle = options.heightStyle,
7012			parent = this.element.parent();
7013
7014		this.active = this._findActive( options.active );
7015		this._addClass( this.active, "ui-accordion-header-active", "ui-state-active" )
7016			._removeClass( this.active, "ui-accordion-header-collapsed" );
7017		this._addClass( this.active.next(), "ui-accordion-content-active" );
7018		this.active.next().show();
7019
7020		this.headers
7021			.attr( "role", "tab" )
7022			.each( function() {
7023				var header = $( this ),
7024					headerId = header.uniqueId().attr( "id" ),
7025					panel = header.next(),
7026					panelId = panel.uniqueId().attr( "id" );
7027				header.attr( "aria-controls", panelId );
7028				panel.attr( "aria-labelledby", headerId );
7029			} )
7030			.next()
7031				.attr( "role", "tabpanel" );
7032
7033		this.headers
7034			.not( this.active )
7035				.attr( {
7036					"aria-selected": "false",
7037					"aria-expanded": "false",
7038					tabIndex: -1
7039				} )
7040				.next()
7041					.attr( {
7042						"aria-hidden": "true"
7043					} )
7044					.hide();
7045
7046		// Make sure at least one header is in the tab order
7047		if ( !this.active.length ) {
7048			this.headers.eq( 0 ).attr( "tabIndex", 0 );
7049		} else {
7050			this.active.attr( {
7051				"aria-selected": "true",
7052				"aria-expanded": "true",
7053				tabIndex: 0
7054			} )
7055				.next()
7056					.attr( {
7057						"aria-hidden": "false"
7058					} );
7059		}
7060
7061		this._createIcons();
7062
7063		this._setupEvents( options.event );
7064
7065		if ( heightStyle === "fill" ) {
7066			maxHeight = parent.height();
7067			this.element.siblings( ":visible" ).each( function() {
7068				var elem = $( this ),
7069					position = elem.css( "position" );
7070
7071				if ( position === "absolute" || position === "fixed" ) {
7072					return;
7073				}
7074				maxHeight -= elem.outerHeight( true );
7075			} );
7076
7077			this.headers.each( function() {
7078				maxHeight -= $( this ).outerHeight( true );
7079			} );
7080
7081			this.headers.next()
7082				.each( function() {
7083					$( this ).height( Math.max( 0, maxHeight -
7084						$( this ).innerHeight() + $( this ).height() ) );
7085				} )
7086				.css( "overflow", "auto" );
7087		} else if ( heightStyle === "auto" ) {
7088			maxHeight = 0;
7089			this.headers.next()
7090				.each( function() {
7091					var isVisible = $( this ).is( ":visible" );
7092					if ( !isVisible ) {
7093						$( this ).show();
7094					}
7095					maxHeight = Math.max( maxHeight, $( this ).css( "height", "" ).height() );
7096					if ( !isVisible ) {
7097						$( this ).hide();
7098					}
7099				} )
7100				.height( maxHeight );
7101		}
7102	},
7103
7104	_activate: function( index ) {
7105		var active = this._findActive( index )[ 0 ];
7106
7107		// Trying to activate the already active panel
7108		if ( active === this.active[ 0 ] ) {
7109			return;
7110		}
7111
7112		// Trying to collapse, simulate a click on the currently active header
7113		active = active || this.active[ 0 ];
7114
7115		this._eventHandler( {
7116			target: active,
7117			currentTarget: active,
7118			preventDefault: $.noop
7119		} );
7120	},
7121
7122	_findActive: function( selector ) {
7123		return typeof selector === "number" ? this.headers.eq( selector ) : $();
7124	},
7125
7126	_setupEvents: function( event ) {
7127		var events = {
7128			keydown: "_keydown"
7129		};
7130		if ( event ) {
7131			$.each( event.split( " " ), function( index, eventName ) {
7132				events[ eventName ] = "_eventHandler";
7133			} );
7134		}
7135
7136		this._off( this.headers.add( this.headers.next() ) );
7137		this._on( this.headers, events );
7138		this._on( this.headers.next(), { keydown: "_panelKeyDown" } );
7139		this._hoverable( this.headers );
7140		this._focusable( this.headers );
7141	},
7142
7143	_eventHandler: function( event ) {
7144		var activeChildren, clickedChildren,
7145			options = this.options,
7146			active = this.active,
7147			clicked = $( event.currentTarget ),
7148			clickedIsActive = clicked[ 0 ] === active[ 0 ],
vendor: 6,030 bytes, lines 7149-7373
7149			collapsing = clickedIsActive && options.collapsible,
7150			toShow = collapsing ? $() : clicked.next(),
7151			toHide = active.next(),
7152			eventData = {
7153				oldHeader: active,
7154				oldPanel: toHide,
7155				newHeader: collapsing ? $() : clicked,
7156				newPanel: toShow
7157			};
7158
7159		event.preventDefault();
7160
7161		if (
7162
7163				// click on active header, but not collapsible
7164				( clickedIsActive && !options.collapsible ) ||
7165
7166				// allow canceling activation
7167				( this._trigger( "beforeActivate", event, eventData ) === false ) ) {
7168			return;
7169		}
7170
7171		options.active = collapsing ? false : this.headers.index( clicked );
7172
7173		// When the call to ._toggle() comes after the class changes
7174		// it causes a very odd bug in IE 8 (see #6720)
7175		this.active = clickedIsActive ? $() : clicked;
7176		this._toggle( eventData );
7177
7178		// Switch classes
7179		// corner classes on the previously active header stay after the animation
7180		this._removeClass( active, "ui-accordion-header-active", "ui-state-active" );
7181		if ( options.icons ) {
7182			activeChildren = active.children( ".ui-accordion-header-icon" );
7183			this._removeClass( activeChildren, null, options.icons.activeHeader )
7184				._addClass( activeChildren, null, options.icons.header );
7185		}
7186
7187		if ( !clickedIsActive ) {
7188			this._removeClass( clicked, "ui-accordion-header-collapsed" )
7189				._addClass( clicked, "ui-accordion-header-active", "ui-state-active" );
7190			if ( options.icons ) {
7191				clickedChildren = clicked.children( ".ui-accordion-header-icon" );
7192				this._removeClass( clickedChildren, null, options.icons.header )
7193					._addClass( clickedChildren, null, options.icons.activeHeader );
7194			}
7195
7196			this._addClass( clicked.next(), "ui-accordion-content-active" );
7197		}
7198	},
7199
7200	_toggle: function( data ) {
7201		var toShow = data.newPanel,
7202			toHide = this.prevShow.length ? this.prevShow : data.oldPanel;
7203
7204		// Handle activating a panel during the animation for another activation
7205		this.prevShow.add( this.prevHide ).stop( true, true );
7206		this.prevShow = toShow;
7207		this.prevHide = toHide;
7208
7209		if ( this.options.animate ) {
7210			this._animate( toShow, toHide, data );
7211		} else {
7212			toHide.hide();
7213			toShow.show();
7214			this._toggleComplete( data );
7215		}
7216
7217		toHide.attr( {
7218			"aria-hidden": "true"
7219		} );
7220		toHide.prev().attr( {
7221			"aria-selected": "false",
7222			"aria-expanded": "false"
7223		} );
7224
7225		// if we're switching panels, remove the old header from the tab order
7226		// if we're opening from collapsed state, remove the previous header from the tab order
7227		// if we're collapsing, then keep the collapsing header in the tab order
7228		if ( toShow.length && toHide.length ) {
7229			toHide.prev().attr( {
7230				"tabIndex": -1,
7231				"aria-expanded": "false"
7232			} );
7233		} else if ( toShow.length ) {
7234			this.headers.filter( function() {
7235				return parseInt( $( this ).attr( "tabIndex" ), 10 ) === 0;
7236			} )
7237				.attr( "tabIndex", -1 );
7238		}
7239
7240		toShow
7241			.attr( "aria-hidden", "false" )
7242			.prev()
7243				.attr( {
7244					"aria-selected": "true",
7245					"aria-expanded": "true",
7246					tabIndex: 0
7247				} );
7248	},
7249
7250	_animate: function( toShow, toHide, data ) {
7251		var total, easing, duration,
7252			that = this,
7253			adjust = 0,
7254			boxSizing = toShow.css( "box-sizing" ),
7255			down = toShow.length &&
7256				( !toHide.length || ( toShow.index() < toHide.index() ) ),
7257			animate = this.options.animate || {},
7258			options = down && animate.down || animate,
7259			complete = function() {
7260				that._toggleComplete( data );
7261			};
7262
7263		if ( typeof options === "number" ) {
7264			duration = options;
7265		}
7266		if ( typeof options === "string" ) {
7267			easing = options;
7268		}
7269
7270		// fall back from options to animation in case of partial down settings
7271		easing = easing || options.easing || animate.easing;
7272		duration = duration || options.duration || animate.duration;
7273
7274		if ( !toHide.length ) {
7275			return toShow.animate( this.showProps, duration, easing, complete );
7276		}
7277		if ( !toShow.length ) {
7278			return toHide.animate( this.hideProps, duration, easing, complete );
7279		}
7280
7281		total = toShow.show().outerHeight();
7282		toHide.animate( this.hideProps, {
7283			duration: duration,
7284			easing: easing,
7285			step: function( now, fx ) {
7286				fx.now = Math.round( now );
7287			}
7288		} );
7289		toShow
7290			.hide()
7291			.animate( this.showProps, {
7292				duration: duration,
7293				easing: easing,
7294				complete: complete,
7295				step: function( now, fx ) {
7296					fx.now = Math.round( now );
7297					if ( fx.prop !== "height" ) {
7298						if ( boxSizing === "content-box" ) {
7299							adjust += fx.now;
7300						}
7301					} else if ( that.options.heightStyle !== "content" ) {
7302						fx.now = Math.round( total - toHide.outerHeight() - adjust );
7303						adjust = 0;
7304					}
7305				}
7306			} );
7307	},
7308
7309	_toggleComplete: function( data ) {
7310		var toHide = data.oldPanel,
7311			prev = toHide.prev();
7312
7313		this._removeClass( toHide, "ui-accordion-content-active" );
7314		this._removeClass( prev, "ui-accordion-header-active" )
7315			._addClass( prev, "ui-accordion-header-collapsed" );
7316
7317		// Work around for rendering bug in IE (#5421)
7318		if ( toHide.length ) {
7319			toHide.parent()[ 0 ].className = toHide.parent()[ 0 ].className;
7320		}
7321		this._trigger( "activate", null, data );
7322	}
7323} );
7324
7325
7326/*!
7327 * jQuery UI Menu 1.12.1
7328 * http://jqueryui.com
7329 *
7330 * Copyright jQuery Foundation and other contributors
7331 * Released under the MIT license.
7332 * http://jquery.org/license
7333 */
7334
7335//>>label: Menu
7336//>>group: Widgets
7337//>>description: Creates nestable menus.
7338//>>docs: http://api.jqueryui.com/menu/
7339//>>demos: http://jqueryui.com/menu/
7340//>>css.structure: ../../themes/base/core.css
7341//>>css.structure: ../../themes/base/menu.css
7342//>>css.theme: ../../themes/base/theme.css
7343
7344
7345
7346var widgetsMenu = $.widget( "ui.menu", {
7347	version: "1.12.1",
7348	defaultElement: "<ul>",
7349	delay: 300,
7350	options: {
7351		icons: {
7352			submenu: "ui-icon-caret-1-e"
7353		},
7354		items: "> *",
7355		menus: "ul",
7356		position: {
7357			my: "left top",
7358			at: "right top"
7359		},
7360		role: "menu",
7361
7362		// Callbacks
7363		blur: null,
7364		focus: null,
7365		select: null
7366	},
7367
7368	_create: function() {
7369		this.activeMenu = this.element;
7370
7371		// Flag used to prevent firing of the click handler
7372		// as the event bubbles up through nested menus
7373		this.mouseHandled = false;
vendor: 139,549 bytes, lines 7374-11665
7374		this.element
7375			.uniqueId()
7376			.attr( {
7377				role: this.options.role,
7378				tabIndex: 0
7379			} );
7380
7381		this._addClass( "ui-menu", "ui-widget ui-widget-content" );
7382		this._on( {
7383
7384			// Prevent focus from sticking to links inside menu after clicking
7385			// them (focus should always stay on UL during navigation).
7386			"mousedown .ui-menu-item": function( event ) {
7387				event.preventDefault();
7388			},
7389			"click .ui-menu-item": function( event ) {
7390				var target = $( event.target );
7391				var active = $( $.ui.safeActiveElement( this.document[ 0 ] ) );
7392				if ( !this.mouseHandled && target.not( ".ui-state-disabled" ).length ) {
7393					this.select( event );
7394
7395					// Only set the mouseHandled flag if the event will bubble, see #9469.
7396					if ( !event.isPropagationStopped() ) {
7397						this.mouseHandled = true;
7398					}
7399
7400					// Open submenu on click
7401					if ( target.has( ".ui-menu" ).length ) {
7402						this.expand( event );
7403					} else if ( !this.element.is( ":focus" ) &&
7404							active.closest( ".ui-menu" ).length ) {
7405
7406						// Redirect focus to the menu
7407						this.element.trigger( "focus", [ true ] );
7408
7409						// If the active item is on the top level, let it stay active.
7410						// Otherwise, blur the active item since it is no longer visible.
7411						if ( this.active && this.active.parents( ".ui-menu" ).length === 1 ) {
7412							clearTimeout( this.timer );
7413						}
7414					}
7415				}
7416			},
7417			"mouseenter .ui-menu-item": function( event ) {
7418
7419				// Ignore mouse events while typeahead is active, see #10458.
7420				// Prevents focusing the wrong item when typeahead causes a scroll while the mouse
7421				// is over an item in the menu
7422				if ( this.previousFilter ) {
7423					return;
7424				}
7425
7426				var actualTarget = $( event.target ).closest( ".ui-menu-item" ),
7427					target = $( event.currentTarget );
7428
7429				// Ignore bubbled events on parent items, see #11641
7430				if ( actualTarget[ 0 ] !== target[ 0 ] ) {
7431					return;
7432				}
7433
7434				// Remove ui-state-active class from siblings of the newly focused menu item
7435				// to avoid a jump caused by adjacent elements both having a class with a border
7436				this._removeClass( target.siblings().children( ".ui-state-active" ),
7437					null, "ui-state-active" );
7438				this.focus( event, target );
7439			},
7440			mouseleave: "collapseAll",
7441			"mouseleave .ui-menu": "collapseAll",
7442			focus: function( event, keepActiveItem ) {
7443
7444				// If there's already an active item, keep it active
7445				// If not, activate the first item
7446				var item = this.active || this.element.find( this.options.items ).eq( 0 );
7447
7448				if ( !keepActiveItem ) {
7449					this.focus( event, item );
7450				}
7451			},
7452			blur: function( event ) {
7453				this._delay( function() {
7454					var notContained = !$.contains(
7455						this.element[ 0 ],
7456						$.ui.safeActiveElement( this.document[ 0 ] )
7457					);
7458					if ( notContained ) {
7459						this.collapseAll( event );
7460					}
7461				} );
7462			},
7463			keydown: "_keydown"
7464		} );
7465
7466		this.refresh();
7467
7468		// Clicks outside of a menu collapse any open menus
7469		this._on( this.document, {
7470			click: function( event ) {
7471				if ( this._closeOnDocumentClick( event ) ) {
7472					this.collapseAll( event );
7473				}
7474
7475				// Reset the mouseHandled flag
7476				this.mouseHandled = false;
7477			}
7478		} );
7479	},
7480
7481	_destroy: function() {
7482		var items = this.element.find( ".ui-menu-item" )
7483				.removeAttr( "role aria-disabled" ),
7484			submenus = items.children( ".ui-menu-item-wrapper" )
7485				.removeUniqueId()
7486				.removeAttr( "tabIndex role aria-haspopup" );
7487
7488		// Destroy (sub)menus
7489		this.element
7490			.removeAttr( "aria-activedescendant" )
7491			.find( ".ui-menu" ).addBack()
7492				.removeAttr( "role aria-labelledby aria-expanded aria-hidden aria-disabled " +
7493					"tabIndex" )
7494				.removeUniqueId()
7495				.show();
7496
7497		submenus.children().each( function() {
7498			var elem = $( this );
7499			if ( elem.data( "ui-menu-submenu-caret" ) ) {
7500				elem.remove();
7501			}
7502		} );
7503	},
7504
7505	_keydown: function( event ) {
7506		var match, prev, character, skip,
7507			preventDefault = true;
7508
7509		switch ( event.keyCode ) {
7510		case $.ui.keyCode.PAGE_UP:
7511			this.previousPage( event );
7512			break;
7513		case $.ui.keyCode.PAGE_DOWN:
7514			this.nextPage( event );
7515			break;
7516		case $.ui.keyCode.HOME:
7517			this._move( "first", "first", event );
7518			break;
7519		case $.ui.keyCode.END:
7520			this._move( "last", "last", event );
7521			break;
7522		case $.ui.keyCode.UP:
7523			this.previous( event );
7524			break;
7525		case $.ui.keyCode.DOWN:
7526			this.next( event );
7527			break;
7528		case $.ui.keyCode.LEFT:
7529			this.collapse( event );
7530			break;
7531		case $.ui.keyCode.RIGHT:
7532			if ( this.active && !this.active.is( ".ui-state-disabled" ) ) {
7533				this.expand( event );
7534			}
7535			break;
7536		case $.ui.keyCode.ENTER:
7537		case $.ui.keyCode.SPACE:
7538			this._activate( event );
7539			break;
7540		case $.ui.keyCode.ESCAPE:
7541			this.collapse( event );
7542			break;
7543		default:
7544			preventDefault = false;
7545			prev = this.previousFilter || "";
7546			skip = false;
7547
7548			// Support number pad values
7549			character = event.keyCode >= 96 && event.keyCode <= 105 ?
7550				( event.keyCode - 96 ).toString() : String.fromCharCode( event.keyCode );
7551
7552			clearTimeout( this.filterTimer );
7553
7554			if ( character === prev ) {
7555				skip = true;
7556			} else {
7557				character = prev + character;
7558			}
7559
7560			match = this._filterMenuItems( character );
7561			match = skip && match.index( this.active.next() ) !== -1 ?
7562				this.active.nextAll( ".ui-menu-item" ) :
7563				match;
7564
7565			// If no matches on the current filter, reset to the last character pressed
7566			// to move down the menu to the first item that starts with that character
7567			if ( !match.length ) {
7568				character = String.fromCharCode( event.keyCode );
7569				match = this._filterMenuItems( character );
7570			}
7571
7572			if ( match.length ) {
7573				this.focus( event, match );
7574				this.previousFilter = character;
7575				this.filterTimer = this._delay( function() {
7576					delete this.previousFilter;
7577				}, 1000 );
7578			} else {
7579				delete this.previousFilter;
7580			}
7581		}
7582
7583		if ( preventDefault ) {
7584			event.preventDefault();
7585		}
7586	},
7587
7588	_activate: function( event ) {
7589		if ( this.active && !this.active.is( ".ui-state-disabled" ) ) {
7590			if ( this.active.children( "[aria-haspopup='true']" ).length ) {
7591				this.expand( event );
7592			} else {
7593				this.select( event );
7594			}
7595		}
7596	},
7597
7598	refresh: function() {
7599		var menus, items, newSubmenus, newItems, newWrappers,
7600			that = this,
7601			icon = this.options.icons.submenu,
7602			submenus = this.element.find( this.options.menus );
7603
7604		this._toggleClass( "ui-menu-icons", null, !!this.element.find( ".ui-icon" ).length );
7605
7606		// Initialize nested menus
7607		newSubmenus = submenus.filter( ":not(.ui-menu)" )
7608			.hide()
7609			.attr( {
7610				role: this.options.role,
7611				"aria-hidden": "true",
7612				"aria-expanded": "false"
7613			} )
7614			.each( function() {
7615				var menu = $( this ),
7616					item = menu.prev(),
7617					submenuCaret = $( "<span>" ).data( "ui-menu-submenu-caret", true );
7618
7619				that._addClass( submenuCaret, "ui-menu-icon", "ui-icon " + icon );
7620				item
7621					.attr( "aria-haspopup", "true" )
7622					.prepend( submenuCaret );
7623				menu.attr( "aria-labelledby", item.attr( "id" ) );
7624			} );
7625
7626		this._addClass( newSubmenus, "ui-menu", "ui-widget ui-widget-content ui-front" );
7627
7628		menus = submenus.add( this.element );
7629		items = menus.find( this.options.items );
7630
7631		// Initialize menu-items containing spaces and/or dashes only as dividers
7632		items.not( ".ui-menu-item" ).each( function() {
7633			var item = $( this );
7634			if ( that._isDivider( item ) ) {
7635				that._addClass( item, "ui-menu-divider", "ui-widget-content" );
7636			}
7637		} );
7638
7639		// Don't refresh list items that are already adapted
7640		newItems = items.not( ".ui-menu-item, .ui-menu-divider" );
7641		newWrappers = newItems.children()
7642			.not( ".ui-menu" )
7643				.uniqueId()
7644				.attr( {
7645					tabIndex: -1,
7646					role: this._itemRole()
7647				} );
7648		this._addClass( newItems, "ui-menu-item" )
7649			._addClass( newWrappers, "ui-menu-item-wrapper" );
7650
7651		// Add aria-disabled attribute to any disabled menu item
7652		items.filter( ".ui-state-disabled" ).attr( "aria-disabled", "true" );
7653
7654		// If the active item has been removed, blur the menu
7655		if ( this.active && !$.contains( this.element[ 0 ], this.active[ 0 ] ) ) {
7656			this.blur();
7657		}
7658	},
7659
7660	_itemRole: function() {
7661		return {
7662			menu: "menuitem",
7663			listbox: "option"
7664		}[ this.options.role ];
7665	},
7666
7667	_setOption: function( key, value ) {
7668		if ( key === "icons" ) {
7669			var icons = this.element.find( ".ui-menu-icon" );
7670			this._removeClass( icons, null, this.options.icons.submenu )
7671				._addClass( icons, null, value.submenu );
7672		}
7673		this._super( key, value );
7674	},
7675
7676	_setOptionDisabled: function( value ) {
7677		this._super( value );
7678
7679		this.element.attr( "aria-disabled", String( value ) );
7680		this._toggleClass( null, "ui-state-disabled", !!value );
7681	},
7682
7683	focus: function( event, item ) {
7684		var nested, focused, activeParent;
7685		this.blur( event, event && event.type === "focus" );
7686
7687		this._scrollIntoView( item );
7688
7689		this.active = item.first();
7690
7691		focused = this.active.children( ".ui-menu-item-wrapper" );
7692		this._addClass( focused, null, "ui-state-active" );
7693
7694		// Only update aria-activedescendant if there's a role
7695		// otherwise we assume focus is managed elsewhere
7696		if ( this.options.role ) {
7697			this.element.attr( "aria-activedescendant", focused.attr( "id" ) );
7698		}
7699
7700		// Highlight active parent menu item, if any
7701		activeParent = this.active
7702			.parent()
7703				.closest( ".ui-menu-item" )
7704					.children( ".ui-menu-item-wrapper" );
7705		this._addClass( activeParent, null, "ui-state-active" );
7706
7707		if ( event && event.type === "keydown" ) {
7708			this._close();
7709		} else {
7710			this.timer = this._delay( function() {
7711				this._close();
7712			}, this.delay );
7713		}
7714
7715		nested = item.children( ".ui-menu" );
7716		if ( nested.length && event && ( /^mouse/.test( event.type ) ) ) {
7717			this._startOpening( nested );
7718		}
7719		this.activeMenu = item.parent();
7720
7721		this._trigger( "focus", event, { item: item } );
7722	},
7723
7724	_scrollIntoView: function( item ) {
7725		var borderTop, paddingTop, offset, scroll, elementHeight, itemHeight;
7726		if ( this._hasScroll() ) {
7727			borderTop = parseFloat( $.css( this.activeMenu[ 0 ], "borderTopWidth" ) ) || 0;
7728			paddingTop = parseFloat( $.css( this.activeMenu[ 0 ], "paddingTop" ) ) || 0;
7729			offset = item.offset().top - this.activeMenu.offset().top - borderTop - paddingTop;
7730			scroll = this.activeMenu.scrollTop();
7731			elementHeight = this.activeMenu.height();
7732			itemHeight = item.outerHeight();
7733
7734			if ( offset < 0 ) {
7735				this.activeMenu.scrollTop( scroll + offset );
7736			} else if ( offset + itemHeight > elementHeight ) {
7737				this.activeMenu.scrollTop( scroll + offset - elementHeight + itemHeight );
7738			}
7739		}
7740	},
7741
7742	blur: function( event, fromFocus ) {
7743		if ( !fromFocus ) {
7744			clearTimeout( this.timer );
7745		}
7746
7747		if ( !this.active ) {
7748			return;
7749		}
7750
7751		this._removeClass( this.active.children( ".ui-menu-item-wrapper" ),
7752			null, "ui-state-active" );
7753
7754		this._trigger( "blur", event, { item: this.active } );
7755		this.active = null;
7756	},
7757
7758	_startOpening: function( submenu ) {
7759		clearTimeout( this.timer );
7760
7761		// Don't open if already open fixes a Firefox bug that caused a .5 pixel
7762		// shift in the submenu position when mousing over the caret icon
7763		if ( submenu.attr( "aria-hidden" ) !== "true" ) {
7764			return;
7765		}
7766
7767		this.timer = this._delay( function() {
7768			this._close();
7769			this._open( submenu );
7770		}, this.delay );
7771	},
7772
7773	_open: function( submenu ) {
7774		var position = $.extend( {
7775			of: this.active
7776		}, this.options.position );
7777
7778		clearTimeout( this.timer );
7779		this.element.find( ".ui-menu" ).not( submenu.parents( ".ui-menu" ) )
7780			.hide()
7781			.attr( "aria-hidden", "true" );
7782
7783		submenu
7784			.show()
7785			.removeAttr( "aria-hidden" )
7786			.attr( "aria-expanded", "true" )
7787			.position( position );
7788	},
7789
7790	collapseAll: function( event, all ) {
7791		clearTimeout( this.timer );
7792		this.timer = this._delay( function() {
7793
7794			// If we were passed an event, look for the submenu that contains the event
7795			var currentMenu = all ? this.element :
7796				$( event && event.target ).closest( this.element.find( ".ui-menu" ) );
7797
7798			// If we found no valid submenu ancestor, use the main menu to close all
7799			// sub menus anyway
7800			if ( !currentMenu.length ) {
7801				currentMenu = this.element;
7802			}
7803
7804			this._close( currentMenu );
7805
7806			this.blur( event );
7807
7808			// Work around active item staying active after menu is blurred
7809			this._removeClass( currentMenu.find( ".ui-state-active" ), null, "ui-state-active" );
7810
7811			this.activeMenu = currentMenu;
7812		}, this.delay );
7813	},
7814
7815	// With no arguments, closes the currently active menu - if nothing is active
7816	// it closes all menus.  If passed an argument, it will search for menus BELOW
7817	_close: function( startMenu ) {
7818		if ( !startMenu ) {
7819			startMenu = this.active ? this.active.parent() : this.element;
7820		}
7821
7822		startMenu.find( ".ui-menu" )
7823			.hide()
7824			.attr( "aria-hidden", "true" )
7825			.attr( "aria-expanded", "false" );
7826	},
7827
7828	_closeOnDocumentClick: function( event ) {
7829		return !$( event.target ).closest( ".ui-menu" ).length;
7830	},
7831
7832	_isDivider: function( item ) {
7833
7834		// Match hyphen, em dash, en dash
7835		return !/[^\-\u2014\u2013\s]/.test( item.text() );
7836	},
7837
7838	collapse: function( event ) {
7839		var newItem = this.active &&
7840			this.active.parent().closest( ".ui-menu-item", this.element );
7841		if ( newItem && newItem.length ) {
7842			this._close();
7843			this.focus( event, newItem );
7844		}
7845	},
7846
7847	expand: function( event ) {
7848		var newItem = this.active &&
7849			this.active
7850				.children( ".ui-menu " )
7851					.find( this.options.items )
7852						.first();
7853
7854		if ( newItem && newItem.length ) {
7855			this._open( newItem.parent() );
7856
7857			// Delay so Firefox will not hide activedescendant change in expanding submenu from AT
7858			this._delay( function() {
7859				this.focus( event, newItem );
7860			} );
7861		}
7862	},
7863
7864	next: function( event ) {
7865		this._move( "next", "first", event );
7866	},
7867
7868	previous: function( event ) {
7869		this._move( "prev", "last", event );
7870	},
7871
7872	isFirstItem: function() {
7873		return this.active && !this.active.prevAll( ".ui-menu-item" ).length;
7874	},
7875
7876	isLastItem: function() {
7877		return this.active && !this.active.nextAll( ".ui-menu-item" ).length;
7878	},
7879
7880	_move: function( direction, filter, event ) {
7881		var next;
7882		if ( this.active ) {
7883			if ( direction === "first" || direction === "last" ) {
7884				next = this.active
7885					[ direction === "first" ? "prevAll" : "nextAll" ]( ".ui-menu-item" )
7886					.eq( -1 );
7887			} else {
7888				next = this.active
7889					[ direction + "All" ]( ".ui-menu-item" )
7890					.eq( 0 );
7891			}
7892		}
7893		if ( !next || !next.length || !this.active ) {
7894			next = this.activeMenu.find( this.options.items )[ filter ]();
7895		}
7896
7897		this.focus( event, next );
7898	},
7899
7900	nextPage: function( event ) {
7901		var item, base, height;
7902
7903		if ( !this.active ) {
7904			this.next( event );
7905			return;
7906		}
7907		if ( this.isLastItem() ) {
7908			return;
7909		}
7910		if ( this._hasScroll() ) {
7911			base = this.active.offset().top;
7912			height = this.element.height();
7913			this.active.nextAll( ".ui-menu-item" ).each( function() {
7914				item = $( this );
7915				return item.offset().top - base - height < 0;
7916			} );
7917
7918			this.focus( event, item );
7919		} else {
7920			this.focus( event, this.activeMenu.find( this.options.items )
7921				[ !this.active ? "first" : "last" ]() );
7922		}
7923	},
7924
7925	previousPage: function( event ) {
7926		var item, base, height;
7927		if ( !this.active ) {
7928			this.next( event );
7929			return;
7930		}
7931		if ( this.isFirstItem() ) {
7932			return;
7933		}
7934		if ( this._hasScroll() ) {
7935			base = this.active.offset().top;
7936			height = this.element.height();
7937			this.active.prevAll( ".ui-menu-item" ).each( function() {
7938				item = $( this );
7939				return item.offset().top - base + height > 0;
7940			} );
7941
7942			this.focus( event, item );
7943		} else {
7944			this.focus( event, this.activeMenu.find( this.options.items ).first() );
7945		}
7946	},
7947
7948	_hasScroll: function() {
7949		return this.element.outerHeight() < this.element.prop( "scrollHeight" );
7950	},
7951
7952	select: function( event ) {
7953
7954		// TODO: It should never be possible to not have an active item at this
7955		// point, but the tests don't trigger mouseenter before click.
7956		this.active = this.active || $( event.target ).closest( ".ui-menu-item" );
7957		var ui = { item: this.active };
7958		if ( !this.active.has( ".ui-menu" ).length ) {
7959			this.collapseAll( event, true );
7960		}
7961		this._trigger( "select", event, ui );
7962	},
7963
7964	_filterMenuItems: function( character ) {
7965		var escapedCharacter = character.replace( /[\-\[\]{}()*+?.,\\\^$|#\s]/g, "\\$&" ),
7966			regex = new RegExp( "^" + escapedCharacter, "i" );
7967
7968		return this.activeMenu
7969			.find( this.options.items )
7970
7971				// Only match on items, not dividers or other content (#10571)
7972				.filter( ".ui-menu-item" )
7973					.filter( function() {
7974						return regex.test(
7975							$.trim( $( this ).children( ".ui-menu-item-wrapper" ).text() ) );
7976					} );
7977	}
7978} );
7979
7980
7981/*!
7982 * jQuery UI Autocomplete 1.12.1
7983 * http://jqueryui.com
7984 *
7985 * Copyright jQuery Foundation and other contributors
7986 * Released under the MIT license.
7987 * http://jquery.org/license
7988 */
7989
7990//>>label: Autocomplete
7991//>>group: Widgets
7992//>>description: Lists suggested words as the user is typing.
7993//>>docs: http://api.jqueryui.com/autocomplete/
7994//>>demos: http://jqueryui.com/autocomplete/
7995//>>css.structure: ../../themes/base/core.css
7996//>>css.structure: ../../themes/base/autocomplete.css
7997//>>css.theme: ../../themes/base/theme.css
7998
7999
8000
8001$.widget( "ui.autocomplete", {
8002	version: "1.12.1",
8003	defaultElement: "<input>",
8004	options: {
8005		appendTo: null,
8006		autoFocus: false,
8007		delay: 300,
8008		minLength: 1,
8009		position: {
8010			my: "left top",
8011			at: "left bottom",
8012			collision: "none"
8013		},
8014		source: null,
8015
8016		// Callbacks
8017		change: null,
8018		close: null,
8019		focus: null,
8020		open: null,
8021		response: null,
8022		search: null,
8023		select: null
8024	},
8025
8026	requestIndex: 0,
8027	pending: 0,
8028
8029	_create: function() {
8030
8031		// Some browsers only repeat keydown events, not keypress events,
8032		// so we use the suppressKeyPress flag to determine if we've already
8033		// handled the keydown event. #7269
8034		// Unfortunately the code for & in keypress is the same as the up arrow,
8035		// so we use the suppressKeyPressRepeat flag to avoid handling keypress
8036		// events when we know the keydown event was used to modify the
8037		// search term. #7799
8038		var suppressKeyPress, suppressKeyPressRepeat, suppressInput,
8039			nodeName = this.element[ 0 ].nodeName.toLowerCase(),
8040			isTextarea = nodeName === "textarea",
8041			isInput = nodeName === "input";
8042
8043		// Textareas are always multi-line
8044		// Inputs are always single-line, even if inside a contentEditable element
8045		// IE also treats inputs as contentEditable
8046		// All other element types are determined by whether or not they're contentEditable
8047		this.isMultiLine = isTextarea || !isInput && this._isContentEditable( this.element );
8048
8049		this.valueMethod = this.element[ isTextarea || isInput ? "val" : "text" ];
8050		this.isNewMenu = true;
8051
8052		this._addClass( "ui-autocomplete-input" );
8053		this.element.attr( "autocomplete", "off" );
8054
8055		this._on( this.element, {
8056			keydown: function( event ) {
8057				if ( this.element.prop( "readOnly" ) ) {
8058					suppressKeyPress = true;
8059					suppressInput = true;
8060					suppressKeyPressRepeat = true;
8061					return;
8062				}
8063
8064				suppressKeyPress = false;
8065				suppressInput = false;
8066				suppressKeyPressRepeat = false;
8067				var keyCode = $.ui.keyCode;
8068				switch ( event.keyCode ) {
8069				case keyCode.PAGE_UP:
8070					suppressKeyPress = true;
8071					this._move( "previousPage", event );
8072					break;
8073				case keyCode.PAGE_DOWN:
8074					suppressKeyPress = true;
8075					this._move( "nextPage", event );
8076					break;
8077				case keyCode.UP:
8078					suppressKeyPress = true;
8079					this._keyEvent( "previous", event );
8080					break;
8081				case keyCode.DOWN:
8082					suppressKeyPress = true;
8083					this._keyEvent( "next", event );
8084					break;
8085				case keyCode.ENTER:
8086
8087					// when menu is open and has focus
8088					if ( this.menu.active ) {
8089
8090						// #6055 - Opera still allows the keypress to occur
8091						// which causes forms to submit
8092						suppressKeyPress = true;
8093						event.preventDefault();
8094						this.menu.select( event );
8095					}
8096					break;
8097				case keyCode.TAB:
8098					if ( this.menu.active ) {
8099						this.menu.select( event );
8100					}
8101					break;
8102				case keyCode.ESCAPE:
8103					if ( this.menu.element.is( ":visible" ) ) {
8104						if ( !this.isMultiLine ) {
8105							this._value( this.term );
8106						}
8107						this.close( event );
8108
8109						// Different browsers have different default behavior for escape
8110						// Single press can mean undo or clear
8111						// Double press in IE means clear the whole form
8112						event.preventDefault();
8113					}
8114					break;
8115				default:
8116					suppressKeyPressRepeat = true;
8117
8118					// search timeout should be triggered before the input value is changed
8119					this._searchTimeout( event );
8120					break;
8121				}
8122			},
8123			keypress: function( event ) {
8124				if ( suppressKeyPress ) {
8125					suppressKeyPress = false;
8126					if ( !this.isMultiLine || this.menu.element.is( ":visible" ) ) {
8127						event.preventDefault();
8128					}
8129					return;
8130				}
8131				if ( suppressKeyPressRepeat ) {
8132					return;
8133				}
8134
8135				// Replicate some key handlers to allow them to repeat in Firefox and Opera
8136				var keyCode = $.ui.keyCode;
8137				switch ( event.keyCode ) {
8138				case keyCode.PAGE_UP:
8139					this._move( "previousPage", event );
8140					break;
8141				case keyCode.PAGE_DOWN:
8142					this._move( "nextPage", event );
8143					break;
8144				case keyCode.UP:
8145					this._keyEvent( "previous", event );
8146					break;
8147				case keyCode.DOWN:
8148					this._keyEvent( "next", event );
8149					break;
8150				}
8151			},
8152			input: function( event ) {
8153				if ( suppressInput ) {
8154					suppressInput = false;
8155					event.preventDefault();
8156					return;
8157				}
8158				this._searchTimeout( event );
8159			},
8160			focus: function() {
8161				this.selectedItem = null;
8162				this.previous = this._value();
8163			},
8164			blur: function( event ) {
8165				if ( this.cancelBlur ) {
8166					delete this.cancelBlur;
8167					return;
8168				}
8169
8170				clearTimeout( this.searching );
8171				this.close( event );
8172				this._change( event );
8173			}
8174		} );
8175
8176		this._initSource();
8177		this.menu = $( "<ul>" )
8178			.appendTo( this._appendTo() )
8179			.menu( {
8180
8181				// disable ARIA support, the live region takes care of that
8182				role: null
8183			} )
8184			.hide()
8185			.menu( "instance" );
8186
8187		this._addClass( this.menu.element, "ui-autocomplete", "ui-front" );
8188		this._on( this.menu.element, {
8189			mousedown: function( event ) {
8190
8191				// prevent moving focus out of the text field
8192				event.preventDefault();
8193
8194				// IE doesn't prevent moving focus even with event.preventDefault()
8195				// so we set a flag to know when we should ignore the blur event
8196				this.cancelBlur = true;
8197				this._delay( function() {
8198					delete this.cancelBlur;
8199
8200					// Support: IE 8 only
8201					// Right clicking a menu item or selecting text from the menu items will
8202					// result in focus moving out of the input. However, we've already received
8203					// and ignored the blur event because of the cancelBlur flag set above. So
8204					// we restore focus to ensure that the menu closes properly based on the user's
8205					// next actions.
8206					if ( this.element[ 0 ] !== $.ui.safeActiveElement( this.document[ 0 ] ) ) {
8207						this.element.trigger( "focus" );
8208					}
8209				} );
8210			},
8211			menufocus: function( event, ui ) {
8212				var label, item;
8213
8214				// support: Firefox
8215				// Prevent accidental activation of menu items in Firefox (#7024 #9118)
8216				if ( this.isNewMenu ) {
8217					this.isNewMenu = false;
8218					if ( event.originalEvent && /^mouse/.test( event.originalEvent.type ) ) {
8219						this.menu.blur();
8220
8221						this.document.one( "mousemove", function() {
8222							$( event.target ).trigger( event.originalEvent );
8223						} );
8224
8225						return;
8226					}
8227				}
8228
8229				item = ui.item.data( "ui-autocomplete-item" );
8230				if ( false !== this._trigger( "focus", event, { item: item } ) ) {
8231
8232					// use value to match what will end up in the input, if it was a key event
8233					if ( event.originalEvent && /^key/.test( event.originalEvent.type ) ) {
8234						this._value( item.value );
8235					}
8236				}
8237
8238				// Announce the value in the liveRegion
8239				label = ui.item.attr( "aria-label" ) || item.value;
8240				if ( label && $.trim( label ).length ) {
8241					this.liveRegion.children().hide();
8242					$( "<div>" ).text( label ).appendTo( this.liveRegion );
8243				}
8244			},
8245			menuselect: function( event, ui ) {
8246				var item = ui.item.data( "ui-autocomplete-item" ),
8247					previous = this.previous;
8248
8249				// Only trigger when focus was lost (click on menu)
8250				if ( this.element[ 0 ] !== $.ui.safeActiveElement( this.document[ 0 ] ) ) {
8251					this.element.trigger( "focus" );
8252					this.previous = previous;
8253
8254					// #6109 - IE triggers two focus events and the second
8255					// is asynchronous, so we need to reset the previous
8256					// term synchronously and asynchronously :-(
8257					this._delay( function() {
8258						this.previous = previous;
8259						this.selectedItem = item;
8260					} );
8261				}
8262
8263				if ( false !== this._trigger( "select", event, { item: item } ) ) {
8264					this._value( item.value );
8265				}
8266
8267				// reset the term after the select event
8268				// this allows custom select handling to work properly
8269				this.term = this._value();
8270
8271				this.close( event );
8272				this.selectedItem = item;
8273			}
8274		} );
8275
8276		this.liveRegion = $( "<div>", {
8277			role: "status",
8278			"aria-live": "assertive",
8279			"aria-relevant": "additions"
8280		} )
8281			.appendTo( this.document[ 0 ].body );
8282
8283		this._addClass( this.liveRegion, null, "ui-helper-hidden-accessible" );
8284
8285		// Turning off autocomplete prevents the browser from remembering the
8286		// value when navigating through history, so we re-enable autocomplete
8287		// if the page is unloaded before the widget is destroyed. #7790
8288		this._on( this.window, {
8289			beforeunload: function() {
8290				this.element.removeAttr( "autocomplete" );
8291			}
8292		} );
8293	},
8294
8295	_destroy: function() {
8296		clearTimeout( this.searching );
8297		this.element.removeAttr( "autocomplete" );
8298		this.menu.element.remove();
8299		this.liveRegion.remove();
8300	},
8301
8302	_setOption: function( key, value ) {
8303		this._super( key, value );
8304		if ( key === "source" ) {
8305			this._initSource();
8306		}
8307		if ( key === "appendTo" ) {
8308			this.menu.element.appendTo( this._appendTo() );
8309		}
8310		if ( key === "disabled" && value && this.xhr ) {
8311			this.xhr.abort();
8312		}
8313	},
8314
8315	_isEventTargetInWidget: function( event ) {
8316		var menuElement = this.menu.element[ 0 ];
8317
8318		return event.target === this.element[ 0 ] ||
8319			event.target === menuElement ||
8320			$.contains( menuElement, event.target );
8321	},
8322
8323	_closeOnClickOutside: function( event ) {
8324		if ( !this._isEventTargetInWidget( event ) ) {
8325			this.close();
8326		}
8327	},
8328
8329	_appendTo: function() {
8330		var element = this.options.appendTo;
8331
8332		if ( element ) {
8333			element = element.jquery || element.nodeType ?
8334				$( element ) :
8335				this.document.find( element ).eq( 0 );
8336		}
8337
8338		if ( !element || !element[ 0 ] ) {
8339			element = this.element.closest( ".ui-front, dialog" );
8340		}
8341
8342		if ( !element.length ) {
8343			element = this.document[ 0 ].body;
8344		}
8345
8346		return element;
8347	},
8348
8349	_initSource: function() {
8350		var array, url,
8351			that = this;
8352		if ( $.isArray( this.options.source ) ) {
8353			array = this.options.source;
8354			this.source = function( request, response ) {
8355				response( $.ui.autocomplete.filter( array, request.term ) );
8356			};
8357		} else if ( typeof this.options.source === "string" ) {
8358			url = this.options.source;
8359			this.source = function( request, response ) {
8360				if ( that.xhr ) {
8361					that.xhr.abort();
8362				}
8363				that.xhr = $.ajax( {
8364					url: url,
8365					data: request,
8366					dataType: "json",
8367					success: function( data ) {
8368						response( data );
8369					},
8370					error: function() {
8371						response( [] );
8372					}
8373				} );
8374			};
8375		} else {
8376			this.source = this.options.source;
8377		}
8378	},
8379
8380	_searchTimeout: function( event ) {
8381		clearTimeout( this.searching );
8382		this.searching = this._delay( function() {
8383
8384			// Search if the value has changed, or if the user retypes the same value (see #7434)
8385			var equalValues = this.term === this._value(),
8386				menuVisible = this.menu.element.is( ":visible" ),
8387				modifierKey = event.altKey || event.ctrlKey || event.metaKey || event.shiftKey;
8388
8389			if ( !equalValues || ( equalValues && !menuVisible && !modifierKey ) ) {
8390				this.selectedItem = null;
8391				this.search( null, event );
8392			}
8393		}, this.options.delay );
8394	},
8395
8396	search: function( value, event ) {
8397		value = value != null ? value : this._value();
8398
8399		// Always save the actual value, not the one passed as an argument
8400		this.term = this._value();
8401
8402		if ( value.length < this.options.minLength ) {
8403			return this.close( event );
8404		}
8405
8406		if ( this._trigger( "search", event ) === false ) {
8407			return;
8408		}
8409
8410		return this._search( value );
8411	},
8412
8413	_search: function( value ) {
8414		this.pending++;
8415		this._addClass( "ui-autocomplete-loading" );
8416		this.cancelSearch = false;
8417
8418		this.source( { term: value }, this._response() );
8419	},
8420
8421	_response: function() {
8422		var index = ++this.requestIndex;
8423
8424		return $.proxy( function( content ) {
8425			if ( index === this.requestIndex ) {
8426				this.__response( content );
8427			}
8428
8429			this.pending--;
8430			if ( !this.pending ) {
8431				this._removeClass( "ui-autocomplete-loading" );
8432			}
8433		}, this );
8434	},
8435
8436	__response: function( content ) {
8437		if ( content ) {
8438			content = this._normalize( content );
8439		}
8440		this._trigger( "response", null, { content: content } );
8441		if ( !this.options.disabled && content && content.length && !this.cancelSearch ) {
8442			this._suggest( content );
8443			this._trigger( "open" );
8444		} else {
8445
8446			// use ._close() instead of .close() so we don't cancel future searches
8447			this._close();
8448		}
8449	},
8450
8451	close: function( event ) {
8452		this.cancelSearch = true;
8453		this._close( event );
8454	},
8455
8456	_close: function( event ) {
8457
8458		// Remove the handler that closes the menu on outside clicks
8459		this._off( this.document, "mousedown" );
8460
8461		if ( this.menu.element.is( ":visible" ) ) {
8462			this.menu.element.hide();
8463			this.menu.blur();
8464			this.isNewMenu = true;
8465			this._trigger( "close", event );
8466		}
8467	},
8468
8469	_change: function( event ) {
8470		if ( this.previous !== this._value() ) {
8471			this._trigger( "change", event, { item: this.selectedItem } );
8472		}
8473	},
8474
8475	_normalize: function( items ) {
8476
8477		// assume all items have the right format when the first item is complete
8478		if ( items.length && items[ 0 ].label && items[ 0 ].value ) {
8479			return items;
8480		}
8481		return $.map( items, function( item ) {
8482			if ( typeof item === "string" ) {
8483				return {
8484					label: item,
8485					value: item
8486				};
8487			}
8488			return $.extend( {}, item, {
8489				label: item.label || item.value,
8490				value: item.value || item.label
8491			} );
8492		} );
8493	},
8494
8495	_suggest: function( items ) {
8496		var ul = this.menu.element.empty();
8497		this._renderMenu( ul, items );
8498		this.isNewMenu = true;
8499		this.menu.refresh();
8500
8501		// Size and position menu
8502		ul.show();
8503		this._resizeMenu();
8504		ul.position( $.extend( {
8505			of: this.element
8506		}, this.options.position ) );
8507
8508		if ( this.options.autoFocus ) {
8509			this.menu.next();
8510		}
8511
8512		// Listen for interactions outside of the widget (#6642)
8513		this._on( this.document, {
8514			mousedown: "_closeOnClickOutside"
8515		} );
8516	},
8517
8518	_resizeMenu: function() {
8519		var ul = this.menu.element;
8520		ul.outerWidth( Math.max(
8521
8522			// Firefox wraps long text (possibly a rounding bug)
8523			// so we add 1px to avoid the wrapping (#7513)
8524			ul.width( "" ).outerWidth() + 1,
8525			this.element.outerWidth()
8526		) );
8527	},
8528
8529	_renderMenu: function( ul, items ) {
8530		var that = this;
8531		$.each( items, function( index, item ) {
8532			that._renderItemData( ul, item );
8533		} );
8534	},
8535
8536	_renderItemData: function( ul, item ) {
8537		return this._renderItem( ul, item ).data( "ui-autocomplete-item", item );
8538	},
8539
8540	_renderItem: function( ul, item ) {
8541		return $( "<li>" )
8542			.append( $( "<div>" ).text( item.label ) )
8543			.appendTo( ul );
8544	},
8545
8546	_move: function( direction, event ) {
8547		if ( !this.menu.element.is( ":visible" ) ) {
8548			this.search( null, event );
8549			return;
8550		}
8551		if ( this.menu.isFirstItem() && /^previous/.test( direction ) ||
8552				this.menu.isLastItem() && /^next/.test( direction ) ) {
8553
8554			if ( !this.isMultiLine ) {
8555				this._value( this.term );
8556			}
8557
8558			this.menu.blur();
8559			return;
8560		}
8561		this.menu[ direction ]( event );
8562	},
8563
8564	widget: function() {
8565		return this.menu.element;
8566	},
8567
8568	_value: function() {
8569		return this.valueMethod.apply( this.element, arguments );
8570	},
8571
8572	_keyEvent: function( keyEvent, event ) {
8573		if ( !this.isMultiLine || this.menu.element.is( ":visible" ) ) {
8574			this._move( keyEvent, event );
8575
8576			// Prevents moving cursor to beginning/end of the text field in some browsers
8577			event.preventDefault();
8578		}
8579	},
8580
8581	// Support: Chrome <=50
8582	// We should be able to just use this.element.prop( "isContentEditable" )
8583	// but hidden elements always report false in Chrome.
8584	// https://code.google.com/p/chromium/issues/detail?id=313082
8585	_isContentEditable: function( element ) {
8586		if ( !element.length ) {
8587			return false;
8588		}
8589
8590		var editable = element.prop( "contentEditable" );
8591
8592		if ( editable === "inherit" ) {
8593		  return this._isContentEditable( element.parent() );
8594		}
8595
8596		return editable === "true";
8597	}
8598} );
8599
8600$.extend( $.ui.autocomplete, {
8601	escapeRegex: function( value ) {
8602		return value.replace( /[\-\[\]{}()*+?.,\\\^$|#\s]/g, "\\$&" );
8603	},
8604	filter: function( array, term ) {
8605		var matcher = new RegExp( $.ui.autocomplete.escapeRegex( term ), "i" );
8606		return $.grep( array, function( value ) {
8607			return matcher.test( value.label || value.value || value );
8608		} );
8609	}
8610} );
8611
8612// Live region extension, adding a `messages` option
8613// NOTE: This is an experimental API. We are still investigating
8614// a full solution for string manipulation and internationalization.
8615$.widget( "ui.autocomplete", $.ui.autocomplete, {
8616	options: {
8617		messages: {
8618			noResults: "No search results.",
8619			results: function( amount ) {
8620				return amount + ( amount > 1 ? " results are" : " result is" ) +
8621					" available, use up and down arrow keys to navigate.";
8622			}
8623		}
8624	},
8625
8626	__response: function( content ) {
8627		var message;
8628		this._superApply( arguments );
8629		if ( this.options.disabled || this.cancelSearch ) {
8630			return;
8631		}
8632		if ( content && content.length ) {
8633			message = this.options.messages.results( content.length );
8634		} else {
8635			message = this.options.messages.noResults;
8636		}
8637		this.liveRegion.children().hide();
8638		$( "<div>" ).text( message ).appendTo( this.liveRegion );
8639	}
8640} );
8641
8642var widgetsAutocomplete = $.ui.autocomplete;
8643
8644
8645/*!
8646 * jQuery UI Controlgroup 1.12.1
8647 * http://jqueryui.com
8648 *
8649 * Copyright jQuery Foundation and other contributors
8650 * Released under the MIT license.
8651 * http://jquery.org/license
8652 */
8653
8654//>>label: Controlgroup
8655//>>group: Widgets
8656//>>description: Visually groups form control widgets
8657//>>docs: http://api.jqueryui.com/controlgroup/
8658//>>demos: http://jqueryui.com/controlgroup/
8659//>>css.structure: ../../themes/base/core.css
8660//>>css.structure: ../../themes/base/controlgroup.css
8661//>>css.theme: ../../themes/base/theme.css
8662
8663
8664var controlgroupCornerRegex = /ui-corner-([a-z]){2,6}/g;
8665
8666var widgetsControlgroup = $.widget( "ui.controlgroup", {
8667	version: "1.12.1",
8668	defaultElement: "<div>",
8669	options: {
8670		direction: "horizontal",
8671		disabled: null,
8672		onlyVisible: true,
8673		items: {
8674			"button": "input[type=button], input[type=submit], input[type=reset], button, a",
8675			"controlgroupLabel": ".ui-controlgroup-label",
8676			"checkboxradio": "input[type='checkbox'], input[type='radio']",
8677			"selectmenu": "select",
8678			"spinner": ".ui-spinner-input"
8679		}
8680	},
8681
8682	_create: function() {
8683		this._enhance();
8684	},
8685
8686	// To support the enhanced option in jQuery Mobile, we isolate DOM manipulation
8687	_enhance: function() {
8688		this.element.attr( "role", "toolbar" );
8689		this.refresh();
8690	},
8691
8692	_destroy: function() {
8693		this._callChildMethod( "destroy" );
8694		this.childWidgets.removeData( "ui-controlgroup-data" );
8695		this.element.removeAttr( "role" );
8696		if ( this.options.items.controlgroupLabel ) {
8697			this.element
8698				.find( this.options.items.controlgroupLabel )
8699				.find( ".ui-controlgroup-label-contents" )
8700				.contents().unwrap();
8701		}
8702	},
8703
8704	_initWidgets: function() {
8705		var that = this,
8706			childWidgets = [];
8707
8708		// First we iterate over each of the items options
8709		$.each( this.options.items, function( widget, selector ) {
8710			var labels;
8711			var options = {};
8712
8713			// Make sure the widget has a selector set
8714			if ( !selector ) {
8715				return;
8716			}
8717
8718			if ( widget === "controlgroupLabel" ) {
8719				labels = that.element.find( selector );
8720				labels.each( function() {
8721					var element = $( this );
8722
8723					if ( element.children( ".ui-controlgroup-label-contents" ).length ) {
8724						return;
8725					}
8726					element.contents()
8727						.wrapAll( "<span class='ui-controlgroup-label-contents'></span>" );
8728				} );
8729				that._addClass( labels, null, "ui-widget ui-widget-content ui-state-default" );
8730				childWidgets = childWidgets.concat( labels.get() );
8731				return;
8732			}
8733
8734			// Make sure the widget actually exists
8735			if ( !$.fn[ widget ] ) {
8736				return;
8737			}
8738
8739			// We assume everything is in the middle to start because we can't determine
8740			// first / last elements until all enhancments are done.
8741			if ( that[ "_" + widget + "Options" ] ) {
8742				options = that[ "_" + widget + "Options" ]( "middle" );
8743			} else {
8744				options = { classes: {} };
8745			}
8746
8747			// Find instances of this widget inside controlgroup and init them
8748			that.element
8749				.find( selector )
8750				.each( function() {
8751					var element = $( this );
8752					var instance = element[ widget ]( "instance" );
8753
8754					// We need to clone the default options for this type of widget to avoid
8755					// polluting the variable options which has a wider scope than a single widget.
8756					var instanceOptions = $.widget.extend( {}, options );
8757
8758					// If the button is the child of a spinner ignore it
8759					// TODO: Find a more generic solution
8760					if ( widget === "button" && element.parent( ".ui-spinner" ).length ) {
8761						return;
8762					}
8763
8764					// Create the widget if it doesn't exist
8765					if ( !instance ) {
8766						instance = element[ widget ]()[ widget ]( "instance" );
8767					}
8768					if ( instance ) {
8769						instanceOptions.classes =
8770							that._resolveClassesValues( instanceOptions.classes, instance );
8771					}
8772					element[ widget ]( instanceOptions );
8773
8774					// Store an instance of the controlgroup to be able to reference
8775					// from the outermost element for changing options and refresh
8776					var widgetElement = element[ widget ]( "widget" );
8777					$.data( widgetElement[ 0 ], "ui-controlgroup-data",
8778						instance ? instance : element[ widget ]( "instance" ) );
8779
8780					childWidgets.push( widgetElement[ 0 ] );
8781				} );
8782		} );
8783
8784		this.childWidgets = $( $.unique( childWidgets ) );
8785		this._addClass( this.childWidgets, "ui-controlgroup-item" );
8786	},
8787
8788	_callChildMethod: function( method ) {
8789		this.childWidgets.each( function() {
8790			var element = $( this ),
8791				data = element.data( "ui-controlgroup-data" );
8792			if ( data && data[ method ] ) {
8793				data[ method ]();
8794			}
8795		} );
8796	},
8797
8798	_updateCornerClass: function( element, position ) {
8799		var remove = "ui-corner-top ui-corner-bottom ui-corner-left ui-corner-right ui-corner-all";
8800		var add = this._buildSimpleOptions( position, "label" ).classes.label;
8801
8802		this._removeClass( element, null, remove );
8803		this._addClass( element, null, add );
8804	},
8805
8806	_buildSimpleOptions: function( position, key ) {
8807		var direction = this.options.direction === "vertical";
8808		var result = {
8809			classes: {}
8810		};
8811		result.classes[ key ] = {
8812			"middle": "",
8813			"first": "ui-corner-" + ( direction ? "top" : "left" ),
8814			"last": "ui-corner-" + ( direction ? "bottom" : "right" ),
8815			"only": "ui-corner-all"
8816		}[ position ];
8817
8818		return result;
8819	},
8820
8821	_spinnerOptions: function( position ) {
8822		var options = this._buildSimpleOptions( position, "ui-spinner" );
8823
8824		options.classes[ "ui-spinner-up" ] = "";
8825		options.classes[ "ui-spinner-down" ] = "";
8826
8827		return options;
8828	},
8829
8830	_buttonOptions: function( position ) {
8831		return this._buildSimpleOptions( position, "ui-button" );
8832	},
8833
8834	_checkboxradioOptions: function( position ) {
8835		return this._buildSimpleOptions( position, "ui-checkboxradio-label" );
8836	},
8837
8838	_selectmenuOptions: function( position ) {
8839		var direction = this.options.direction === "vertical";
8840		return {
8841			width: direction ? "auto" : false,
8842			classes: {
8843				middle: {
8844					"ui-selectmenu-button-open": "",
8845					"ui-selectmenu-button-closed": ""
8846				},
8847				first: {
8848					"ui-selectmenu-button-open": "ui-corner-" + ( direction ? "top" : "tl" ),
8849					"ui-selectmenu-button-closed": "ui-corner-" + ( direction ? "top" : "left" )
8850				},
8851				last: {
8852					"ui-selectmenu-button-open": direction ? "" : "ui-corner-tr",
8853					"ui-selectmenu-button-closed": "ui-corner-" + ( direction ? "bottom" : "right" )
8854				},
8855				only: {
8856					"ui-selectmenu-button-open": "ui-corner-top",
8857					"ui-selectmenu-button-closed": "ui-corner-all"
8858				}
8859
8860			}[ position ]
8861		};
8862	},
8863
8864	_resolveClassesValues: function( classes, instance ) {
8865		var result = {};
8866		$.each( classes, function( key ) {
8867			var current = instance.options.classes[ key ] || "";
8868			current = $.trim( current.replace( controlgroupCornerRegex, "" ) );
8869			result[ key ] = ( current + " " + classes[ key ] ).replace( /\s+/g, " " );
8870		} );
8871		return result;
8872	},
8873
8874	_setOption: function( key, value ) {
8875		if ( key === "direction" ) {
8876			this._removeClass( "ui-controlgroup-" + this.options.direction );
8877		}
8878
8879		this._super( key, value );
8880		if ( key === "disabled" ) {
8881			this._callChildMethod( value ? "disable" : "enable" );
8882			return;
8883		}
8884
8885		this.refresh();
8886	},
8887
8888	refresh: function() {
8889		var children,
8890			that = this;
8891
8892		this._addClass( "ui-controlgroup ui-controlgroup-" + this.options.direction );
8893
8894		if ( this.options.direction === "horizontal" ) {
8895			this._addClass( null, "ui-helper-clearfix" );
8896		}
8897		this._initWidgets();
8898
8899		children = this.childWidgets;
8900
8901		// We filter here because we need to track all childWidgets not just the visible ones
8902		if ( this.options.onlyVisible ) {
8903			children = children.filter( ":visible" );
8904		}
8905
8906		if ( children.length ) {
8907
8908			// We do this last because we need to make sure all enhancment is done
8909			// before determining first and last
8910			$.each( [ "first", "last" ], function( index, value ) {
8911				var instance = children[ value ]().data( "ui-controlgroup-data" );
8912
8913				if ( instance && that[ "_" + instance.widgetName + "Options" ] ) {
8914					var options = that[ "_" + instance.widgetName + "Options" ](
8915						children.length === 1 ? "only" : value
8916					);
8917					options.classes = that._resolveClassesValues( options.classes, instance );
8918					instance.element[ instance.widgetName ]( options );
8919				} else {
8920					that._updateCornerClass( children[ value ](), value );
8921				}
8922			} );
8923
8924			// Finally call the refresh method on each of the child widgets.
8925			this._callChildMethod( "refresh" );
8926		}
8927	}
8928} );
8929
8930/*!
8931 * jQuery UI Checkboxradio 1.12.1
8932 * http://jqueryui.com
8933 *
8934 * Copyright jQuery Foundation and other contributors
8935 * Released under the MIT license.
8936 * http://jquery.org/license
8937 */
8938
8939//>>label: Checkboxradio
8940//>>group: Widgets
8941//>>description: Enhances a form with multiple themeable checkboxes or radio buttons.
8942//>>docs: http://api.jqueryui.com/checkboxradio/
8943//>>demos: http://jqueryui.com/checkboxradio/
8944//>>css.structure: ../../themes/base/core.css
8945//>>css.structure: ../../themes/base/button.css
8946//>>css.structure: ../../themes/base/checkboxradio.css
8947//>>css.theme: ../../themes/base/theme.css
8948
8949
8950
8951$.widget( "ui.checkboxradio", [ $.ui.formResetMixin, {
8952	version: "1.12.1",
8953	options: {
8954		disabled: null,
8955		label: null,
8956		icon: true,
8957		classes: {
8958			"ui-checkboxradio-label": "ui-corner-all",
8959			"ui-checkboxradio-icon": "ui-corner-all"
8960		}
8961	},
8962
8963	_getCreateOptions: function() {
8964		var disabled, labels;
8965		var that = this;
8966		var options = this._super() || {};
8967
8968		// We read the type here, because it makes more sense to throw a element type error first,
8969		// rather then the error for lack of a label. Often if its the wrong type, it
8970		// won't have a label (e.g. calling on a div, btn, etc)
8971		this._readType();
8972
8973		labels = this.element.labels();
8974
8975		// If there are multiple labels, use the last one
8976		this.label = $( labels[ labels.length - 1 ] );
8977		if ( !this.label.length ) {
8978			$.error( "No label found for checkboxradio widget" );
8979		}
8980
8981		this.originalLabel = "";
8982
8983		// We need to get the label text but this may also need to make sure it does not contain the
8984		// input itself.
8985		this.label.contents().not( this.element[ 0 ] ).each( function() {
8986
8987			// The label contents could be text, html, or a mix. We concat each element to get a
8988			// string representation of the label, without the input as part of it.
8989			that.originalLabel += this.nodeType === 3 ? $( this ).text() : this.outerHTML;
8990		} );
8991
8992		// Set the label option if we found label text
8993		if ( this.originalLabel ) {
8994			options.label = this.originalLabel;
8995		}
8996
8997		disabled = this.element[ 0 ].disabled;
8998		if ( disabled != null ) {
8999			options.disabled = disabled;
9000		}
9001		return options;
9002	},
9003
9004	_create: function() {
9005		var checked = this.element[ 0 ].checked;
9006
9007		this._bindFormResetHandler();
9008
9009		if ( this.options.disabled == null ) {
9010			this.options.disabled = this.element[ 0 ].disabled;
9011		}
9012
9013		this._setOption( "disabled", this.options.disabled );
9014		this._addClass( "ui-checkboxradio", "ui-helper-hidden-accessible" );
9015		this._addClass( this.label, "ui-checkboxradio-label", "ui-button ui-widget" );
9016
9017		if ( this.type === "radio" ) {
9018			this._addClass( this.label, "ui-checkboxradio-radio-label" );
9019		}
9020
9021		if ( this.options.label && this.options.label !== this.originalLabel ) {
9022			this._updateLabel();
9023		} else if ( this.originalLabel ) {
9024			this.options.label = this.originalLabel;
9025		}
9026
9027		this._enhance();
9028
9029		if ( checked ) {
9030			this._addClass( this.label, "ui-checkboxradio-checked", "ui-state-active" );
9031			if ( this.icon ) {
9032				this._addClass( this.icon, null, "ui-state-hover" );
9033			}
9034		}
9035
9036		this._on( {
9037			change: "_toggleClasses",
9038			focus: function() {
9039				this._addClass( this.label, null, "ui-state-focus ui-visual-focus" );
9040			},
9041			blur: function() {
9042				this._removeClass( this.label, null, "ui-state-focus ui-visual-focus" );
9043			}
9044		} );
9045	},
9046
9047	_readType: function() {
9048		var nodeName = this.element[ 0 ].nodeName.toLowerCase();
9049		this.type = this.element[ 0 ].type;
9050		if ( nodeName !== "input" || !/radio|checkbox/.test( this.type ) ) {
9051			$.error( "Can't create checkboxradio on element.nodeName=" + nodeName +
9052				" and element.type=" + this.type );
9053		}
9054	},
9055
9056	// Support jQuery Mobile enhanced option
9057	_enhance: function() {
9058		this._updateIcon( this.element[ 0 ].checked );
9059	},
9060
9061	widget: function() {
9062		return this.label;
9063	},
9064
9065	_getRadioGroup: function() {
9066		var group;
9067		var name = this.element[ 0 ].name;
9068		var nameSelector = "input[name='" + $.ui.escapeSelector( name ) + "']";
9069
9070		if ( !name ) {
9071			return $( [] );
9072		}
9073
9074		if ( this.form.length ) {
9075			group = $( this.form[ 0 ].elements ).filter( nameSelector );
9076		} else {
9077
9078			// Not inside a form, check all inputs that also are not inside a form
9079			group = $( nameSelector ).filter( function() {
9080				return $( this ).form().length === 0;
9081			} );
9082		}
9083
9084		return group.not( this.element );
9085	},
9086
9087	_toggleClasses: function() {
9088		var checked = this.element[ 0 ].checked;
9089		this._toggleClass( this.label, "ui-checkboxradio-checked", "ui-state-active", checked );
9090
9091		if ( this.options.icon && this.type === "checkbox" ) {
9092			this._toggleClass( this.icon, null, "ui-icon-check ui-state-checked", checked )
9093				._toggleClass( this.icon, null, "ui-icon-blank", !checked );
9094		}
9095
9096		if ( this.type === "radio" ) {
9097			this._getRadioGroup()
9098				.each( function() {
9099					var instance = $( this ).checkboxradio( "instance" );
9100
9101					if ( instance ) {
9102						instance._removeClass( instance.label,
9103							"ui-checkboxradio-checked", "ui-state-active" );
9104					}
9105				} );
9106		}
9107	},
9108
9109	_destroy: function() {
9110		this._unbindFormResetHandler();
9111
9112		if ( this.icon ) {
9113			this.icon.remove();
9114			this.iconSpace.remove();
9115		}
9116	},
9117
9118	_setOption: function( key, value ) {
9119
9120		// We don't allow the value to be set to nothing
9121		if ( key === "label" && !value ) {
9122			return;
9123		}
9124
9125		this._super( key, value );
9126
9127		if ( key === "disabled" ) {
9128			this._toggleClass( this.label, null, "ui-state-disabled", value );
9129			this.element[ 0 ].disabled = value;
9130
9131			// Don't refresh when setting disabled
9132			return;
9133		}
9134		this.refresh();
9135	},
9136
9137	_updateIcon: function( checked ) {
9138		var toAdd = "ui-icon ui-icon-background ";
9139
9140		if ( this.options.icon ) {
9141			if ( !this.icon ) {
9142				this.icon = $( "<span>" );
9143				this.iconSpace = $( "<span> </span>" );
9144				this._addClass( this.iconSpace, "ui-checkboxradio-icon-space" );
9145			}
9146
9147			if ( this.type === "checkbox" ) {
9148				toAdd += checked ? "ui-icon-check ui-state-checked" : "ui-icon-blank";
9149				this._removeClass( this.icon, null, checked ? "ui-icon-blank" : "ui-icon-check" );
9150			} else {
9151				toAdd += "ui-icon-blank";
9152			}
9153			this._addClass( this.icon, "ui-checkboxradio-icon", toAdd );
9154			if ( !checked ) {
9155				this._removeClass( this.icon, null, "ui-icon-check ui-state-checked" );
9156			}
9157			this.icon.prependTo( this.label ).after( this.iconSpace );
9158		} else if ( this.icon !== undefined ) {
9159			this.icon.remove();
9160			this.iconSpace.remove();
9161			delete this.icon;
9162		}
9163	},
9164
9165	_updateLabel: function() {
9166
9167		// Remove the contents of the label ( minus the icon, icon space, and input )
9168		var contents = this.label.contents().not( this.element[ 0 ] );
9169		if ( this.icon ) {
9170			contents = contents.not( this.icon[ 0 ] );
9171		}
9172		if ( this.iconSpace ) {
9173			contents = contents.not( this.iconSpace[ 0 ] );
9174		}
9175		contents.remove();
9176
9177		this.label.append( this.options.label );
9178	},
9179
9180	refresh: function() {
9181		var checked = this.element[ 0 ].checked,
9182			isDisabled = this.element[ 0 ].disabled;
9183
9184		this._updateIcon( checked );
9185		this._toggleClass( this.label, "ui-checkboxradio-checked", "ui-state-active", checked );
9186		if ( this.options.label !== null ) {
9187			this._updateLabel();
9188		}
9189
9190		if ( isDisabled !== this.options.disabled ) {
9191			this._setOptions( { "disabled": isDisabled } );
9192		}
9193	}
9194
9195} ] );
9196
9197var widgetsCheckboxradio = $.ui.checkboxradio;
9198
9199
9200/*!
9201 * jQuery UI Button 1.12.1
9202 * http://jqueryui.com
9203 *
9204 * Copyright jQuery Foundation and other contributors
9205 * Released under the MIT license.
9206 * http://jquery.org/license
9207 */
9208
9209//>>label: Button
9210//>>group: Widgets
9211//>>description: Enhances a form with themeable buttons.
9212//>>docs: http://api.jqueryui.com/button/
9213//>>demos: http://jqueryui.com/button/
9214//>>css.structure: ../../themes/base/core.css
9215//>>css.structure: ../../themes/base/button.css
9216//>>css.theme: ../../themes/base/theme.css
9217
9218
9219
9220$.widget( "ui.button", {
9221	version: "1.12.1",
9222	defaultElement: "<button>",
9223	options: {
9224		classes: {
9225			"ui-button": "ui-corner-all"
9226		},
9227		disabled: null,
9228		icon: null,
9229		iconPosition: "beginning",
9230		label: null,
9231		showLabel: true
9232	},
9233
9234	_getCreateOptions: function() {
9235		var disabled,
9236
9237			// This is to support cases like in jQuery Mobile where the base widget does have
9238			// an implementation of _getCreateOptions
9239			options = this._super() || {};
9240
9241		this.isInput = this.element.is( "input" );
9242
9243		disabled = this.element[ 0 ].disabled;
9244		if ( disabled != null ) {
9245			options.disabled = disabled;
9246		}
9247
9248		this.originalLabel = this.isInput ? this.element.val() : this.element.html();
9249		if ( this.originalLabel ) {
9250			options.label = this.originalLabel;
9251		}
9252
9253		return options;
9254	},
9255
9256	_create: function() {
9257		if ( !this.option.showLabel & !this.options.icon ) {
9258			this.options.showLabel = true;
9259		}
9260
9261		// We have to check the option again here even though we did in _getCreateOptions,
9262		// because null may have been passed on init which would override what was set in
9263		// _getCreateOptions
9264		if ( this.options.disabled == null ) {
9265			this.options.disabled = this.element[ 0 ].disabled || false;
9266		}
9267
9268		this.hasTitle = !!this.element.attr( "title" );
9269
9270		// Check to see if the label needs to be set or if its already correct
9271		if ( this.options.label && this.options.label !== this.originalLabel ) {
9272			if ( this.isInput ) {
9273				this.element.val( this.options.label );
9274			} else {
9275				this.element.html( this.options.label );
9276			}
9277		}
9278		this._addClass( "ui-button", "ui-widget" );
9279		this._setOption( "disabled", this.options.disabled );
9280		this._enhance();
9281
9282		if ( this.element.is( "a" ) ) {
9283			this._on( {
9284				"keyup": function( event ) {
9285					if ( event.keyCode === $.ui.keyCode.SPACE ) {
9286						event.preventDefault();
9287
9288						// Support: PhantomJS <= 1.9, IE 8 Only
9289						// If a native click is available use it so we actually cause navigation
9290						// otherwise just trigger a click event
9291						if ( this.element[ 0 ].click ) {
9292							this.element[ 0 ].click();
9293						} else {
9294							this.element.trigger( "click" );
9295						}
9296					}
9297				}
9298			} );
9299		}
9300	},
9301
9302	_enhance: function() {
9303		if ( !this.element.is( "button" ) ) {
9304			this.element.attr( "role", "button" );
9305		}
9306
9307		if ( this.options.icon ) {
9308			this._updateIcon( "icon", this.options.icon );
9309			this._updateTooltip();
9310		}
9311	},
9312
9313	_updateTooltip: function() {
9314		this.title = this.element.attr( "title" );
9315
9316		if ( !this.options.showLabel && !this.title ) {
9317			this.element.attr( "title", this.options.label );
9318		}
9319	},
9320
9321	_updateIcon: function( option, value ) {
9322		var icon = option !== "iconPosition",
9323			position = icon ? this.options.iconPosition : value,
9324			displayBlock = position === "top" || position === "bottom";
9325
9326		// Create icon
9327		if ( !this.icon ) {
9328			this.icon = $( "<span>" );
9329
9330			this._addClass( this.icon, "ui-button-icon", "ui-icon" );
9331
9332			if ( !this.options.showLabel ) {
9333				this._addClass( "ui-button-icon-only" );
9334			}
9335		} else if ( icon ) {
9336
9337			// If we are updating the icon remove the old icon class
9338			this._removeClass( this.icon, null, this.options.icon );
9339		}
9340
9341		// If we are updating the icon add the new icon class
9342		if ( icon ) {
9343			this._addClass( this.icon, null, value );
9344		}
9345
9346		this._attachIcon( position );
9347
9348		// If the icon is on top or bottom we need to add the ui-widget-icon-block class and remove
9349		// the iconSpace if there is one.
9350		if ( displayBlock ) {
9351			this._addClass( this.icon, null, "ui-widget-icon-block" );
9352			if ( this.iconSpace ) {
9353				this.iconSpace.remove();
9354			}
9355		} else {
9356
9357			// Position is beginning or end so remove the ui-widget-icon-block class and add the
9358			// space if it does not exist
9359			if ( !this.iconSpace ) {
9360				this.iconSpace = $( "<span> </span>" );
9361				this._addClass( this.iconSpace, "ui-button-icon-space" );
9362			}
9363			this._removeClass( this.icon, null, "ui-wiget-icon-block" );
9364			this._attachIconSpace( position );
9365		}
9366	},
9367
9368	_destroy: function() {
9369		this.element.removeAttr( "role" );
9370
9371		if ( this.icon ) {
9372			this.icon.remove();
9373		}
9374		if ( this.iconSpace ) {
9375			this.iconSpace.remove();
9376		}
9377		if ( !this.hasTitle ) {
9378			this.element.removeAttr( "title" );
9379		}
9380	},
9381
9382	_attachIconSpace: function( iconPosition ) {
9383		this.icon[ /^(?:end|bottom)/.test( iconPosition ) ? "before" : "after" ]( this.iconSpace );
9384	},
9385
9386	_attachIcon: function( iconPosition ) {
9387		this.element[ /^(?:end|bottom)/.test( iconPosition ) ? "append" : "prepend" ]( this.icon );
9388	},
9389
9390	_setOptions: function( options ) {
9391		var newShowLabel = options.showLabel === undefined ?
9392				this.options.showLabel :
9393				options.showLabel,
9394			newIcon = options.icon === undefined ? this.options.icon : options.icon;
9395
9396		if ( !newShowLabel && !newIcon ) {
9397			options.showLabel = true;
9398		}
9399		this._super( options );
9400	},
9401
9402	_setOption: function( key, value ) {
9403		if ( key === "icon" ) {
9404			if ( value ) {
9405				this._updateIcon( key, value );
9406			} else if ( this.icon ) {
9407				this.icon.remove();
9408				if ( this.iconSpace ) {
9409					this.iconSpace.remove();
9410				}
9411			}
9412		}
9413
9414		if ( key === "iconPosition" ) {
9415			this._updateIcon( key, value );
9416		}
9417
9418		// Make sure we can't end up with a button that has neither text nor icon
9419		if ( key === "showLabel" ) {
9420				this._toggleClass( "ui-button-icon-only", null, !value );
9421				this._updateTooltip();
9422		}
9423
9424		if ( key === "label" ) {
9425			if ( this.isInput ) {
9426				this.element.val( value );
9427			} else {
9428
9429				// If there is an icon, append it, else nothing then append the value
9430				// this avoids removal of the icon when setting label text
9431				this.element.html( value );
9432				if ( this.icon ) {
9433					this._attachIcon( this.options.iconPosition );
9434					this._attachIconSpace( this.options.iconPosition );
9435				}
9436			}
9437		}
9438
9439		this._super( key, value );
9440
9441		if ( key === "disabled" ) {
9442			this._toggleClass( null, "ui-state-disabled", value );
9443			this.element[ 0 ].disabled = value;
9444			if ( value ) {
9445				this.element.blur();
9446			}
9447		}
9448	},
9449
9450	refresh: function() {
9451
9452		// Make sure to only check disabled if its an element that supports this otherwise
9453		// check for the disabled class to determine state
9454		var isDisabled = this.element.is( "input, button" ) ?
9455			this.element[ 0 ].disabled : this.element.hasClass( "ui-button-disabled" );
9456
9457		if ( isDisabled !== this.options.disabled ) {
9458			this._setOptions( { disabled: isDisabled } );
9459		}
9460
9461		this._updateTooltip();
9462	}
9463} );
9464
9465// DEPRECATED
9466if ( $.uiBackCompat !== false ) {
9467
9468	// Text and Icons options
9469	$.widget( "ui.button", $.ui.button, {
9470		options: {
9471			text: true,
9472			icons: {
9473				primary: null,
9474				secondary: null
9475			}
9476		},
9477
9478		_create: function() {
9479			if ( this.options.showLabel && !this.options.text ) {
9480				this.options.showLabel = this.options.text;
9481			}
9482			if ( !this.options.showLabel && this.options.text ) {
9483				this.options.text = this.options.showLabel;
9484			}
9485			if ( !this.options.icon && ( this.options.icons.primary ||
9486					this.options.icons.secondary ) ) {
9487				if ( this.options.icons.primary ) {
9488					this.options.icon = this.options.icons.primary;
9489				} else {
9490					this.options.icon = this.options.icons.secondary;
9491					this.options.iconPosition = "end";
9492				}
9493			} else if ( this.options.icon ) {
9494				this.options.icons.primary = this.options.icon;
9495			}
9496			this._super();
9497		},
9498
9499		_setOption: function( key, value ) {
9500			if ( key === "text" ) {
9501				this._super( "showLabel", value );
9502				return;
9503			}
9504			if ( key === "showLabel" ) {
9505				this.options.text = value;
9506			}
9507			if ( key === "icon" ) {
9508				this.options.icons.primary = value;
9509			}
9510			if ( key === "icons" ) {
9511				if ( value.primary ) {
9512					this._super( "icon", value.primary );
9513					this._super( "iconPosition", "beginning" );
9514				} else if ( value.secondary ) {
9515					this._super( "icon", value.secondary );
9516					this._super( "iconPosition", "end" );
9517				}
9518			}
9519			this._superApply( arguments );
9520		}
9521	} );
9522
9523	$.fn.button = ( function( orig ) {
9524		return function() {
9525			if ( !this.length || ( this.length && this[ 0 ].tagName !== "INPUT" ) ||
9526					( this.length && this[ 0 ].tagName === "INPUT" && (
9527						this.attr( "type" ) !== "checkbox" && this.attr( "type" ) !== "radio"
9528					) ) ) {
9529				return orig.apply( this, arguments );
9530			}
9531			if ( !$.ui.checkboxradio ) {
9532				$.error( "Checkboxradio widget missing" );
9533			}
9534			if ( arguments.length === 0 ) {
9535				return this.checkboxradio( {
9536					"icon": false
9537				} );
9538			}
9539			return this.checkboxradio.apply( this, arguments );
9540		};
9541	} )( $.fn.button );
9542
9543	$.fn.buttonset = function() {
9544		if ( !$.ui.controlgroup ) {
9545			$.error( "Controlgroup widget missing" );
9546		}
9547		if ( arguments[ 0 ] === "option" && arguments[ 1 ] === "items" && arguments[ 2 ] ) {
9548			return this.controlgroup.apply( this,
9549				[ arguments[ 0 ], "items.button", arguments[ 2 ] ] );
9550		}
9551		if ( arguments[ 0 ] === "option" && arguments[ 1 ] === "items" ) {
9552			return this.controlgroup.apply( this, [ arguments[ 0 ], "items.button" ] );
9553		}
9554		if ( typeof arguments[ 0 ] === "object" && arguments[ 0 ].items ) {
9555			arguments[ 0 ].items = {
9556				button: arguments[ 0 ].items
9557			};
9558		}
9559		return this.controlgroup.apply( this, arguments );
9560	};
9561}
9562
9563var widgetsButton = $.ui.button;
9564
9565
9566// jscs:disable maximumLineLength
9567/* jscs:disable requireCamelCaseOrUpperCaseIdentifiers */
9568/*!
9569 * jQuery UI Datepicker 1.12.1
9570 * http://jqueryui.com
9571 *
9572 * Copyright jQuery Foundation and other contributors
9573 * Released under the MIT license.
9574 * http://jquery.org/license
9575 */
9576
9577//>>label: Datepicker
9578//>>group: Widgets
9579//>>description: Displays a calendar from an input or inline for selecting dates.
9580//>>docs: http://api.jqueryui.com/datepicker/
9581//>>demos: http://jqueryui.com/datepicker/
9582//>>css.structure: ../../themes/base/core.css
9583//>>css.structure: ../../themes/base/datepicker.css
9584//>>css.theme: ../../themes/base/theme.css
9585
9586
9587
9588$.extend( $.ui, { datepicker: { version: "1.12.1" } } );
9589
9590var datepicker_instActive;
9591
9592function datepicker_getZindex( elem ) {
9593	var position, value;
9594	while ( elem.length && elem[ 0 ] !== document ) {
9595
9596		// Ignore z-index if position is set to a value where z-index is ignored by the browser
9597		// This makes behavior of this function consistent across browsers
9598		// WebKit always returns auto if the element is positioned
9599		position = elem.css( "position" );
9600		if ( position === "absolute" || position === "relative" || position === "fixed" ) {
9601
9602			// IE returns 0 when zIndex is not specified
9603			// other browsers return a string
9604			// we ignore the case of nested elements with an explicit value of 0
9605			// <div style="z-index: -10;"><div style="z-index: 0;"></div></div>
9606			value = parseInt( elem.css( "zIndex" ), 10 );
9607			if ( !isNaN( value ) && value !== 0 ) {
9608				return value;
9609			}
9610		}
9611		elem = elem.parent();
9612	}
9613
9614	return 0;
9615}
9616/* Date picker manager.
9617   Use the singleton instance of this class, $.datepicker, to interact with the date picker.
9618   Settings for (groups of) date pickers are maintained in an instance object,
9619   allowing multiple different settings on the same page. */
9620
9621function Datepicker() {
9622	this._curInst = null; // The current instance in use
9623	this._keyEvent = false; // If the last event was a key event
9624	this._disabledInputs = []; // List of date picker inputs that have been disabled
9625	this._datepickerShowing = false; // True if the popup picker is showing , false if not
9626	this._inDialog = false; // True if showing within a "dialog", false if not
9627	this._mainDivId = "ui-datepicker-div"; // The ID of the main datepicker division
9628	this._inlineClass = "ui-datepicker-inline"; // The name of the inline marker class
9629	this._appendClass = "ui-datepicker-append"; // The name of the append marker class
9630	this._triggerClass = "ui-datepicker-trigger"; // The name of the trigger marker class
9631	this._dialogClass = "ui-datepicker-dialog"; // The name of the dialog marker class
9632	this._disableClass = "ui-datepicker-disabled"; // The name of the disabled covering marker class
9633	this._unselectableClass = "ui-datepicker-unselectable"; // The name of the unselectable cell marker class
9634	this._currentClass = "ui-datepicker-current-day"; // The name of the current day marker class
9635	this._dayOverClass = "ui-datepicker-days-cell-over"; // The name of the day hover marker class
9636	this.regional = []; // Available regional settings, indexed by language code
9637	this.regional[ "" ] = { // Default regional settings
9638		closeText: "Done", // Display text for close link
9639		prevText: "Prev", // Display text for previous month link
9640		nextText: "Next", // Display text for next month link
9641		currentText: "Today", // Display text for current month link
9642		monthNames: [ "January","February","March","April","May","June",
9643			"July","August","September","October","November","December" ], // Names of months for drop-down and formatting
9644		monthNamesShort: [ "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" ], // For formatting
9645		dayNames: [ "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday" ], // For formatting
9646		dayNamesShort: [ "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" ], // For formatting
9647		dayNamesMin: [ "Su","Mo","Tu","We","Th","Fr","Sa" ], // Column headings for days starting at Sunday
9648		weekHeader: "Wk", // Column header for week of the year
9649		dateFormat: "mm/dd/yy", // See format options on parseDate
9650		firstDay: 0, // The first day of the week, Sun = 0, Mon = 1, ...
9651		isRTL: false, // True if right-to-left language, false if left-to-right
9652		showMonthAfterYear: false, // True if the year select precedes month, false for month then year
9653		yearSuffix: "" // Additional text to append to the year in the month headers
9654	};
9655	this._defaults = { // Global defaults for all the date picker instances
9656		showOn: "focus", // "focus" for popup on focus,
9657			// "button" for trigger button, or "both" for either
9658		showAnim: "fadeIn", // Name of jQuery animation for popup
9659		showOptions: {}, // Options for enhanced animations
9660		defaultDate: null, // Used when field is blank: actual date,
9661			// +/-number for offset from today, null for today
9662		appendText: "", // Display text following the input box, e.g. showing the format
9663		buttonText: "...", // Text for trigger button
9664		buttonImage: "", // URL for trigger button image
9665		buttonImageOnly: false, // True if the image appears alone, false if it appears on a button
9666		hideIfNoPrevNext: false, // True to hide next/previous month links
9667			// if not applicable, false to just disable them
9668		navigationAsDateFormat: false, // True if date formatting applied to prev/today/next links
9669		gotoCurrent: false, // True if today link goes back to current selection instead
9670		changeMonth: false, // True if month can be selected directly, false if only prev/next
9671		changeYear: false, // True if year can be selected directly, false if only prev/next
9672		yearRange: "c-10:c+10", // Range of years to display in drop-down,
9673			// either relative to today's year (-nn:+nn), relative to currently displayed year
9674			// (c-nn:c+nn), absolute (nnnn:nnnn), or a combination of the above (nnnn:-n)
9675		showOtherMonths: false, // True to show dates in other months, false to leave blank
9676		selectOtherMonths: false, // True to allow selection of dates in other months, false for unselectable
9677		showWeek: false, // True to show week of the year, false to not show it
9678		calculateWeek: this.iso8601Week, // How to calculate the week of the year,
9679			// takes a Date and returns the number of the week for it
9680		shortYearCutoff: "+10", // Short year values < this are in the current century,
9681			// > this are in the previous century,
9682			// string value starting with "+" for current year + value
9683		minDate: null, // The earliest selectable date, or null for no limit
9684		maxDate: null, // The latest selectable date, or null for no limit
9685		duration: "fast", // Duration of display/closure
9686		beforeShowDay: null, // Function that takes a date and returns an array with
9687			// [0] = true if selectable, false if not, [1] = custom CSS class name(s) or "",
9688			// [2] = cell title (optional), e.g. $.datepicker.noWeekends
9689		beforeShow: null, // Function that takes an input field and
9690			// returns a set of custom settings for the date picker
9691		onSelect: null, // Define a callback function when a date is selected
9692		onChangeMonthYear: null, // Define a callback function when the month or year is changed
9693		onClose: null, // Define a callback function when the datepicker is closed
9694		numberOfMonths: 1, // Number of months to show at a time
9695		showCurrentAtPos: 0, // The position in multipe months at which to show the current month (starting at 0)
9696		stepMonths: 1, // Number of months to step back/forward
9697		stepBigMonths: 12, // Number of months to step back/forward for the big links
9698		altField: "", // Selector for an alternate field to store selected dates into
9699		altFormat: "", // The date format to use for the alternate field
9700		constrainInput: true, // The input is constrained by the current date format
9701		showButtonPanel: false, // True to show button panel, false to not show it
9702		autoSize: false, // True to size the input for the date format, false to leave as is
9703		disabled: false // The initial disabled state
9704	};
9705	$.extend( this._defaults, this.regional[ "" ] );
9706	this.regional.en = $.extend( true, {}, this.regional[ "" ] );
9707	this.regional[ "en-US" ] = $.extend( true, {}, this.regional.en );
9708	this.dpDiv = datepicker_bindHover( $( "<div id='" + this._mainDivId + "' class='ui-datepicker ui-widget ui-widget-content ui-helper-clearfix ui-corner-all'></div>" ) );
9709}
9710
9711$.extend( Datepicker.prototype, {
9712	/* Class name added to elements to indicate already configured with a date picker. */
9713	markerClassName: "hasDatepicker",
9714
9715	//Keep track of the maximum number of rows displayed (see #7043)
9716	maxRows: 4,
9717
9718	// TODO rename to "widget" when switching to widget factory
9719	_widgetDatepicker: function() {
9720		return this.dpDiv;
9721	},
9722
9723	/* Override the default settings for all instances of the date picker.
9724	 * @param  settings  object - the new settings to use as defaults (anonymous object)
9725	 * @return the manager object
9726	 */
9727	setDefaults: function( settings ) {
9728		datepicker_extendRemove( this._defaults, settings || {} );
9729		return this;
9730	},
9731
9732	/* Attach the date picker to a jQuery selection.
9733	 * @param  target	element - the target input field or division or span
9734	 * @param  settings  object - the new settings to use for this date picker instance (anonymous)
9735	 */
9736	_attachDatepicker: function( target, settings ) {
9737		var nodeName, inline, inst;
9738		nodeName = target.nodeName.toLowerCase();
9739		inline = ( nodeName === "div" || nodeName === "span" );
9740		if ( !target.id ) {
9741			this.uuid += 1;
9742			target.id = "dp" + this.uuid;
9743		}
9744		inst = this._newInst( $( target ), inline );
9745		inst.settings = $.extend( {}, settings || {} );
9746		if ( nodeName === "input" ) {
9747			this._connectDatepicker( target, inst );
9748		} else if ( inline ) {
9749			this._inlineDatepicker( target, inst );
9750		}
9751	},
9752
9753	/* Create a new instance object. */
9754	_newInst: function( target, inline ) {
9755		var id = target[ 0 ].id.replace( /([^A-Za-z0-9_\-])/g, "\\\\$1" ); // escape jQuery meta chars
9756		return { id: id, input: target, // associated target
9757			selectedDay: 0, selectedMonth: 0, selectedYear: 0, // current selection
9758			drawMonth: 0, drawYear: 0, // month being drawn
9759			inline: inline, // is datepicker inline or not
9760			dpDiv: ( !inline ? this.dpDiv : // presentation div
9761			datepicker_bindHover( $( "<div class='" + this._inlineClass + " ui-datepicker ui-widget ui-widget-content ui-helper-clearfix ui-corner-all'></div>" ) ) ) };
9762	},
9763
9764	/* Attach the date picker to an input field. */
9765	_connectDatepicker: function( target, inst ) {
9766		var input = $( target );
9767		inst.append = $( [] );
9768		inst.trigger = $( [] );
9769		if ( input.hasClass( this.markerClassName ) ) {
9770			return;
9771		}
9772		this._attachments( input, inst );
9773		input.addClass( this.markerClassName ).on( "keydown", this._doKeyDown ).
9774			on( "keypress", this._doKeyPress ).on( "keyup", this._doKeyUp );
9775		this._autoSize( inst );
9776		$.data( target, "datepicker", inst );
9777
9778		//If disabled option is true, disable the datepicker once it has been attached to the input (see ticket #5665)
9779		if ( inst.settings.disabled ) {
9780			this._disableDatepicker( target );
9781		}
9782	},
9783
9784	/* Make attachments based on settings. */
9785	_attachments: function( input, inst ) {
9786		var showOn, buttonText, buttonImage,
9787			appendText = this._get( inst, "appendText" ),
9788			isRTL = this._get( inst, "isRTL" );
9789
9790		if ( inst.append ) {
9791			inst.append.remove();
9792		}
9793		if ( appendText ) {
9794			inst.append = $( "<span class='" + this._appendClass + "'>" + appendText + "</span>" );
9795			input[ isRTL ? "before" : "after" ]( inst.append );
9796		}
9797
9798		input.off( "focus", this._showDatepicker );
9799
9800		if ( inst.trigger ) {
9801			inst.trigger.remove();
9802		}
9803
9804		showOn = this._get( inst, "showOn" );
9805		if ( showOn === "focus" || showOn === "both" ) { // pop-up date picker when in the marked field
9806			input.on( "focus", this._showDatepicker );
9807		}
9808		if ( showOn === "button" || showOn === "both" ) { // pop-up date picker when button clicked
9809			buttonText = this._get( inst, "buttonText" );
9810			buttonImage = this._get( inst, "buttonImage" );
9811			inst.trigger = $( this._get( inst, "buttonImageOnly" ) ?
9812				$( "<img/>" ).addClass( this._triggerClass ).
9813					attr( { src: buttonImage, alt: buttonText, title: buttonText } ) :
9814				$( "<button type='button'></button>" ).addClass( this._triggerClass ).
9815					html( !buttonImage ? buttonText : $( "<img/>" ).attr(
9816					{ src:buttonImage, alt:buttonText, title:buttonText } ) ) );
9817			input[ isRTL ? "before" : "after" ]( inst.trigger );
9818			inst.trigger.on( "click", function() {
9819				if ( $.datepicker._datepickerShowing && $.datepicker._lastInput === input[ 0 ] ) {
9820					$.datepicker._hideDatepicker();
9821				} else if ( $.datepicker._datepickerShowing && $.datepicker._lastInput !== input[ 0 ] ) {
9822					$.datepicker._hideDatepicker();
9823					$.datepicker._showDatepicker( input[ 0 ] );
9824				} else {
9825					$.datepicker._showDatepicker( input[ 0 ] );
9826				}
9827				return false;
9828			} );
9829		}
9830	},
9831
9832	/* Apply the maximum length for the date format. */
9833	_autoSize: function( inst ) {
9834		if ( this._get( inst, "autoSize" ) && !inst.inline ) {
9835			var findMax, max, maxI, i,
9836				date = new Date( 2009, 12 - 1, 20 ), // Ensure double digits
9837				dateFormat = this._get( inst, "dateFormat" );
9838
9839			if ( dateFormat.match( /[DM]/ ) ) {
9840				findMax = function( names ) {
9841					max = 0;
9842					maxI = 0;
9843					for ( i = 0; i < names.length; i++ ) {
9844						if ( names[ i ].length > max ) {
9845							max = names[ i ].length;
9846							maxI = i;
9847						}
9848					}
9849					return maxI;
9850				};
9851				date.setMonth( findMax( this._get( inst, ( dateFormat.match( /MM/ ) ?
9852					"monthNames" : "monthNamesShort" ) ) ) );
9853				date.setDate( findMax( this._get( inst, ( dateFormat.match( /DD/ ) ?
9854					"dayNames" : "dayNamesShort" ) ) ) + 20 - date.getDay() );
9855			}
9856			inst.input.attr( "size", this._formatDate( inst, date ).length );
9857		}
9858	},
9859
9860	/* Attach an inline date picker to a div. */
9861	_inlineDatepicker: function( target, inst ) {
9862		var divSpan = $( target );
9863		if ( divSpan.hasClass( this.markerClassName ) ) {
9864			return;
9865		}
9866		divSpan.addClass( this.markerClassName ).append( inst.dpDiv );
9867		$.data( target, "datepicker", inst );
9868		this._setDate( inst, this._getDefaultDate( inst ), true );
9869		this._updateDatepicker( inst );
9870		this._updateAlternate( inst );
9871
9872		//If disabled option is true, disable the datepicker before showing it (see ticket #5665)
9873		if ( inst.settings.disabled ) {
9874			this._disableDatepicker( target );
9875		}
9876
9877		// Set display:block in place of inst.dpDiv.show() which won't work on disconnected elements
9878		// http://bugs.jqueryui.com/ticket/7552 - A Datepicker created on a detached div has zero height
9879		inst.dpDiv.css( "display", "block" );
9880	},
9881
9882	/* Pop-up the date picker in a "dialog" box.
9883	 * @param  input element - ignored
9884	 * @param  date	string or Date - the initial date to display
9885	 * @param  onSelect  function - the function to call when a date is selected
9886	 * @param  settings  object - update the dialog date picker instance's settings (anonymous object)
9887	 * @param  pos int[2] - coordinates for the dialog's position within the screen or
9888	 *					event - with x/y coordinates or
9889	 *					leave empty for default (screen centre)
9890	 * @return the manager object
9891	 */
9892	_dialogDatepicker: function( input, date, onSelect, settings, pos ) {
9893		var id, browserWidth, browserHeight, scrollX, scrollY,
9894			inst = this._dialogInst; // internal instance
9895
9896		if ( !inst ) {
9897			this.uuid += 1;
9898			id = "dp" + this.uuid;
9899			this._dialogInput = $( "<input type='text' id='" + id +
9900				"' style='position: absolute; top: -100px; width: 0px;'/>" );
9901			this._dialogInput.on( "keydown", this._doKeyDown );
9902			$( "body" ).append( this._dialogInput );
9903			inst = this._dialogInst = this._newInst( this._dialogInput, false );
9904			inst.settings = {};
9905			$.data( this._dialogInput[ 0 ], "datepicker", inst );
9906		}
9907		datepicker_extendRemove( inst.settings, settings || {} );
9908		date = ( date && date.constructor === Date ? this._formatDate( inst, date ) : date );
9909		this._dialogInput.val( date );
9910
9911		this._pos = ( pos ? ( pos.length ? pos : [ pos.pageX, pos.pageY ] ) : null );
9912		if ( !this._pos ) {
9913			browserWidth = document.documentElement.clientWidth;
9914			browserHeight = document.documentElement.clientHeight;
9915			scrollX = document.documentElement.scrollLeft || document.body.scrollLeft;
9916			scrollY = document.documentElement.scrollTop || document.body.scrollTop;
9917			this._pos = // should use actual width/height below
9918				[ ( browserWidth / 2 ) - 100 + scrollX, ( browserHeight / 2 ) - 150 + scrollY ];
9919		}
9920
9921		// Move input on screen for focus, but hidden behind dialog
9922		this._dialogInput.css( "left", ( this._pos[ 0 ] + 20 ) + "px" ).css( "top", this._pos[ 1 ] + "px" );
9923		inst.settings.onSelect = onSelect;
9924		this._inDialog = true;
9925		this.dpDiv.addClass( this._dialogClass );
9926		this._showDatepicker( this._dialogInput[ 0 ] );
9927		if ( $.blockUI ) {
9928			$.blockUI( this.dpDiv );
9929		}
9930		$.data( this._dialogInput[ 0 ], "datepicker", inst );
9931		return this;
9932	},
9933
9934	/* Detach a datepicker from its control.
9935	 * @param  target	element - the target input field or division or span
9936	 */
9937	_destroyDatepicker: function( target ) {
9938		var nodeName,
9939			$target = $( target ),
9940			inst = $.data( target, "datepicker" );
9941
9942		if ( !$target.hasClass( this.markerClassName ) ) {
9943			return;
9944		}
9945
9946		nodeName = target.nodeName.toLowerCase();
9947		$.removeData( target, "datepicker" );
9948		if ( nodeName === "input" ) {
9949			inst.append.remove();
9950			inst.trigger.remove();
9951			$target.removeClass( this.markerClassName ).
9952				off( "focus", this._showDatepicker ).
9953				off( "keydown", this._doKeyDown ).
9954				off( "keypress", this._doKeyPress ).
9955				off( "keyup", this._doKeyUp );
9956		} else if ( nodeName === "div" || nodeName === "span" ) {
9957			$target.removeClass( this.markerClassName ).empty();
9958		}
9959
9960		if ( datepicker_instActive === inst ) {
9961			datepicker_instActive = null;
9962		}
9963	},
9964
9965	/* Enable the date picker to a jQuery selection.
9966	 * @param  target	element - the target input field or division or span
9967	 */
9968	_enableDatepicker: function( target ) {
9969		var nodeName, inline,
9970			$target = $( target ),
9971			inst = $.data( target, "datepicker" );
9972
9973		if ( !$target.hasClass( this.markerClassName ) ) {
9974			return;
9975		}
9976
9977		nodeName = target.nodeName.toLowerCase();
9978		if ( nodeName === "input" ) {
9979			target.disabled = false;
9980			inst.trigger.filter( "button" ).
9981				each( function() { this.disabled = false; } ).end().
9982				filter( "img" ).css( { opacity: "1.0", cursor: "" } );
9983		} else if ( nodeName === "div" || nodeName === "span" ) {
9984			inline = $target.children( "." + this._inlineClass );
9985			inline.children().removeClass( "ui-state-disabled" );
9986			inline.find( "select.ui-datepicker-month, select.ui-datepicker-year" ).
9987				prop( "disabled", false );
9988		}
9989		this._disabledInputs = $.map( this._disabledInputs,
9990			function( value ) { return ( value === target ? null : value ); } ); // delete entry
9991	},
9992
9993	/* Disable the date picker to a jQuery selection.
9994	 * @param  target	element - the target input field or division or span
9995	 */
9996	_disableDatepicker: function( target ) {
9997		var nodeName, inline,
9998			$target = $( target ),
9999			inst = $.data( target, "datepicker" );
10000
10001		if ( !$target.hasClass( this.markerClassName ) ) {
10002			return;
10003		}
10004
10005		nodeName = target.nodeName.toLowerCase();
10006		if ( nodeName === "input" ) {
10007			target.disabled = true;
10008			inst.trigger.filter( "button" ).
10009				each( function() { this.disabled = true; } ).end().
10010				filter( "img" ).css( { opacity: "0.5", cursor: "default" } );
10011		} else if ( nodeName === "div" || nodeName === "span" ) {
10012			inline = $target.children( "." + this._inlineClass );
10013			inline.children().addClass( "ui-state-disabled" );
10014			inline.find( "select.ui-datepicker-month, select.ui-datepicker-year" ).
10015				prop( "disabled", true );
10016		}
10017		this._disabledInputs = $.map( this._disabledInputs,
10018			function( value ) { return ( value === target ? null : value ); } ); // delete entry
10019		this._disabledInputs[ this._disabledInputs.length ] = target;
10020	},
10021
10022	/* Is the first field in a jQuery collection disabled as a datepicker?
10023	 * @param  target	element - the target input field or division or span
10024	 * @return boolean - true if disabled, false if enabled
10025	 */
10026	_isDisabledDatepicker: function( target ) {
10027		if ( !target ) {
10028			return false;
10029		}
10030		for ( var i = 0; i < this._disabledInputs.length; i++ ) {
10031			if ( this._disabledInputs[ i ] === target ) {
10032				return true;
10033			}
10034		}
10035		return false;
10036	},
10037
10038	/* Retrieve the instance data for the target control.
10039	 * @param  target  element - the target input field or division or span
10040	 * @return  object - the associated instance data
10041	 * @throws  error if a jQuery problem getting data
10042	 */
10043	_getInst: function( target ) {
10044		try {
10045			return $.data( target, "datepicker" );
10046		}
10047		catch ( err ) {
10048			throw "Missing instance data for this datepicker";
10049		}
10050	},
10051
10052	/* Update or retrieve the settings for a date picker attached to an input field or division.
10053	 * @param  target  element - the target input field or division or span
10054	 * @param  name	object - the new settings to update or
10055	 *				string - the name of the setting to change or retrieve,
10056	 *				when retrieving also "all" for all instance settings or
10057	 *				"defaults" for all global defaults
10058	 * @param  value   any - the new value for the setting
10059	 *				(omit if above is an object or to retrieve a value)
10060	 */
10061	_optionDatepicker: function( target, name, value ) {
10062		var settings, date, minDate, maxDate,
10063			inst = this._getInst( target );
10064
10065		if ( arguments.length === 2 && typeof name === "string" ) {
10066			return ( name === "defaults" ? $.extend( {}, $.datepicker._defaults ) :
10067				( inst ? ( name === "all" ? $.extend( {}, inst.settings ) :
10068				this._get( inst, name ) ) : null ) );
10069		}
10070
10071		settings = name || {};
10072		if ( typeof name === "string" ) {
10073			settings = {};
10074			settings[ name ] = value;
10075		}
10076
10077		if ( inst ) {
10078			if ( this._curInst === inst ) {
10079				this._hideDatepicker();
10080			}
10081
10082			date = this._getDateDatepicker( target, true );
10083			minDate = this._getMinMaxDate( inst, "min" );
10084			maxDate = this._getMinMaxDate( inst, "max" );
10085			datepicker_extendRemove( inst.settings, settings );
10086
10087			// reformat the old minDate/maxDate values if dateFormat changes and a new minDate/maxDate isn't provided
10088			if ( minDate !== null && settings.dateFormat !== undefined && settings.minDate === undefined ) {
10089				inst.settings.minDate = this._formatDate( inst, minDate );
10090			}
10091			if ( maxDate !== null && settings.dateFormat !== undefined && settings.maxDate === undefined ) {
10092				inst.settings.maxDate = this._formatDate( inst, maxDate );
10093			}
10094			if ( "disabled" in settings ) {
10095				if ( settings.disabled ) {
10096					this._disableDatepicker( target );
10097				} else {
10098					this._enableDatepicker( target );
10099				}
10100			}
10101			this._attachments( $( target ), inst );
10102			this._autoSize( inst );
10103			this._setDate( inst, date );
10104			this._updateAlternate( inst );
10105			this._updateDatepicker( inst );
10106		}
10107	},
10108
10109	// Change method deprecated
10110	_changeDatepicker: function( target, name, value ) {
10111		this._optionDatepicker( target, name, value );
10112	},
10113
10114	/* Redraw the date picker attached to an input field or division.
10115	 * @param  target  element - the target input field or division or span
10116	 */
10117	_refreshDatepicker: function( target ) {
10118		var inst = this._getInst( target );
10119		if ( inst ) {
10120			this._updateDatepicker( inst );
10121		}
10122	},
10123
10124	/* Set the dates for a jQuery selection.
10125	 * @param  target element - the target input field or division or span
10126	 * @param  date	Date - the new date
10127	 */
10128	_setDateDatepicker: function( target, date ) {
10129		var inst = this._getInst( target );
10130		if ( inst ) {
10131			this._setDate( inst, date );
10132			this._updateDatepicker( inst );
10133			this._updateAlternate( inst );
10134		}
10135	},
10136
10137	/* Get the date(s) for the first entry in a jQuery selection.
10138	 * @param  target element - the target input field or division or span
10139	 * @param  noDefault boolean - true if no default date is to be used
10140	 * @return Date - the current date
10141	 */
10142	_getDateDatepicker: function( target, noDefault ) {
10143		var inst = this._getInst( target );
10144		if ( inst && !inst.inline ) {
10145			this._setDateFromField( inst, noDefault );
10146		}
10147		return ( inst ? this._getDate( inst ) : null );
10148	},
10149
10150	/* Handle keystrokes. */
10151	_doKeyDown: function( event ) {
10152		var onSelect, dateStr, sel,
10153			inst = $.datepicker._getInst( event.target ),
10154			handled = true,
10155			isRTL = inst.dpDiv.is( ".ui-datepicker-rtl" );
10156
10157		inst._keyEvent = true;
10158		if ( $.datepicker._datepickerShowing ) {
10159			switch ( event.keyCode ) {
10160				case 9: $.datepicker._hideDatepicker();
10161						handled = false;
10162						break; // hide on tab out
10163				case 13: sel = $( "td." + $.datepicker._dayOverClass + ":not(." +
10164									$.datepicker._currentClass + ")", inst.dpDiv );
10165						if ( sel[ 0 ] ) {
10166							$.datepicker._selectDay( event.target, inst.selectedMonth, inst.selectedYear, sel[ 0 ] );
10167						}
10168
10169						onSelect = $.datepicker._get( inst, "onSelect" );
10170						if ( onSelect ) {
10171							dateStr = $.datepicker._formatDate( inst );
10172
10173							// Trigger custom callback
10174							onSelect.apply( ( inst.input ? inst.input[ 0 ] : null ), [ dateStr, inst ] );
10175						} else {
10176							$.datepicker._hideDatepicker();
10177						}
10178
10179						return false; // don't submit the form
10180				case 27: $.datepicker._hideDatepicker();
10181						break; // hide on escape
10182				case 33: $.datepicker._adjustDate( event.target, ( event.ctrlKey ?
10183							-$.datepicker._get( inst, "stepBigMonths" ) :
10184							-$.datepicker._get( inst, "stepMonths" ) ), "M" );
10185						break; // previous month/year on page up/+ ctrl
10186				case 34: $.datepicker._adjustDate( event.target, ( event.ctrlKey ?
10187							+$.datepicker._get( inst, "stepBigMonths" ) :
10188							+$.datepicker._get( inst, "stepMonths" ) ), "M" );
10189						break; // next month/year on page down/+ ctrl
10190				case 35: if ( event.ctrlKey || event.metaKey ) {
10191							$.datepicker._clearDate( event.target );
10192						}
10193						handled = event.ctrlKey || event.metaKey;
10194						break; // clear on ctrl or command +end
10195				case 36: if ( event.ctrlKey || event.metaKey ) {
10196							$.datepicker._gotoToday( event.target );
10197						}
10198						handled = event.ctrlKey || event.metaKey;
10199						break; // current on ctrl or command +home
10200				case 37: if ( event.ctrlKey || event.metaKey ) {
10201							$.datepicker._adjustDate( event.target, ( isRTL ? +1 : -1 ), "D" );
10202						}
10203						handled = event.ctrlKey || event.metaKey;
10204
10205						// -1 day on ctrl or command +left
10206						if ( event.originalEvent.altKey ) {
10207							$.datepicker._adjustDate( event.target, ( event.ctrlKey ?
10208								-$.datepicker._get( inst, "stepBigMonths" ) :
10209								-$.datepicker._get( inst, "stepMonths" ) ), "M" );
10210						}
10211
10212						// next month/year on alt +left on Mac
10213						break;
10214				case 38: if ( event.ctrlKey || event.metaKey ) {
10215							$.datepicker._adjustDate( event.target, -7, "D" );
10216						}
10217						handled = event.ctrlKey || event.metaKey;
10218						break; // -1 week on ctrl or command +up
10219				case 39: if ( event.ctrlKey || event.metaKey ) {
10220							$.datepicker._adjustDate( event.target, ( isRTL ? -1 : +1 ), "D" );
10221						}
10222						handled = event.ctrlKey || event.metaKey;
10223
10224						// +1 day on ctrl or command +right
10225						if ( event.originalEvent.altKey ) {
10226							$.datepicker._adjustDate( event.target, ( event.ctrlKey ?
10227								+$.datepicker._get( inst, "stepBigMonths" ) :
10228								+$.datepicker._get( inst, "stepMonths" ) ), "M" );
10229						}
10230
10231						// next month/year on alt +right
10232						break;
10233				case 40: if ( event.ctrlKey || event.metaKey ) {
10234							$.datepicker._adjustDate( event.target, +7, "D" );
10235						}
10236						handled = event.ctrlKey || event.metaKey;
10237						break; // +1 week on ctrl or command +down
10238				default: handled = false;
10239			}
10240		} else if ( event.keyCode === 36 && event.ctrlKey ) { // display the date picker on ctrl+home
10241			$.datepicker._showDatepicker( this );
10242		} else {
10243			handled = false;
10244		}
10245
10246		if ( handled ) {
10247			event.preventDefault();
10248			event.stopPropagation();
10249		}
10250	},
10251
10252	/* Filter entered characters - based on date format. */
10253	_doKeyPress: function( event ) {
10254		var chars, chr,
10255			inst = $.datepicker._getInst( event.target );
10256
10257		if ( $.datepicker._get( inst, "constrainInput" ) ) {
10258			chars = $.datepicker._possibleChars( $.datepicker._get( inst, "dateFormat" ) );
10259			chr = String.fromCharCode( event.charCode == null ? event.keyCode : event.charCode );
10260			return event.ctrlKey || event.metaKey || ( chr < " " || !chars || chars.indexOf( chr ) > -1 );
10261		}
10262	},
10263
10264	/* Synchronise manual entry and field/alternate field. */
10265	_doKeyUp: function( event ) {
10266		var date,
10267			inst = $.datepicker._getInst( event.target );
10268
10269		if ( inst.input.val() !== inst.lastVal ) {
10270			try {
10271				date = $.datepicker.parseDate( $.datepicker._get( inst, "dateFormat" ),
10272					( inst.input ? inst.input.val() : null ),
10273					$.datepicker._getFormatConfig( inst ) );
10274
10275				if ( date ) { // only if valid
10276					$.datepicker._setDateFromField( inst );
10277					$.datepicker._updateAlternate( inst );
10278					$.datepicker._updateDatepicker( inst );
10279				}
10280			}
10281			catch ( err ) {
10282			}
10283		}
10284		return true;
10285	},
10286
10287	/* Pop-up the date picker for a given input field.
10288	 * If false returned from beforeShow event handler do not show.
10289	 * @param  input  element - the input field attached to the date picker or
10290	 *					event - if triggered by focus
10291	 */
10292	_showDatepicker: function( input ) {
10293		input = input.target || input;
10294		if ( input.nodeName.toLowerCase() !== "input" ) { // find from button/image trigger
10295			input = $( "input", input.parentNode )[ 0 ];
10296		}
10297
10298		if ( $.datepicker._isDisabledDatepicker( input ) || $.datepicker._lastInput === input ) { // already here
10299			return;
10300		}
10301
10302		var inst, beforeShow, beforeShowSettings, isFixed,
10303			offset, showAnim, duration;
10304
10305		inst = $.datepicker._getInst( input );
10306		if ( $.datepicker._curInst && $.datepicker._curInst !== inst ) {
10307			$.datepicker._curInst.dpDiv.stop( true, true );
10308			if ( inst && $.datepicker._datepickerShowing ) {
10309				$.datepicker._hideDatepicker( $.datepicker._curInst.input[ 0 ] );
10310			}
10311		}
10312
10313		beforeShow = $.datepicker._get( inst, "beforeShow" );
10314		beforeShowSettings = beforeShow ? beforeShow.apply( input, [ input, inst ] ) : {};
10315		if ( beforeShowSettings === false ) {
10316			return;
10317		}
10318		datepicker_extendRemove( inst.settings, beforeShowSettings );
10319
10320		inst.lastVal = null;
10321		$.datepicker._lastInput = input;
10322		$.datepicker._setDateFromField( inst );
10323
10324		if ( $.datepicker._inDialog ) { // hide cursor
10325			input.value = "";
10326		}
10327		if ( !$.datepicker._pos ) { // position below input
10328			$.datepicker._pos = $.datepicker._findPos( input );
10329			$.datepicker._pos[ 1 ] += input.offsetHeight; // add the height
10330		}
10331
10332		isFixed = false;
10333		$( input ).parents().each( function() {
10334			isFixed |= $( this ).css( "position" ) === "fixed";
10335			return !isFixed;
10336		} );
10337
10338		offset = { left: $.datepicker._pos[ 0 ], top: $.datepicker._pos[ 1 ] };
10339		$.datepicker._pos = null;
10340
10341		//to avoid flashes on Firefox
10342		inst.dpDiv.empty();
10343
10344		// determine sizing offscreen
10345		inst.dpDiv.css( { position: "absolute", display: "block", top: "-1000px" } );
10346		$.datepicker._updateDatepicker( inst );
10347
10348		// fix width for dynamic number of date pickers
10349		// and adjust position before showing
10350		offset = $.datepicker._checkOffset( inst, offset, isFixed );
10351		inst.dpDiv.css( { position: ( $.datepicker._inDialog && $.blockUI ?
10352			"static" : ( isFixed ? "fixed" : "absolute" ) ), display: "none",
10353			left: offset.left + "px", top: offset.top + "px" } );
10354
10355		if ( !inst.inline ) {
10356			showAnim = $.datepicker._get( inst, "showAnim" );
10357			duration = $.datepicker._get( inst, "duration" );
10358			inst.dpDiv.css( "z-index", datepicker_getZindex( $( input ) ) + 1 );
10359			$.datepicker._datepickerShowing = true;
10360
10361			if ( $.effects && $.effects.effect[ showAnim ] ) {
10362				inst.dpDiv.show( showAnim, $.datepicker._get( inst, "showOptions" ), duration );
10363			} else {
10364				inst.dpDiv[ showAnim || "show" ]( showAnim ? duration : null );
10365			}
10366
10367			if ( $.datepicker._shouldFocusInput( inst ) ) {
10368				inst.input.trigger( "focus" );
10369			}
10370
10371			$.datepicker._curInst = inst;
10372		}
10373	},
10374
10375	/* Generate the date picker content. */
10376	_updateDatepicker: function( inst ) {
10377		this.maxRows = 4; //Reset the max number of rows being displayed (see #7043)
10378		datepicker_instActive = inst; // for delegate hover events
10379		inst.dpDiv.empty().append( this._generateHTML( inst ) );
10380		this._attachHandlers( inst );
10381
10382		var origyearshtml,
10383			numMonths = this._getNumberOfMonths( inst ),
10384			cols = numMonths[ 1 ],
10385			width = 17,
10386			activeCell = inst.dpDiv.find( "." + this._dayOverClass + " a" );
10387
10388		if ( activeCell.length > 0 ) {
10389			datepicker_handleMouseover.apply( activeCell.get( 0 ) );
10390		}
10391
10392		inst.dpDiv.removeClass( "ui-datepicker-multi-2 ui-datepicker-multi-3 ui-datepicker-multi-4" ).width( "" );
10393		if ( cols > 1 ) {
10394			inst.dpDiv.addClass( "ui-datepicker-multi-" + cols ).css( "width", ( width * cols ) + "em" );
10395		}
10396		inst.dpDiv[ ( numMonths[ 0 ] !== 1 || numMonths[ 1 ] !== 1 ? "add" : "remove" ) +
10397			"Class" ]( "ui-datepicker-multi" );
10398		inst.dpDiv[ ( this._get( inst, "isRTL" ) ? "add" : "remove" ) +
10399			"Class" ]( "ui-datepicker-rtl" );
10400
10401		if ( inst === $.datepicker._curInst && $.datepicker._datepickerShowing && $.datepicker._shouldFocusInput( inst ) ) {
10402			inst.input.trigger( "focus" );
10403		}
10404
10405		// Deffered render of the years select (to avoid flashes on Firefox)
10406		if ( inst.yearshtml ) {
10407			origyearshtml = inst.yearshtml;
10408			setTimeout( function() {
10409
10410				//assure that inst.yearshtml didn't change.
10411				if ( origyearshtml === inst.yearshtml && inst.yearshtml ) {
10412					inst.dpDiv.find( "select.ui-datepicker-year:first" ).replaceWith( inst.yearshtml );
10413				}
10414				origyearshtml = inst.yearshtml = null;
10415			}, 0 );
10416		}
10417	},
10418
10419	// #6694 - don't focus the input if it's already focused
10420	// this breaks the change event in IE
10421	// Support: IE and jQuery <1.9
10422	_shouldFocusInput: function( inst ) {
10423		return inst.input && inst.input.is( ":visible" ) && !inst.input.is( ":disabled" ) && !inst.input.is( ":focus" );
10424	},
10425
10426	/* Check positioning to remain on screen. */
10427	_checkOffset: function( inst, offset, isFixed ) {
10428		var dpWidth = inst.dpDiv.outerWidth(),
10429			dpHeight = inst.dpDiv.outerHeight(),
10430			inputWidth = inst.input ? inst.input.outerWidth() : 0,
10431			inputHeight = inst.input ? inst.input.outerHeight() : 0,
10432			viewWidth = document.documentElement.clientWidth + ( isFixed ? 0 : $( document ).scrollLeft() ),
10433			viewHeight = document.documentElement.clientHeight + ( isFixed ? 0 : $( document ).scrollTop() );
10434
10435		offset.left -= ( this._get( inst, "isRTL" ) ? ( dpWidth - inputWidth ) : 0 );
10436		offset.left -= ( isFixed && offset.left === inst.input.offset().left ) ? $( document ).scrollLeft() : 0;
10437		offset.top -= ( isFixed && offset.top === ( inst.input.offset().top + inputHeight ) ) ? $( document ).scrollTop() : 0;
10438
10439		// Now check if datepicker is showing outside window viewport - move to a better place if so.
10440		offset.left -= Math.min( offset.left, ( offset.left + dpWidth > viewWidth && viewWidth > dpWidth ) ?
10441			Math.abs( offset.left + dpWidth - viewWidth ) : 0 );
10442		offset.top -= Math.min( offset.top, ( offset.top + dpHeight > viewHeight && viewHeight > dpHeight ) ?
10443			Math.abs( dpHeight + inputHeight ) : 0 );
10444
10445		return offset;
10446	},
10447
10448	/* Find an object's position on the screen. */
10449	_findPos: function( obj ) {
10450		var position,
10451			inst = this._getInst( obj ),
10452			isRTL = this._get( inst, "isRTL" );
10453
10454		while ( obj && ( obj.type === "hidden" || obj.nodeType !== 1 || $.expr.filters.hidden( obj ) ) ) {
10455			obj = obj[ isRTL ? "previousSibling" : "nextSibling" ];
10456		}
10457
10458		position = $( obj ).offset();
10459		return [ position.left, position.top ];
10460	},
10461
10462	/* Hide the date picker from view.
10463	 * @param  input  element - the input field attached to the date picker
10464	 */
10465	_hideDatepicker: function( input ) {
10466		var showAnim, duration, postProcess, onClose,
10467			inst = this._curInst;
10468
10469		if ( !inst || ( input && inst !== $.data( input, "datepicker" ) ) ) {
10470			return;
10471		}
10472
10473		if ( this._datepickerShowing ) {
10474			showAnim = this._get( inst, "showAnim" );
10475			duration = this._get( inst, "duration" );
10476			postProcess = function() {
10477				$.datepicker._tidyDialog( inst );
10478			};
10479
10480			// DEPRECATED: after BC for 1.8.x $.effects[ showAnim ] is not needed
10481			if ( $.effects && ( $.effects.effect[ showAnim ] || $.effects[ showAnim ] ) ) {
10482				inst.dpDiv.hide( showAnim, $.datepicker._get( inst, "showOptions" ), duration, postProcess );
10483			} else {
10484				inst.dpDiv[ ( showAnim === "slideDown" ? "slideUp" :
10485					( showAnim === "fadeIn" ? "fadeOut" : "hide" ) ) ]( ( showAnim ? duration : null ), postProcess );
10486			}
10487
10488			if ( !showAnim ) {
10489				postProcess();
10490			}
10491			this._datepickerShowing = false;
10492
10493			onClose = this._get( inst, "onClose" );
10494			if ( onClose ) {
10495				onClose.apply( ( inst.input ? inst.input[ 0 ] : null ), [ ( inst.input ? inst.input.val() : "" ), inst ] );
10496			}
10497
10498			this._lastInput = null;
10499			if ( this._inDialog ) {
10500				this._dialogInput.css( { position: "absolute", left: "0", top: "-100px" } );
10501				if ( $.blockUI ) {
10502					$.unblockUI();
10503					$( "body" ).append( this.dpDiv );
10504				}
10505			}
10506			this._inDialog = false;
10507		}
10508	},
10509
10510	/* Tidy up after a dialog display. */
10511	_tidyDialog: function( inst ) {
10512		inst.dpDiv.removeClass( this._dialogClass ).off( ".ui-datepicker-calendar" );
10513	},
10514
10515	/* Close date picker if clicked elsewhere. */
10516	_checkExternalClick: function( event ) {
10517		if ( !$.datepicker._curInst ) {
10518			return;
10519		}
10520
10521		var $target = $( event.target ),
10522			inst = $.datepicker._getInst( $target[ 0 ] );
10523
10524		if ( ( ( $target[ 0 ].id !== $.datepicker._mainDivId &&
10525				$target.parents( "#" + $.datepicker._mainDivId ).length === 0 &&
10526				!$target.hasClass( $.datepicker.markerClassName ) &&
10527				!$target.closest( "." + $.datepicker._triggerClass ).length &&
10528				$.datepicker._datepickerShowing && !( $.datepicker._inDialog && $.blockUI ) ) ) ||
10529			( $target.hasClass( $.datepicker.markerClassName ) && $.datepicker._curInst !== inst ) ) {
10530				$.datepicker._hideDatepicker();
10531		}
10532	},
10533
10534	/* Adjust one of the date sub-fields. */
10535	_adjustDate: function( id, offset, period ) {
10536		var target = $( id ),
10537			inst = this._getInst( target[ 0 ] );
10538
10539		if ( this._isDisabledDatepicker( target[ 0 ] ) ) {
10540			return;
10541		}
10542		this._adjustInstDate( inst, offset +
10543			( period === "M" ? this._get( inst, "showCurrentAtPos" ) : 0 ), // undo positioning
10544			period );
10545		this._updateDatepicker( inst );
10546	},
10547
10548	/* Action for current link. */
10549	_gotoToday: function( id ) {
10550		var date,
10551			target = $( id ),
10552			inst = this._getInst( target[ 0 ] );
10553
10554		if ( this._get( inst, "gotoCurrent" ) && inst.currentDay ) {
10555			inst.selectedDay = inst.currentDay;
10556			inst.drawMonth = inst.selectedMonth = inst.currentMonth;
10557			inst.drawYear = inst.selectedYear = inst.currentYear;
10558		} else {
10559			date = new Date();
10560			inst.selectedDay = date.getDate();
10561			inst.drawMonth = inst.selectedMonth = date.getMonth();
10562			inst.drawYear = inst.selectedYear = date.getFullYear();
10563		}
10564		this._notifyChange( inst );
10565		this._adjustDate( target );
10566	},
10567
10568	/* Action for selecting a new month/year. */
10569	_selectMonthYear: function( id, select, period ) {
10570		var target = $( id ),
10571			inst = this._getInst( target[ 0 ] );
10572
10573		inst[ "selected" + ( period === "M" ? "Month" : "Year" ) ] =
10574		inst[ "draw" + ( period === "M" ? "Month" : "Year" ) ] =
10575			parseInt( select.options[ select.selectedIndex ].value, 10 );
10576
10577		this._notifyChange( inst );
10578		this._adjustDate( target );
10579	},
10580
10581	/* Action for selecting a day. */
10582	_selectDay: function( id, month, year, td ) {
10583		var inst,
10584			target = $( id );
10585
10586		if ( $( td ).hasClass( this._unselectableClass ) || this._isDisabledDatepicker( target[ 0 ] ) ) {
10587			return;
10588		}
10589
10590		inst = this._getInst( target[ 0 ] );
10591		inst.selectedDay = inst.currentDay = $( "a", td ).html();
10592		inst.selectedMonth = inst.currentMonth = month;
10593		inst.selectedYear = inst.currentYear = year;
10594		this._selectDate( id, this._formatDate( inst,
10595			inst.currentDay, inst.currentMonth, inst.currentYear ) );
10596	},
10597
10598	/* Erase the input field and hide the date picker. */
10599	_clearDate: function( id ) {
10600		var target = $( id );
10601		this._selectDate( target, "" );
10602	},
10603
10604	/* Update the input field with the selected date. */
10605	_selectDate: function( id, dateStr ) {
10606		var onSelect,
10607			target = $( id ),
10608			inst = this._getInst( target[ 0 ] );
10609
10610		dateStr = ( dateStr != null ? dateStr : this._formatDate( inst ) );
10611		if ( inst.input ) {
10612			inst.input.val( dateStr );
10613		}
10614		this._updateAlternate( inst );
10615
10616		onSelect = this._get( inst, "onSelect" );
10617		if ( onSelect ) {
10618			onSelect.apply( ( inst.input ? inst.input[ 0 ] : null ), [ dateStr, inst ] );  // trigger custom callback
10619		} else if ( inst.input ) {
10620			inst.input.trigger( "change" ); // fire the change event
10621		}
10622
10623		if ( inst.inline ) {
10624			this._updateDatepicker( inst );
10625		} else {
10626			this._hideDatepicker();
10627			this._lastInput = inst.input[ 0 ];
10628			if ( typeof( inst.input[ 0 ] ) !== "object" ) {
10629				inst.input.trigger( "focus" ); // restore focus
10630			}
10631			this._lastInput = null;
10632		}
10633	},
10634
10635	/* Update any alternate field to synchronise with the main field. */
10636	_updateAlternate: function( inst ) {
10637		var altFormat, date, dateStr,
10638			altField = this._get( inst, "altField" );
10639
10640		if ( altField ) { // update alternate field too
10641			altFormat = this._get( inst, "altFormat" ) || this._get( inst, "dateFormat" );
10642			date = this._getDate( inst );
10643			dateStr = this.formatDate( altFormat, date, this._getFormatConfig( inst ) );
10644			$( altField ).val( dateStr );
10645		}
10646	},
10647
10648	/* Set as beforeShowDay function to prevent selection of weekends.
10649	 * @param  date  Date - the date to customise
10650	 * @return [boolean, string] - is this date selectable?, what is its CSS class?
10651	 */
10652	noWeekends: function( date ) {
10653		var day = date.getDay();
10654		return [ ( day > 0 && day < 6 ), "" ];
10655	},
10656
10657	/* Set as calculateWeek to determine the week of the year based on the ISO 8601 definition.
10658	 * @param  date  Date - the date to get the week for
10659	 * @return  number - the number of the week within the year that contains this date
10660	 */
10661	iso8601Week: function( date ) {
10662		var time,
10663			checkDate = new Date( date.getTime() );
10664
10665		// Find Thursday of this week starting on Monday
10666		checkDate.setDate( checkDate.getDate() + 4 - ( checkDate.getDay() || 7 ) );
10667
10668		time = checkDate.getTime();
10669		checkDate.setMonth( 0 ); // Compare with Jan 1
10670		checkDate.setDate( 1 );
10671		return Math.floor( Math.round( ( time - checkDate ) / 86400000 ) / 7 ) + 1;
10672	},
10673
10674	/* Parse a string value into a date object.
10675	 * See formatDate below for the possible formats.
10676	 *
10677	 * @param  format string - the expected format of the date
10678	 * @param  value string - the date in the above format
10679	 * @param  settings Object - attributes include:
10680	 *					shortYearCutoff  number - the cutoff year for determining the century (optional)
10681	 *					dayNamesShort	string[7] - abbreviated names of the days from Sunday (optional)
10682	 *					dayNames		string[7] - names of the days from Sunday (optional)
10683	 *					monthNamesShort string[12] - abbreviated names of the months (optional)
10684	 *					monthNames		string[12] - names of the months (optional)
10685	 * @return  Date - the extracted date value or null if value is blank
10686	 */
10687	parseDate: function( format, value, settings ) {
10688		if ( format == null || value == null ) {
10689			throw "Invalid arguments";
10690		}
10691
10692		value = ( typeof value === "object" ? value.toString() : value + "" );
10693		if ( value === "" ) {
10694			return null;
10695		}
10696
10697		var iFormat, dim, extra,
10698			iValue = 0,
10699			shortYearCutoffTemp = ( settings ? settings.shortYearCutoff : null ) || this._defaults.shortYearCutoff,
10700			shortYearCutoff = ( typeof shortYearCutoffTemp !== "string" ? shortYearCutoffTemp :
10701				new Date().getFullYear() % 100 + parseInt( shortYearCutoffTemp, 10 ) ),
10702			dayNamesShort = ( settings ? settings.dayNamesShort : null ) || this._defaults.dayNamesShort,
10703			dayNames = ( settings ? settings.dayNames : null ) || this._defaults.dayNames,
10704			monthNamesShort = ( settings ? settings.monthNamesShort : null ) || this._defaults.monthNamesShort,
10705			monthNames = ( settings ? settings.monthNames : null ) || this._defaults.monthNames,
10706			year = -1,
10707			month = -1,
10708			day = -1,
10709			doy = -1,
10710			literal = false,
10711			date,
10712
10713			// Check whether a format character is doubled
10714			lookAhead = function( match ) {
10715				var matches = ( iFormat + 1 < format.length && format.charAt( iFormat + 1 ) === match );
10716				if ( matches ) {
10717					iFormat++;
10718				}
10719				return matches;
10720			},
10721
10722			// Extract a number from the string value
10723			getNumber = function( match ) {
10724				var isDoubled = lookAhead( match ),
10725					size = ( match === "@" ? 14 : ( match === "!" ? 20 :
10726					( match === "y" && isDoubled ? 4 : ( match === "o" ? 3 : 2 ) ) ) ),
10727					minSize = ( match === "y" ? size : 1 ),
10728					digits = new RegExp( "^\\d{" + minSize + "," + size + "}" ),
10729					num = value.substring( iValue ).match( digits );
10730				if ( !num ) {
10731					throw "Missing number at position " + iValue;
10732				}
10733				iValue += num[ 0 ].length;
10734				return parseInt( num[ 0 ], 10 );
10735			},
10736
10737			// Extract a name from the string value and convert to an index
10738			getName = function( match, shortNames, longNames ) {
10739				var index = -1,
10740					names = $.map( lookAhead( match ) ? longNames : shortNames, function( v, k ) {
10741						return [ [ k, v ] ];
10742					} ).sort( function( a, b ) {
10743						return -( a[ 1 ].length - b[ 1 ].length );
10744					} );
10745
10746				$.each( names, function( i, pair ) {
10747					var name = pair[ 1 ];
10748					if ( value.substr( iValue, name.length ).toLowerCase() === name.toLowerCase() ) {
10749						index = pair[ 0 ];
10750						iValue += name.length;
10751						return false;
10752					}
10753				} );
10754				if ( index !== -1 ) {
10755					return index + 1;
10756				} else {
10757					throw "Unknown name at position " + iValue;
10758				}
10759			},
10760
10761			// Confirm that a literal character matches the string value
10762			checkLiteral = function() {
10763				if ( value.charAt( iValue ) !== format.charAt( iFormat ) ) {
10764					throw "Unexpected literal at position " + iValue;
10765				}
10766				iValue++;
10767			};
10768
10769		for ( iFormat = 0; iFormat < format.length; iFormat++ ) {
10770			if ( literal ) {
10771				if ( format.charAt( iFormat ) === "'" && !lookAhead( "'" ) ) {
10772					literal = false;
10773				} else {
10774					checkLiteral();
10775				}
10776			} else {
10777				switch ( format.charAt( iFormat ) ) {
10778					case "d":
10779						day = getNumber( "d" );
10780						break;
10781					case "D":
10782						getName( "D", dayNamesShort, dayNames );
10783						break;
10784					case "o":
10785						doy = getNumber( "o" );
10786						break;
10787					case "m":
10788						month = getNumber( "m" );
10789						break;
10790					case "M":
10791						month = getName( "M", monthNamesShort, monthNames );
10792						break;
10793					case "y":
10794						year = getNumber( "y" );
10795						break;
10796					case "@":
10797						date = new Date( getNumber( "@" ) );
10798						year = date.getFullYear();
10799						month = date.getMonth() + 1;
10800						day = date.getDate();
10801						break;
10802					case "!":
10803						date = new Date( ( getNumber( "!" ) - this._ticksTo1970 ) / 10000 );
10804						year = date.getFullYear();
10805						month = date.getMonth() + 1;
10806						day = date.getDate();
10807						break;
10808					case "'":
10809						if ( lookAhead( "'" ) ) {
10810							checkLiteral();
10811						} else {
10812							literal = true;
10813						}
10814						break;
10815					default:
10816						checkLiteral();
10817				}
10818			}
10819		}
10820
10821		if ( iValue < value.length ) {
10822			extra = value.substr( iValue );
10823			if ( !/^\s+/.test( extra ) ) {
10824				throw "Extra/unparsed characters found in date: " + extra;
10825			}
10826		}
10827
10828		if ( year === -1 ) {
10829			year = new Date().getFullYear();
10830		} else if ( year < 100 ) {
10831			year += new Date().getFullYear() - new Date().getFullYear() % 100 +
10832				( year <= shortYearCutoff ? 0 : -100 );
10833		}
10834
10835		if ( doy > -1 ) {
10836			month = 1;
10837			day = doy;
10838			do {
10839				dim = this._getDaysInMonth( year, month - 1 );
10840				if ( day <= dim ) {
10841					break;
10842				}
10843				month++;
10844				day -= dim;
10845			} while ( true );
10846		}
10847
10848		date = this._daylightSavingAdjust( new Date( year, month - 1, day ) );
10849		if ( date.getFullYear() !== year || date.getMonth() + 1 !== month || date.getDate() !== day ) {
10850			throw "Invalid date"; // E.g. 31/02/00
10851		}
10852		return date;
10853	},
10854
10855	/* Standard date formats. */
10856	ATOM: "yy-mm-dd", // RFC 3339 (ISO 8601)
10857	COOKIE: "D, dd M yy",
10858	ISO_8601: "yy-mm-dd",
10859	RFC_822: "D, d M y",
10860	RFC_850: "DD, dd-M-y",
10861	RFC_1036: "D, d M y",
10862	RFC_1123: "D, d M yy",
10863	RFC_2822: "D, d M yy",
10864	RSS: "D, d M y", // RFC 822
10865	TICKS: "!",
10866	TIMESTAMP: "@",
10867	W3C: "yy-mm-dd", // ISO 8601
10868
10869	_ticksTo1970: ( ( ( 1970 - 1 ) * 365 + Math.floor( 1970 / 4 ) - Math.floor( 1970 / 100 ) +
10870		Math.floor( 1970 / 400 ) ) * 24 * 60 * 60 * 10000000 ),
10871
10872	/* Format a date object into a string value.
10873	 * The format can be combinations of the following:
10874	 * d  - day of month (no leading zero)
10875	 * dd - day of month (two digit)
10876	 * o  - day of year (no leading zeros)
10877	 * oo - day of year (three digit)
10878	 * D  - day name short
10879	 * DD - day name long
10880	 * m  - month of year (no leading zero)
10881	 * mm - month of year (two digit)
10882	 * M  - month name short
10883	 * MM - month name long
10884	 * y  - year (two digit)
10885	 * yy - year (four digit)
10886	 * @ - Unix timestamp (ms since 01/01/1970)
10887	 * ! - Windows ticks (100ns since 01/01/0001)
10888	 * "..." - literal text
10889	 * '' - single quote
10890	 *
10891	 * @param  format string - the desired format of the date
10892	 * @param  date Date - the date value to format
10893	 * @param  settings Object - attributes include:
10894	 *					dayNamesShort	string[7] - abbreviated names of the days from Sunday (optional)
10895	 *					dayNames		string[7] - names of the days from Sunday (optional)
10896	 *					monthNamesShort string[12] - abbreviated names of the months (optional)
10897	 *					monthNames		string[12] - names of the months (optional)
10898	 * @return  string - the date in the above format
10899	 */
10900	formatDate: function( format, date, settings ) {
10901		if ( !date ) {
10902			return "";
10903		}
10904
10905		var iFormat,
10906			dayNamesShort = ( settings ? settings.dayNamesShort : null ) || this._defaults.dayNamesShort,
10907			dayNames = ( settings ? settings.dayNames : null ) || this._defaults.dayNames,
10908			monthNamesShort = ( settings ? settings.monthNamesShort : null ) || this._defaults.monthNamesShort,
10909			monthNames = ( settings ? settings.monthNames : null ) || this._defaults.monthNames,
10910
10911			// Check whether a format character is doubled
10912			lookAhead = function( match ) {
10913				var matches = ( iFormat + 1 < format.length && format.charAt( iFormat + 1 ) === match );
10914				if ( matches ) {
10915					iFormat++;
10916				}
10917				return matches;
10918			},
10919
10920			// Format a number, with leading zero if necessary
10921			formatNumber = function( match, value, len ) {
10922				var num = "" + value;
10923				if ( lookAhead( match ) ) {
10924					while ( num.length < len ) {
10925						num = "0" + num;
10926					}
10927				}
10928				return num;
10929			},
10930
10931			// Format a name, short or long as requested
10932			formatName = function( match, value, shortNames, longNames ) {
10933				return ( lookAhead( match ) ? longNames[ value ] : shortNames[ value ] );
10934			},
10935			output = "",
10936			literal = false;
10937
10938		if ( date ) {
10939			for ( iFormat = 0; iFormat < format.length; iFormat++ ) {
10940				if ( literal ) {
10941					if ( format.charAt( iFormat ) === "'" && !lookAhead( "'" ) ) {
10942						literal = false;
10943					} else {
10944						output += format.charAt( iFormat );
10945					}
10946				} else {
10947					switch ( format.charAt( iFormat ) ) {
10948						case "d":
10949							output += formatNumber( "d", date.getDate(), 2 );
10950							break;
10951						case "D":
10952							output += formatName( "D", date.getDay(), dayNamesShort, dayNames );
10953							break;
10954						case "o":
10955							output += formatNumber( "o",
10956								Math.round( ( new Date( date.getFullYear(), date.getMonth(), date.getDate() ).getTime() - new Date( date.getFullYear(), 0, 0 ).getTime() ) / 86400000 ), 3 );
10957							break;
10958						case "m":
10959							output += formatNumber( "m", date.getMonth() + 1, 2 );
10960							break;
10961						case "M":
10962							output += formatName( "M", date.getMonth(), monthNamesShort, monthNames );
10963							break;
10964						case "y":
10965							output += ( lookAhead( "y" ) ? date.getFullYear() :
10966								( date.getFullYear() % 100 < 10 ? "0" : "" ) + date.getFullYear() % 100 );
10967							break;
10968						case "@":
10969							output += date.getTime();
10970							break;
10971						case "!":
10972							output += date.getTime() * 10000 + this._ticksTo1970;
10973							break;
10974						case "'":
10975							if ( lookAhead( "'" ) ) {
10976								output += "'";
10977							} else {
10978								literal = true;
10979							}
10980							break;
10981						default:
10982							output += format.charAt( iFormat );
10983					}
10984				}
10985			}
10986		}
10987		return output;
10988	},
10989
10990	/* Extract all possible characters from the date format. */
10991	_possibleChars: function( format ) {
10992		var iFormat,
10993			chars = "",
10994			literal = false,
10995
10996			// Check whether a format character is doubled
10997			lookAhead = function( match ) {
10998				var matches = ( iFormat + 1 < format.length && format.charAt( iFormat + 1 ) === match );
10999				if ( matches ) {
11000					iFormat++;
11001				}
11002				return matches;
11003			};
11004
11005		for ( iFormat = 0; iFormat < format.length; iFormat++ ) {
11006			if ( literal ) {
11007				if ( format.charAt( iFormat ) === "'" && !lookAhead( "'" ) ) {
11008					literal = false;
11009				} else {
11010					chars += format.charAt( iFormat );
11011				}
11012			} else {
11013				switch ( format.charAt( iFormat ) ) {
11014					case "d": case "m": case "y": case "@":
11015						chars += "0123456789";
11016						break;
11017					case "D": case "M":
11018						return null; // Accept anything
11019					case "'":
11020						if ( lookAhead( "'" ) ) {
11021							chars += "'";
11022						} else {
11023							literal = true;
11024						}
11025						break;
11026					default:
11027						chars += format.charAt( iFormat );
11028				}
11029			}
11030		}
11031		return chars;
11032	},
11033
11034	/* Get a setting value, defaulting if necessary. */
11035	_get: function( inst, name ) {
11036		return inst.settings[ name ] !== undefined ?
11037			inst.settings[ name ] : this._defaults[ name ];
11038	},
11039
11040	/* Parse existing date and initialise date picker. */
11041	_setDateFromField: function( inst, noDefault ) {
11042		if ( inst.input.val() === inst.lastVal ) {
11043			return;
11044		}
11045
11046		var dateFormat = this._get( inst, "dateFormat" ),
11047			dates = inst.lastVal = inst.input ? inst.input.val() : null,
11048			defaultDate = this._getDefaultDate( inst ),
11049			date = defaultDate,
11050			settings = this._getFormatConfig( inst );
11051
11052		try {
11053			date = this.parseDate( dateFormat, dates, settings ) || defaultDate;
11054		} catch ( event ) {
11055			dates = ( noDefault ? "" : dates );
11056		}
11057		inst.selectedDay = date.getDate();
11058		inst.drawMonth = inst.selectedMonth = date.getMonth();
11059		inst.drawYear = inst.selectedYear = date.getFullYear();
11060		inst.currentDay = ( dates ? date.getDate() : 0 );
11061		inst.currentMonth = ( dates ? date.getMonth() : 0 );
11062		inst.currentYear = ( dates ? date.getFullYear() : 0 );
11063		this._adjustInstDate( inst );
11064	},
11065
11066	/* Retrieve the default date shown on opening. */
11067	_getDefaultDate: function( inst ) {
11068		return this._restrictMinMax( inst,
11069			this._determineDate( inst, this._get( inst, "defaultDate" ), new Date() ) );
11070	},
11071
11072	/* A date may be specified as an exact value or a relative one. */
11073	_determineDate: function( inst, date, defaultDate ) {
11074		var offsetNumeric = function( offset ) {
11075				var date = new Date();
11076				date.setDate( date.getDate() + offset );
11077				return date;
11078			},
11079			offsetString = function( offset ) {
11080				try {
11081					return $.datepicker.parseDate( $.datepicker._get( inst, "dateFormat" ),
11082						offset, $.datepicker._getFormatConfig( inst ) );
11083				}
11084				catch ( e ) {
11085
11086					// Ignore
11087				}
11088
11089				var date = ( offset.toLowerCase().match( /^c/ ) ?
11090					$.datepicker._getDate( inst ) : null ) || new Date(),
11091					year = date.getFullYear(),
11092					month = date.getMonth(),
11093					day = date.getDate(),
11094					pattern = /([+\-]?[0-9]+)\s*(d|D|w|W|m|M|y|Y)?/g,
11095					matches = pattern.exec( offset );
11096
11097				while ( matches ) {
11098					switch ( matches[ 2 ] || "d" ) {
11099						case "d" : case "D" :
11100							day += parseInt( matches[ 1 ], 10 ); break;
11101						case "w" : case "W" :
11102							day += parseInt( matches[ 1 ], 10 ) * 7; break;
11103						case "m" : case "M" :
11104							month += parseInt( matches[ 1 ], 10 );
11105							day = Math.min( day, $.datepicker._getDaysInMonth( year, month ) );
11106							break;
11107						case "y": case "Y" :
11108							year += parseInt( matches[ 1 ], 10 );
11109							day = Math.min( day, $.datepicker._getDaysInMonth( year, month ) );
11110							break;
11111					}
11112					matches = pattern.exec( offset );
11113				}
11114				return new Date( year, month, day );
11115			},
11116			newDate = ( date == null || date === "" ? defaultDate : ( typeof date === "string" ? offsetString( date ) :
11117				( typeof date === "number" ? ( isNaN( date ) ? defaultDate : offsetNumeric( date ) ) : new Date( date.getTime() ) ) ) );
11118
11119		newDate = ( newDate && newDate.toString() === "Invalid Date" ? defaultDate : newDate );
11120		if ( newDate ) {
11121			newDate.setHours( 0 );
11122			newDate.setMinutes( 0 );
11123			newDate.setSeconds( 0 );
11124			newDate.setMilliseconds( 0 );
11125		}
11126		return this._daylightSavingAdjust( newDate );
11127	},
11128
11129	/* Handle switch to/from daylight saving.
11130	 * Hours may be non-zero on daylight saving cut-over:
11131	 * > 12 when midnight changeover, but then cannot generate
11132	 * midnight datetime, so jump to 1AM, otherwise reset.
11133	 * @param  date  (Date) the date to check
11134	 * @return  (Date) the corrected date
11135	 */
11136	_daylightSavingAdjust: function( date ) {
11137		if ( !date ) {
11138			return null;
11139		}
11140		date.setHours( date.getHours() > 12 ? date.getHours() + 2 : 0 );
11141		return date;
11142	},
11143
11144	/* Set the date(s) directly. */
11145	_setDate: function( inst, date, noChange ) {
11146		var clear = !date,
11147			origMonth = inst.selectedMonth,
11148			origYear = inst.selectedYear,
11149			newDate = this._restrictMinMax( inst, this._determineDate( inst, date, new Date() ) );
11150
11151		inst.selectedDay = inst.currentDay = newDate.getDate();
11152		inst.drawMonth = inst.selectedMonth = inst.currentMonth = newDate.getMonth();
11153		inst.drawYear = inst.selectedYear = inst.currentYear = newDate.getFullYear();
11154		if ( ( origMonth !== inst.selectedMonth || origYear !== inst.selectedYear ) && !noChange ) {
11155			this._notifyChange( inst );
11156		}
11157		this._adjustInstDate( inst );
11158		if ( inst.input ) {
11159			inst.input.val( clear ? "" : this._formatDate( inst ) );
11160		}
11161	},
11162
11163	/* Retrieve the date(s) directly. */
11164	_getDate: function( inst ) {
11165		var startDate = ( !inst.currentYear || ( inst.input && inst.input.val() === "" ) ? null :
11166			this._daylightSavingAdjust( new Date(
11167			inst.currentYear, inst.currentMonth, inst.currentDay ) ) );
11168			return startDate;
11169	},
11170
11171	/* Attach the onxxx handlers.  These are declared statically so
11172	 * they work with static code transformers like Caja.
11173	 */
11174	_attachHandlers: function( inst ) {
11175		var stepMonths = this._get( inst, "stepMonths" ),
11176			id = "#" + inst.id.replace( /\\\\/g, "\\" );
11177		inst.dpDiv.find( "[data-handler]" ).map( function() {
11178			var handler = {
11179				prev: function() {
11180					$.datepicker._adjustDate( id, -stepMonths, "M" );
11181				},
11182				next: function() {
11183					$.datepicker._adjustDate( id, +stepMonths, "M" );
11184				},
11185				hide: function() {
11186					$.datepicker._hideDatepicker();
11187				},
11188				today: function() {
11189					$.datepicker._gotoToday( id );
11190				},
11191				selectDay: function() {
11192					$.datepicker._selectDay( id, +this.getAttribute( "data-month" ), +this.getAttribute( "data-year" ), this );
11193					return false;
11194				},
11195				selectMonth: function() {
11196					$.datepicker._selectMonthYear( id, this, "M" );
11197					return false;
11198				},
11199				selectYear: function() {
11200					$.datepicker._selectMonthYear( id, this, "Y" );
11201					return false;
11202				}
11203			};
11204			$( this ).on( this.getAttribute( "data-event" ), handler[ this.getAttribute( "data-handler" ) ] );
11205		} );
11206	},
11207
11208	/* Generate the HTML for the current state of the date picker. */
11209	_generateHTML: function( inst ) {
11210		var maxDraw, prevText, prev, nextText, next, currentText, gotoDate,
11211			controls, buttonPanel, firstDay, showWeek, dayNames, dayNamesMin,
11212			monthNames, monthNamesShort, beforeShowDay, showOtherMonths,
11213			selectOtherMonths, defaultDate, html, dow, row, group, col, selectedDate,
11214			cornerClass, calender, thead, day, daysInMonth, leadDays, curRows, numRows,
11215			printDate, dRow, tbody, daySettings, otherMonth, unselectable,
11216			tempDate = new Date(),
11217			today = this._daylightSavingAdjust(
11218				new Date( tempDate.getFullYear(), tempDate.getMonth(), tempDate.getDate() ) ), // clear time
11219			isRTL = this._get( inst, "isRTL" ),
11220			showButtonPanel = this._get( inst, "showButtonPanel" ),
11221			hideIfNoPrevNext = this._get( inst, "hideIfNoPrevNext" ),
11222			navigationAsDateFormat = this._get( inst, "navigationAsDateFormat" ),
11223			numMonths = this._getNumberOfMonths( inst ),
11224			showCurrentAtPos = this._get( inst, "showCurrentAtPos" ),
11225			stepMonths = this._get( inst, "stepMonths" ),
11226			isMultiMonth = ( numMonths[ 0 ] !== 1 || numMonths[ 1 ] !== 1 ),
11227			currentDate = this._daylightSavingAdjust( ( !inst.currentDay ? new Date( 9999, 9, 9 ) :
11228				new Date( inst.currentYear, inst.currentMonth, inst.currentDay ) ) ),
11229			minDate = this._getMinMaxDate( inst, "min" ),
11230			maxDate = this._getMinMaxDate( inst, "max" ),
11231			drawMonth = inst.drawMonth - showCurrentAtPos,
11232			drawYear = inst.drawYear;
11233
11234		if ( drawMonth < 0 ) {
11235			drawMonth += 12;
11236			drawYear--;
11237		}
11238		if ( maxDate ) {
11239			maxDraw = this._daylightSavingAdjust( new Date( maxDate.getFullYear(),
11240				maxDate.getMonth() - ( numMonths[ 0 ] * numMonths[ 1 ] ) + 1, maxDate.getDate() ) );
11241			maxDraw = ( minDate && maxDraw < minDate ? minDate : maxDraw );
11242			while ( this._daylightSavingAdjust( new Date( drawYear, drawMonth, 1 ) ) > maxDraw ) {
11243				drawMonth--;
11244				if ( drawMonth < 0 ) {
11245					drawMonth = 11;
11246					drawYear--;
11247				}
11248			}
11249		}
11250		inst.drawMonth = drawMonth;
11251		inst.drawYear = drawYear;
11252
11253		prevText = this._get( inst, "prevText" );
11254		prevText = ( !navigationAsDateFormat ? prevText : this.formatDate( prevText,
11255			this._daylightSavingAdjust( new Date( drawYear, drawMonth - stepMonths, 1 ) ),
11256			this._getFormatConfig( inst ) ) );
11257
11258		prev = ( this._canAdjustMonth( inst, -1, drawYear, drawMonth ) ?
11259			"<a class='ui-datepicker-prev ui-corner-all' data-handler='prev' data-event='click'" +
11260			" title='" + prevText + "'><span class='ui-icon ui-icon-circle-triangle-" + ( isRTL ? "e" : "w" ) + "'>" + prevText + "</span></a>" :
11261			( 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>" ) );
11262
11263		nextText = this._get( inst, "nextText" );
11264		nextText = ( !navigationAsDateFormat ? nextText : this.formatDate( nextText,
11265			this._daylightSavingAdjust( new Date( drawYear, drawMonth + stepMonths, 1 ) ),
11266			this._getFormatConfig( inst ) ) );
11267
11268		next = ( this._canAdjustMonth( inst, +1, drawYear, drawMonth ) ?
11269			"<a class='ui-datepicker-next ui-corner-all' data-handler='next' data-event='click'" +
11270			" title='" + nextText + "'><span class='ui-icon ui-icon-circle-triangle-" + ( isRTL ? "w" : "e" ) + "'>" + nextText + "</span></a>" :
11271			( 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>" ) );
11272
11273		currentText = this._get( inst, "currentText" );
11274		gotoDate = ( this._get( inst, "gotoCurrent" ) && inst.currentDay ? currentDate : today );
11275		currentText = ( !navigationAsDateFormat ? currentText :
11276			this.formatDate( currentText, gotoDate, this._getFormatConfig( inst ) ) );
11277
11278		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'>" +
11279			this._get( inst, "closeText" ) + "</button>" : "" );
11280
11281		buttonPanel = ( showButtonPanel ) ? "<div class='ui-datepicker-buttonpane ui-widget-content'>" + ( isRTL ? controls : "" ) +
11282			( 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'" +
11283			">" + currentText + "</button>" : "" ) + ( isRTL ? "" : controls ) + "</div>" : "";
11284
11285		firstDay = parseInt( this._get( inst, "firstDay" ), 10 );
11286		firstDay = ( isNaN( firstDay ) ? 0 : firstDay );
11287
11288		showWeek = this._get( inst, "showWeek" );
11289		dayNames = this._get( inst, "dayNames" );
11290		dayNamesMin = this._get( inst, "dayNamesMin" );
11291		monthNames = this._get( inst, "monthNames" );
11292		monthNamesShort = this._get( inst, "monthNamesShort" );
11293		beforeShowDay = this._get( inst, "beforeShowDay" );
11294		showOtherMonths = this._get( inst, "showOtherMonths" );
11295		selectOtherMonths = this._get( inst, "selectOtherMonths" );
11296		defaultDate = this._getDefaultDate( inst );
11297		html = "";
11298
11299		for ( row = 0; row < numMonths[ 0 ]; row++ ) {
11300			group = "";
11301			this.maxRows = 4;
11302			for ( col = 0; col < numMonths[ 1 ]; col++ ) {
11303				selectedDate = this._daylightSavingAdjust( new Date( drawYear, drawMonth, inst.selectedDay ) );
11304				cornerClass = " ui-corner-all";
11305				calender = "";
11306				if ( isMultiMonth ) {
11307					calender += "<div class='ui-datepicker-group";
11308					if ( numMonths[ 1 ] > 1 ) {
11309						switch ( col ) {
11310							case 0: calender += " ui-datepicker-group-first";
11311								cornerClass = " ui-corner-" + ( isRTL ? "right" : "left" ); break;
11312							case numMonths[ 1 ] - 1: calender += " ui-datepicker-group-last";
11313								cornerClass = " ui-corner-" + ( isRTL ? "left" : "right" ); break;
11314							default: calender += " ui-datepicker-group-middle"; cornerClass = ""; break;
11315						}
11316					}
11317					calender += "'>";
11318				}
11319				calender += "<div class='ui-datepicker-header ui-widget-header ui-helper-clearfix" + cornerClass + "'>" +
11320					( /all|left/.test( cornerClass ) && row === 0 ? ( isRTL ? next : prev ) : "" ) +
11321					( /all|right/.test( cornerClass ) && row === 0 ? ( isRTL ? prev : next ) : "" ) +
11322					this._generateMonthYearHeader( inst, drawMonth, drawYear, minDate, maxDate,
11323					row > 0 || col > 0, monthNames, monthNamesShort ) + // draw month headers
11324					"</div><table class='ui-datepicker-calendar'><thead>" +
11325					"<tr>";
11326				thead = ( showWeek ? "<th class='ui-datepicker-week-col'>" + this._get( inst, "weekHeader" ) + "</th>" : "" );
11327				for ( dow = 0; dow < 7; dow++ ) { // days of the week
11328					day = ( dow + firstDay ) % 7;
11329					thead += "<th scope='col'" + ( ( dow + firstDay + 6 ) % 7 >= 5 ? " class='ui-datepicker-week-end'" : "" ) + ">" +
11330						"<span title='" + dayNames[ day ] + "'>" + dayNamesMin[ day ] + "</span></th>";
11331				}
11332				calender += thead + "</tr></thead><tbody>";
11333				daysInMonth = this._getDaysInMonth( drawYear, drawMonth );
11334				if ( drawYear === inst.selectedYear && drawMonth === inst.selectedMonth ) {
11335					inst.selectedDay = Math.min( inst.selectedDay, daysInMonth );
11336				}
11337				leadDays = ( this._getFirstDayOfMonth( drawYear, drawMonth ) - firstDay + 7 ) % 7;
11338				curRows = Math.ceil( ( leadDays + daysInMonth ) / 7 ); // calculate the number of rows to generate
11339				numRows = ( isMultiMonth ? this.maxRows > curRows ? this.maxRows : curRows : curRows ); //If multiple months, use the higher number of rows (see #7043)
11340				this.maxRows = numRows;
11341				printDate = this._daylightSavingAdjust( new Date( drawYear, drawMonth, 1 - leadDays ) );
11342				for ( dRow = 0; dRow < numRows; dRow++ ) { // create date picker rows
11343					calender += "<tr>";
11344					tbody = ( !showWeek ? "" : "<td class='ui-datepicker-week-col'>" +
11345						this._get( inst, "calculateWeek" )( printDate ) + "</td>" );
11346					for ( dow = 0; dow < 7; dow++ ) { // create date picker days
11347						daySettings = ( beforeShowDay ?
11348							beforeShowDay.apply( ( inst.input ? inst.input[ 0 ] : null ), [ printDate ] ) : [ true, "" ] );
11349						otherMonth = ( printDate.getMonth() !== drawMonth );
11350						unselectable = ( otherMonth && !selectOtherMonths ) || !daySettings[ 0 ] ||
11351							( minDate && printDate < minDate ) || ( maxDate && printDate > maxDate );
11352						tbody += "<td class='" +
11353							( ( dow + firstDay + 6 ) % 7 >= 5 ? " ui-datepicker-week-end" : "" ) + // highlight weekends
11354							( otherMonth ? " ui-datepicker-other-month" : "" ) + // highlight days from other months
11355							( ( printDate.getTime() === selectedDate.getTime() && drawMonth === inst.selectedMonth && inst._keyEvent ) || // user pressed key
11356							( defaultDate.getTime() === printDate.getTime() && defaultDate.getTime() === selectedDate.getTime() ) ?
11357
11358							// or defaultDate is current printedDate and defaultDate is selectedDate
11359							" " + this._dayOverClass : "" ) + // highlight selected day
11360							( unselectable ? " " + this._unselectableClass + " ui-state-disabled" : "" ) +  // highlight unselectable days
11361							( otherMonth && !showOtherMonths ? "" : " " + daySettings[ 1 ] + // highlight custom dates
11362							( printDate.getTime() === currentDate.getTime() ? " " + this._currentClass : "" ) + // highlight selected day
11363							( printDate.getTime() === today.getTime() ? " ui-datepicker-today" : "" ) ) + "'" + // highlight today (if different)
11364							( ( !otherMonth || showOtherMonths ) && daySettings[ 2 ] ? " title='" + daySettings[ 2 ].replace( /'/g, "&#39;" ) + "'" : "" ) + // cell title
11365							( unselectable ? "" : " data-handler='selectDay' data-event='click' data-month='" + printDate.getMonth() + "' data-year='" + printDate.getFullYear() + "'" ) + ">" + // actions
11366							( otherMonth && !showOtherMonths ? "&#xa0;" : // display for other months
11367							( unselectable ? "<span class='ui-state-default'>" + printDate.getDate() + "</span>" : "<a class='ui-state-default" +
11368							( printDate.getTime() === today.getTime() ? " ui-state-highlight" : "" ) +
11369							( printDate.getTime() === currentDate.getTime() ? " ui-state-active" : "" ) + // highlight selected day
11370							( otherMonth ? " ui-priority-secondary" : "" ) + // distinguish dates from other months
11371							"' href='#'>" + printDate.getDate() + "</a>" ) ) + "</td>"; // display selectable date
11372						printDate.setDate( printDate.getDate() + 1 );
11373						printDate = this._daylightSavingAdjust( printDate );
11374					}
11375					calender += tbody + "</tr>";
11376				}
11377				drawMonth++;
11378				if ( drawMonth > 11 ) {
11379					drawMonth = 0;
11380					drawYear++;
11381				}
11382				calender += "</tbody></table>" + ( isMultiMonth ? "</div>" +
11383							( ( numMonths[ 0 ] > 0 && col === numMonths[ 1 ] - 1 ) ? "<div class='ui-datepicker-row-break'></div>" : "" ) : "" );
11384				group += calender;
11385			}
11386			html += group;
11387		}
11388		html += buttonPanel;
11389		inst._keyEvent = false;
11390		return html;
11391	},
11392
11393	/* Generate the month and year header. */
11394	_generateMonthYearHeader: function( inst, drawMonth, drawYear, minDate, maxDate,
11395			secondary, monthNames, monthNamesShort ) {
11396
11397		var inMinYear, inMaxYear, month, years, thisYear, determineYear, year, endYear,
11398			changeMonth = this._get( inst, "changeMonth" ),
11399			changeYear = this._get( inst, "changeYear" ),
11400			showMonthAfterYear = this._get( inst, "showMonthAfterYear" ),
11401			html = "<div class='ui-datepicker-title'>",
11402			monthHtml = "";
11403
11404		// Month selection
11405		if ( secondary || !changeMonth ) {
11406			monthHtml += "<span class='ui-datepicker-month'>" + monthNames[ drawMonth ] + "</span>";
11407		} else {
11408			inMinYear = ( minDate && minDate.getFullYear() === drawYear );
11409			inMaxYear = ( maxDate && maxDate.getFullYear() === drawYear );
11410			monthHtml += "<select class='ui-datepicker-month' data-handler='selectMonth' data-event='change'>";
11411			for ( month = 0; month < 12; month++ ) {
11412				if ( ( !inMinYear || month >= minDate.getMonth() ) && ( !inMaxYear || month <= maxDate.getMonth() ) ) {
11413					monthHtml += "<option value='" + month + "'" +
11414						( month === drawMonth ? " selected='selected'" : "" ) +
11415						">" + monthNamesShort[ month ] + "</option>";
11416				}
11417			}
11418			monthHtml += "</select>";
11419		}
11420
11421		if ( !showMonthAfterYear ) {
11422			html += monthHtml + ( secondary || !( changeMonth && changeYear ) ? "&#xa0;" : "" );
11423		}
11424
11425		// Year selection
11426		if ( !inst.yearshtml ) {
11427			inst.yearshtml = "";
11428			if ( secondary || !changeYear ) {
11429				html += "<span class='ui-datepicker-year'>" + drawYear + "</span>";
11430			} else {
11431
11432				// determine range of years to display
11433				years = this._get( inst, "yearRange" ).split( ":" );
11434				thisYear = new Date().getFullYear();
11435				determineYear = function( value ) {
11436					var year = ( value.match( /c[+\-].*/ ) ? drawYear + parseInt( value.substring( 1 ), 10 ) :
11437						( value.match( /[+\-].*/ ) ? thisYear + parseInt( value, 10 ) :
11438						parseInt( value, 10 ) ) );
11439					return ( isNaN( year ) ? thisYear : year );
11440				};
11441				year = determineYear( years[ 0 ] );
11442				endYear = Math.max( year, determineYear( years[ 1 ] || "" ) );
11443				year = ( minDate ? Math.max( year, minDate.getFullYear() ) : year );
11444				endYear = ( maxDate ? Math.min( endYear, maxDate.getFullYear() ) : endYear );
11445				inst.yearshtml += "<select class='ui-datepicker-year' data-handler='selectYear' data-event='change'>";
11446				for ( ; year <= endYear; year++ ) {
11447					inst.yearshtml += "<option value='" + year + "'" +
11448						( year === drawYear ? " selected='selected'" : "" ) +
11449						">" + year + "</option>";
11450				}
11451				inst.yearshtml += "</select>";
11452
11453				html += inst.yearshtml;
11454				inst.yearshtml = null;
11455			}
11456		}
11457
11458		html += this._get( inst, "yearSuffix" );
11459		if ( showMonthAfterYear ) {
11460			html += ( secondary || !( changeMonth && changeYear ) ? "&#xa0;" : "" ) + monthHtml;
11461		}
11462		html += "</div>"; // Close datepicker_header
11463		return html;
11464	},
11465
11466	/* Adjust one of the date sub-fields. */
11467	_adjustInstDate: function( inst, offset, period ) {
11468		var year = inst.selectedYear + ( period === "Y" ? offset : 0 ),
11469			month = inst.selectedMonth + ( period === "M" ? offset : 0 ),
11470			day = Math.min( inst.selectedDay, this._getDaysInMonth( year, month ) ) + ( period === "D" ? offset : 0 ),
11471			date = this._restrictMinMax( inst, this._daylightSavingAdjust( new Date( year, month, day ) ) );
11472
11473		inst.selectedDay = date.getDate();
11474		inst.drawMonth = inst.selectedMonth = date.getMonth();
11475		inst.drawYear = inst.selectedYear = date.getFullYear();
11476		if ( period === "M" || period === "Y" ) {
11477			this._notifyChange( inst );
11478		}
11479	},
11480
11481	/* Ensure a date is within any min/max bounds. */
11482	_restrictMinMax: function( inst, date ) {
11483		var minDate = this._getMinMaxDate( inst, "min" ),
11484			maxDate = this._getMinMaxDate( inst, "max" ),
11485			newDate = ( minDate && date < minDate ? minDate : date );
11486		return ( maxDate && newDate > maxDate ? maxDate : newDate );
11487	},
11488
11489	/* Notify change of month/year. */
11490	_notifyChange: function( inst ) {
11491		var onChange = this._get( inst, "onChangeMonthYear" );
11492		if ( onChange ) {
11493			onChange.apply( ( inst.input ? inst.input[ 0 ] : null ),
11494				[ inst.selectedYear, inst.selectedMonth + 1, inst ] );
11495		}
11496	},
11497
11498	/* Determine the number of months to show. */
11499	_getNumberOfMonths: function( inst ) {
11500		var numMonths = this._get( inst, "numberOfMonths" );
11501		return ( numMonths == null ? [ 1, 1 ] : ( typeof numMonths === "number" ? [ 1, numMonths ] : numMonths ) );
11502	},
11503
11504	/* Determine the current maximum date - ensure no time components are set. */
11505	_getMinMaxDate: function( inst, minMax ) {
11506		return this._determineDate( inst, this._get( inst, minMax + "Date" ), null );
11507	},
11508
11509	/* Find the number of days in a given month. */
11510	_getDaysInMonth: function( year, month ) {
11511		return 32 - this._daylightSavingAdjust( new Date( year, month, 32 ) ).getDate();
11512	},
11513
11514	/* Find the day of the week of the first of a month. */
11515	_getFirstDayOfMonth: function( year, month ) {
11516		return new Date( year, month, 1 ).getDay();
11517	},
11518
11519	/* Determines if we should allow a "next/prev" month display change. */
11520	_canAdjustMonth: function( inst, offset, curYear, curMonth ) {
11521		var numMonths = this._getNumberOfMonths( inst ),
11522			date = this._daylightSavingAdjust( new Date( curYear,
11523			curMonth + ( offset < 0 ? offset : numMonths[ 0 ] * numMonths[ 1 ] ), 1 ) );
11524
11525		if ( offset < 0 ) {
11526			date.setDate( this._getDaysInMonth( date.getFullYear(), date.getMonth() ) );
11527		}
11528		return this._isInRange( inst, date );
11529	},
11530
11531	/* Is the given date in the accepted range? */
11532	_isInRange: function( inst, date ) {
11533		var yearSplit, currentYear,
11534			minDate = this._getMinMaxDate( inst, "min" ),
11535			maxDate = this._getMinMaxDate( inst, "max" ),
11536			minYear = null,
11537			maxYear = null,
11538			years = this._get( inst, "yearRange" );
11539			if ( years ) {
11540				yearSplit = years.split( ":" );
11541				currentYear = new Date().getFullYear();
11542				minYear = parseInt( yearSplit[ 0 ], 10 );
11543				maxYear = parseInt( yearSplit[ 1 ], 10 );
11544				if ( yearSplit[ 0 ].match( /[+\-].*/ ) ) {
11545					minYear += currentYear;
11546				}
11547				if ( yearSplit[ 1 ].match( /[+\-].*/ ) ) {
11548					maxYear += currentYear;
11549				}
11550			}
11551
11552		return ( ( !minDate || date.getTime() >= minDate.getTime() ) &&
11553			( !maxDate || date.getTime() <= maxDate.getTime() ) &&
11554			( !minYear || date.getFullYear() >= minYear ) &&
11555			( !maxYear || date.getFullYear() <= maxYear ) );
11556	},
11557
11558	/* Provide the configuration settings for formatting/parsing. */
11559	_getFormatConfig: function( inst ) {
11560		var shortYearCutoff = this._get( inst, "shortYearCutoff" );
11561		shortYearCutoff = ( typeof shortYearCutoff !== "string" ? shortYearCutoff :
11562			new Date().getFullYear() % 100 + parseInt( shortYearCutoff, 10 ) );
11563		return { shortYearCutoff: shortYearCutoff,
11564			dayNamesShort: this._get( inst, "dayNamesShort" ), dayNames: this._get( inst, "dayNames" ),
11565			monthNamesShort: this._get( inst, "monthNamesShort" ), monthNames: this._get( inst, "monthNames" ) };
11566	},
11567
11568	/* Format the given date for display. */
11569	_formatDate: function( inst, day, month, year ) {
11570		if ( !day ) {
11571			inst.currentDay = inst.selectedDay;
11572			inst.currentMonth = inst.selectedMonth;
11573			inst.currentYear = inst.selectedYear;
11574		}
11575		var date = ( day ? ( typeof day === "object" ? day :
11576			this._daylightSavingAdjust( new Date( year, month, day ) ) ) :
11577			this._daylightSavingAdjust( new Date( inst.currentYear, inst.currentMonth, inst.currentDay ) ) );
11578		return this.formatDate( this._get( inst, "dateFormat" ), date, this._getFormatConfig( inst ) );
11579	}
11580} );
11581
11582/*
11583 * Bind hover events for datepicker elements.
11584 * Done via delegate so the binding only occurs once in the lifetime of the parent div.
11585 * Global datepicker_instActive, set by _updateDatepicker allows the handlers to find their way back to the active picker.
11586 */
11587function datepicker_bindHover( dpDiv ) {
11588	var selector = "button, .ui-datepicker-prev, .ui-datepicker-next, .ui-datepicker-calendar td a";
11589	return dpDiv.on( "mouseout", selector, function() {
11590			$( this ).removeClass( "ui-state-hover" );
11591			if ( this.className.indexOf( "ui-datepicker-prev" ) !== -1 ) {
11592				$( this ).removeClass( "ui-datepicker-prev-hover" );
11593			}
11594			if ( this.className.indexOf( "ui-datepicker-next" ) !== -1 ) {
11595				$( this ).removeClass( "ui-datepicker-next-hover" );
11596			}
11597		} )
11598		.on( "mouseover", selector, datepicker_handleMouseover );
11599}
11600
11601function datepicker_handleMouseover() {
11602	if ( !$.datepicker._isDisabledDatepicker( datepicker_instActive.inline ? datepicker_instActive.dpDiv.parent()[ 0 ] : datepicker_instActive.input[ 0 ] ) ) {
11603		$( this ).parents( ".ui-datepicker-calendar" ).find( "a" ).removeClass( "ui-state-hover" );
11604		$( this ).addClass( "ui-state-hover" );
11605		if ( this.className.indexOf( "ui-datepicker-prev" ) !== -1 ) {
11606			$( this ).addClass( "ui-datepicker-prev-hover" );
11607		}
11608		if ( this.className.indexOf( "ui-datepicker-next" ) !== -1 ) {
11609			$( this ).addClass( "ui-datepicker-next-hover" );
11610		}
11611	}
11612}
11613
11614/* jQuery extend now ignores nulls! */
11615function datepicker_extendRemove( target, props ) {
11616	$.extend( target, props );
11617	for ( var name in props ) {
11618		if ( props[ name ] == null ) {
11619			target[ name ] = props[ name ];
11620		}
11621	}
11622	return target;
11623}
11624
11625/* Invoke the datepicker functionality.
11626   @param  options  string - a command, optionally followed by additional parameters or
11627					Object - settings for attaching new datepicker functionality
11628   @return  jQuery object */
11629$.fn.datepicker = function( options ) {
11630
11631	/* Verify an empty collection wasn't passed - Fixes #6976 */
11632	if ( !this.length ) {
11633		return this;
11634	}
11635
11636	/* Initialise the date picker. */
11637	if ( !$.datepicker.initialized ) {
11638		$( document ).on( "mousedown", $.datepicker._checkExternalClick );
11639		$.datepicker.initialized = true;
11640	}
11641
11642	/* Append datepicker main container to body if not exist. */
11643	if ( $( "#" + $.datepicker._mainDivId ).length === 0 ) {
11644		$( "body" ).append( $.datepicker.dpDiv );
11645	}
11646
11647	var otherArgs = Array.prototype.slice.call( arguments, 1 );
11648	if ( typeof options === "string" && ( options === "isDisabled" || options === "getDate" || options === "widget" ) ) {
11649		return $.datepicker[ "_" + options + "Datepicker" ].
11650			apply( $.datepicker, [ this[ 0 ] ].concat( otherArgs ) );
11651	}
11652	if ( options === "option" && arguments.length === 2 && typeof arguments[ 1 ] === "string" ) {
11653		return $.datepicker[ "_" + options + "Datepicker" ].
11654			apply( $.datepicker, [ this[ 0 ] ].concat( otherArgs ) );
11655	}
11656	return this.each( function() {
11657		typeof options === "string" ?
11658			$.datepicker[ "_" + options + "Datepicker" ].
11659				apply( $.datepicker, [ this ].concat( otherArgs ) ) :
11660			$.datepicker._attachDatepicker( this, options );
11661	} );
11662};
11663
11664$.datepicker = new Datepicker(); // singleton instance
11665$.datepicker.initialized = false;
vendor: 36,125 bytes, lines 11666-13138
11666$.datepicker.uuid = new Date().getTime();
11667$.datepicker.version = "1.12.1";
11668
11669var widgetsDatepicker = $.datepicker;
11670
11671
11672/*!
11673 * jQuery UI Dialog 1.12.1
11674 * http://jqueryui.com
11675 *
11676 * Copyright jQuery Foundation and other contributors
11677 * Released under the MIT license.
11678 * http://jquery.org/license
11679 */
11680
11681//>>label: Dialog
11682//>>group: Widgets
11683//>>description: Displays customizable dialog windows.
11684//>>docs: http://api.jqueryui.com/dialog/
11685//>>demos: http://jqueryui.com/dialog/
11686//>>css.structure: ../../themes/base/core.css
11687//>>css.structure: ../../themes/base/dialog.css
11688//>>css.theme: ../../themes/base/theme.css
11689
11690
11691
11692$.widget( "ui.dialog", {
11693	version: "1.12.1",
11694	options: {
11695		appendTo: "body",
11696		autoOpen: true,
11697		buttons: [],
11698		classes: {
11699			"ui-dialog": "ui-corner-all",
11700			"ui-dialog-titlebar": "ui-corner-all"
11701		},
11702		closeOnEscape: true,
11703		closeText: "Close",
11704		draggable: true,
11705		hide: null,
11706		height: "auto",
11707		maxHeight: null,
11708		maxWidth: null,
11709		minHeight: 150,
11710		minWidth: 150,
11711		modal: false,
11712		position: {
11713			my: "center",
11714			at: "center",
11715			of: window,
11716			collision: "fit",
11717
11718			// Ensure the titlebar is always visible
11719			using: function( pos ) {
11720				var topOffset = $( this ).css( pos ).offset().top;
11721				if ( topOffset < 0 ) {
11722					$( this ).css( "top", pos.top - topOffset );
11723				}
11724			}
11725		},
11726		resizable: true,
11727		show: null,
11728		title: null,
11729		width: 300,
11730
11731		// Callbacks
11732		beforeClose: null,
11733		close: null,
11734		drag: null,
11735		dragStart: null,
11736		dragStop: null,
11737		focus: null,
11738		open: null,
11739		resize: null,
11740		resizeStart: null,
11741		resizeStop: null
11742	},
11743
11744	sizeRelatedOptions: {
11745		buttons: true,
11746		height: true,
11747		maxHeight: true,
11748		maxWidth: true,
11749		minHeight: true,
11750		minWidth: true,
11751		width: true
11752	},
11753
11754	resizableRelatedOptions: {
11755		maxHeight: true,
11756		maxWidth: true,
11757		minHeight: true,
11758		minWidth: true
11759	},
11760
11761	_create: function() {
11762		this.originalCss = {
11763			display: this.element[ 0 ].style.display,
11764			width: this.element[ 0 ].style.width,
11765			minHeight: this.element[ 0 ].style.minHeight,
11766			maxHeight: this.element[ 0 ].style.maxHeight,
11767			height: this.element[ 0 ].style.height
11768		};
11769		this.originalPosition = {
11770			parent: this.element.parent(),
11771			index: this.element.parent().children().index( this.element )
11772		};
11773		this.originalTitle = this.element.attr( "title" );
11774		if ( this.options.title == null && this.originalTitle != null ) {
11775			this.options.title = this.originalTitle;
11776		}
11777
11778		// Dialogs can't be disabled
11779		if ( this.options.disabled ) {
11780			this.options.disabled = false;
11781		}
11782
11783		this._createWrapper();
11784
11785		this.element
11786			.show()
11787			.removeAttr( "title" )
11788			.appendTo( this.uiDialog );
11789
11790		this._addClass( "ui-dialog-content", "ui-widget-content" );
11791
11792		this._createTitlebar();
11793		this._createButtonPane();
11794
11795		if ( this.options.draggable && $.fn.draggable ) {
11796			this._makeDraggable();
11797		}
11798		if ( this.options.resizable && $.fn.resizable ) {
11799			this._makeResizable();
11800		}
11801
11802		this._isOpen = false;
11803
11804		this._trackFocus();
11805	},
11806
11807	_init: function() {
11808		if ( this.options.autoOpen ) {
11809			this.open();
11810		}
11811	},
11812
11813	_appendTo: function() {
11814		var element = this.options.appendTo;
11815		if ( element && ( element.jquery || element.nodeType ) ) {
11816			return $( element );
11817		}
11818		return this.document.find( element || "body" ).eq( 0 );
11819	},
11820
11821	_destroy: function() {
11822		var next,
11823			originalPosition = this.originalPosition;
11824
11825		this._untrackInstance();
11826		this._destroyOverlay();
11827
11828		this.element
11829			.removeUniqueId()
11830			.css( this.originalCss )
11831
11832			// Without detaching first, the following becomes really slow
11833			.detach();
11834
11835		this.uiDialog.remove();
11836
11837		if ( this.originalTitle ) {
11838			this.element.attr( "title", this.originalTitle );
11839		}
11840
11841		next = originalPosition.parent.children().eq( originalPosition.index );
11842
11843		// Don't try to place the dialog next to itself (#8613)
11844		if ( next.length && next[ 0 ] !== this.element[ 0 ] ) {
11845			next.before( this.element );
11846		} else {
11847			originalPosition.parent.append( this.element );
11848		}
11849	},
11850
11851	widget: function() {
11852		return this.uiDialog;
11853	},
11854
11855	disable: $.noop,
11856	enable: $.noop,
11857
11858	close: function( event ) {
11859		var that = this;
11860
11861		if ( !this._isOpen || this._trigger( "beforeClose", event ) === false ) {
11862			return;
11863		}
11864
11865		this._isOpen = false;
11866		this._focusedElement = null;
11867		this._destroyOverlay();
11868		this._untrackInstance();
11869
11870		if ( !this.opener.filter( ":focusable" ).trigger( "focus" ).length ) {
11871
11872			// Hiding a focused element doesn't trigger blur in WebKit
11873			// so in case we have nothing to focus on, explicitly blur the active element
11874			// https://bugs.webkit.org/show_bug.cgi?id=47182
11875			$.ui.safeBlur( $.ui.safeActiveElement( this.document[ 0 ] ) );
11876		}
11877
11878		this._hide( this.uiDialog, this.options.hide, function() {
11879			that._trigger( "close", event );
11880		} );
11881	},
11882
11883	isOpen: function() {
11884		return this._isOpen;
11885	},
11886
11887	moveToTop: function() {
11888		this._moveToTop();
11889	},
11890
11891	_moveToTop: function( event, silent ) {
11892		var moved = false,
11893			zIndices = this.uiDialog.siblings( ".ui-front:visible" ).map( function() {
11894				return +$( this ).css( "z-index" );
11895			} ).get(),
11896			zIndexMax = Math.max.apply( null, zIndices );
11897
11898		if ( zIndexMax >= +this.uiDialog.css( "z-index" ) ) {
11899			this.uiDialog.css( "z-index", zIndexMax + 1 );
11900			moved = true;
11901		}
11902
11903		if ( moved && !silent ) {
11904			this._trigger( "focus", event );
11905		}
11906		return moved;
11907	},
11908
11909	open: function() {
11910		var that = this;
11911		if ( this._isOpen ) {
11912			if ( this._moveToTop() ) {
11913				this._focusTabbable();
11914			}
11915			return;
11916		}
11917
11918		this._isOpen = true;
11919		this.opener = $( $.ui.safeActiveElement( this.document[ 0 ] ) );
11920
11921		this._size();
11922		this._position();
11923		this._createOverlay();
11924		this._moveToTop( null, true );
11925
11926		// Ensure the overlay is moved to the top with the dialog, but only when
11927		// opening. The overlay shouldn't move after the dialog is open so that
11928		// modeless dialogs opened after the modal dialog stack properly.
11929		if ( this.overlay ) {
11930			this.overlay.css( "z-index", this.uiDialog.css( "z-index" ) - 1 );
11931		}
11932
11933		this._show( this.uiDialog, this.options.show, function() {
11934			that._focusTabbable();
11935			that._trigger( "focus" );
11936		} );
11937
11938		// Track the dialog immediately upon openening in case a focus event
11939		// somehow occurs outside of the dialog before an element inside the
11940		// dialog is focused (#10152)
11941		this._makeFocusTarget();
11942
11943		this._trigger( "open" );
11944	},
11945
11946	_focusTabbable: function() {
11947
11948		// Set focus to the first match:
11949		// 1. An element that was focused previously
11950		// 2. First element inside the dialog matching [autofocus]
11951		// 3. Tabbable element inside the content element
11952		// 4. Tabbable element inside the buttonpane
11953		// 5. The close button
11954		// 6. The dialog itself
11955		var hasFocus = this._focusedElement;
11956		if ( !hasFocus ) {
11957			hasFocus = this.element.find( "[autofocus]" );
11958		}
11959		if ( !hasFocus.length ) {
11960			hasFocus = this.element.find( ":tabbable" );
11961		}
11962		if ( !hasFocus.length ) {
11963			hasFocus = this.uiDialogButtonPane.find( ":tabbable" );
11964		}
11965		if ( !hasFocus.length ) {
11966			hasFocus = this.uiDialogTitlebarClose.filter( ":tabbable" );
11967		}
11968		if ( !hasFocus.length ) {
11969			hasFocus = this.uiDialog;
11970		}
11971		hasFocus.eq( 0 ).trigger( "focus" );
11972	},
11973
11974	_keepFocus: function( event ) {
11975		function checkFocus() {
11976			var activeElement = $.ui.safeActiveElement( this.document[ 0 ] ),
11977				isActive = this.uiDialog[ 0 ] === activeElement ||
11978					$.contains( this.uiDialog[ 0 ], activeElement );
11979			if ( !isActive ) {
11980				this._focusTabbable();
11981			}
11982		}
11983		event.preventDefault();
11984		checkFocus.call( this );
11985
11986		// support: IE
11987		// IE <= 8 doesn't prevent moving focus even with event.preventDefault()
11988		// so we check again later
11989		this._delay( checkFocus );
11990	},
11991
11992	_createWrapper: function() {
11993		this.uiDialog = $( "<div>" )
11994			.hide()
11995			.attr( {
11996
11997				// Setting tabIndex makes the div focusable
11998				tabIndex: -1,
11999				role: "dialog"
12000			} )
12001			.appendTo( this._appendTo() );
12002
12003		this._addClass( this.uiDialog, "ui-dialog", "ui-widget ui-widget-content ui-front" );
12004		this._on( this.uiDialog, {
12005			keydown: function( event ) {
12006				if ( this.options.closeOnEscape && !event.isDefaultPrevented() && event.keyCode &&
12007						event.keyCode === $.ui.keyCode.ESCAPE ) {
12008					event.preventDefault();
12009					this.close( event );
12010					return;
12011				}
12012
12013				// Prevent tabbing out of dialogs
12014				if ( event.keyCode !== $.ui.keyCode.TAB || event.isDefaultPrevented() ) {
12015					return;
12016				}
12017				var tabbables = this.uiDialog.find( ":tabbable" ),
12018					first = tabbables.filter( ":first" ),
12019					last = tabbables.filter( ":last" );
12020
12021				if ( ( event.target === last[ 0 ] || event.target === this.uiDialog[ 0 ] ) &&
12022						!event.shiftKey ) {
12023					this._delay( function() {
12024						first.trigger( "focus" );
12025					} );
12026					event.preventDefault();
12027				} else if ( ( event.target === first[ 0 ] ||
12028						event.target === this.uiDialog[ 0 ] ) && event.shiftKey ) {
12029					this._delay( function() {
12030						last.trigger( "focus" );
12031					} );
12032					event.preventDefault();
12033				}
12034			},
12035			mousedown: function( event ) {
12036				if ( this._moveToTop( event ) ) {
12037					this._focusTabbable();
12038				}
12039			}
12040		} );
12041
12042		// We assume that any existing aria-describedby attribute means
12043		// that the dialog content is marked up properly
12044		// otherwise we brute force the content as the description
12045		if ( !this.element.find( "[aria-describedby]" ).length ) {
12046			this.uiDialog.attr( {
12047				"aria-describedby": this.element.uniqueId().attr( "id" )
12048			} );
12049		}
12050	},
12051
12052	_createTitlebar: function() {
12053		var uiDialogTitle;
12054
12055		this.uiDialogTitlebar = $( "<div>" );
12056		this._addClass( this.uiDialogTitlebar,
12057			"ui-dialog-titlebar", "ui-widget-header ui-helper-clearfix" );
12058		this._on( this.uiDialogTitlebar, {
12059			mousedown: function( event ) {
12060
12061				// Don't prevent click on close button (#8838)
12062				// Focusing a dialog that is partially scrolled out of view
12063				// causes the browser to scroll it into view, preventing the click event
12064				if ( !$( event.target ).closest( ".ui-dialog-titlebar-close" ) ) {
12065
12066					// Dialog isn't getting focus when dragging (#8063)
12067					this.uiDialog.trigger( "focus" );
12068				}
12069			}
12070		} );
12071
12072		// Support: IE
12073		// Use type="button" to prevent enter keypresses in textboxes from closing the
12074		// dialog in IE (#9312)
12075		this.uiDialogTitlebarClose = $( "<button type='button'></button>" )
12076			.button( {
12077				label: $( "<a>" ).text( this.options.closeText ).html(),
12078				icon: "ui-icon-closethick",
12079				showLabel: false
12080			} )
12081			.appendTo( this.uiDialogTitlebar );
12082
12083		this._addClass( this.uiDialogTitlebarClose, "ui-dialog-titlebar-close" );
12084		this._on( this.uiDialogTitlebarClose, {
12085			click: function( event ) {
12086				event.preventDefault();
12087				this.close( event );
12088			}
12089		} );
12090
12091		uiDialogTitle = $( "<span>" ).uniqueId().prependTo( this.uiDialogTitlebar );
12092		this._addClass( uiDialogTitle, "ui-dialog-title" );
12093		this._title( uiDialogTitle );
12094
12095		this.uiDialogTitlebar.prependTo( this.uiDialog );
12096
12097		this.uiDialog.attr( {
12098			"aria-labelledby": uiDialogTitle.attr( "id" )
12099		} );
12100	},
12101
12102	_title: function( title ) {
12103		if ( this.options.title ) {
12104			title.text( this.options.title );
12105		} else {
12106			title.html( "&#160;" );
12107		}
12108	},
12109
12110	_createButtonPane: function() {
12111		this.uiDialogButtonPane = $( "<div>" );
12112		this._addClass( this.uiDialogButtonPane, "ui-dialog-buttonpane",
12113			"ui-widget-content ui-helper-clearfix" );
12114
12115		this.uiButtonSet = $( "<div>" )
12116			.appendTo( this.uiDialogButtonPane );
12117		this._addClass( this.uiButtonSet, "ui-dialog-buttonset" );
12118
12119		this._createButtons();
12120	},
12121
12122	_createButtons: function() {
12123		var that = this,
12124			buttons = this.options.buttons;
12125
12126		// If we already have a button pane, remove it
12127		this.uiDialogButtonPane.remove();
12128		this.uiButtonSet.empty();
12129
12130		if ( $.isEmptyObject( buttons ) || ( $.isArray( buttons ) && !buttons.length ) ) {
12131			this._removeClass( this.uiDialog, "ui-dialog-buttons" );
12132			return;
12133		}
12134
12135		$.each( buttons, function( name, props ) {
12136			var click, buttonOptions;
12137			props = $.isFunction( props ) ?
12138				{ click: props, text: name } :
12139				props;
12140
12141			// Default to a non-submitting button
12142			props = $.extend( { type: "button" }, props );
12143
12144			// Change the context for the click callback to be the main element
12145			click = props.click;
12146			buttonOptions = {
12147				icon: props.icon,
12148				iconPosition: props.iconPosition,
12149				showLabel: props.showLabel,
12150
12151				// Deprecated options
12152				icons: props.icons,
12153				text: props.text
12154			};
12155
12156			delete props.click;
12157			delete props.icon;
12158			delete props.iconPosition;
12159			delete props.showLabel;
12160
12161			// Deprecated options
12162			delete props.icons;
12163			if ( typeof props.text === "boolean" ) {
12164				delete props.text;
12165			}
12166
12167			$( "<button></button>", props )
12168				.button( buttonOptions )
12169				.appendTo( that.uiButtonSet )
12170				.on( "click", function() {
12171					click.apply( that.element[ 0 ], arguments );
12172				} );
12173		} );
12174		this._addClass( this.uiDialog, "ui-dialog-buttons" );
12175		this.uiDialogButtonPane.appendTo( this.uiDialog );
12176	},
12177
12178	_makeDraggable: function() {
12179		var that = this,
12180			options = this.options;
12181
12182		function filteredUi( ui ) {
12183			return {
12184				position: ui.position,
12185				offset: ui.offset
12186			};
12187		}
12188
12189		this.uiDialog.draggable( {
12190			cancel: ".ui-dialog-content, .ui-dialog-titlebar-close",
12191			handle: ".ui-dialog-titlebar",
12192			containment: "document",
12193			start: function( event, ui ) {
12194				that._addClass( $( this ), "ui-dialog-dragging" );
12195				that._blockFrames();
12196				that._trigger( "dragStart", event, filteredUi( ui ) );
12197			},
12198			drag: function( event, ui ) {
12199				that._trigger( "drag", event, filteredUi( ui ) );
12200			},
12201			stop: function( event, ui ) {
12202				var left = ui.offset.left - that.document.scrollLeft(),
12203					top = ui.offset.top - that.document.scrollTop();
12204
12205				options.position = {
12206					my: "left top",
12207					at: "left" + ( left >= 0 ? "+" : "" ) + left + " " +
12208						"top" + ( top >= 0 ? "+" : "" ) + top,
12209					of: that.window
12210				};
12211				that._removeClass( $( this ), "ui-dialog-dragging" );
12212				that._unblockFrames();
12213				that._trigger( "dragStop", event, filteredUi( ui ) );
12214			}
12215		} );
12216	},
12217
12218	_makeResizable: function() {
12219		var that = this,
12220			options = this.options,
12221			handles = options.resizable,
12222
12223			// .ui-resizable has position: relative defined in the stylesheet
12224			// but dialogs have to use absolute or fixed positioning
12225			position = this.uiDialog.css( "position" ),
12226			resizeHandles = typeof handles === "string" ?
12227				handles :
12228				"n,e,s,w,se,sw,ne,nw";
12229
12230		function filteredUi( ui ) {
12231			return {
12232				originalPosition: ui.originalPosition,
12233				originalSize: ui.originalSize,
12234				position: ui.position,
12235				size: ui.size
12236			};
12237		}
12238
12239		this.uiDialog.resizable( {
12240			cancel: ".ui-dialog-content",
12241			containment: "document",
12242			alsoResize: this.element,
12243			maxWidth: options.maxWidth,
12244			maxHeight: options.maxHeight,
12245			minWidth: options.minWidth,
12246			minHeight: this._minHeight(),
12247			handles: resizeHandles,
12248			start: function( event, ui ) {
12249				that._addClass( $( this ), "ui-dialog-resizing" );
12250				that._blockFrames();
12251				that._trigger( "resizeStart", event, filteredUi( ui ) );
12252			},
12253			resize: function( event, ui ) {
12254				that._trigger( "resize", event, filteredUi( ui ) );
12255			},
12256			stop: function( event, ui ) {
12257				var offset = that.uiDialog.offset(),
12258					left = offset.left - that.document.scrollLeft(),
12259					top = offset.top - that.document.scrollTop();
12260
12261				options.height = that.uiDialog.height();
12262				options.width = that.uiDialog.width();
12263				options.position = {
12264					my: "left top",
12265					at: "left" + ( left >= 0 ? "+" : "" ) + left + " " +
12266						"top" + ( top >= 0 ? "+" : "" ) + top,
12267					of: that.window
12268				};
12269				that._removeClass( $( this ), "ui-dialog-resizing" );
12270				that._unblockFrames();
12271				that._trigger( "resizeStop", event, filteredUi( ui ) );
12272			}
12273		} )
12274			.css( "position", position );
12275	},
12276
12277	_trackFocus: function() {
12278		this._on( this.widget(), {
12279			focusin: function( event ) {
12280				this._makeFocusTarget();
12281				this._focusedElement = $( event.target );
12282			}
12283		} );
12284	},
12285
12286	_makeFocusTarget: function() {
12287		this._untrackInstance();
12288		this._trackingInstances().unshift( this );
12289	},
12290
12291	_untrackInstance: function() {
12292		var instances = this._trackingInstances(),
12293			exists = $.inArray( this, instances );
12294		if ( exists !== -1 ) {
12295			instances.splice( exists, 1 );
12296		}
12297	},
12298
12299	_trackingInstances: function() {
12300		var instances = this.document.data( "ui-dialog-instances" );
12301		if ( !instances ) {
12302			instances = [];
12303			this.document.data( "ui-dialog-instances", instances );
12304		}
12305		return instances;
12306	},
12307
12308	_minHeight: function() {
12309		var options = this.options;
12310
12311		return options.height === "auto" ?
12312			options.minHeight :
12313			Math.min( options.minHeight, options.height );
12314	},
12315
12316	_position: function() {
12317
12318		// Need to show the dialog to get the actual offset in the position plugin
12319		var isVisible = this.uiDialog.is( ":visible" );
12320		if ( !isVisible ) {
12321			this.uiDialog.show();
12322		}
12323		this.uiDialog.position( this.options.position );
12324		if ( !isVisible ) {
12325			this.uiDialog.hide();
12326		}
12327	},
12328
12329	_setOptions: function( options ) {
12330		var that = this,
12331			resize = false,
12332			resizableOptions = {};
12333
12334		$.each( options, function( key, value ) {
12335			that._setOption( key, value );
12336
12337			if ( key in that.sizeRelatedOptions ) {
12338				resize = true;
12339			}
12340			if ( key in that.resizableRelatedOptions ) {
12341				resizableOptions[ key ] = value;
12342			}
12343		} );
12344
12345		if ( resize ) {
12346			this._size();
12347			this._position();
12348		}
12349		if ( this.uiDialog.is( ":data(ui-resizable)" ) ) {
12350			this.uiDialog.resizable( "option", resizableOptions );
12351		}
12352	},
12353
12354	_setOption: function( key, value ) {
12355		var isDraggable, isResizable,
12356			uiDialog = this.uiDialog;
12357
12358		if ( key === "disabled" ) {
12359			return;
12360		}
12361
12362		this._super( key, value );
12363
12364		if ( key === "appendTo" ) {
12365			this.uiDialog.appendTo( this._appendTo() );
12366		}
12367
12368		if ( key === "buttons" ) {
12369			this._createButtons();
12370		}
12371
12372		if ( key === "closeText" ) {
12373			this.uiDialogTitlebarClose.button( {
12374
12375				// Ensure that we always pass a string
12376				label: $( "<a>" ).text( "" + this.options.closeText ).html()
12377			} );
12378		}
12379
12380		if ( key === "draggable" ) {
12381			isDraggable = uiDialog.is( ":data(ui-draggable)" );
12382			if ( isDraggable && !value ) {
12383				uiDialog.draggable( "destroy" );
12384			}
12385
12386			if ( !isDraggable && value ) {
12387				this._makeDraggable();
12388			}
12389		}
12390
12391		if ( key === "position" ) {
12392			this._position();
12393		}
12394
12395		if ( key === "resizable" ) {
12396
12397			// currently resizable, becoming non-resizable
12398			isResizable = uiDialog.is( ":data(ui-resizable)" );
12399			if ( isResizable && !value ) {
12400				uiDialog.resizable( "destroy" );
12401			}
12402
12403			// Currently resizable, changing handles
12404			if ( isResizable && typeof value === "string" ) {
12405				uiDialog.resizable( "option", "handles", value );
12406			}
12407
12408			// Currently non-resizable, becoming resizable
12409			if ( !isResizable && value !== false ) {
12410				this._makeResizable();
12411			}
12412		}
12413
12414		if ( key === "title" ) {
12415			this._title( this.uiDialogTitlebar.find( ".ui-dialog-title" ) );
12416		}
12417	},
12418
12419	_size: function() {
12420
12421		// If the user has resized the dialog, the .ui-dialog and .ui-dialog-content
12422		// divs will both have width and height set, so we need to reset them
12423		var nonContentHeight, minContentHeight, maxContentHeight,
12424			options = this.options;
12425
12426		// Reset content sizing
12427		this.element.show().css( {
12428			width: "auto",
12429			minHeight: 0,
12430			maxHeight: "none",
12431			height: 0
12432		} );
12433
12434		if ( options.minWidth > options.width ) {
12435			options.width = options.minWidth;
12436		}
12437
12438		// Reset wrapper sizing
12439		// determine the height of all the non-content elements
12440		nonContentHeight = this.uiDialog.css( {
12441			height: "auto",
12442			width: options.width
12443		} )
12444			.outerHeight();
12445		minContentHeight = Math.max( 0, options.minHeight - nonContentHeight );
12446		maxContentHeight = typeof options.maxHeight === "number" ?
12447			Math.max( 0, options.maxHeight - nonContentHeight ) :
12448			"none";
12449
12450		if ( options.height === "auto" ) {
12451			this.element.css( {
12452				minHeight: minContentHeight,
12453				maxHeight: maxContentHeight,
12454				height: "auto"
12455			} );
12456		} else {
12457			this.element.height( Math.max( 0, options.height - nonContentHeight ) );
12458		}
12459
12460		if ( this.uiDialog.is( ":data(ui-resizable)" ) ) {
12461			this.uiDialog.resizable( "option", "minHeight", this._minHeight() );
12462		}
12463	},
12464
12465	_blockFrames: function() {
12466		this.iframeBlocks = this.document.find( "iframe" ).map( function() {
12467			var iframe = $( this );
12468
12469			return $( "<div>" )
12470				.css( {
12471					position: "absolute",
12472					width: iframe.outerWidth(),
12473					height: iframe.outerHeight()
12474				} )
12475				.appendTo( iframe.parent() )
12476				.offset( iframe.offset() )[ 0 ];
12477		} );
12478	},
12479
12480	_unblockFrames: function() {
12481		if ( this.iframeBlocks ) {
12482			this.iframeBlocks.remove();
12483			delete this.iframeBlocks;
12484		}
12485	},
12486
12487	_allowInteraction: function( event ) {
12488		if ( $( event.target ).closest( ".ui-dialog" ).length ) {
12489			return true;
12490		}
12491
12492		// TODO: Remove hack when datepicker implements
12493		// the .ui-front logic (#8989)
12494		return !!$( event.target ).closest( ".ui-datepicker" ).length;
12495	},
12496
12497	_createOverlay: function() {
12498		if ( !this.options.modal ) {
12499			return;
12500		}
12501
12502		// We use a delay in case the overlay is created from an
12503		// event that we're going to be cancelling (#2804)
12504		var isOpening = true;
12505		this._delay( function() {
12506			isOpening = false;
12507		} );
12508
12509		if ( !this.document.data( "ui-dialog-overlays" ) ) {
12510
12511			// Prevent use of anchors and inputs
12512			// Using _on() for an event handler shared across many instances is
12513			// safe because the dialogs stack and must be closed in reverse order
12514			this._on( this.document, {
12515				focusin: function( event ) {
12516					if ( isOpening ) {
12517						return;
12518					}
12519
12520					if ( !this._allowInteraction( event ) ) {
12521						event.preventDefault();
12522						this._trackingInstances()[ 0 ]._focusTabbable();
12523					}
12524				}
12525			} );
12526		}
12527
12528		this.overlay = $( "<div>" )
12529			.appendTo( this._appendTo() );
12530
12531		this._addClass( this.overlay, null, "ui-widget-overlay ui-front" );
12532		this._on( this.overlay, {
12533			mousedown: "_keepFocus"
12534		} );
12535		this.document.data( "ui-dialog-overlays",
12536			( this.document.data( "ui-dialog-overlays" ) || 0 ) + 1 );
12537	},
12538
12539	_destroyOverlay: function() {
12540		if ( !this.options.modal ) {
12541			return;
12542		}
12543
12544		if ( this.overlay ) {
12545			var overlays = this.document.data( "ui-dialog-overlays" ) - 1;
12546
12547			if ( !overlays ) {
12548				this._off( this.document, "focusin" );
12549				this.document.removeData( "ui-dialog-overlays" );
12550			} else {
12551				this.document.data( "ui-dialog-overlays", overlays );
12552			}
12553
12554			this.overlay.remove();
12555			this.overlay = null;
12556		}
12557	}
12558} );
12559
12560// DEPRECATED
12561// TODO: switch return back to widget declaration at top of file when this is removed
12562if ( $.uiBackCompat !== false ) {
12563
12564	// Backcompat for dialogClass option
12565	$.widget( "ui.dialog", $.ui.dialog, {
12566		options: {
12567			dialogClass: ""
12568		},
12569		_createWrapper: function() {
12570			this._super();
12571			this.uiDialog.addClass( this.options.dialogClass );
12572		},
12573		_setOption: function( key, value ) {
12574			if ( key === "dialogClass" ) {
12575				this.uiDialog
12576					.removeClass( this.options.dialogClass )
12577					.addClass( value );
12578			}
12579			this._superApply( arguments );
12580		}
12581	} );
12582}
12583
12584var widgetsDialog = $.ui.dialog;
12585
12586
12587/*!
12588 * jQuery UI Progressbar 1.12.1
12589 * http://jqueryui.com
12590 *
12591 * Copyright jQuery Foundation and other contributors
12592 * Released under the MIT license.
12593 * http://jquery.org/license
12594 */
12595
12596//>>label: Progressbar
12597//>>group: Widgets
12598// jscs:disable maximumLineLength
12599//>>description: Displays a status indicator for loading state, standard percentage, and other progress indicators.
12600// jscs:enable maximumLineLength
12601//>>docs: http://api.jqueryui.com/progressbar/
12602//>>demos: http://jqueryui.com/progressbar/
12603//>>css.structure: ../../themes/base/core.css
12604//>>css.structure: ../../themes/base/progressbar.css
12605//>>css.theme: ../../themes/base/theme.css
12606
12607
12608
12609var widgetsProgressbar = $.widget( "ui.progressbar", {
12610	version: "1.12.1",
12611	options: {
12612		classes: {
12613			"ui-progressbar": "ui-corner-all",
12614			"ui-progressbar-value": "ui-corner-left",
12615			"ui-progressbar-complete": "ui-corner-right"
12616		},
12617		max: 100,
12618		value: 0,
12619
12620		change: null,
12621		complete: null
12622	},
12623
12624	min: 0,
12625
12626	_create: function() {
12627
12628		// Constrain initial value
12629		this.oldValue = this.options.value = this._constrainedValue();
12630
12631		this.element.attr( {
12632
12633			// Only set static values; aria-valuenow and aria-valuemax are
12634			// set inside _refreshValue()
12635			role: "progressbar",
12636			"aria-valuemin": this.min
12637		} );
12638		this._addClass( "ui-progressbar", "ui-widget ui-widget-content" );
12639
12640		this.valueDiv = $( "<div>" ).appendTo( this.element );
12641		this._addClass( this.valueDiv, "ui-progressbar-value", "ui-widget-header" );
12642		this._refreshValue();
12643	},
12644
12645	_destroy: function() {
12646		this.element.removeAttr( "role aria-valuemin aria-valuemax aria-valuenow" );
12647
12648		this.valueDiv.remove();
12649	},
12650
12651	value: function( newValue ) {
12652		if ( newValue === undefined ) {
12653			return this.options.value;
12654		}
12655
12656		this.options.value = this._constrainedValue( newValue );
12657		this._refreshValue();
12658	},
12659
12660	_constrainedValue: function( newValue ) {
12661		if ( newValue === undefined ) {
12662			newValue = this.options.value;
12663		}
12664
12665		this.indeterminate = newValue === false;
12666
12667		// Sanitize value
12668		if ( typeof newValue !== "number" ) {
12669			newValue = 0;
12670		}
12671
12672		return this.indeterminate ? false :
12673			Math.min( this.options.max, Math.max( this.min, newValue ) );
12674	},
12675
12676	_setOptions: function( options ) {
12677
12678		// Ensure "value" option is set after other values (like max)
12679		var value = options.value;
12680		delete options.value;
12681
12682		this._super( options );
12683
12684		this.options.value = this._constrainedValue( value );
12685		this._refreshValue();
12686	},
12687
12688	_setOption: function( key, value ) {
12689		if ( key === "max" ) {
12690
12691			// Don't allow a max less than min
12692			value = Math.max( this.min, value );
12693		}
12694		this._super( key, value );
12695	},
12696
12697	_setOptionDisabled: function( value ) {
12698		this._super( value );
12699
12700		this.element.attr( "aria-disabled", value );
12701		this._toggleClass( null, "ui-state-disabled", !!value );
12702	},
12703
12704	_percentage: function() {
12705		return this.indeterminate ?
12706			100 :
12707			100 * ( this.options.value - this.min ) / ( this.options.max - this.min );
12708	},
12709
12710	_refreshValue: function() {
12711		var value = this.options.value,
12712			percentage = this._percentage();
12713
12714		this.valueDiv
12715			.toggle( this.indeterminate || value > this.min )
12716			.width( percentage.toFixed( 0 ) + "%" );
12717
12718		this
12719			._toggleClass( this.valueDiv, "ui-progressbar-complete", null,
12720				value === this.options.max )
12721			._toggleClass( "ui-progressbar-indeterminate", null, this.indeterminate );
12722
12723		if ( this.indeterminate ) {
12724			this.element.removeAttr( "aria-valuenow" );
12725			if ( !this.overlayDiv ) {
12726				this.overlayDiv = $( "<div>" ).appendTo( this.valueDiv );
12727				this._addClass( this.overlayDiv, "ui-progressbar-overlay" );
12728			}
12729		} else {
12730			this.element.attr( {
12731				"aria-valuemax": this.options.max,
12732				"aria-valuenow": value
12733			} );
12734			if ( this.overlayDiv ) {
12735				this.overlayDiv.remove();
12736				this.overlayDiv = null;
12737			}
12738		}
12739
12740		if ( this.oldValue !== value ) {
12741			this.oldValue = value;
12742			this._trigger( "change" );
12743		}
12744		if ( value === this.options.max ) {
12745			this._trigger( "complete" );
12746		}
12747	}
12748} );
12749
12750
12751/*!
12752 * jQuery UI Selectmenu 1.12.1
12753 * http://jqueryui.com
12754 *
12755 * Copyright jQuery Foundation and other contributors
12756 * Released under the MIT license.
12757 * http://jquery.org/license
12758 */
12759
12760//>>label: Selectmenu
12761//>>group: Widgets
12762// jscs:disable maximumLineLength
12763//>>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.
12764// jscs:enable maximumLineLength
12765//>>docs: http://api.jqueryui.com/selectmenu/
12766//>>demos: http://jqueryui.com/selectmenu/
12767//>>css.structure: ../../themes/base/core.css
12768//>>css.structure: ../../themes/base/selectmenu.css, ../../themes/base/button.css
12769//>>css.theme: ../../themes/base/theme.css
12770
12771
12772
12773var widgetsSelectmenu = $.widget( "ui.selectmenu", [ $.ui.formResetMixin, {
12774	version: "1.12.1",
12775	defaultElement: "<select>",
12776	options: {
12777		appendTo: null,
12778		classes: {
12779			"ui-selectmenu-button-open": "ui-corner-top",
12780			"ui-selectmenu-button-closed": "ui-corner-all"
12781		},
12782		disabled: null,
12783		icons: {
12784			button: "ui-icon-triangle-1-s"
12785		},
12786		position: {
12787			my: "left top",
12788			at: "left bottom",
12789			collision: "none"
12790		},
12791		width: false,
12792
12793		// Callbacks
12794		change: null,
12795		close: null,
12796		focus: null,
12797		open: null,
12798		select: null
12799	},
12800
12801	_create: function() {
12802		var selectmenuId = this.element.uniqueId().attr( "id" );
12803		this.ids = {
12804			element: selectmenuId,
12805			button: selectmenuId + "-button",
12806			menu: selectmenuId + "-menu"
12807		};
12808
12809		this._drawButton();
12810		this._drawMenu();
12811		this._bindFormResetHandler();
12812
12813		this._rendered = false;
12814		this.menuItems = $();
12815	},
12816
12817	_drawButton: function() {
12818		var icon,
12819			that = this,
12820			item = this._parseOption(
12821				this.element.find( "option:selected" ),
12822				this.element[ 0 ].selectedIndex
12823			);
12824
12825		// Associate existing label with the new button
12826		this.labels = this.element.labels().attr( "for", this.ids.button );
12827		this._on( this.labels, {
12828			click: function( event ) {
12829				this.button.focus();
12830				event.preventDefault();
12831			}
12832		} );
12833
12834		// Hide original select element
12835		this.element.hide();
12836
12837		// Create button
12838		this.button = $( "<span>", {
12839			tabindex: this.options.disabled ? -1 : 0,
12840			id: this.ids.button,
12841			role: "combobox",
12842			"aria-expanded": "false",
12843			"aria-autocomplete": "list",
12844			"aria-owns": this.ids.menu,
12845			"aria-haspopup": "true",
12846			title: this.element.attr( "title" )
12847		} )
12848			.insertAfter( this.element );
12849
12850		this._addClass( this.button, "ui-selectmenu-button ui-selectmenu-button-closed",
12851			"ui-button ui-widget" );
12852
12853		icon = $( "<span>" ).appendTo( this.button );
12854		this._addClass( icon, "ui-selectmenu-icon", "ui-icon " + this.options.icons.button );
12855		this.buttonItem = this._renderButtonItem( item )
12856			.appendTo( this.button );
12857
12858		if ( this.options.width !== false ) {
12859			this._resizeButton();
12860		}
12861
12862		this._on( this.button, this._buttonEvents );
12863		this.button.one( "focusin", function() {
12864
12865			// Delay rendering the menu items until the button receives focus.
12866			// The menu may have already been rendered via a programmatic open.
12867			if ( !that._rendered ) {
12868				that._refreshMenu();
12869			}
12870		} );
12871	},
12872
12873	_drawMenu: function() {
12874		var that = this;
12875
12876		// Create menu
12877		this.menu = $( "<ul>", {
12878			"aria-hidden": "true",
12879			"aria-labelledby": this.ids.button,
12880			id: this.ids.menu
12881		} );
12882
12883		// Wrap menu
12884		this.menuWrap = $( "<div>" ).append( this.menu );
12885		this._addClass( this.menuWrap, "ui-selectmenu-menu", "ui-front" );
12886		this.menuWrap.appendTo( this._appendTo() );
12887
12888		// Initialize menu widget
12889		this.menuInstance = this.menu
12890			.menu( {
12891				classes: {
12892					"ui-menu": "ui-corner-bottom"
12893				},
12894				role: "listbox",
12895				select: function( event, ui ) {
12896					event.preventDefault();
12897
12898					// Support: IE8
12899					// If the item was selected via a click, the text selection
12900					// will be destroyed in IE
12901					that._setSelection();
12902
12903					that._select( ui.item.data( "ui-selectmenu-item" ), event );
12904				},
12905				focus: function( event, ui ) {
12906					var item = ui.item.data( "ui-selectmenu-item" );
12907
12908					// Prevent inital focus from firing and check if its a newly focused item
12909					if ( that.focusIndex != null && item.index !== that.focusIndex ) {
12910						that._trigger( "focus", event, { item: item } );
12911						if ( !that.isOpen ) {
12912							that._select( item, event );
12913						}
12914					}
12915					that.focusIndex = item.index;
12916
12917					that.button.attr( "aria-activedescendant",
12918						that.menuItems.eq( item.index ).attr( "id" ) );
12919				}
12920			} )
12921			.menu( "instance" );
12922
12923		// Don't close the menu on mouseleave
12924		this.menuInstance._off( this.menu, "mouseleave" );
12925
12926		// Cancel the menu's collapseAll on document click
12927		this.menuInstance._closeOnDocumentClick = function() {
12928			return false;
12929		};
12930
12931		// Selects often contain empty items, but never contain dividers
12932		this.menuInstance._isDivider = function() {
12933			return false;
12934		};
12935	},
12936
12937	refresh: function() {
12938		this._refreshMenu();
12939		this.buttonItem.replaceWith(
12940			this.buttonItem = this._renderButtonItem(
12941
12942				// Fall back to an empty object in case there are no options
12943				this._getSelectedItem().data( "ui-selectmenu-item" ) || {}
12944			)
12945		);
12946		if ( this.options.width === null ) {
12947			this._resizeButton();
12948		}
12949	},
12950
12951	_refreshMenu: function() {
12952		var item,
12953			options = this.element.find( "option" );
12954
12955		this.menu.empty();
12956
12957		this._parseOptions( options );
12958		this._renderMenu( this.menu, this.items );
12959
12960		this.menuInstance.refresh();
12961		this.menuItems = this.menu.find( "li" )
12962			.not( ".ui-selectmenu-optgroup" )
12963				.find( ".ui-menu-item-wrapper" );
12964
12965		this._rendered = true;
12966
12967		if ( !options.length ) {
12968			return;
12969		}
12970
12971		item = this._getSelectedItem();
12972
12973		// Update the menu to have the correct item focused
12974		this.menuInstance.focus( null, item );
12975		this._setAria( item.data( "ui-selectmenu-item" ) );
12976
12977		// Set disabled state
12978		this._setOption( "disabled", this.element.prop( "disabled" ) );
12979	},
12980
12981	open: function( event ) {
12982		if ( this.options.disabled ) {
12983			return;
12984		}
12985
12986		// If this is the first time the menu is being opened, render the items
12987		if ( !this._rendered ) {
12988			this._refreshMenu();
12989		} else {
12990
12991			// Menu clears focus on close, reset focus to selected item
12992			this._removeClass( this.menu.find( ".ui-state-active" ), null, "ui-state-active" );
12993			this.menuInstance.focus( null, this._getSelectedItem() );
12994		}
12995
12996		// If there are no options, don't open the menu
12997		if ( !this.menuItems.length ) {
12998			return;
12999		}
13000
13001		this.isOpen = true;
13002		this._toggleAttr();
13003		this._resizeMenu();
13004		this._position();
13005
13006		this._on( this.document, this._documentClick );
13007
13008		this._trigger( "open", event );
13009	},
13010
13011	_position: function() {
13012		this.menuWrap.position( $.extend( { of: this.button }, this.options.position ) );
13013	},
13014
13015	close: function( event ) {
13016		if ( !this.isOpen ) {
13017			return;
13018		}
13019
13020		this.isOpen = false;
13021		this._toggleAttr();
13022
13023		this.range = null;
13024		this._off( this.document );
13025
13026		this._trigger( "close", event );
13027	},
13028
13029	widget: function() {
13030		return this.button;
13031	},
13032
13033	menuWidget: function() {
13034		return this.menu;
13035	},
13036
13037	_renderButtonItem: function( item ) {
13038		var buttonItem = $( "<span>" );
13039
13040		this._setText( buttonItem, item.label );
13041		this._addClass( buttonItem, "ui-selectmenu-text" );
13042
13043		return buttonItem;
13044	},
13045
13046	_renderMenu: function( ul, items ) {
13047		var that = this,
13048			currentOptgroup = "";
13049
13050		$.each( items, function( index, item ) {
13051			var li;
13052
13053			if ( item.optgroup !== currentOptgroup ) {
13054				li = $( "<li>", {
13055					text: item.optgroup
13056				} );
13057				that._addClass( li, "ui-selectmenu-optgroup", "ui-menu-divider" +
13058					( item.element.parent( "optgroup" ).prop( "disabled" ) ?
13059						" ui-state-disabled" :
13060						"" ) );
13061
13062				li.appendTo( ul );
13063
13064				currentOptgroup = item.optgroup;
13065			}
13066
13067			that._renderItemData( ul, item );
13068		} );
13069	},
13070
13071	_renderItemData: function( ul, item ) {
13072		return this._renderItem( ul, item ).data( "ui-selectmenu-item", item );
13073	},
13074
13075	_renderItem: function( ul, item ) {
13076		var li = $( "<li>" ),
13077			wrapper = $( "<div>", {
13078				title: item.element.attr( "title" )
13079			} );
13080
13081		if ( item.disabled ) {
13082			this._addClass( li, null, "ui-state-disabled" );
13083		}
13084		this._setText( wrapper, item.label );
13085
13086		return li.append( wrapper ).appendTo( ul );
13087	},
13088
13089	_setText: function( element, value ) {
13090		if ( value ) {
13091			element.text( value );
13092		} else {
13093			element.html( "&#160;" );
13094		}
13095	},
13096
13097	_move: function( direction, event ) {
13098		var item, next,
13099			filter = ".ui-menu-item";
13100
13101		if ( this.isOpen ) {
13102			item = this.menuItems.eq( this.focusIndex ).parent( "li" );
13103		} else {
13104			item = this.menuItems.eq( this.element[ 0 ].selectedIndex ).parent( "li" );
13105			filter += ":not(.ui-state-disabled)";
13106		}
13107
13108		if ( direction === "first" || direction === "last" ) {
13109			next = item[ direction === "first" ? "prevAll" : "nextAll" ]( filter ).eq( -1 );
13110		} else {
13111			next = item[ direction + "All" ]( filter ).eq( 0 );
13112		}
13113
13114		if ( next.length ) {
13115			this.menuInstance.focus( event, next );
13116		}
13117	},
13118
13119	_getSelectedItem: function() {
13120		return this.menuItems.eq( this.element[ 0 ].selectedIndex ).parent( "li" );
13121	},
13122
13123	_toggle: function( event ) {
13124		this[ this.isOpen ? "close" : "open" ]( event );
13125	},
13126
13127	_setSelection: function() {
13128		var selection;
13129
13130		if ( !this.range ) {
13131			return;
13132		}
13133
13134		if ( window.getSelection ) {
13135			selection = window.getSelection();
13136			selection.removeAllRanges();
13137			selection.addRange( this.range );
13138
vendor: 25,061 bytes, lines 13139-14121
13139		// Support: IE8
13140		} else {
13141			this.range.select();
13142		}
13143
13144		// Support: IE
13145		// Setting the text selection kills the button focus in IE, but
13146		// restoring the focus doesn't kill the selection.
13147		this.button.focus();
13148	},
13149
13150	_documentClick: {
13151		mousedown: function( event ) {
13152			if ( !this.isOpen ) {
13153				return;
13154			}
13155
13156			if ( !$( event.target ).closest( ".ui-selectmenu-menu, #" +
13157					$.ui.escapeSelector( this.ids.button ) ).length ) {
13158				this.close( event );
13159			}
13160		}
13161	},
13162
13163	_buttonEvents: {
13164
13165		// Prevent text selection from being reset when interacting with the selectmenu (#10144)
13166		mousedown: function() {
13167			var selection;
13168
13169			if ( window.getSelection ) {
13170				selection = window.getSelection();
13171				if ( selection.rangeCount ) {
13172					this.range = selection.getRangeAt( 0 );
13173				}
13174
13175			// Support: IE8
13176			} else {
13177				this.range = document.selection.createRange();
13178			}
13179		},
13180
13181		click: function( event ) {
13182			this._setSelection();
13183			this._toggle( event );
13184		},
13185
13186		keydown: function( event ) {
13187			var preventDefault = true;
13188			switch ( event.keyCode ) {
13189			case $.ui.keyCode.TAB:
13190			case $.ui.keyCode.ESCAPE:
13191				this.close( event );
13192				preventDefault = false;
13193				break;
13194			case $.ui.keyCode.ENTER:
13195				if ( this.isOpen ) {
13196					this._selectFocusedItem( event );
13197				}
13198				break;
13199			case $.ui.keyCode.UP:
13200				if ( event.altKey ) {
13201					this._toggle( event );
13202				} else {
13203					this._move( "prev", event );
13204				}
13205				break;
13206			case $.ui.keyCode.DOWN:
13207				if ( event.altKey ) {
13208					this._toggle( event );
13209				} else {
13210					this._move( "next", event );
13211				}
13212				break;
13213			case $.ui.keyCode.SPACE:
13214				if ( this.isOpen ) {
13215					this._selectFocusedItem( event );
13216				} else {
13217					this._toggle( event );
13218				}
13219				break;
13220			case $.ui.keyCode.LEFT:
13221				this._move( "prev", event );
13222				break;
13223			case $.ui.keyCode.RIGHT:
13224				this._move( "next", event );
13225				break;
13226			case $.ui.keyCode.HOME:
13227			case $.ui.keyCode.PAGE_UP:
13228				this._move( "first", event );
13229				break;
13230			case $.ui.keyCode.END:
13231			case $.ui.keyCode.PAGE_DOWN:
13232				this._move( "last", event );
13233				break;
13234			default:
13235				this.menu.trigger( event );
13236				preventDefault = false;
13237			}
13238
13239			if ( preventDefault ) {
13240				event.preventDefault();
13241			}
13242		}
13243	},
13244
13245	_selectFocusedItem: function( event ) {
13246		var item = this.menuItems.eq( this.focusIndex ).parent( "li" );
13247		if ( !item.hasClass( "ui-state-disabled" ) ) {
13248			this._select( item.data( "ui-selectmenu-item" ), event );
13249		}
13250	},
13251
13252	_select: function( item, event ) {
13253		var oldIndex = this.element[ 0 ].selectedIndex;
13254
13255		// Change native select element
13256		this.element[ 0 ].selectedIndex = item.index;
13257		this.buttonItem.replaceWith( this.buttonItem = this._renderButtonItem( item ) );
13258		this._setAria( item );
13259		this._trigger( "select", event, { item: item } );
13260
13261		if ( item.index !== oldIndex ) {
13262			this._trigger( "change", event, { item: item } );
13263		}
13264
13265		this.close( event );
13266	},
13267
13268	_setAria: function( item ) {
13269		var id = this.menuItems.eq( item.index ).attr( "id" );
13270
13271		this.button.attr( {
13272			"aria-labelledby": id,
13273			"aria-activedescendant": id
13274		} );
13275		this.menu.attr( "aria-activedescendant", id );
13276	},
13277
13278	_setOption: function( key, value ) {
13279		if ( key === "icons" ) {
13280			var icon = this.button.find( "span.ui-icon" );
13281			this._removeClass( icon, null, this.options.icons.button )
13282				._addClass( icon, null, value.button );
13283		}
13284
13285		this._super( key, value );
13286
13287		if ( key === "appendTo" ) {
13288			this.menuWrap.appendTo( this._appendTo() );
13289		}
13290
13291		if ( key === "width" ) {
13292			this._resizeButton();
13293		}
13294	},
13295
13296	_setOptionDisabled: function( value ) {
13297		this._super( value );
13298
13299		this.menuInstance.option( "disabled", value );
13300		this.button.attr( "aria-disabled", value );
13301		this._toggleClass( this.button, null, "ui-state-disabled", value );
13302
13303		this.element.prop( "disabled", value );
13304		if ( value ) {
13305			this.button.attr( "tabindex", -1 );
13306			this.close();
13307		} else {
13308			this.button.attr( "tabindex", 0 );
13309		}
13310	},
13311
13312	_appendTo: function() {
13313		var element = this.options.appendTo;
13314
13315		if ( element ) {
13316			element = element.jquery || element.nodeType ?
13317				$( element ) :
13318				this.document.find( element ).eq( 0 );
13319		}
13320
13321		if ( !element || !element[ 0 ] ) {
13322			element = this.element.closest( ".ui-front, dialog" );
13323		}
13324
13325		if ( !element.length ) {
13326			element = this.document[ 0 ].body;
13327		}
13328
13329		return element;
13330	},
13331
13332	_toggleAttr: function() {
13333		this.button.attr( "aria-expanded", this.isOpen );
13334
13335		// We can't use two _toggleClass() calls here, because we need to make sure
13336		// we always remove classes first and add them second, otherwise if both classes have the
13337		// same theme class, it will be removed after we add it.
13338		this._removeClass( this.button, "ui-selectmenu-button-" +
13339			( this.isOpen ? "closed" : "open" ) )
13340			._addClass( this.button, "ui-selectmenu-button-" +
13341				( this.isOpen ? "open" : "closed" ) )
13342			._toggleClass( this.menuWrap, "ui-selectmenu-open", null, this.isOpen );
13343
13344		this.menu.attr( "aria-hidden", !this.isOpen );
13345	},
13346
13347	_resizeButton: function() {
13348		var width = this.options.width;
13349
13350		// For `width: false`, just remove inline style and stop
13351		if ( width === false ) {
13352			this.button.css( "width", "" );
13353			return;
13354		}
13355
13356		// For `width: null`, match the width of the original element
13357		if ( width === null ) {
13358			width = this.element.show().outerWidth();
13359			this.element.hide();
13360		}
13361
13362		this.button.outerWidth( width );
13363	},
13364
13365	_resizeMenu: function() {
13366		this.menu.outerWidth( Math.max(
13367			this.button.outerWidth(),
13368
13369			// Support: IE10
13370			// IE10 wraps long text (possibly a rounding bug)
13371			// so we add 1px to avoid the wrapping
13372			this.menu.width( "" ).outerWidth() + 1
13373		) );
13374	},
13375
13376	_getCreateOptions: function() {
13377		var options = this._super();
13378
13379		options.disabled = this.element.prop( "disabled" );
13380
13381		return options;
13382	},
13383
13384	_parseOptions: function( options ) {
13385		var that = this,
13386			data = [];
13387		options.each( function( index, item ) {
13388			data.push( that._parseOption( $( item ), index ) );
13389		} );
13390		this.items = data;
13391	},
13392
13393	_parseOption: function( option, index ) {
13394		var optgroup = option.parent( "optgroup" );
13395
13396		return {
13397			element: option,
13398			index: index,
13399			value: option.val(),
13400			label: option.text(),
13401			optgroup: optgroup.attr( "label" ) || "",
13402			disabled: optgroup.prop( "disabled" ) || option.prop( "disabled" )
13403		};
13404	},
13405
13406	_destroy: function() {
13407		this._unbindFormResetHandler();
13408		this.menuWrap.remove();
13409		this.button.remove();
13410		this.element.show();
13411		this.element.removeUniqueId();
13412		this.labels.attr( "for", this.ids.element );
13413	}
13414} ] );
13415
13416
13417/*!
13418 * jQuery UI Slider 1.12.1
13419 * http://jqueryui.com
13420 *
13421 * Copyright jQuery Foundation and other contributors
13422 * Released under the MIT license.
13423 * http://jquery.org/license
13424 */
13425
13426//>>label: Slider
13427//>>group: Widgets
13428//>>description: Displays a flexible slider with ranges and accessibility via keyboard.
13429//>>docs: http://api.jqueryui.com/slider/
13430//>>demos: http://jqueryui.com/slider/
13431//>>css.structure: ../../themes/base/core.css
13432//>>css.structure: ../../themes/base/slider.css
13433//>>css.theme: ../../themes/base/theme.css
13434
13435
13436
13437var widgetsSlider = $.widget( "ui.slider", $.ui.mouse, {
13438	version: "1.12.1",
13439	widgetEventPrefix: "slide",
13440
13441	options: {
13442		animate: false,
13443		classes: {
13444			"ui-slider": "ui-corner-all",
13445			"ui-slider-handle": "ui-corner-all",
13446
13447			// Note: ui-widget-header isn't the most fittingly semantic framework class for this
13448			// element, but worked best visually with a variety of themes
13449			"ui-slider-range": "ui-corner-all ui-widget-header"
13450		},
13451		distance: 0,
13452		max: 100,
13453		min: 0,
13454		orientation: "horizontal",
13455		range: false,
13456		step: 1,
13457		value: 0,
13458		values: null,
13459
13460		// Callbacks
13461		change: null,
13462		slide: null,
13463		start: null,
13464		stop: null
13465	},
13466
13467	// Number of pages in a slider
13468	// (how many times can you page up/down to go through the whole range)
13469	numPages: 5,
13470
13471	_create: function() {
13472		this._keySliding = false;
13473		this._mouseSliding = false;
13474		this._animateOff = true;
13475		this._handleIndex = null;
13476		this._detectOrientation();
13477		this._mouseInit();
13478		this._calculateNewMax();
13479
13480		this._addClass( "ui-slider ui-slider-" + this.orientation,
13481			"ui-widget ui-widget-content" );
13482
13483		this._refresh();
13484
13485		this._animateOff = false;
13486	},
13487
13488	_refresh: function() {
13489		this._createRange();
13490		this._createHandles();
13491		this._setupEvents();
13492		this._refreshValue();
13493	},
13494
13495	_createHandles: function() {
13496		var i, handleCount,
13497			options = this.options,
13498			existingHandles = this.element.find( ".ui-slider-handle" ),
13499			handle = "<span tabindex='0'></span>",
13500			handles = [];
13501
13502		handleCount = ( options.values && options.values.length ) || 1;
13503
13504		if ( existingHandles.length > handleCount ) {
13505			existingHandles.slice( handleCount ).remove();
13506			existingHandles = existingHandles.slice( 0, handleCount );
13507		}
13508
13509		for ( i = existingHandles.length; i < handleCount; i++ ) {
13510			handles.push( handle );
13511		}
13512
13513		this.handles = existingHandles.add( $( handles.join( "" ) ).appendTo( this.element ) );
13514
13515		this._addClass( this.handles, "ui-slider-handle", "ui-state-default" );
13516
13517		this.handle = this.handles.eq( 0 );
13518
13519		this.handles.each( function( i ) {
13520			$( this )
13521				.data( "ui-slider-handle-index", i )
13522				.attr( "tabIndex", 0 );
13523		} );
13524	},
13525
13526	_createRange: function() {
13527		var options = this.options;
13528
13529		if ( options.range ) {
13530			if ( options.range === true ) {
13531				if ( !options.values ) {
13532					options.values = [ this._valueMin(), this._valueMin() ];
13533				} else if ( options.values.length && options.values.length !== 2 ) {
13534					options.values = [ options.values[ 0 ], options.values[ 0 ] ];
13535				} else if ( $.isArray( options.values ) ) {
13536					options.values = options.values.slice( 0 );
13537				}
13538			}
13539
13540			if ( !this.range || !this.range.length ) {
13541				this.range = $( "<div>" )
13542					.appendTo( this.element );
13543
13544				this._addClass( this.range, "ui-slider-range" );
13545			} else {
13546				this._removeClass( this.range, "ui-slider-range-min ui-slider-range-max" );
13547
13548				// Handle range switching from true to min/max
13549				this.range.css( {
13550					"left": "",
13551					"bottom": ""
13552				} );
13553			}
13554			if ( options.range === "min" || options.range === "max" ) {
13555				this._addClass( this.range, "ui-slider-range-" + options.range );
13556			}
13557		} else {
13558			if ( this.range ) {
13559				this.range.remove();
13560			}
13561			this.range = null;
13562		}
13563	},
13564
13565	_setupEvents: function() {
13566		this._off( this.handles );
13567		this._on( this.handles, this._handleEvents );
13568		this._hoverable( this.handles );
13569		this._focusable( this.handles );
13570	},
13571
13572	_destroy: function() {
13573		this.handles.remove();
13574		if ( this.range ) {
13575			this.range.remove();
13576		}
13577
13578		this._mouseDestroy();
13579	},
13580
13581	_mouseCapture: function( event ) {
13582		var position, normValue, distance, closestHandle, index, allowed, offset, mouseOverHandle,
13583			that = this,
13584			o = this.options;
13585
13586		if ( o.disabled ) {
13587			return false;
13588		}
13589
13590		this.elementSize = {
13591			width: this.element.outerWidth(),
13592			height: this.element.outerHeight()
13593		};
13594		this.elementOffset = this.element.offset();
13595
13596		position = { x: event.pageX, y: event.pageY };
13597		normValue = this._normValueFromMouse( position );
13598		distance = this._valueMax() - this._valueMin() + 1;
13599		this.handles.each( function( i ) {
13600			var thisDistance = Math.abs( normValue - that.values( i ) );
13601			if ( ( distance > thisDistance ) ||
13602				( distance === thisDistance &&
13603					( i === that._lastChangedValue || that.values( i ) === o.min ) ) ) {
13604				distance = thisDistance;
13605				closestHandle = $( this );
13606				index = i;
13607			}
13608		} );
13609
13610		allowed = this._start( event, index );
13611		if ( allowed === false ) {
13612			return false;
13613		}
13614		this._mouseSliding = true;
13615
13616		this._handleIndex = index;
13617
13618		this._addClass( closestHandle, null, "ui-state-active" );
13619		closestHandle.trigger( "focus" );
13620
13621		offset = closestHandle.offset();
13622		mouseOverHandle = !$( event.target ).parents().addBack().is( ".ui-slider-handle" );
13623		this._clickOffset = mouseOverHandle ? { left: 0, top: 0 } : {
13624			left: event.pageX - offset.left - ( closestHandle.width() / 2 ),
13625			top: event.pageY - offset.top -
13626				( closestHandle.height() / 2 ) -
13627				( parseInt( closestHandle.css( "borderTopWidth" ), 10 ) || 0 ) -
13628				( parseInt( closestHandle.css( "borderBottomWidth" ), 10 ) || 0 ) +
13629				( parseInt( closestHandle.css( "marginTop" ), 10 ) || 0 )
13630		};
13631
13632		if ( !this.handles.hasClass( "ui-state-hover" ) ) {
13633			this._slide( event, index, normValue );
13634		}
13635		this._animateOff = true;
13636		return true;
13637	},
13638
13639	_mouseStart: function() {
13640		return true;
13641	},
13642
13643	_mouseDrag: function( event ) {
13644		var position = { x: event.pageX, y: event.pageY },
13645			normValue = this._normValueFromMouse( position );
13646
13647		this._slide( event, this._handleIndex, normValue );
13648
13649		return false;
13650	},
13651
13652	_mouseStop: function( event ) {
13653		this._removeClass( this.handles, null, "ui-state-active" );
13654		this._mouseSliding = false;
13655
13656		this._stop( event, this._handleIndex );
13657		this._change( event, this._handleIndex );
13658
13659		this._handleIndex = null;
13660		this._clickOffset = null;
13661		this._animateOff = false;
13662
13663		return false;
13664	},
13665
13666	_detectOrientation: function() {
13667		this.orientation = ( this.options.orientation === "vertical" ) ? "vertical" : "horizontal";
13668	},
13669
13670	_normValueFromMouse: function( position ) {
13671		var pixelTotal,
13672			pixelMouse,
13673			percentMouse,
13674			valueTotal,
13675			valueMouse;
13676
13677		if ( this.orientation === "horizontal" ) {
13678			pixelTotal = this.elementSize.width;
13679			pixelMouse = position.x - this.elementOffset.left -
13680				( this._clickOffset ? this._clickOffset.left : 0 );
13681		} else {
13682			pixelTotal = this.elementSize.height;
13683			pixelMouse = position.y - this.elementOffset.top -
13684				( this._clickOffset ? this._clickOffset.top : 0 );
13685		}
13686
13687		percentMouse = ( pixelMouse / pixelTotal );
13688		if ( percentMouse > 1 ) {
13689			percentMouse = 1;
13690		}
13691		if ( percentMouse < 0 ) {
13692			percentMouse = 0;
13693		}
13694		if ( this.orientation === "vertical" ) {
13695			percentMouse = 1 - percentMouse;
13696		}
13697
13698		valueTotal = this._valueMax() - this._valueMin();
13699		valueMouse = this._valueMin() + percentMouse * valueTotal;
13700
13701		return this._trimAlignValue( valueMouse );
13702	},
13703
13704	_uiHash: function( index, value, values ) {
13705		var uiHash = {
13706			handle: this.handles[ index ],
13707			handleIndex: index,
13708			value: value !== undefined ? value : this.value()
13709		};
13710
13711		if ( this._hasMultipleValues() ) {
13712			uiHash.value = value !== undefined ? value : this.values( index );
13713			uiHash.values = values || this.values();
13714		}
13715
13716		return uiHash;
13717	},
13718
13719	_hasMultipleValues: function() {
13720		return this.options.values && this.options.values.length;
13721	},
13722
13723	_start: function( event, index ) {
13724		return this._trigger( "start", event, this._uiHash( index ) );
13725	},
13726
13727	_slide: function( event, index, newVal ) {
13728		var allowed, otherVal,
13729			currentValue = this.value(),
13730			newValues = this.values();
13731
13732		if ( this._hasMultipleValues() ) {
13733			otherVal = this.values( index ? 0 : 1 );
13734			currentValue = this.values( index );
13735
13736			if ( this.options.values.length === 2 && this.options.range === true ) {
13737				newVal =  index === 0 ? Math.min( otherVal, newVal ) : Math.max( otherVal, newVal );
13738			}
13739
13740			newValues[ index ] = newVal;
13741		}
13742
13743		if ( newVal === currentValue ) {
13744			return;
13745		}
13746
13747		allowed = this._trigger( "slide", event, this._uiHash( index, newVal, newValues ) );
13748
13749		// A slide can be canceled by returning false from the slide callback
13750		if ( allowed === false ) {
13751			return;
13752		}
13753
13754		if ( this._hasMultipleValues() ) {
13755			this.values( index, newVal );
13756		} else {
13757			this.value( newVal );
13758		}
13759	},
13760
13761	_stop: function( event, index ) {
13762		this._trigger( "stop", event, this._uiHash( index ) );
13763	},
13764
13765	_change: function( event, index ) {
13766		if ( !this._keySliding && !this._mouseSliding ) {
13767
13768			//store the last changed value index for reference when handles overlap
13769			this._lastChangedValue = index;
13770			this._trigger( "change", event, this._uiHash( index ) );
13771		}
13772	},
13773
13774	value: function( newValue ) {
13775		if ( arguments.length ) {
13776			this.options.value = this._trimAlignValue( newValue );
13777			this._refreshValue();
13778			this._change( null, 0 );
13779			return;
13780		}
13781
13782		return this._value();
13783	},
13784
13785	values: function( index, newValue ) {
13786		var vals,
13787			newValues,
13788			i;
13789
13790		if ( arguments.length > 1 ) {
13791			this.options.values[ index ] = this._trimAlignValue( newValue );
13792			this._refreshValue();
13793			this._change( null, index );
13794			return;
13795		}
13796
13797		if ( arguments.length ) {
13798			if ( $.isArray( arguments[ 0 ] ) ) {
13799				vals = this.options.values;
13800				newValues = arguments[ 0 ];
13801				for ( i = 0; i < vals.length; i += 1 ) {
13802					vals[ i ] = this._trimAlignValue( newValues[ i ] );
13803					this._change( null, i );
13804				}
13805				this._refreshValue();
13806			} else {
13807				if ( this._hasMultipleValues() ) {
13808					return this._values( index );
13809				} else {
13810					return this.value();
13811				}
13812			}
13813		} else {
13814			return this._values();
13815		}
13816	},
13817
13818	_setOption: function( key, value ) {
13819		var i,
13820			valsLength = 0;
13821
13822		if ( key === "range" && this.options.range === true ) {
13823			if ( value === "min" ) {
13824				this.options.value = this._values( 0 );
13825				this.options.values = null;
13826			} else if ( value === "max" ) {
13827				this.options.value = this._values( this.options.values.length - 1 );
13828				this.options.values = null;
13829			}
13830		}
13831
13832		if ( $.isArray( this.options.values ) ) {
13833			valsLength = this.options.values.length;
13834		}
13835
13836		this._super( key, value );
13837
13838		switch ( key ) {
13839			case "orientation":
13840				this._detectOrientation();
13841				this._removeClass( "ui-slider-horizontal ui-slider-vertical" )
13842					._addClass( "ui-slider-" + this.orientation );
13843				this._refreshValue();
13844				if ( this.options.range ) {
13845					this._refreshRange( value );
13846				}
13847
13848				// Reset positioning from previous orientation
13849				this.handles.css( value === "horizontal" ? "bottom" : "left", "" );
13850				break;
13851			case "value":
13852				this._animateOff = true;
13853				this._refreshValue();
13854				this._change( null, 0 );
13855				this._animateOff = false;
13856				break;
13857			case "values":
13858				this._animateOff = true;
13859				this._refreshValue();
13860
13861				// Start from the last handle to prevent unreachable handles (#9046)
13862				for ( i = valsLength - 1; i >= 0; i-- ) {
13863					this._change( null, i );
13864				}
13865				this._animateOff = false;
13866				break;
13867			case "step":
13868			case "min":
13869			case "max":
13870				this._animateOff = true;
13871				this._calculateNewMax();
13872				this._refreshValue();
13873				this._animateOff = false;
13874				break;
13875			case "range":
13876				this._animateOff = true;
13877				this._refresh();
13878				this._animateOff = false;
13879				break;
13880		}
13881	},
13882
13883	_setOptionDisabled: function( value ) {
13884		this._super( value );
13885
13886		this._toggleClass( null, "ui-state-disabled", !!value );
13887	},
13888
13889	//internal value getter
13890	// _value() returns value trimmed by min and max, aligned by step
13891	_value: function() {
13892		var val = this.options.value;
13893		val = this._trimAlignValue( val );
13894
13895		return val;
13896	},
13897
13898	//internal values getter
13899	// _values() returns array of values trimmed by min and max, aligned by step
13900	// _values( index ) returns single value trimmed by min and max, aligned by step
13901	_values: function( index ) {
13902		var val,
13903			vals,
13904			i;
13905
13906		if ( arguments.length ) {
13907			val = this.options.values[ index ];
13908			val = this._trimAlignValue( val );
13909
13910			return val;
13911		} else if ( this._hasMultipleValues() ) {
13912
13913			// .slice() creates a copy of the array
13914			// this copy gets trimmed by min and max and then returned
13915			vals = this.options.values.slice();
13916			for ( i = 0; i < vals.length; i += 1 ) {
13917				vals[ i ] = this._trimAlignValue( vals[ i ] );
13918			}
13919
13920			return vals;
13921		} else {
13922			return [];
13923		}
13924	},
13925
13926	// Returns the step-aligned value that val is closest to, between (inclusive) min and max
13927	_trimAlignValue: function( val ) {
13928		if ( val <= this._valueMin() ) {
13929			return this._valueMin();
13930		}
13931		if ( val >= this._valueMax() ) {
13932			return this._valueMax();
13933		}
13934		var step = ( this.options.step > 0 ) ? this.options.step : 1,
13935			valModStep = ( val - this._valueMin() ) % step,
13936			alignValue = val - valModStep;
13937
13938		if ( Math.abs( valModStep ) * 2 >= step ) {
13939			alignValue += ( valModStep > 0 ) ? step : ( -step );
13940		}
13941
13942		// Since JavaScript has problems with large floats, round
13943		// the final value to 5 digits after the decimal point (see #4124)
13944		return parseFloat( alignValue.toFixed( 5 ) );
13945	},
13946
13947	_calculateNewMax: function() {
13948		var max = this.options.max,
13949			min = this._valueMin(),
13950			step = this.options.step,
13951			aboveMin = Math.round( ( max - min ) / step ) * step;
13952		max = aboveMin + min;
13953		if ( max > this.options.max ) {
13954
13955			//If max is not divisible by step, rounding off may increase its value
13956			max -= step;
13957		}
13958		this.max = parseFloat( max.toFixed( this._precision() ) );
13959	},
13960
13961	_precision: function() {
13962		var precision = this._precisionOf( this.options.step );
13963		if ( this.options.min !== null ) {
13964			precision = Math.max( precision, this._precisionOf( this.options.min ) );
13965		}
13966		return precision;
13967	},
13968
13969	_precisionOf: function( num ) {
13970		var str = num.toString(),
13971			decimal = str.indexOf( "." );
13972		return decimal === -1 ? 0 : str.length - decimal - 1;
13973	},
13974
13975	_valueMin: function() {
13976		return this.options.min;
13977	},
13978
13979	_valueMax: function() {
13980		return this.max;
13981	},
13982
13983	_refreshRange: function( orientation ) {
13984		if ( orientation === "vertical" ) {
13985			this.range.css( { "width": "", "left": "" } );
13986		}
13987		if ( orientation === "horizontal" ) {
13988			this.range.css( { "height": "", "bottom": "" } );
13989		}
13990	},
13991
13992	_refreshValue: function() {
13993		var lastValPercent, valPercent, value, valueMin, valueMax,
13994			oRange = this.options.range,
13995			o = this.options,
13996			that = this,
13997			animate = ( !this._animateOff ) ? o.animate : false,
13998			_set = {};
13999
14000		if ( this._hasMultipleValues() ) {
14001			this.handles.each( function( i ) {
14002				valPercent = ( that.values( i ) - that._valueMin() ) / ( that._valueMax() -
14003					that._valueMin() ) * 100;
14004				_set[ that.orientation === "horizontal" ? "left" : "bottom" ] = valPercent + "%";
14005				$( this ).stop( 1, 1 )[ animate ? "animate" : "css" ]( _set, o.animate );
14006				if ( that.options.range === true ) {
14007					if ( that.orientation === "horizontal" ) {
14008						if ( i === 0 ) {
14009							that.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( {
14010								left: valPercent + "%"
14011							}, o.animate );
14012						}
14013						if ( i === 1 ) {
14014							that.range[ animate ? "animate" : "css" ]( {
14015								width: ( valPercent - lastValPercent ) + "%"
14016							}, {
14017								queue: false,
14018								duration: o.animate
14019							} );
14020						}
14021					} else {
14022						if ( i === 0 ) {
14023							that.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( {
14024								bottom: ( valPercent ) + "%"
14025							}, o.animate );
14026						}
14027						if ( i === 1 ) {
14028							that.range[ animate ? "animate" : "css" ]( {
14029								height: ( valPercent - lastValPercent ) + "%"
14030							}, {
14031								queue: false,
14032								duration: o.animate
14033							} );
14034						}
14035					}
14036				}
14037				lastValPercent = valPercent;
14038			} );
14039		} else {
14040			value = this.value();
14041			valueMin = this._valueMin();
14042			valueMax = this._valueMax();
14043			valPercent = ( valueMax !== valueMin ) ?
14044					( value - valueMin ) / ( valueMax - valueMin ) * 100 :
14045					0;
14046			_set[ this.orientation === "horizontal" ? "left" : "bottom" ] = valPercent + "%";
14047			this.handle.stop( 1, 1 )[ animate ? "animate" : "css" ]( _set, o.animate );
14048
14049			if ( oRange === "min" && this.orientation === "horizontal" ) {
14050				this.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( {
14051					width: valPercent + "%"
14052				}, o.animate );
14053			}
14054			if ( oRange === "max" && this.orientation === "horizontal" ) {
14055				this.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( {
14056					width: ( 100 - valPercent ) + "%"
14057				}, o.animate );
14058			}
14059			if ( oRange === "min" && this.orientation === "vertical" ) {
14060				this.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( {
14061					height: valPercent + "%"
14062				}, o.animate );
14063			}
14064			if ( oRange === "max" && this.orientation === "vertical" ) {
14065				this.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( {
14066					height: ( 100 - valPercent ) + "%"
14067				}, o.animate );
14068			}
14069		}
14070	},
14071
14072	_handleEvents: {
14073		keydown: function( event ) {
14074			var allowed, curVal, newVal, step,
14075				index = $( event.target ).data( "ui-slider-handle-index" );
14076
14077			switch ( event.keyCode ) {
14078				case $.ui.keyCode.HOME:
14079				case $.ui.keyCode.END:
14080				case $.ui.keyCode.PAGE_UP:
14081				case $.ui.keyCode.PAGE_DOWN:
14082				case $.ui.keyCode.UP:
14083				case $.ui.keyCode.RIGHT:
14084				case $.ui.keyCode.DOWN:
14085				case $.ui.keyCode.LEFT:
14086					event.preventDefault();
14087					if ( !this._keySliding ) {
14088						this._keySliding = true;
14089						this._addClass( $( event.target ), null, "ui-state-active" );
14090						allowed = this._start( event, index );
14091						if ( allowed === false ) {
14092							return;
14093						}
14094					}
14095					break;
14096			}
14097
14098			step = this.options.step;
14099			if ( this._hasMultipleValues() ) {
14100				curVal = newVal = this.values( index );
14101			} else {
14102				curVal = newVal = this.value();
14103			}
14104
14105			switch ( event.keyCode ) {
14106				case $.ui.keyCode.HOME:
14107					newVal = this._valueMin();
14108					break;
14109				case $.ui.keyCode.END:
14110					newVal = this._valueMax();
14111					break;
14112				case $.ui.keyCode.PAGE_UP:
14113					newVal = this._trimAlignValue(
14114						curVal + ( ( this._valueMax() - this._valueMin() ) / this.numPages )
14115					);
14116					break;
14117				case $.ui.keyCode.PAGE_DOWN:
14118					newVal = this._trimAlignValue(
14119						curVal - ( ( this._valueMax() - this._valueMin() ) / this.numPages ) );
14120					break;
14121				case $.ui.keyCode.UP:
vendor: 5,058 bytes, lines 14122-14320
14122				case $.ui.keyCode.RIGHT:
14123					if ( curVal === this._valueMax() ) {
14124						return;
14125					}
14126					newVal = this._trimAlignValue( curVal + step );
14127					break;
14128				case $.ui.keyCode.DOWN:
14129				case $.ui.keyCode.LEFT:
14130					if ( curVal === this._valueMin() ) {
14131						return;
14132					}
14133					newVal = this._trimAlignValue( curVal - step );
14134					break;
14135			}
14136
14137			this._slide( event, index, newVal );
14138		},
14139		keyup: function( event ) {
14140			var index = $( event.target ).data( "ui-slider-handle-index" );
14141
14142			if ( this._keySliding ) {
14143				this._keySliding = false;
14144				this._stop( event, index );
14145				this._change( event, index );
14146				this._removeClass( $( event.target ), null, "ui-state-active" );
14147			}
14148		}
14149	}
14150} );
14151
14152
14153/*!
14154 * jQuery UI Spinner 1.12.1
14155 * http://jqueryui.com
14156 *
14157 * Copyright jQuery Foundation and other contributors
14158 * Released under the MIT license.
14159 * http://jquery.org/license
14160 */
14161
14162//>>label: Spinner
14163//>>group: Widgets
14164//>>description: Displays buttons to easily input numbers via the keyboard or mouse.
14165//>>docs: http://api.jqueryui.com/spinner/
14166//>>demos: http://jqueryui.com/spinner/
14167//>>css.structure: ../../themes/base/core.css
14168//>>css.structure: ../../themes/base/spinner.css
14169//>>css.theme: ../../themes/base/theme.css
14170
14171
14172
14173function spinnerModifer( fn ) {
14174	return function() {
14175		var previous = this.element.val();
14176		fn.apply( this, arguments );
14177		this._refresh();
14178		if ( previous !== this.element.val() ) {
14179			this._trigger( "change" );
14180		}
14181	};
14182}
14183
14184$.widget( "ui.spinner", {
14185	version: "1.12.1",
14186	defaultElement: "<input>",
14187	widgetEventPrefix: "spin",
14188	options: {
14189		classes: {
14190			"ui-spinner": "ui-corner-all",
14191			"ui-spinner-down": "ui-corner-br",
14192			"ui-spinner-up": "ui-corner-tr"
14193		},
14194		culture: null,
14195		icons: {
14196			down: "ui-icon-triangle-1-s",
14197			up: "ui-icon-triangle-1-n"
14198		},
14199		incremental: true,
14200		max: null,
14201		min: null,
14202		numberFormat: null,
14203		page: 10,
14204		step: 1,
14205
14206		change: null,
14207		spin: null,
14208		start: null,
14209		stop: null
14210	},
14211
14212	_create: function() {
14213
14214		// handle string values that need to be parsed
14215		this._setOption( "max", this.options.max );
14216		this._setOption( "min", this.options.min );
14217		this._setOption( "step", this.options.step );
14218
14219		// Only format if there is a value, prevents the field from being marked
14220		// as invalid in Firefox, see #9573.
14221		if ( this.value() !== "" ) {
14222
14223			// Format the value, but don't constrain.
14224			this._value( this.element.val(), true );
14225		}
14226
14227		this._draw();
14228		this._on( this._events );
14229		this._refresh();
14230
14231		// Turning off autocomplete prevents the browser from remembering the
14232		// value when navigating through history, so we re-enable autocomplete
14233		// if the page is unloaded before the widget is destroyed. #7790
14234		this._on( this.window, {
14235			beforeunload: function() {
14236				this.element.removeAttr( "autocomplete" );
14237			}
14238		} );
14239	},
14240
14241	_getCreateOptions: function() {
14242		var options = this._super();
14243		var element = this.element;
14244
14245		$.each( [ "min", "max", "step" ], function( i, option ) {
14246			var value = element.attr( option );
14247			if ( value != null && value.length ) {
14248				options[ option ] = value;
14249			}
14250		} );
14251
14252		return options;
14253	},
14254
14255	_events: {
14256		keydown: function( event ) {
14257			if ( this._start( event ) && this._keydown( event ) ) {
14258				event.preventDefault();
14259			}
14260		},
14261		keyup: "_stop",
14262		focus: function() {
14263			this.previous = this.element.val();
14264		},
14265		blur: function( event ) {
14266			if ( this.cancelBlur ) {
14267				delete this.cancelBlur;
14268				return;
14269			}
14270
14271			this._stop();
14272			this._refresh();
14273			if ( this.previous !== this.element.val() ) {
14274				this._trigger( "change", event );
14275			}
14276		},
14277		mousewheel: function( event, delta ) {
14278			if ( !delta ) {
14279				return;
14280			}
14281			if ( !this.spinning && !this._start( event ) ) {
14282				return false;
14283			}
14284
14285			this._spin( ( delta > 0 ? 1 : -1 ) * this.options.step, event );
14286			clearTimeout( this.mousewheelTimer );
14287			this.mousewheelTimer = this._delay( function() {
14288				if ( this.spinning ) {
14289					this._stop( event );
14290				}
14291			}, 100 );
14292			event.preventDefault();
14293		},
14294		"mousedown .ui-spinner-button": function( event ) {
14295			var previous;
14296
14297			// We never want the buttons to have focus; whenever the user is
14298			// interacting with the spinner, the focus should be on the input.
14299			// If the input is focused then this.previous is properly set from
14300			// when the input first received focus. If the input is not focused
14301			// then we need to set this.previous based on the value before spinning.
14302			previous = this.element[ 0 ] === $.ui.safeActiveElement( this.document[ 0 ] ) ?
14303				this.previous : this.element.val();
14304			function checkFocus() {
14305				var isActive = this.element[ 0 ] === $.ui.safeActiveElement( this.document[ 0 ] );
14306				if ( !isActive ) {
14307					this.element.trigger( "focus" );
14308					this.previous = previous;
14309
14310					// support: IE
14311					// IE sets focus asynchronously, so we need to check if focus
14312					// moved off of the input because the user clicked on the button.
14313					this._delay( function() {
14314						this.previous = previous;
14315					} );
14316				}
14317			}
14318
14319			// Ensure focus is on (or stays on) the text field
14320			event.preventDefault();
vendor: 42,977 bytes, lines 14321-15975
14321			checkFocus.call( this );
14322
14323			// Support: IE
14324			// IE doesn't prevent moving focus even with event.preventDefault()
14325			// so we set a flag to know when we should ignore the blur event
14326			// and check (again) if focus moved off of the input.
14327			this.cancelBlur = true;
14328			this._delay( function() {
14329				delete this.cancelBlur;
14330				checkFocus.call( this );
14331			} );
14332
14333			if ( this._start( event ) === false ) {
14334				return;
14335			}
14336
14337			this._repeat( null, $( event.currentTarget )
14338				.hasClass( "ui-spinner-up" ) ? 1 : -1, event );
14339		},
14340		"mouseup .ui-spinner-button": "_stop",
14341		"mouseenter .ui-spinner-button": function( event ) {
14342
14343			// button will add ui-state-active if mouse was down while mouseleave and kept down
14344			if ( !$( event.currentTarget ).hasClass( "ui-state-active" ) ) {
14345				return;
14346			}
14347
14348			if ( this._start( event ) === false ) {
14349				return false;
14350			}
14351			this._repeat( null, $( event.currentTarget )
14352				.hasClass( "ui-spinner-up" ) ? 1 : -1, event );
14353		},
14354
14355		// TODO: do we really want to consider this a stop?
14356		// shouldn't we just stop the repeater and wait until mouseup before
14357		// we trigger the stop event?
14358		"mouseleave .ui-spinner-button": "_stop"
14359	},
14360
14361	// Support mobile enhanced option and make backcompat more sane
14362	_enhance: function() {
14363		this.uiSpinner = this.element
14364			.attr( "autocomplete", "off" )
14365			.wrap( "<span>" )
14366			.parent()
14367
14368				// Add buttons
14369				.append(
14370					"<a></a><a></a>"
14371				);
14372	},
14373
14374	_draw: function() {
14375		this._enhance();
14376
14377		this._addClass( this.uiSpinner, "ui-spinner", "ui-widget ui-widget-content" );
14378		this._addClass( "ui-spinner-input" );
14379
14380		this.element.attr( "role", "spinbutton" );
14381
14382		// Button bindings
14383		this.buttons = this.uiSpinner.children( "a" )
14384			.attr( "tabIndex", -1 )
14385			.attr( "aria-hidden", true )
14386			.button( {
14387				classes: {
14388					"ui-button": ""
14389				}
14390			} );
14391
14392		// TODO: Right now button does not support classes this is already updated in button PR
14393		this._removeClass( this.buttons, "ui-corner-all" );
14394
14395		this._addClass( this.buttons.first(), "ui-spinner-button ui-spinner-up" );
14396		this._addClass( this.buttons.last(), "ui-spinner-button ui-spinner-down" );
14397		this.buttons.first().button( {
14398			"icon": this.options.icons.up,
14399			"showLabel": false
14400		} );
14401		this.buttons.last().button( {
14402			"icon": this.options.icons.down,
14403			"showLabel": false
14404		} );
14405
14406		// IE 6 doesn't understand height: 50% for the buttons
14407		// unless the wrapper has an explicit height
14408		if ( this.buttons.height() > Math.ceil( this.uiSpinner.height() * 0.5 ) &&
14409				this.uiSpinner.height() > 0 ) {
14410			this.uiSpinner.height( this.uiSpinner.height() );
14411		}
14412	},
14413
14414	_keydown: function( event ) {
14415		var options = this.options,
14416			keyCode = $.ui.keyCode;
14417
14418		switch ( event.keyCode ) {
14419		case keyCode.UP:
14420			this._repeat( null, 1, event );
14421			return true;
14422		case keyCode.DOWN:
14423			this._repeat( null, -1, event );
14424			return true;
14425		case keyCode.PAGE_UP:
14426			this._repeat( null, options.page, event );
14427			return true;
14428		case keyCode.PAGE_DOWN:
14429			this._repeat( null, -options.page, event );
14430			return true;
14431		}
14432
14433		return false;
14434	},
14435
14436	_start: function( event ) {
14437		if ( !this.spinning && this._trigger( "start", event ) === false ) {
14438			return false;
14439		}
14440
14441		if ( !this.counter ) {
14442			this.counter = 1;
14443		}
14444		this.spinning = true;
14445		return true;
14446	},
14447
14448	_repeat: function( i, steps, event ) {
14449		i = i || 500;
14450
14451		clearTimeout( this.timer );
14452		this.timer = this._delay( function() {
14453			this._repeat( 40, steps, event );
14454		}, i );
14455
14456		this._spin( steps * this.options.step, event );
14457	},
14458
14459	_spin: function( step, event ) {
14460		var value = this.value() || 0;
14461
14462		if ( !this.counter ) {
14463			this.counter = 1;
14464		}
14465
14466		value = this._adjustValue( value + step * this._increment( this.counter ) );
14467
14468		if ( !this.spinning || this._trigger( "spin", event, { value: value } ) !== false ) {
14469			this._value( value );
14470			this.counter++;
14471		}
14472	},
14473
14474	_increment: function( i ) {
14475		var incremental = this.options.incremental;
14476
14477		if ( incremental ) {
14478			return $.isFunction( incremental ) ?
14479				incremental( i ) :
14480				Math.floor( i * i * i / 50000 - i * i / 500 + 17 * i / 200 + 1 );
14481		}
14482
14483		return 1;
14484	},
14485
14486	_precision: function() {
14487		var precision = this._precisionOf( this.options.step );
14488		if ( this.options.min !== null ) {
14489			precision = Math.max( precision, this._precisionOf( this.options.min ) );
14490		}
14491		return precision;
14492	},
14493
14494	_precisionOf: function( num ) {
14495		var str = num.toString(),
14496			decimal = str.indexOf( "." );
14497		return decimal === -1 ? 0 : str.length - decimal - 1;
14498	},
14499
14500	_adjustValue: function( value ) {
14501		var base, aboveMin,
14502			options = this.options;
14503
14504		// Make sure we're at a valid step
14505		// - find out where we are relative to the base (min or 0)
14506		base = options.min !== null ? options.min : 0;
14507		aboveMin = value - base;
14508
14509		// - round to the nearest step
14510		aboveMin = Math.round( aboveMin / options.step ) * options.step;
14511
14512		// - rounding is based on 0, so adjust back to our base
14513		value = base + aboveMin;
14514
14515		// Fix precision from bad JS floating point math
14516		value = parseFloat( value.toFixed( this._precision() ) );
14517
14518		// Clamp the value
14519		if ( options.max !== null && value > options.max ) {
14520			return options.max;
14521		}
14522		if ( options.min !== null && value < options.min ) {
14523			return options.min;
14524		}
14525
14526		return value;
14527	},
14528
14529	_stop: function( event ) {
14530		if ( !this.spinning ) {
14531			return;
14532		}
14533
14534		clearTimeout( this.timer );
14535		clearTimeout( this.mousewheelTimer );
14536		this.counter = 0;
14537		this.spinning = false;
14538		this._trigger( "stop", event );
14539	},
14540
14541	_setOption: function( key, value ) {
14542		var prevValue, first, last;
14543
14544		if ( key === "culture" || key === "numberFormat" ) {
14545			prevValue = this._parse( this.element.val() );
14546			this.options[ key ] = value;
14547			this.element.val( this._format( prevValue ) );
14548			return;
14549		}
14550
14551		if ( key === "max" || key === "min" || key === "step" ) {
14552			if ( typeof value === "string" ) {
14553				value = this._parse( value );
14554			}
14555		}
14556		if ( key === "icons" ) {
14557			first = this.buttons.first().find( ".ui-icon" );
14558			this._removeClass( first, null, this.options.icons.up );
14559			this._addClass( first, null, value.up );
14560			last = this.buttons.last().find( ".ui-icon" );
14561			this._removeClass( last, null, this.options.icons.down );
14562			this._addClass( last, null, value.down );
14563		}
14564
14565		this._super( key, value );
14566	},
14567
14568	_setOptionDisabled: function( value ) {
14569		this._super( value );
14570
14571		this._toggleClass( this.uiSpinner, null, "ui-state-disabled", !!value );
14572		this.element.prop( "disabled", !!value );
14573		this.buttons.button( value ? "disable" : "enable" );
14574	},
14575
14576	_setOptions: spinnerModifer( function( options ) {
14577		this._super( options );
14578	} ),
14579
14580	_parse: function( val ) {
14581		if ( typeof val === "string" && val !== "" ) {
14582			val = window.Globalize && this.options.numberFormat ?
14583				Globalize.parseFloat( val, 10, this.options.culture ) : +val;
14584		}
14585		return val === "" || isNaN( val ) ? null : val;
14586	},
14587
14588	_format: function( value ) {
14589		if ( value === "" ) {
14590			return "";
14591		}
14592		return window.Globalize && this.options.numberFormat ?
14593			Globalize.format( value, this.options.numberFormat, this.options.culture ) :
14594			value;
14595	},
14596
14597	_refresh: function() {
14598		this.element.attr( {
14599			"aria-valuemin": this.options.min,
14600			"aria-valuemax": this.options.max,
14601
14602			// TODO: what should we do with values that can't be parsed?
14603			"aria-valuenow": this._parse( this.element.val() )
14604		} );
14605	},
14606
14607	isValid: function() {
14608		var value = this.value();
14609
14610		// Null is invalid
14611		if ( value === null ) {
14612			return false;
14613		}
14614
14615		// If value gets adjusted, it's invalid
14616		return value === this._adjustValue( value );
14617	},
14618
14619	// Update the value without triggering change
14620	_value: function( value, allowAny ) {
14621		var parsed;
14622		if ( value !== "" ) {
14623			parsed = this._parse( value );
14624			if ( parsed !== null ) {
14625				if ( !allowAny ) {
14626					parsed = this._adjustValue( parsed );
14627				}
14628				value = this._format( parsed );
14629			}
14630		}
14631		this.element.val( value );
14632		this._refresh();
14633	},
14634
14635	_destroy: function() {
14636		this.element
14637			.prop( "disabled", false )
14638			.removeAttr( "autocomplete role aria-valuemin aria-valuemax aria-valuenow" );
14639
14640		this.uiSpinner.replaceWith( this.element );
14641	},
14642
14643	stepUp: spinnerModifer( function( steps ) {
14644		this._stepUp( steps );
14645	} ),
14646	_stepUp: function( steps ) {
14647		if ( this._start() ) {
14648			this._spin( ( steps || 1 ) * this.options.step );
14649			this._stop();
14650		}
14651	},
14652
14653	stepDown: spinnerModifer( function( steps ) {
14654		this._stepDown( steps );
14655	} ),
14656	_stepDown: function( steps ) {
14657		if ( this._start() ) {
14658			this._spin( ( steps || 1 ) * -this.options.step );
14659			this._stop();
14660		}
14661	},
14662
14663	pageUp: spinnerModifer( function( pages ) {
14664		this._stepUp( ( pages || 1 ) * this.options.page );
14665	} ),
14666
14667	pageDown: spinnerModifer( function( pages ) {
14668		this._stepDown( ( pages || 1 ) * this.options.page );
14669	} ),
14670
14671	value: function( newVal ) {
14672		if ( !arguments.length ) {
14673			return this._parse( this.element.val() );
14674		}
14675		spinnerModifer( this._value ).call( this, newVal );
14676	},
14677
14678	widget: function() {
14679		return this.uiSpinner;
14680	}
14681} );
14682
14683// DEPRECATED
14684// TODO: switch return back to widget declaration at top of file when this is removed
14685if ( $.uiBackCompat !== false ) {
14686
14687	// Backcompat for spinner html extension points
14688	$.widget( "ui.spinner", $.ui.spinner, {
14689		_enhance: function() {
14690			this.uiSpinner = this.element
14691				.attr( "autocomplete", "off" )
14692				.wrap( this._uiSpinnerHtml() )
14693				.parent()
14694
14695					// Add buttons
14696					.append( this._buttonHtml() );
14697		},
14698		_uiSpinnerHtml: function() {
14699			return "<span>";
14700		},
14701
14702		_buttonHtml: function() {
14703			return "<a></a><a></a>";
14704		}
14705	} );
14706}
14707
14708var widgetsSpinner = $.ui.spinner;
14709
14710
14711/*!
14712 * jQuery UI Tabs 1.12.1
14713 * http://jqueryui.com
14714 *
14715 * Copyright jQuery Foundation and other contributors
14716 * Released under the MIT license.
14717 * http://jquery.org/license
14718 */
14719
14720//>>label: Tabs
14721//>>group: Widgets
14722//>>description: Transforms a set of container elements into a tab structure.
14723//>>docs: http://api.jqueryui.com/tabs/
14724//>>demos: http://jqueryui.com/tabs/
14725//>>css.structure: ../../themes/base/core.css
14726//>>css.structure: ../../themes/base/tabs.css
14727//>>css.theme: ../../themes/base/theme.css
14728
14729
14730
14731$.widget( "ui.tabs", {
14732	version: "1.12.1",
14733	delay: 300,
14734	options: {
14735		active: null,
14736		classes: {
14737			"ui-tabs": "ui-corner-all",
14738			"ui-tabs-nav": "ui-corner-all",
14739			"ui-tabs-panel": "ui-corner-bottom",
14740			"ui-tabs-tab": "ui-corner-top"
14741		},
14742		collapsible: false,
14743		event: "click",
14744		heightStyle: "content",
14745		hide: null,
14746		show: null,
14747
14748		// Callbacks
14749		activate: null,
14750		beforeActivate: null,
14751		beforeLoad: null,
14752		load: null
14753	},
14754
14755	_isLocal: ( function() {
14756		var rhash = /#.*$/;
14757
14758		return function( anchor ) {
14759			var anchorUrl, locationUrl;
14760
14761			anchorUrl = anchor.href.replace( rhash, "" );
14762			locationUrl = location.href.replace( rhash, "" );
14763
14764			// Decoding may throw an error if the URL isn't UTF-8 (#9518)
14765			try {
14766				anchorUrl = decodeURIComponent( anchorUrl );
14767			} catch ( error ) {}
14768			try {
14769				locationUrl = decodeURIComponent( locationUrl );
14770			} catch ( error ) {}
14771
14772			return anchor.hash.length > 1 && anchorUrl === locationUrl;
14773		};
14774	} )(),
14775
14776	_create: function() {
14777		var that = this,
14778			options = this.options;
14779
14780		this.running = false;
14781
14782		this._addClass( "ui-tabs", "ui-widget ui-widget-content" );
14783		this._toggleClass( "ui-tabs-collapsible", null, options.collapsible );
14784
14785		this._processTabs();
14786		options.active = this._initialActive();
14787
14788		// Take disabling tabs via class attribute from HTML
14789		// into account and update option properly.
14790		if ( $.isArray( options.disabled ) ) {
14791			options.disabled = $.unique( options.disabled.concat(
14792				$.map( this.tabs.filter( ".ui-state-disabled" ), function( li ) {
14793					return that.tabs.index( li );
14794				} )
14795			) ).sort();
14796		}
14797
14798		// Check for length avoids error when initializing empty list
14799		if ( this.options.active !== false && this.anchors.length ) {
14800			this.active = this._findActive( options.active );
14801		} else {
14802			this.active = $();
14803		}
14804
14805		this._refresh();
14806
14807		if ( this.active.length ) {
14808			this.load( options.active );
14809		}
14810	},
14811
14812	_initialActive: function() {
14813		var active = this.options.active,
14814			collapsible = this.options.collapsible,
14815			locationHash = location.hash.substring( 1 );
14816
14817		if ( active === null ) {
14818
14819			// check the fragment identifier in the URL
14820			if ( locationHash ) {
14821				this.tabs.each( function( i, tab ) {
14822					if ( $( tab ).attr( "aria-controls" ) === locationHash ) {
14823						active = i;
14824						return false;
14825					}
14826				} );
14827			}
14828
14829			// Check for a tab marked active via a class
14830			if ( active === null ) {
14831				active = this.tabs.index( this.tabs.filter( ".ui-tabs-active" ) );
14832			}
14833
14834			// No active tab, set to false
14835			if ( active === null || active === -1 ) {
14836				active = this.tabs.length ? 0 : false;
14837			}
14838		}
14839
14840		// Handle numbers: negative, out of range
14841		if ( active !== false ) {
14842			active = this.tabs.index( this.tabs.eq( active ) );
14843			if ( active === -1 ) {
14844				active = collapsible ? false : 0;
14845			}
14846		}
14847
14848		// Don't allow collapsible: false and active: false
14849		if ( !collapsible && active === false && this.anchors.length ) {
14850			active = 0;
14851		}
14852
14853		return active;
14854	},
14855
14856	_getCreateEventData: function() {
14857		return {
14858			tab: this.active,
14859			panel: !this.active.length ? $() : this._getPanelForTab( this.active )
14860		};
14861	},
14862
14863	_tabKeydown: function( event ) {
14864		var focusedTab = $( $.ui.safeActiveElement( this.document[ 0 ] ) ).closest( "li" ),
14865			selectedIndex = this.tabs.index( focusedTab ),
14866			goingForward = true;
14867
14868		if ( this._handlePageNav( event ) ) {
14869			return;
14870		}
14871
14872		switch ( event.keyCode ) {
14873		case $.ui.keyCode.RIGHT:
14874		case $.ui.keyCode.DOWN:
14875			selectedIndex++;
14876			break;
14877		case $.ui.keyCode.UP:
14878		case $.ui.keyCode.LEFT:
14879			goingForward = false;
14880			selectedIndex--;
14881			break;
14882		case $.ui.keyCode.END:
14883			selectedIndex = this.anchors.length - 1;
14884			break;
14885		case $.ui.keyCode.HOME:
14886			selectedIndex = 0;
14887			break;
14888		case $.ui.keyCode.SPACE:
14889
14890			// Activate only, no collapsing
14891			event.preventDefault();
14892			clearTimeout( this.activating );
14893			this._activate( selectedIndex );
14894			return;
14895		case $.ui.keyCode.ENTER:
14896
14897			// Toggle (cancel delayed activation, allow collapsing)
14898			event.preventDefault();
14899			clearTimeout( this.activating );
14900
14901			// Determine if we should collapse or activate
14902			this._activate( selectedIndex === this.options.active ? false : selectedIndex );
14903			return;
14904		default:
14905			return;
14906		}
14907
14908		// Focus the appropriate tab, based on which key was pressed
14909		event.preventDefault();
14910		clearTimeout( this.activating );
14911		selectedIndex = this._focusNextTab( selectedIndex, goingForward );
14912
14913		// Navigating with control/command key will prevent automatic activation
14914		if ( !event.ctrlKey && !event.metaKey ) {
14915
14916			// Update aria-selected immediately so that AT think the tab is already selected.
14917			// Otherwise AT may confuse the user by stating that they need to activate the tab,
14918			// but the tab will already be activated by the time the announcement finishes.
14919			focusedTab.attr( "aria-selected", "false" );
14920			this.tabs.eq( selectedIndex ).attr( "aria-selected", "true" );
14921
14922			this.activating = this._delay( function() {
14923				this.option( "active", selectedIndex );
14924			}, this.delay );
14925		}
14926	},
14927
14928	_panelKeydown: function( event ) {
14929		if ( this._handlePageNav( event ) ) {
14930			return;
14931		}
14932
14933		// Ctrl+up moves focus to the current tab
14934		if ( event.ctrlKey && event.keyCode === $.ui.keyCode.UP ) {
14935			event.preventDefault();
14936			this.active.trigger( "focus" );
14937		}
14938	},
14939
14940	// Alt+page up/down moves focus to the previous/next tab (and activates)
14941	_handlePageNav: function( event ) {
14942		if ( event.altKey && event.keyCode === $.ui.keyCode.PAGE_UP ) {
14943			this._activate( this._focusNextTab( this.options.active - 1, false ) );
14944			return true;
14945		}
14946		if ( event.altKey && event.keyCode === $.ui.keyCode.PAGE_DOWN ) {
14947			this._activate( this._focusNextTab( this.options.active + 1, true ) );
14948			return true;
14949		}
14950	},
14951
14952	_findNextTab: function( index, goingForward ) {
14953		var lastTabIndex = this.tabs.length - 1;
14954
14955		function constrain() {
14956			if ( index > lastTabIndex ) {
14957				index = 0;
14958			}
14959			if ( index < 0 ) {
14960				index = lastTabIndex;
14961			}
14962			return index;
14963		}
14964
14965		while ( $.inArray( constrain(), this.options.disabled ) !== -1 ) {
14966			index = goingForward ? index + 1 : index - 1;
14967		}
14968
14969		return index;
14970	},
14971
14972	_focusNextTab: function( index, goingForward ) {
14973		index = this._findNextTab( index, goingForward );
14974		this.tabs.eq( index ).trigger( "focus" );
14975		return index;
14976	},
14977
14978	_setOption: function( key, value ) {
14979		if ( key === "active" ) {
14980
14981			// _activate() will handle invalid values and update this.options
14982			this._activate( value );
14983			return;
14984		}
14985
14986		this._super( key, value );
14987
14988		if ( key === "collapsible" ) {
14989			this._toggleClass( "ui-tabs-collapsible", null, value );
14990
14991			// Setting collapsible: false while collapsed; open first panel
14992			if ( !value && this.options.active === false ) {
14993				this._activate( 0 );
14994			}
14995		}
14996
14997		if ( key === "event" ) {
14998			this._setupEvents( value );
14999		}
15000
15001		if ( key === "heightStyle" ) {
15002			this._setupHeightStyle( value );
15003		}
15004	},
15005
15006	_sanitizeSelector: function( hash ) {
15007		return hash ? hash.replace( /[!"$%&'()*+,.\/:;<=>?@\[\]\^`{|}~]/g, "\\$&" ) : "";
15008	},
15009
15010	refresh: function() {
15011		var options = this.options,
15012			lis = this.tablist.children( ":has(a[href])" );
15013
15014		// Get disabled tabs from class attribute from HTML
15015		// this will get converted to a boolean if needed in _refresh()
15016		options.disabled = $.map( lis.filter( ".ui-state-disabled" ), function( tab ) {
15017			return lis.index( tab );
15018		} );
15019
15020		this._processTabs();
15021
15022		// Was collapsed or no tabs
15023		if ( options.active === false || !this.anchors.length ) {
15024			options.active = false;
15025			this.active = $();
15026
15027		// was active, but active tab is gone
15028		} else if ( this.active.length && !$.contains( this.tablist[ 0 ], this.active[ 0 ] ) ) {
15029
15030			// all remaining tabs are disabled
15031			if ( this.tabs.length === options.disabled.length ) {
15032				options.active = false;
15033				this.active = $();
15034
15035			// activate previous tab
15036			} else {
15037				this._activate( this._findNextTab( Math.max( 0, options.active - 1 ), false ) );
15038			}
15039
15040		// was active, active tab still exists
15041		} else {
15042
15043			// make sure active index is correct
15044			options.active = this.tabs.index( this.active );
15045		}
15046
15047		this._refresh();
15048	},
15049
15050	_refresh: function() {
15051		this._setOptionDisabled( this.options.disabled );
15052		this._setupEvents( this.options.event );
15053		this._setupHeightStyle( this.options.heightStyle );
15054
15055		this.tabs.not( this.active ).attr( {
15056			"aria-selected": "false",
15057			"aria-expanded": "false",
15058			tabIndex: -1
15059		} );
15060		this.panels.not( this._getPanelForTab( this.active ) )
15061			.hide()
15062			.attr( {
15063				"aria-hidden": "true"
15064			} );
15065
15066		// Make sure one tab is in the tab order
15067		if ( !this.active.length ) {
15068			this.tabs.eq( 0 ).attr( "tabIndex", 0 );
15069		} else {
15070			this.active
15071				.attr( {
15072					"aria-selected": "true",
15073					"aria-expanded": "true",
15074					tabIndex: 0
15075				} );
15076			this._addClass( this.active, "ui-tabs-active", "ui-state-active" );
15077			this._getPanelForTab( this.active )
15078				.show()
15079				.attr( {
15080					"aria-hidden": "false"
15081				} );
15082		}
15083	},
15084
15085	_processTabs: function() {
15086		var that = this,
15087			prevTabs = this.tabs,
15088			prevAnchors = this.anchors,
15089			prevPanels = this.panels;
15090
15091		this.tablist = this._getList().attr( "role", "tablist" );
15092		this._addClass( this.tablist, "ui-tabs-nav",
15093			"ui-helper-reset ui-helper-clearfix ui-widget-header" );
15094
15095		// Prevent users from focusing disabled tabs via click
15096		this.tablist
15097			.on( "mousedown" + this.eventNamespace, "> li", function( event ) {
15098				if ( $( this ).is( ".ui-state-disabled" ) ) {
15099					event.preventDefault();
15100				}
15101			} )
15102
15103			// Support: IE <9
15104			// Preventing the default action in mousedown doesn't prevent IE
15105			// from focusing the element, so if the anchor gets focused, blur.
15106			// We don't have to worry about focusing the previously focused
15107			// element since clicking on a non-focusable element should focus
15108			// the body anyway.
15109			.on( "focus" + this.eventNamespace, ".ui-tabs-anchor", function() {
15110				if ( $( this ).closest( "li" ).is( ".ui-state-disabled" ) ) {
15111					this.blur();
15112				}
15113			} );
15114
15115		this.tabs = this.tablist.find( "> li:has(a[href])" )
15116			.attr( {
15117				role: "tab",
15118				tabIndex: -1
15119			} );
15120		this._addClass( this.tabs, "ui-tabs-tab", "ui-state-default" );
15121
15122		this.anchors = this.tabs.map( function() {
15123			return $( "a", this )[ 0 ];
15124		} )
15125			.attr( {
15126				role: "presentation",
15127				tabIndex: -1
15128			} );
15129		this._addClass( this.anchors, "ui-tabs-anchor" );
15130
15131		this.panels = $();
15132
15133		this.anchors.each( function( i, anchor ) {
15134			var selector, panel, panelId,
15135				anchorId = $( anchor ).uniqueId().attr( "id" ),
15136				tab = $( anchor ).closest( "li" ),
15137				originalAriaControls = tab.attr( "aria-controls" );
15138
15139			// Inline tab
15140			if ( that._isLocal( anchor ) ) {
15141				selector = anchor.hash;
15142				panelId = selector.substring( 1 );
15143				panel = that.element.find( that._sanitizeSelector( selector ) );
15144
15145			// remote tab
15146			} else {
15147
15148				// If the tab doesn't already have aria-controls,
15149				// generate an id by using a throw-away element
15150				panelId = tab.attr( "aria-controls" ) || $( {} ).uniqueId()[ 0 ].id;
15151				selector = "#" + panelId;
15152				panel = that.element.find( selector );
15153				if ( !panel.length ) {
15154					panel = that._createPanel( panelId );
15155					panel.insertAfter( that.panels[ i - 1 ] || that.tablist );
15156				}
15157				panel.attr( "aria-live", "polite" );
15158			}
15159
15160			if ( panel.length ) {
15161				that.panels = that.panels.add( panel );
15162			}
15163			if ( originalAriaControls ) {
15164				tab.data( "ui-tabs-aria-controls", originalAriaControls );
15165			}
15166			tab.attr( {
15167				"aria-controls": panelId,
15168				"aria-labelledby": anchorId
15169			} );
15170			panel.attr( "aria-labelledby", anchorId );
15171		} );
15172
15173		this.panels.attr( "role", "tabpanel" );
15174		this._addClass( this.panels, "ui-tabs-panel", "ui-widget-content" );
15175
15176		// Avoid memory leaks (#10056)
15177		if ( prevTabs ) {
15178			this._off( prevTabs.not( this.tabs ) );
15179			this._off( prevAnchors.not( this.anchors ) );
15180			this._off( prevPanels.not( this.panels ) );
15181		}
15182	},
15183
15184	// Allow overriding how to find the list for rare usage scenarios (#7715)
15185	_getList: function() {
15186		return this.tablist || this.element.find( "ol, ul" ).eq( 0 );
15187	},
15188
15189	_createPanel: function( id ) {
15190		return $( "<div>" )
15191			.attr( "id", id )
15192			.data( "ui-tabs-destroy", true );
15193	},
15194
15195	_setOptionDisabled: function( disabled ) {
15196		var currentItem, li, i;
15197
15198		if ( $.isArray( disabled ) ) {
15199			if ( !disabled.length ) {
15200				disabled = false;
15201			} else if ( disabled.length === this.anchors.length ) {
15202				disabled = true;
15203			}
15204		}
15205
15206		// Disable tabs
15207		for ( i = 0; ( li = this.tabs[ i ] ); i++ ) {
15208			currentItem = $( li );
15209			if ( disabled === true || $.inArray( i, disabled ) !== -1 ) {
15210				currentItem.attr( "aria-disabled", "true" );
15211				this._addClass( currentItem, null, "ui-state-disabled" );
15212			} else {
15213				currentItem.removeAttr( "aria-disabled" );
15214				this._removeClass( currentItem, null, "ui-state-disabled" );
15215			}
15216		}
15217
15218		this.options.disabled = disabled;
15219
15220		this._toggleClass( this.widget(), this.widgetFullName + "-disabled", null,
15221			disabled === true );
15222	},
15223
15224	_setupEvents: function( event ) {
15225		var events = {};
15226		if ( event ) {
15227			$.each( event.split( " " ), function( index, eventName ) {
15228				events[ eventName ] = "_eventHandler";
15229			} );
15230		}
15231
15232		this._off( this.anchors.add( this.tabs ).add( this.panels ) );
15233
15234		// Always prevent the default action, even when disabled
15235		this._on( true, this.anchors, {
15236			click: function( event ) {
15237				event.preventDefault();
15238			}
15239		} );
15240		this._on( this.anchors, events );
15241		this._on( this.tabs, { keydown: "_tabKeydown" } );
15242		this._on( this.panels, { keydown: "_panelKeydown" } );
15243
15244		this._focusable( this.tabs );
15245		this._hoverable( this.tabs );
15246	},
15247
15248	_setupHeightStyle: function( heightStyle ) {
15249		var maxHeight,
15250			parent = this.element.parent();
15251
15252		if ( heightStyle === "fill" ) {
15253			maxHeight = parent.height();
15254			maxHeight -= this.element.outerHeight() - this.element.height();
15255
15256			this.element.siblings( ":visible" ).each( function() {
15257				var elem = $( this ),
15258					position = elem.css( "position" );
15259
15260				if ( position === "absolute" || position === "fixed" ) {
15261					return;
15262				}
15263				maxHeight -= elem.outerHeight( true );
15264			} );
15265
15266			this.element.children().not( this.panels ).each( function() {
15267				maxHeight -= $( this ).outerHeight( true );
15268			} );
15269
15270			this.panels.each( function() {
15271				$( this ).height( Math.max( 0, maxHeight -
15272					$( this ).innerHeight() + $( this ).height() ) );
15273			} )
15274				.css( "overflow", "auto" );
15275		} else if ( heightStyle === "auto" ) {
15276			maxHeight = 0;
15277			this.panels.each( function() {
15278				maxHeight = Math.max( maxHeight, $( this ).height( "" ).height() );
15279			} ).height( maxHeight );
15280		}
15281	},
15282
15283	_eventHandler: function( event ) {
15284		var options = this.options,
15285			active = this.active,
15286			anchor = $( event.currentTarget ),
15287			tab = anchor.closest( "li" ),
15288			clickedIsActive = tab[ 0 ] === active[ 0 ],
15289			collapsing = clickedIsActive && options.collapsible,
15290			toShow = collapsing ? $() : this._getPanelForTab( tab ),
15291			toHide = !active.length ? $() : this._getPanelForTab( active ),
15292			eventData = {
15293				oldTab: active,
15294				oldPanel: toHide,
15295				newTab: collapsing ? $() : tab,
15296				newPanel: toShow
15297			};
15298
15299		event.preventDefault();
15300
15301		if ( tab.hasClass( "ui-state-disabled" ) ||
15302
15303				// tab is already loading
15304				tab.hasClass( "ui-tabs-loading" ) ||
15305
15306				// can't switch durning an animation
15307				this.running ||
15308
15309				// click on active header, but not collapsible
15310				( clickedIsActive && !options.collapsible ) ||
15311
15312				// allow canceling activation
15313				( this._trigger( "beforeActivate", event, eventData ) === false ) ) {
15314			return;
15315		}
15316
15317		options.active = collapsing ? false : this.tabs.index( tab );
15318
15319		this.active = clickedIsActive ? $() : tab;
15320		if ( this.xhr ) {
15321			this.xhr.abort();
15322		}
15323
15324		if ( !toHide.length && !toShow.length ) {
15325			$.error( "jQuery UI Tabs: Mismatching fragment identifier." );
15326		}
15327
15328		if ( toShow.length ) {
15329			this.load( this.tabs.index( tab ), event );
15330		}
15331		this._toggle( event, eventData );
15332	},
15333
15334	// Handles show/hide for selecting tabs
15335	_toggle: function( event, eventData ) {
15336		var that = this,
15337			toShow = eventData.newPanel,
15338			toHide = eventData.oldPanel;
15339
15340		this.running = true;
15341
15342		function complete() {
15343			that.running = false;
15344			that._trigger( "activate", event, eventData );
15345		}
15346
15347		function show() {
15348			that._addClass( eventData.newTab.closest( "li" ), "ui-tabs-active", "ui-state-active" );
15349
15350			if ( toShow.length && that.options.show ) {
15351				that._show( toShow, that.options.show, complete );
15352			} else {
15353				toShow.show();
15354				complete();
15355			}
15356		}
15357
15358		// Start out by hiding, then showing, then completing
15359		if ( toHide.length && this.options.hide ) {
15360			this._hide( toHide, this.options.hide, function() {
15361				that._removeClass( eventData.oldTab.closest( "li" ),
15362					"ui-tabs-active", "ui-state-active" );
15363				show();
15364			} );
15365		} else {
15366			this._removeClass( eventData.oldTab.closest( "li" ),
15367				"ui-tabs-active", "ui-state-active" );
15368			toHide.hide();
15369			show();
15370		}
15371
15372		toHide.attr( "aria-hidden", "true" );
15373		eventData.oldTab.attr( {
15374			"aria-selected": "false",
15375			"aria-expanded": "false"
15376		} );
15377
15378		// If we're switching tabs, remove the old tab from the tab order.
15379		// If we're opening from collapsed state, remove the previous tab from the tab order.
15380		// If we're collapsing, then keep the collapsing tab in the tab order.
15381		if ( toShow.length && toHide.length ) {
15382			eventData.oldTab.attr( "tabIndex", -1 );
15383		} else if ( toShow.length ) {
15384			this.tabs.filter( function() {
15385				return $( this ).attr( "tabIndex" ) === 0;
15386			} )
15387				.attr( "tabIndex", -1 );
15388		}
15389
15390		toShow.attr( "aria-hidden", "false" );
15391		eventData.newTab.attr( {
15392			"aria-selected": "true",
15393			"aria-expanded": "true",
15394			tabIndex: 0
15395		} );
15396	},
15397
15398	_activate: function( index ) {
15399		var anchor,
15400			active = this._findActive( index );
15401
15402		// Trying to activate the already active panel
15403		if ( active[ 0 ] === this.active[ 0 ] ) {
15404			return;
15405		}
15406
15407		// Trying to collapse, simulate a click on the current active header
15408		if ( !active.length ) {
15409			active = this.active;
15410		}
15411
15412		anchor = active.find( ".ui-tabs-anchor" )[ 0 ];
15413		this._eventHandler( {
15414			target: anchor,
15415			currentTarget: anchor,
15416			preventDefault: $.noop
15417		} );
15418	},
15419
15420	_findActive: function( index ) {
15421		return index === false ? $() : this.tabs.eq( index );
15422	},
15423
15424	_getIndex: function( index ) {
15425
15426		// meta-function to give users option to provide a href string instead of a numerical index.
15427		if ( typeof index === "string" ) {
15428			index = this.anchors.index( this.anchors.filter( "[href$='" +
15429				$.ui.escapeSelector( index ) + "']" ) );
15430		}
15431
15432		return index;
15433	},
15434
15435	_destroy: function() {
15436		if ( this.xhr ) {
15437			this.xhr.abort();
15438		}
15439
15440		this.tablist
15441			.removeAttr( "role" )
15442			.off( this.eventNamespace );
15443
15444		this.anchors
15445			.removeAttr( "role tabIndex" )
15446			.removeUniqueId();
15447
15448		this.tabs.add( this.panels ).each( function() {
15449			if ( $.data( this, "ui-tabs-destroy" ) ) {
15450				$( this ).remove();
15451			} else {
15452				$( this ).removeAttr( "role tabIndex " +
15453					"aria-live aria-busy aria-selected aria-labelledby aria-hidden aria-expanded" );
15454			}
15455		} );
15456
15457		this.tabs.each( function() {
15458			var li = $( this ),
15459				prev = li.data( "ui-tabs-aria-controls" );
15460			if ( prev ) {
15461				li
15462					.attr( "aria-controls", prev )
15463					.removeData( "ui-tabs-aria-controls" );
15464			} else {
15465				li.removeAttr( "aria-controls" );
15466			}
15467		} );
15468
15469		this.panels.show();
15470
15471		if ( this.options.heightStyle !== "content" ) {
15472			this.panels.css( "height", "" );
15473		}
15474	},
15475
15476	enable: function( index ) {
15477		var disabled = this.options.disabled;
15478		if ( disabled === false ) {
15479			return;
15480		}
15481
15482		if ( index === undefined ) {
15483			disabled = false;
15484		} else {
15485			index = this._getIndex( index );
15486			if ( $.isArray( disabled ) ) {
15487				disabled = $.map( disabled, function( num ) {
15488					return num !== index ? num : null;
15489				} );
15490			} else {
15491				disabled = $.map( this.tabs, function( li, num ) {
15492					return num !== index ? num : null;
15493				} );
15494			}
15495		}
15496		this._setOptionDisabled( disabled );
15497	},
15498
15499	disable: function( index ) {
15500		var disabled = this.options.disabled;
15501		if ( disabled === true ) {
15502			return;
15503		}
15504
15505		if ( index === undefined ) {
15506			disabled = true;
15507		} else {
15508			index = this._getIndex( index );
15509			if ( $.inArray( index, disabled ) !== -1 ) {
15510				return;
15511			}
15512			if ( $.isArray( disabled ) ) {
15513				disabled = $.merge( [ index ], disabled ).sort();
15514			} else {
15515				disabled = [ index ];
15516			}
15517		}
15518		this._setOptionDisabled( disabled );
15519	},
15520
15521	load: function( index, event ) {
15522		index = this._getIndex( index );
15523		var that = this,
15524			tab = this.tabs.eq( index ),
15525			anchor = tab.find( ".ui-tabs-anchor" ),
15526			panel = this._getPanelForTab( tab ),
15527			eventData = {
15528				tab: tab,
15529				panel: panel
15530			},
15531			complete = function( jqXHR, status ) {
15532				if ( status === "abort" ) {
15533					that.panels.stop( false, true );
15534				}
15535
15536				that._removeClass( tab, "ui-tabs-loading" );
15537				panel.removeAttr( "aria-busy" );
15538
15539				if ( jqXHR === that.xhr ) {
15540					delete that.xhr;
15541				}
15542			};
15543
15544		// Not remote
15545		if ( this._isLocal( anchor[ 0 ] ) ) {
15546			return;
15547		}
15548
15549		this.xhr = $.ajax( this._ajaxSettings( anchor, event, eventData ) );
15550
15551		// Support: jQuery <1.8
15552		// jQuery <1.8 returns false if the request is canceled in beforeSend,
15553		// but as of 1.8, $.ajax() always returns a jqXHR object.
15554		if ( this.xhr && this.xhr.statusText !== "canceled" ) {
15555			this._addClass( tab, "ui-tabs-loading" );
15556			panel.attr( "aria-busy", "true" );
15557
15558			this.xhr
15559				.done( function( response, status, jqXHR ) {
15560
15561					// support: jQuery <1.8
15562					// http://bugs.jquery.com/ticket/11778
15563					setTimeout( function() {
15564						panel.html( response );
15565						that._trigger( "load", event, eventData );
15566
15567						complete( jqXHR, status );
15568					}, 1 );
15569				} )
15570				.fail( function( jqXHR, status ) {
15571
15572					// support: jQuery <1.8
15573					// http://bugs.jquery.com/ticket/11778
15574					setTimeout( function() {
15575						complete( jqXHR, status );
15576					}, 1 );
15577				} );
15578		}
15579	},
15580
15581	_ajaxSettings: function( anchor, event, eventData ) {
15582		var that = this;
15583		return {
15584
15585			// Support: IE <11 only
15586			// Strip any hash that exists to prevent errors with the Ajax request
15587			url: anchor.attr( "href" ).replace( /#.*$/, "" ),
15588			beforeSend: function( jqXHR, settings ) {
15589				return that._trigger( "beforeLoad", event,
15590					$.extend( { jqXHR: jqXHR, ajaxSettings: settings }, eventData ) );
15591			}
15592		};
15593	},
15594
15595	_getPanelForTab: function( tab ) {
15596		var id = $( tab ).attr( "aria-controls" );
15597		return this.element.find( this._sanitizeSelector( "#" + id ) );
15598	}
15599} );
15600
15601// DEPRECATED
15602// TODO: Switch return back to widget declaration at top of file when this is removed
15603if ( $.uiBackCompat !== false ) {
15604
15605	// Backcompat for ui-tab class (now ui-tabs-tab)
15606	$.widget( "ui.tabs", $.ui.tabs, {
15607		_processTabs: function() {
15608			this._superApply( arguments );
15609			this._addClass( this.tabs, "ui-tab" );
15610		}
15611	} );
15612}
15613
15614var widgetsTabs = $.ui.tabs;
15615
15616
15617/*!
15618 * jQuery UI Tooltip 1.12.1
15619 * http://jqueryui.com
15620 *
15621 * Copyright jQuery Foundation and other contributors
15622 * Released under the MIT license.
15623 * http://jquery.org/license
15624 */
15625
15626//>>label: Tooltip
15627//>>group: Widgets
15628//>>description: Shows additional information for any element on hover or focus.
15629//>>docs: http://api.jqueryui.com/tooltip/
15630//>>demos: http://jqueryui.com/tooltip/
15631//>>css.structure: ../../themes/base/core.css
15632//>>css.structure: ../../themes/base/tooltip.css
15633//>>css.theme: ../../themes/base/theme.css
15634
15635
15636
15637$.widget( "ui.tooltip", {
15638	version: "1.12.1",
15639	options: {
15640		classes: {
15641			"ui-tooltip": "ui-corner-all ui-widget-shadow"
15642		},
15643		content: function() {
15644
15645			// support: IE<9, Opera in jQuery <1.7
15646			// .text() can't accept undefined, so coerce to a string
15647			var title = $( this ).attr( "title" ) || "";
15648
15649			// Escape title, since we're going from an attribute to raw HTML
15650			return $( "<a>" ).text( title ).html();
15651		},
15652		hide: true,
15653
15654		// Disabled elements have inconsistent behavior across browsers (#8661)
15655		items: "[title]:not([disabled])",
15656		position: {
15657			my: "left top+15",
15658			at: "left bottom",
15659			collision: "flipfit flip"
15660		},
15661		show: true,
15662		track: false,
15663
15664		// Callbacks
15665		close: null,
15666		open: null
15667	},
15668
15669	_addDescribedBy: function( elem, id ) {
15670		var describedby = ( elem.attr( "aria-describedby" ) || "" ).split( /\s+/ );
15671		describedby.push( id );
15672		elem
15673			.data( "ui-tooltip-id", id )
15674			.attr( "aria-describedby", $.trim( describedby.join( " " ) ) );
15675	},
15676
15677	_removeDescribedBy: function( elem ) {
15678		var id = elem.data( "ui-tooltip-id" ),
15679			describedby = ( elem.attr( "aria-describedby" ) || "" ).split( /\s+/ ),
15680			index = $.inArray( id, describedby );
15681
15682		if ( index !== -1 ) {
15683			describedby.splice( index, 1 );
15684		}
15685
15686		elem.removeData( "ui-tooltip-id" );
15687		describedby = $.trim( describedby.join( " " ) );
15688		if ( describedby ) {
15689			elem.attr( "aria-describedby", describedby );
15690		} else {
15691			elem.removeAttr( "aria-describedby" );
15692		}
15693	},
15694
15695	_create: function() {
15696		this._on( {
15697			mouseover: "open",
15698			focusin: "open"
15699		} );
15700
15701		// IDs of generated tooltips, needed for destroy
15702		this.tooltips = {};
15703
15704		// IDs of parent tooltips where we removed the title attribute
15705		this.parents = {};
15706
15707		// Append the aria-live region so tooltips announce correctly
15708		this.liveRegion = $( "<div>" )
15709			.attr( {
15710				role: "log",
15711				"aria-live": "assertive",
15712				"aria-relevant": "additions"
15713			} )
15714			.appendTo( this.document[ 0 ].body );
15715		this._addClass( this.liveRegion, null, "ui-helper-hidden-accessible" );
15716
15717		this.disabledTitles = $( [] );
15718	},
15719
15720	_setOption: function( key, value ) {
15721		var that = this;
15722
15723		this._super( key, value );
15724
15725		if ( key === "content" ) {
15726			$.each( this.tooltips, function( id, tooltipData ) {
15727				that._updateContent( tooltipData.element );
15728			} );
15729		}
15730	},
15731
15732	_setOptionDisabled: function( value ) {
15733		this[ value ? "_disable" : "_enable" ]();
15734	},
15735
15736	_disable: function() {
15737		var that = this;
15738
15739		// Close open tooltips
15740		$.each( this.tooltips, function( id, tooltipData ) {
15741			var event = $.Event( "blur" );
15742			event.target = event.currentTarget = tooltipData.element[ 0 ];
15743			that.close( event, true );
15744		} );
15745
15746		// Remove title attributes to prevent native tooltips
15747		this.disabledTitles = this.disabledTitles.add(
15748			this.element.find( this.options.items ).addBack()
15749				.filter( function() {
15750					var element = $( this );
15751					if ( element.is( "[title]" ) ) {
15752						return element
15753							.data( "ui-tooltip-title", element.attr( "title" ) )
15754							.removeAttr( "title" );
15755					}
15756				} )
15757		);
15758	},
15759
15760	_enable: function() {
15761
15762		// restore title attributes
15763		this.disabledTitles.each( function() {
15764			var element = $( this );
15765			if ( element.data( "ui-tooltip-title" ) ) {
15766				element.attr( "title", element.data( "ui-tooltip-title" ) );
15767			}
15768		} );
15769		this.disabledTitles = $( [] );
15770	},
15771
15772	open: function( event ) {
15773		var that = this,
15774			target = $( event ? event.target : this.element )
15775
15776				// we need closest here due to mouseover bubbling,
15777				// but always pointing at the same event target
15778				.closest( this.options.items );
15779
15780		// No element to show a tooltip for or the tooltip is already open
15781		if ( !target.length || target.data( "ui-tooltip-id" ) ) {
15782			return;
15783		}
15784
15785		if ( target.attr( "title" ) ) {
15786			target.data( "ui-tooltip-title", target.attr( "title" ) );
15787		}
15788
15789		target.data( "ui-tooltip-open", true );
15790
15791		// Kill parent tooltips, custom or native, for hover
15792		if ( event && event.type === "mouseover" ) {
15793			target.parents().each( function() {
15794				var parent = $( this ),
15795					blurEvent;
15796				if ( parent.data( "ui-tooltip-open" ) ) {
15797					blurEvent = $.Event( "blur" );
15798					blurEvent.target = blurEvent.currentTarget = this;
15799					that.close( blurEvent, true );
15800				}
15801				if ( parent.attr( "title" ) ) {
15802					parent.uniqueId();
15803					that.parents[ this.id ] = {
15804						element: this,
15805						title: parent.attr( "title" )
15806					};
15807					parent.attr( "title", "" );
15808				}
15809			} );
15810		}
15811
15812		this._registerCloseHandlers( event, target );
15813		this._updateContent( target, event );
15814	},
15815
15816	_updateContent: function( target, event ) {
15817		var content,
15818			contentOption = this.options.content,
15819			that = this,
15820			eventType = event ? event.type : null;
15821
15822		if ( typeof contentOption === "string" || contentOption.nodeType ||
15823				contentOption.jquery ) {
15824			return this._open( event, target, contentOption );
15825		}
15826
15827		content = contentOption.call( target[ 0 ], function( response ) {
15828
15829			// IE may instantly serve a cached response for ajax requests
15830			// delay this call to _open so the other call to _open runs first
15831			that._delay( function() {
15832
15833				// Ignore async response if tooltip was closed already
15834				if ( !target.data( "ui-tooltip-open" ) ) {
15835					return;
15836				}
15837
15838				// JQuery creates a special event for focusin when it doesn't
15839				// exist natively. To improve performance, the native event
15840				// object is reused and the type is changed. Therefore, we can't
15841				// rely on the type being correct after the event finished
15842				// bubbling, so we set it back to the previous value. (#8740)
15843				if ( event ) {
15844					event.type = eventType;
15845				}
15846				this._open( event, target, response );
15847			} );
15848		} );
15849		if ( content ) {
15850			this._open( event, target, content );
15851		}
15852	},
15853
15854	_open: function( event, target, content ) {
15855		var tooltipData, tooltip, delayedShow, a11yContent,
15856			positionOption = $.extend( {}, this.options.position );
15857
15858		if ( !content ) {
15859			return;
15860		}
15861
15862		// Content can be updated multiple times. If the tooltip already
15863		// exists, then just update the content and bail.
15864		tooltipData = this._find( target );
15865		if ( tooltipData ) {
15866			tooltipData.tooltip.find( ".ui-tooltip-content" ).html( content );
15867			return;
15868		}
15869
15870		// If we have a title, clear it to prevent the native tooltip
15871		// we have to check first to avoid defining a title if none exists
15872		// (we don't want to cause an element to start matching [title])
15873		//
15874		// We use removeAttr only for key events, to allow IE to export the correct
15875		// accessible attributes. For mouse events, set to empty string to avoid
15876		// native tooltip showing up (happens only when removing inside mouseover).
15877		if ( target.is( "[title]" ) ) {
15878			if ( event && event.type === "mouseover" ) {
15879				target.attr( "title", "" );
15880			} else {
15881				target.removeAttr( "title" );
15882			}
15883		}
15884
15885		tooltipData = this._tooltip( target );
15886		tooltip = tooltipData.tooltip;
15887		this._addDescribedBy( target, tooltip.attr( "id" ) );
15888		tooltip.find( ".ui-tooltip-content" ).html( content );
15889
15890		// Support: Voiceover on OS X, JAWS on IE <= 9
15891		// JAWS announces deletions even when aria-relevant="additions"
15892		// Voiceover will sometimes re-read the entire log region's contents from the beginning
15893		this.liveRegion.children().hide();
15894		a11yContent = $( "<div>" ).html( tooltip.find( ".ui-tooltip-content" ).html() );
15895		a11yContent.removeAttr( "name" ).find( "[name]" ).removeAttr( "name" );
15896		a11yContent.removeAttr( "id" ).find( "[id]" ).removeAttr( "id" );
15897		a11yContent.appendTo( this.liveRegion );
15898
15899		function position( event ) {
15900			positionOption.of = event;
15901			if ( tooltip.is( ":hidden" ) ) {
15902				return;
15903			}
15904			tooltip.position( positionOption );
15905		}
15906		if ( this.options.track && event && /^mouse/.test( event.type ) ) {
15907			this._on( this.document, {
15908				mousemove: position
15909			} );
15910
15911			// trigger once to override element-relative positioning
15912			position( event );
15913		} else {
15914			tooltip.position( $.extend( {
15915				of: target
15916			}, this.options.position ) );
15917		}
15918
15919		tooltip.hide();
15920
15921		this._show( tooltip, this.options.show );
15922
15923		// Handle tracking tooltips that are shown with a delay (#8644). As soon
15924		// as the tooltip is visible, position the tooltip using the most recent
15925		// event.
15926		// Adds the check to add the timers only when both delay and track options are set (#14682)
15927		if ( this.options.track && this.options.show && this.options.show.delay ) {
15928			delayedShow = this.delayedShow = setInterval( function() {
15929				if ( tooltip.is( ":visible" ) ) {
15930					position( positionOption.of );
15931					clearInterval( delayedShow );
15932				}
15933			}, $.fx.interval );
15934		}
15935
15936		this._trigger( "open", event, { tooltip: tooltip } );
15937	},
15938
15939	_registerCloseHandlers: function( event, target ) {
15940		var events = {
15941			keyup: function( event ) {
15942				if ( event.keyCode === $.ui.keyCode.ESCAPE ) {
15943					var fakeEvent = $.Event( event );
15944					fakeEvent.currentTarget = target[ 0 ];
15945					this.close( fakeEvent, true );
15946				}
15947			}
15948		};
15949
15950		// Only bind remove handler for delegated targets. Non-delegated
15951		// tooltips will handle this in destroy.
15952		if ( target[ 0 ] !== this.element[ 0 ] ) {
15953			events.remove = function() {
15954				this._removeTooltip( this._find( target ).tooltip );
15955			};
15956		}
15957
15958		if ( !event || event.type === "mouseover" ) {
15959			events.mouseleave = "close";
15960		}
15961		if ( !event || event.type === "focusin" ) {
15962			events.focusout = "close";
15963		}
15964		this._on( true, target, events );
15965	},
15966
15967	close: function( event ) {
15968		var tooltip,
15969			that = this,
15970			target = $( event ? event.currentTarget : this.element ),
15971			tooltipData = this._find( target );
15972
15973		// The tooltip may already be closed
15974		if ( !tooltipData ) {
15975
vendor: 17,492 bytes, lines 15976-16676
15976			// We set ui-tooltip-open immediately upon open (in open()), but only set the
15977			// additional data once there's actually content to show (in _open()). So even if the
15978			// tooltip doesn't have full data, we always remove ui-tooltip-open in case we're in
15979			// the period between open() and _open().
15980			target.removeData( "ui-tooltip-open" );
15981			return;
15982		}
15983
15984		tooltip = tooltipData.tooltip;
15985
15986		// Disabling closes the tooltip, so we need to track when we're closing
15987		// to avoid an infinite loop in case the tooltip becomes disabled on close
15988		if ( tooltipData.closing ) {
15989			return;
15990		}
15991
15992		// Clear the interval for delayed tracking tooltips
15993		clearInterval( this.delayedShow );
15994
15995		// Only set title if we had one before (see comment in _open())
15996		// If the title attribute has changed since open(), don't restore
15997		if ( target.data( "ui-tooltip-title" ) && !target.attr( "title" ) ) {
15998			target.attr( "title", target.data( "ui-tooltip-title" ) );
15999		}
16000
16001		this._removeDescribedBy( target );
16002
16003		tooltipData.hiding = true;
16004		tooltip.stop( true );
16005		this._hide( tooltip, this.options.hide, function() {
16006			that._removeTooltip( $( this ) );
16007		} );
16008
16009		target.removeData( "ui-tooltip-open" );
16010		this._off( target, "mouseleave focusout keyup" );
16011
16012		// Remove 'remove' binding only on delegated targets
16013		if ( target[ 0 ] !== this.element[ 0 ] ) {
16014			this._off( target, "remove" );
16015		}
16016		this._off( this.document, "mousemove" );
16017
16018		if ( event && event.type === "mouseleave" ) {
16019			$.each( this.parents, function( id, parent ) {
16020				$( parent.element ).attr( "title", parent.title );
16021				delete that.parents[ id ];
16022			} );
16023		}
16024
16025		tooltipData.closing = true;
16026		this._trigger( "close", event, { tooltip: tooltip } );
16027		if ( !tooltipData.hiding ) {
16028			tooltipData.closing = false;
16029		}
16030	},
16031
16032	_tooltip: function( element ) {
16033		var tooltip = $( "<div>" ).attr( "role", "tooltip" ),
16034			content = $( "<div>" ).appendTo( tooltip ),
16035			id = tooltip.uniqueId().attr( "id" );
16036
16037		this._addClass( content, "ui-tooltip-content" );
16038		this._addClass( tooltip, "ui-tooltip", "ui-widget ui-widget-content" );
16039
16040		tooltip.appendTo( this._appendTo( element ) );
16041
16042		return this.tooltips[ id ] = {
16043			element: element,
16044			tooltip: tooltip
16045		};
16046	},
16047
16048	_find: function( target ) {
16049		var id = target.data( "ui-tooltip-id" );
16050		return id ? this.tooltips[ id ] : null;
16051	},
16052
16053	_removeTooltip: function( tooltip ) {
16054		tooltip.remove();
16055		delete this.tooltips[ tooltip.attr( "id" ) ];
16056	},
16057
16058	_appendTo: function( target ) {
16059		var element = target.closest( ".ui-front, dialog" );
16060
16061		if ( !element.length ) {
16062			element = this.document[ 0 ].body;
16063		}
16064
16065		return element;
16066	},
16067
16068	_destroy: function() {
16069		var that = this;
16070
16071		// Close open tooltips
16072		$.each( this.tooltips, function( id, tooltipData ) {
16073
16074			// Delegate to close method to handle common cleanup
16075			var event = $.Event( "blur" ),
16076				element = tooltipData.element;
16077			event.target = event.currentTarget = element[ 0 ];
16078			that.close( event, true );
16079
16080			// Remove immediately; destroying an open tooltip doesn't use the
16081			// hide animation
16082			$( "#" + id ).remove();
16083
16084			// Restore the title
16085			if ( element.data( "ui-tooltip-title" ) ) {
16086
16087				// If the title attribute has changed since open(), don't restore
16088				if ( !element.attr( "title" ) ) {
16089					element.attr( "title", element.data( "ui-tooltip-title" ) );
16090				}
16091				element.removeData( "ui-tooltip-title" );
16092			}
16093		} );
16094		this.liveRegion.remove();
16095	}
16096} );
16097
16098// DEPRECATED
16099// TODO: Switch return back to widget declaration at top of file when this is removed
16100if ( $.uiBackCompat !== false ) {
16101
16102	// Backcompat for tooltipClass option
16103	$.widget( "ui.tooltip", $.ui.tooltip, {
16104		options: {
16105			tooltipClass: null
16106		},
16107		_tooltip: function() {
16108			var tooltipData = this._superApply( arguments );
16109			if ( this.options.tooltipClass ) {
16110				tooltipData.tooltip.addClass( this.options.tooltipClass );
16111			}
16112			return tooltipData;
16113		}
16114	} );
16115}
16116
16117var widgetsTooltip = $.ui.tooltip;
16118
16119
16120/*!
16121 * jQuery UI Effects 1.12.1
16122 * http://jqueryui.com
16123 *
16124 * Copyright jQuery Foundation and other contributors
16125 * Released under the MIT license.
16126 * http://jquery.org/license
16127 */
16128
16129//>>label: Effects Core
16130//>>group: Effects
16131// jscs:disable maximumLineLength
16132//>>description: Extends the internal jQuery effects. Includes morphing and easing. Required by all other effects.
16133// jscs:enable maximumLineLength
16134//>>docs: http://api.jqueryui.com/category/effects-core/
16135//>>demos: http://jqueryui.com/effect/
16136
16137
16138
16139var dataSpace = "ui-effects-",
16140	dataSpaceStyle = "ui-effects-style",
16141	dataSpaceAnimated = "ui-effects-animated",
16142
16143	// Create a local jQuery because jQuery Color relies on it and the
16144	// global may not exist with AMD and a custom build (#10199)
16145	jQuery = $;
16146
16147$.effects = {
16148	effect: {}
16149};
16150
16151/*!
16152 * jQuery Color Animations v2.1.2
16153 * https://github.com/jquery/jquery-color
16154 *
16155 * Copyright 2014 jQuery Foundation and other contributors
16156 * Released under the MIT license.
16157 * http://jquery.org/license
16158 *
16159 * Date: Wed Jan 16 08:47:09 2013 -0600
16160 */
16161( function( jQuery, undefined ) {
16162
16163	var stepHooks = "backgroundColor borderBottomColor borderLeftColor borderRightColor " +
16164		"borderTopColor color columnRuleColor outlineColor textDecorationColor textEmphasisColor",
16165
16166	// Plusequals test for += 100 -= 100
16167	rplusequals = /^([\-+])=\s*(\d+\.?\d*)/,
16168
16169	// A set of RE's that can match strings and generate color tuples.
16170	stringParsers = [ {
16171			re: /rgba?\(\s*(\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(\d{1,3})\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/,
16172			parse: function( execResult ) {
16173				return [
16174					execResult[ 1 ],
16175					execResult[ 2 ],
16176					execResult[ 3 ],
16177					execResult[ 4 ]
16178				];
16179			}
16180		}, {
16181			re: /rgba?\(\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/,
16182			parse: function( execResult ) {
16183				return [
16184					execResult[ 1 ] * 2.55,
16185					execResult[ 2 ] * 2.55,
16186					execResult[ 3 ] * 2.55,
16187					execResult[ 4 ]
16188				];
16189			}
16190		}, {
16191
16192			// This regex ignores A-F because it's compared against an already lowercased string
16193			re: /#([a-f0-9]{2})([a-f0-9]{2})([a-f0-9]{2})/,
16194			parse: function( execResult ) {
16195				return [
16196					parseInt( execResult[ 1 ], 16 ),
16197					parseInt( execResult[ 2 ], 16 ),
16198					parseInt( execResult[ 3 ], 16 )
16199				];
16200			}
16201		}, {
16202
16203			// This regex ignores A-F because it's compared against an already lowercased string
16204			re: /#([a-f0-9])([a-f0-9])([a-f0-9])/,
16205			parse: function( execResult ) {
16206				return [
16207					parseInt( execResult[ 1 ] + execResult[ 1 ], 16 ),
16208					parseInt( execResult[ 2 ] + execResult[ 2 ], 16 ),
16209					parseInt( execResult[ 3 ] + execResult[ 3 ], 16 )
16210				];
16211			}
16212		}, {
16213			re: /hsla?\(\s*(\d+(?:\.\d+)?)\s*,\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/,
16214			space: "hsla",
16215			parse: function( execResult ) {
16216				return [
16217					execResult[ 1 ],
16218					execResult[ 2 ] / 100,
16219					execResult[ 3 ] / 100,
16220					execResult[ 4 ]
16221				];
16222			}
16223		} ],
16224
16225	// JQuery.Color( )
16226	color = jQuery.Color = function( color, green, blue, alpha ) {
16227		return new jQuery.Color.fn.parse( color, green, blue, alpha );
16228	},
16229	spaces = {
16230		rgba: {
16231			props: {
16232				red: {
16233					idx: 0,
16234					type: "byte"
16235				},
16236				green: {
16237					idx: 1,
16238					type: "byte"
16239				},
16240				blue: {
16241					idx: 2,
16242					type: "byte"
16243				}
16244			}
16245		},
16246
16247		hsla: {
16248			props: {
16249				hue: {
16250					idx: 0,
16251					type: "degrees"
16252				},
16253				saturation: {
16254					idx: 1,
16255					type: "percent"
16256				},
16257				lightness: {
16258					idx: 2,
16259					type: "percent"
16260				}
16261			}
16262		}
16263	},
16264	propTypes = {
16265		"byte": {
16266			floor: true,
16267			max: 255
16268		},
16269		"percent": {
16270			max: 1
16271		},
16272		"degrees": {
16273			mod: 360,
16274			floor: true
16275		}
16276	},
16277	support = color.support = {},
16278
16279	// Element for support tests
16280	supportElem = jQuery( "<p>" )[ 0 ],
16281
16282	// Colors = jQuery.Color.names
16283	colors,
16284
16285	// Local aliases of functions called often
16286	each = jQuery.each;
16287
16288// Determine rgba support immediately
16289supportElem.style.cssText = "background-color:rgba(1,1,1,.5)";
16290support.rgba = supportElem.style.backgroundColor.indexOf( "rgba" ) > -1;
16291
16292// Define cache name and alpha properties
16293// for rgba and hsla spaces
16294each( spaces, function( spaceName, space ) {
16295	space.cache = "_" + spaceName;
16296	space.props.alpha = {
16297		idx: 3,
16298		type: "percent",
16299		def: 1
16300	};
16301} );
16302
16303function clamp( value, prop, allowEmpty ) {
16304	var type = propTypes[ prop.type ] || {};
16305
16306	if ( value == null ) {
16307		return ( allowEmpty || !prop.def ) ? null : prop.def;
16308	}
16309
16310	// ~~ is an short way of doing floor for positive numbers
16311	value = type.floor ? ~~value : parseFloat( value );
16312
16313	// IE will pass in empty strings as value for alpha,
16314	// which will hit this case
16315	if ( isNaN( value ) ) {
16316		return prop.def;
16317	}
16318
16319	if ( type.mod ) {
16320
16321		// We add mod before modding to make sure that negatives values
16322		// get converted properly: -10 -> 350
16323		return ( value + type.mod ) % type.mod;
16324	}
16325
16326	// For now all property types without mod have min and max
16327	return 0 > value ? 0 : type.max < value ? type.max : value;
16328}
16329
16330function stringParse( string ) {
16331	var inst = color(),
16332		rgba = inst._rgba = [];
16333
16334	string = string.toLowerCase();
16335
16336	each( stringParsers, function( i, parser ) {
16337		var parsed,
16338			match = parser.re.exec( string ),
16339			values = match && parser.parse( match ),
16340			spaceName = parser.space || "rgba";
16341
16342		if ( values ) {
16343			parsed = inst[ spaceName ]( values );
16344
16345			// If this was an rgba parse the assignment might happen twice
16346			// oh well....
16347			inst[ spaces[ spaceName ].cache ] = parsed[ spaces[ spaceName ].cache ];
16348			rgba = inst._rgba = parsed._rgba;
16349
16350			// Exit each( stringParsers ) here because we matched
16351			return false;
16352		}
16353	} );
16354
16355	// Found a stringParser that handled it
16356	if ( rgba.length ) {
16357
16358		// If this came from a parsed string, force "transparent" when alpha is 0
16359		// chrome, (and maybe others) return "transparent" as rgba(0,0,0,0)
16360		if ( rgba.join() === "0,0,0,0" ) {
16361			jQuery.extend( rgba, colors.transparent );
16362		}
16363		return inst;
16364	}
16365
16366	// Named colors
16367	return colors[ string ];
16368}
16369
16370color.fn = jQuery.extend( color.prototype, {
16371	parse: function( red, green, blue, alpha ) {
16372		if ( red === undefined ) {
16373			this._rgba = [ null, null, null, null ];
16374			return this;
16375		}
16376		if ( red.jquery || red.nodeType ) {
16377			red = jQuery( red ).css( green );
16378			green = undefined;
16379		}
16380
16381		var inst = this,
16382			type = jQuery.type( red ),
16383			rgba = this._rgba = [];
16384
16385		// More than 1 argument specified - assume ( red, green, blue, alpha )
16386		if ( green !== undefined ) {
16387			red = [ red, green, blue, alpha ];
16388			type = "array";
16389		}
16390
16391		if ( type === "string" ) {
16392			return this.parse( stringParse( red ) || colors._default );
16393		}
16394
16395		if ( type === "array" ) {
16396			each( spaces.rgba.props, function( key, prop ) {
16397				rgba[ prop.idx ] = clamp( red[ prop.idx ], prop );
16398			} );
16399			return this;
16400		}
16401
16402		if ( type === "object" ) {
16403			if ( red instanceof color ) {
16404				each( spaces, function( spaceName, space ) {
16405					if ( red[ space.cache ] ) {
16406						inst[ space.cache ] = red[ space.cache ].slice();
16407					}
16408				} );
16409			} else {
16410				each( spaces, function( spaceName, space ) {
16411					var cache = space.cache;
16412					each( space.props, function( key, prop ) {
16413
16414						// If the cache doesn't exist, and we know how to convert
16415						if ( !inst[ cache ] && space.to ) {
16416
16417							// If the value was null, we don't need to copy it
16418							// if the key was alpha, we don't need to copy it either
16419							if ( key === "alpha" || red[ key ] == null ) {
16420								return;
16421							}
16422							inst[ cache ] = space.to( inst._rgba );
16423						}
16424
16425						// This is the only case where we allow nulls for ALL properties.
16426						// call clamp with alwaysAllowEmpty
16427						inst[ cache ][ prop.idx ] = clamp( red[ key ], prop, true );
16428					} );
16429
16430					// Everything defined but alpha?
16431					if ( inst[ cache ] &&
16432							jQuery.inArray( null, inst[ cache ].slice( 0, 3 ) ) < 0 ) {
16433
16434						// Use the default of 1
16435						inst[ cache ][ 3 ] = 1;
16436						if ( space.from ) {
16437							inst._rgba = space.from( inst[ cache ] );
16438						}
16439					}
16440				} );
16441			}
16442			return this;
16443		}
16444	},
16445	is: function( compare ) {
16446		var is = color( compare ),
16447			same = true,
16448			inst = this;
16449
16450		each( spaces, function( _, space ) {
16451			var localCache,
16452				isCache = is[ space.cache ];
16453			if ( isCache ) {
16454				localCache = inst[ space.cache ] || space.to && space.to( inst._rgba ) || [];
16455				each( space.props, function( _, prop ) {
16456					if ( isCache[ prop.idx ] != null ) {
16457						same = ( isCache[ prop.idx ] === localCache[ prop.idx ] );
16458						return same;
16459					}
16460				} );
16461			}
16462			return same;
16463		} );
16464		return same;
16465	},
16466	_space: function() {
16467		var used = [],
16468			inst = this;
16469		each( spaces, function( spaceName, space ) {
16470			if ( inst[ space.cache ] ) {
16471				used.push( spaceName );
16472			}
16473		} );
16474		return used.pop();
16475	},
16476	transition: function( other, distance ) {
16477		var end = color( other ),
16478			spaceName = end._space(),
16479			space = spaces[ spaceName ],
16480			startColor = this.alpha() === 0 ? color( "transparent" ) : this,
16481			start = startColor[ space.cache ] || space.to( startColor._rgba ),
16482			result = start.slice();
16483
16484		end = end[ space.cache ];
16485		each( space.props, function( key, prop ) {
16486			var index = prop.idx,
16487				startValue = start[ index ],
16488				endValue = end[ index ],
16489				type = propTypes[ prop.type ] || {};
16490
16491			// If null, don't override start value
16492			if ( endValue === null ) {
16493				return;
16494			}
16495
16496			// If null - use end
16497			if ( startValue === null ) {
16498				result[ index ] = endValue;
16499			} else {
16500				if ( type.mod ) {
16501					if ( endValue - startValue > type.mod / 2 ) {
16502						startValue += type.mod;
16503					} else if ( startValue - endValue > type.mod / 2 ) {
16504						startValue -= type.mod;
16505					}
16506				}
16507				result[ index ] = clamp( ( endValue - startValue ) * distance + startValue, prop );
16508			}
16509		} );
16510		return this[ spaceName ]( result );
16511	},
16512	blend: function( opaque ) {
16513
16514		// If we are already opaque - return ourself
16515		if ( this._rgba[ 3 ] === 1 ) {
16516			return this;
16517		}
16518
16519		var rgb = this._rgba.slice(),
16520			a = rgb.pop(),
16521			blend = color( opaque )._rgba;
16522
16523		return color( jQuery.map( rgb, function( v, i ) {
16524			return ( 1 - a ) * blend[ i ] + a * v;
16525		} ) );
16526	},
16527	toRgbaString: function() {
16528		var prefix = "rgba(",
16529			rgba = jQuery.map( this._rgba, function( v, i ) {
16530				return v == null ? ( i > 2 ? 1 : 0 ) : v;
16531			} );
16532
16533		if ( rgba[ 3 ] === 1 ) {
16534			rgba.pop();
16535			prefix = "rgb(";
16536		}
16537
16538		return prefix + rgba.join() + ")";
16539	},
16540	toHslaString: function() {
16541		var prefix = "hsla(",
16542			hsla = jQuery.map( this.hsla(), function( v, i ) {
16543				if ( v == null ) {
16544					v = i > 2 ? 1 : 0;
16545				}
16546
16547				// Catch 1 and 2
16548				if ( i && i < 3 ) {
16549					v = Math.round( v * 100 ) + "%";
16550				}
16551				return v;
16552			} );
16553
16554		if ( hsla[ 3 ] === 1 ) {
16555			hsla.pop();
16556			prefix = "hsl(";
16557		}
16558		return prefix + hsla.join() + ")";
16559	},
16560	toHexString: function( includeAlpha ) {
16561		var rgba = this._rgba.slice(),
16562			alpha = rgba.pop();
16563
16564		if ( includeAlpha ) {
16565			rgba.push( ~~( alpha * 255 ) );
16566		}
16567
16568		return "#" + jQuery.map( rgba, function( v ) {
16569
16570			// Default to 0 when nulls exist
16571			v = ( v || 0 ).toString( 16 );
16572			return v.length === 1 ? "0" + v : v;
16573		} ).join( "" );
16574	},
16575	toString: function() {
16576		return this._rgba[ 3 ] === 0 ? "transparent" : this.toRgbaString();
16577	}
16578} );
16579color.fn.parse.prototype = color.fn;
16580
16581// Hsla conversions adapted from:
16582// https://code.google.com/p/maashaack/source/browse/packages/graphics/trunk/src/graphics/colors/HUE2RGB.as?r=5021
16583
16584function hue2rgb( p, q, h ) {
16585	h = ( h + 1 ) % 1;
16586	if ( h * 6 < 1 ) {
16587		return p + ( q - p ) * h * 6;
16588	}
16589	if ( h * 2 < 1 ) {
16590		return q;
16591	}
16592	if ( h * 3 < 2 ) {
16593		return p + ( q - p ) * ( ( 2 / 3 ) - h ) * 6;
16594	}
16595	return p;
16596}
16597
16598spaces.hsla.to = function( rgba ) {
16599	if ( rgba[ 0 ] == null || rgba[ 1 ] == null || rgba[ 2 ] == null ) {
16600		return [ null, null, null, rgba[ 3 ] ];
16601	}
16602	var r = rgba[ 0 ] / 255,
16603		g = rgba[ 1 ] / 255,
16604		b = rgba[ 2 ] / 255,
16605		a = rgba[ 3 ],
16606		max = Math.max( r, g, b ),
16607		min = Math.min( r, g, b ),
16608		diff = max - min,
16609		add = max + min,
16610		l = add * 0.5,
16611		h, s;
16612
16613	if ( min === max ) {
16614		h = 0;
16615	} else if ( r === max ) {
16616		h = ( 60 * ( g - b ) / diff ) + 360;
16617	} else if ( g === max ) {
16618		h = ( 60 * ( b - r ) / diff ) + 120;
16619	} else {
16620		h = ( 60 * ( r - g ) / diff ) + 240;
16621	}
16622
16623	// Chroma (diff) == 0 means greyscale which, by definition, saturation = 0%
16624	// otherwise, saturation is based on the ratio of chroma (diff) to lightness (add)
16625	if ( diff === 0 ) {
16626		s = 0;
16627	} else if ( l <= 0.5 ) {
16628		s = diff / add;
16629	} else {
16630		s = diff / ( 2 - add );
16631	}
16632	return [ Math.round( h ) % 360, s, l, a == null ? 1 : a ];
16633};
16634
16635spaces.hsla.from = function( hsla ) {
16636	if ( hsla[ 0 ] == null || hsla[ 1 ] == null || hsla[ 2 ] == null ) {
16637		return [ null, null, null, hsla[ 3 ] ];
16638	}
16639	var h = hsla[ 0 ] / 360,
16640		s = hsla[ 1 ],
16641		l = hsla[ 2 ],
16642		a = hsla[ 3 ],
16643		q = l <= 0.5 ? l * ( 1 + s ) : l + s - l * s,
16644		p = 2 * l - q;
16645
16646	return [
16647		Math.round( hue2rgb( p, q, h + ( 1 / 3 ) ) * 255 ),
16648		Math.round( hue2rgb( p, q, h ) * 255 ),
16649		Math.round( hue2rgb( p, q, h - ( 1 / 3 ) ) * 255 ),
16650		a
16651	];
16652};
16653
16654each( spaces, function( spaceName, space ) {
16655	var props = space.props,
16656		cache = space.cache,
16657		to = space.to,
16658		from = space.from;
16659
16660	// Makes rgba() and hsla()
16661	color.fn[ spaceName ] = function( value ) {
16662
16663		// Generate a cache for this space if it doesn't exist
16664		if ( to && !this[ cache ] ) {
16665			this[ cache ] = to( this._rgba );
16666		}
16667		if ( value === undefined ) {
16668			return this[ cache ].slice();
16669		}
16670
16671		var ret,
16672			type = jQuery.type( value ),
16673			arr = ( type === "array" || type === "object" ) ? value : arguments,
16674			local = this[ cache ].slice();
16675
16676		each( props, function( key, prop ) {
vendor: 50,833 bytes, lines 16677-18662
16677			var val = arr[ type === "object" ? key : prop.idx ];
16678			if ( val == null ) {
16679				val = local[ prop.idx ];
16680			}
16681			local[ prop.idx ] = clamp( val, prop );
16682		} );
16683
16684		if ( from ) {
16685			ret = color( from( local ) );
16686			ret[ cache ] = local;
16687			return ret;
16688		} else {
16689			return color( local );
16690		}
16691	};
16692
16693	// Makes red() green() blue() alpha() hue() saturation() lightness()
16694	each( props, function( key, prop ) {
16695
16696		// Alpha is included in more than one space
16697		if ( color.fn[ key ] ) {
16698			return;
16699		}
16700		color.fn[ key ] = function( value ) {
16701			var vtype = jQuery.type( value ),
16702				fn = ( key === "alpha" ? ( this._hsla ? "hsla" : "rgba" ) : spaceName ),
16703				local = this[ fn ](),
16704				cur = local[ prop.idx ],
16705				match;
16706
16707			if ( vtype === "undefined" ) {
16708				return cur;
16709			}
16710
16711			if ( vtype === "function" ) {
16712				value = value.call( this, cur );
16713				vtype = jQuery.type( value );
16714			}
16715			if ( value == null && prop.empty ) {
16716				return this;
16717			}
16718			if ( vtype === "string" ) {
16719				match = rplusequals.exec( value );
16720				if ( match ) {
16721					value = cur + parseFloat( match[ 2 ] ) * ( match[ 1 ] === "+" ? 1 : -1 );
16722				}
16723			}
16724			local[ prop.idx ] = value;
16725			return this[ fn ]( local );
16726		};
16727	} );
16728} );
16729
16730// Add cssHook and .fx.step function for each named hook.
16731// accept a space separated string of properties
16732color.hook = function( hook ) {
16733	var hooks = hook.split( " " );
16734	each( hooks, function( i, hook ) {
16735		jQuery.cssHooks[ hook ] = {
16736			set: function( elem, value ) {
16737				var parsed, curElem,
16738					backgroundColor = "";
16739
16740				if ( value !== "transparent" && ( jQuery.type( value ) !== "string" ||
16741						( parsed = stringParse( value ) ) ) ) {
16742					value = color( parsed || value );
16743					if ( !support.rgba && value._rgba[ 3 ] !== 1 ) {
16744						curElem = hook === "backgroundColor" ? elem.parentNode : elem;
16745						while (
16746							( backgroundColor === "" || backgroundColor === "transparent" ) &&
16747							curElem && curElem.style
16748						) {
16749							try {
16750								backgroundColor = jQuery.css( curElem, "backgroundColor" );
16751								curElem = curElem.parentNode;
16752							} catch ( e ) {
16753							}
16754						}
16755
16756						value = value.blend( backgroundColor && backgroundColor !== "transparent" ?
16757							backgroundColor :
16758							"_default" );
16759					}
16760
16761					value = value.toRgbaString();
16762				}
16763				try {
16764					elem.style[ hook ] = value;
16765				} catch ( e ) {
16766
16767					// Wrapped to prevent IE from throwing errors on "invalid" values like
16768					// 'auto' or 'inherit'
16769				}
16770			}
16771		};
16772		jQuery.fx.step[ hook ] = function( fx ) {
16773			if ( !fx.colorInit ) {
16774				fx.start = color( fx.elem, hook );
16775				fx.end = color( fx.end );
16776				fx.colorInit = true;
16777			}
16778			jQuery.cssHooks[ hook ].set( fx.elem, fx.start.transition( fx.end, fx.pos ) );
16779		};
16780	} );
16781
16782};
16783
16784color.hook( stepHooks );
16785
16786jQuery.cssHooks.borderColor = {
16787	expand: function( value ) {
16788		var expanded = {};
16789
16790		each( [ "Top", "Right", "Bottom", "Left" ], function( i, part ) {
16791			expanded[ "border" + part + "Color" ] = value;
16792		} );
16793		return expanded;
16794	}
16795};
16796
16797// Basic color names only.
16798// Usage of any of the other color names requires adding yourself or including
16799// jquery.color.svg-names.js.
16800colors = jQuery.Color.names = {
16801
16802	// 4.1. Basic color keywords
16803	aqua: "#00ffff",
16804	black: "#000000",
16805	blue: "#0000ff",
16806	fuchsia: "#ff00ff",
16807	gray: "#808080",
16808	green: "#008000",
16809	lime: "#00ff00",
16810	maroon: "#800000",
16811	navy: "#000080",
16812	olive: "#808000",
16813	purple: "#800080",
16814	red: "#ff0000",
16815	silver: "#c0c0c0",
16816	teal: "#008080",
16817	white: "#ffffff",
16818	yellow: "#ffff00",
16819
16820	// 4.2.3. "transparent" color keyword
16821	transparent: [ null, null, null, 0 ],
16822
16823	_default: "#ffffff"
16824};
16825
16826} )( jQuery );
16827
16828/******************************************************************************/
16829/****************************** CLASS ANIMATIONS ******************************/
16830/******************************************************************************/
16831( function() {
16832
16833var classAnimationActions = [ "add", "remove", "toggle" ],
16834	shorthandStyles = {
16835		border: 1,
16836		borderBottom: 1,
16837		borderColor: 1,
16838		borderLeft: 1,
16839		borderRight: 1,
16840		borderTop: 1,
16841		borderWidth: 1,
16842		margin: 1,
16843		padding: 1
16844	};
16845
16846$.each(
16847	[ "borderLeftStyle", "borderRightStyle", "borderBottomStyle", "borderTopStyle" ],
16848	function( _, prop ) {
16849		$.fx.step[ prop ] = function( fx ) {
16850			if ( fx.end !== "none" && !fx.setAttr || fx.pos === 1 && !fx.setAttr ) {
16851				jQuery.style( fx.elem, prop, fx.end );
16852				fx.setAttr = true;
16853			}
16854		};
16855	}
16856);
16857
16858function getElementStyles( elem ) {
16859	var key, len,
16860		style = elem.ownerDocument.defaultView ?
16861			elem.ownerDocument.defaultView.getComputedStyle( elem, null ) :
16862			elem.currentStyle,
16863		styles = {};
16864
16865	if ( style && style.length && style[ 0 ] && style[ style[ 0 ] ] ) {
16866		len = style.length;
16867		while ( len-- ) {
16868			key = style[ len ];
16869			if ( typeof style[ key ] === "string" ) {
16870				styles[ $.camelCase( key ) ] = style[ key ];
16871			}
16872		}
16873
16874	// Support: Opera, IE <9
16875	} else {
16876		for ( key in style ) {
16877			if ( typeof style[ key ] === "string" ) {
16878				styles[ key ] = style[ key ];
16879			}
16880		}
16881	}
16882
16883	return styles;
16884}
16885
16886function styleDifference( oldStyle, newStyle ) {
16887	var diff = {},
16888		name, value;
16889
16890	for ( name in newStyle ) {
16891		value = newStyle[ name ];
16892		if ( oldStyle[ name ] !== value ) {
16893			if ( !shorthandStyles[ name ] ) {
16894				if ( $.fx.step[ name ] || !isNaN( parseFloat( value ) ) ) {
16895					diff[ name ] = value;
16896				}
16897			}
16898		}
16899	}
16900
16901	return diff;
16902}
16903
16904// Support: jQuery <1.8
16905if ( !$.fn.addBack ) {
16906	$.fn.addBack = function( selector ) {
16907		return this.add( selector == null ?
16908			this.prevObject : this.prevObject.filter( selector )
16909		);
16910	};
16911}
16912
16913$.effects.animateClass = function( value, duration, easing, callback ) {
16914	var o = $.speed( duration, easing, callback );
16915
16916	return this.queue( function() {
16917		var animated = $( this ),
16918			baseClass = animated.attr( "class" ) || "",
16919			applyClassChange,
16920			allAnimations = o.children ? animated.find( "*" ).addBack() : animated;
16921
16922		// Map the animated objects to store the original styles.
16923		allAnimations = allAnimations.map( function() {
16924			var el = $( this );
16925			return {
16926				el: el,
16927				start: getElementStyles( this )
16928			};
16929		} );
16930
16931		// Apply class change
16932		applyClassChange = function() {
16933			$.each( classAnimationActions, function( i, action ) {
16934				if ( value[ action ] ) {
16935					animated[ action + "Class" ]( value[ action ] );
16936				}
16937			} );
16938		};
16939		applyClassChange();
16940
16941		// Map all animated objects again - calculate new styles and diff
16942		allAnimations = allAnimations.map( function() {
16943			this.end = getElementStyles( this.el[ 0 ] );
16944			this.diff = styleDifference( this.start, this.end );
16945			return this;
16946		} );
16947
16948		// Apply original class
16949		animated.attr( "class", baseClass );
16950
16951		// Map all animated objects again - this time collecting a promise
16952		allAnimations = allAnimations.map( function() {
16953			var styleInfo = this,
16954				dfd = $.Deferred(),
16955				opts = $.extend( {}, o, {
16956					queue: false,
16957					complete: function() {
16958						dfd.resolve( styleInfo );
16959					}
16960				} );
16961
16962			this.el.animate( this.diff, opts );
16963			return dfd.promise();
16964		} );
16965
16966		// Once all animations have completed:
16967		$.when.apply( $, allAnimations.get() ).done( function() {
16968
16969			// Set the final class
16970			applyClassChange();
16971
16972			// For each animated element,
16973			// clear all css properties that were animated
16974			$.each( arguments, function() {
16975				var el = this.el;
16976				$.each( this.diff, function( key ) {
16977					el.css( key, "" );
16978				} );
16979			} );
16980
16981			// This is guarnteed to be there if you use jQuery.speed()
16982			// it also handles dequeuing the next anim...
16983			o.complete.call( animated[ 0 ] );
16984		} );
16985	} );
16986};
16987
16988$.fn.extend( {
16989	addClass: ( function( orig ) {
16990		return function( classNames, speed, easing, callback ) {
16991			return speed ?
16992				$.effects.animateClass.call( this,
16993					{ add: classNames }, speed, easing, callback ) :
16994				orig.apply( this, arguments );
16995		};
16996	} )( $.fn.addClass ),
16997
16998	removeClass: ( function( orig ) {
16999		return function( classNames, speed, easing, callback ) {
17000			return arguments.length > 1 ?
17001				$.effects.animateClass.call( this,
17002					{ remove: classNames }, speed, easing, callback ) :
17003				orig.apply( this, arguments );
17004		};
17005	} )( $.fn.removeClass ),
17006
17007	toggleClass: ( function( orig ) {
17008		return function( classNames, force, speed, easing, callback ) {
17009			if ( typeof force === "boolean" || force === undefined ) {
17010				if ( !speed ) {
17011
17012					// Without speed parameter
17013					return orig.apply( this, arguments );
17014				} else {
17015					return $.effects.animateClass.call( this,
17016						( force ? { add: classNames } : { remove: classNames } ),
17017						speed, easing, callback );
17018				}
17019			} else {
17020
17021				// Without force parameter
17022				return $.effects.animateClass.call( this,
17023					{ toggle: classNames }, force, speed, easing );
17024			}
17025		};
17026	} )( $.fn.toggleClass ),
17027
17028	switchClass: function( remove, add, speed, easing, callback ) {
17029		return $.effects.animateClass.call( this, {
17030			add: add,
17031			remove: remove
17032		}, speed, easing, callback );
17033	}
17034} );
17035
17036} )();
17037
17038/******************************************************************************/
17039/*********************************** EFFECTS **********************************/
17040/******************************************************************************/
17041
17042( function() {
17043
17044if ( $.expr && $.expr.filters && $.expr.filters.animated ) {
17045	$.expr.filters.animated = ( function( orig ) {
17046		return function( elem ) {
17047			return !!$( elem ).data( dataSpaceAnimated ) || orig( elem );
17048		};
17049	} )( $.expr.filters.animated );
17050}
17051
17052if ( $.uiBackCompat !== false ) {
17053	$.extend( $.effects, {
17054
17055		// Saves a set of properties in a data storage
17056		save: function( element, set ) {
17057			var i = 0, length = set.length;
17058			for ( ; i < length; i++ ) {
17059				if ( set[ i ] !== null ) {
17060					element.data( dataSpace + set[ i ], element[ 0 ].style[ set[ i ] ] );
17061				}
17062			}
17063		},
17064
17065		// Restores a set of previously saved properties from a data storage
17066		restore: function( element, set ) {
17067			var val, i = 0, length = set.length;
17068			for ( ; i < length; i++ ) {
17069				if ( set[ i ] !== null ) {
17070					val = element.data( dataSpace + set[ i ] );
17071					element.css( set[ i ], val );
17072				}
17073			}
17074		},
17075
17076		setMode: function( el, mode ) {
17077			if ( mode === "toggle" ) {
17078				mode = el.is( ":hidden" ) ? "show" : "hide";
17079			}
17080			return mode;
17081		},
17082
17083		// Wraps the element around a wrapper that copies position properties
17084		createWrapper: function( element ) {
17085
17086			// If the element is already wrapped, return it
17087			if ( element.parent().is( ".ui-effects-wrapper" ) ) {
17088				return element.parent();
17089			}
17090
17091			// Wrap the element
17092			var props = {
17093					width: element.outerWidth( true ),
17094					height: element.outerHeight( true ),
17095					"float": element.css( "float" )
17096				},
17097				wrapper = $( "<div></div>" )
17098					.addClass( "ui-effects-wrapper" )
17099					.css( {
17100						fontSize: "100%",
17101						background: "transparent",
17102						border: "none",
17103						margin: 0,
17104						padding: 0
17105					} ),
17106
17107				// Store the size in case width/height are defined in % - Fixes #5245
17108				size = {
17109					width: element.width(),
17110					height: element.height()
17111				},
17112				active = document.activeElement;
17113
17114			// Support: Firefox
17115			// Firefox incorrectly exposes anonymous content
17116			// https://bugzilla.mozilla.org/show_bug.cgi?id=561664
17117			try {
17118				active.id;
17119			} catch ( e ) {
17120				active = document.body;
17121			}
17122
17123			element.wrap( wrapper );
17124
17125			// Fixes #7595 - Elements lose focus when wrapped.
17126			if ( element[ 0 ] === active || $.contains( element[ 0 ], active ) ) {
17127				$( active ).trigger( "focus" );
17128			}
17129
17130			// Hotfix for jQuery 1.4 since some change in wrap() seems to actually
17131			// lose the reference to the wrapped element
17132			wrapper = element.parent();
17133
17134			// Transfer positioning properties to the wrapper
17135			if ( element.css( "position" ) === "static" ) {
17136				wrapper.css( { position: "relative" } );
17137				element.css( { position: "relative" } );
17138			} else {
17139				$.extend( props, {
17140					position: element.css( "position" ),
17141					zIndex: element.css( "z-index" )
17142				} );
17143				$.each( [ "top", "left", "bottom", "right" ], function( i, pos ) {
17144					props[ pos ] = element.css( pos );
17145					if ( isNaN( parseInt( props[ pos ], 10 ) ) ) {
17146						props[ pos ] = "auto";
17147					}
17148				} );
17149				element.css( {
17150					position: "relative",
17151					top: 0,
17152					left: 0,
17153					right: "auto",
17154					bottom: "auto"
17155				} );
17156			}
17157			element.css( size );
17158
17159			return wrapper.css( props ).show();
17160		},
17161
17162		removeWrapper: function( element ) {
17163			var active = document.activeElement;
17164
17165			if ( element.parent().is( ".ui-effects-wrapper" ) ) {
17166				element.parent().replaceWith( element );
17167
17168				// Fixes #7595 - Elements lose focus when wrapped.
17169				if ( element[ 0 ] === active || $.contains( element[ 0 ], active ) ) {
17170					$( active ).trigger( "focus" );
17171				}
17172			}
17173
17174			return element;
17175		}
17176	} );
17177}
17178
17179$.extend( $.effects, {
17180	version: "1.12.1",
17181
17182	define: function( name, mode, effect ) {
17183		if ( !effect ) {
17184			effect = mode;
17185			mode = "effect";
17186		}
17187
17188		$.effects.effect[ name ] = effect;
17189		$.effects.effect[ name ].mode = mode;
17190
17191		return effect;
17192	},
17193
17194	scaledDimensions: function( element, percent, direction ) {
17195		if ( percent === 0 ) {
17196			return {
17197				height: 0,
17198				width: 0,
17199				outerHeight: 0,
17200				outerWidth: 0
17201			};
17202		}
17203
17204		var x = direction !== "horizontal" ? ( ( percent || 100 ) / 100 ) : 1,
17205			y = direction !== "vertical" ? ( ( percent || 100 ) / 100 ) : 1;
17206
17207		return {
17208			height: element.height() * y,
17209			width: element.width() * x,
17210			outerHeight: element.outerHeight() * y,
17211			outerWidth: element.outerWidth() * x
17212		};
17213
17214	},
17215
17216	clipToBox: function( animation ) {
17217		return {
17218			width: animation.clip.right - animation.clip.left,
17219			height: animation.clip.bottom - animation.clip.top,
17220			left: animation.clip.left,
17221			top: animation.clip.top
17222		};
17223	},
17224
17225	// Injects recently queued functions to be first in line (after "inprogress")
17226	unshift: function( element, queueLength, count ) {
17227		var queue = element.queue();
17228
17229		if ( queueLength > 1 ) {
17230			queue.splice.apply( queue,
17231				[ 1, 0 ].concat( queue.splice( queueLength, count ) ) );
17232		}
17233		element.dequeue();
17234	},
17235
17236	saveStyle: function( element ) {
17237		element.data( dataSpaceStyle, element[ 0 ].style.cssText );
17238	},
17239
17240	restoreStyle: function( element ) {
17241		element[ 0 ].style.cssText = element.data( dataSpaceStyle ) || "";
17242		element.removeData( dataSpaceStyle );
17243	},
17244
17245	mode: function( element, mode ) {
17246		var hidden = element.is( ":hidden" );
17247
17248		if ( mode === "toggle" ) {
17249			mode = hidden ? "show" : "hide";
17250		}
17251		if ( hidden ? mode === "hide" : mode === "show" ) {
17252			mode = "none";
17253		}
17254		return mode;
17255	},
17256
17257	// Translates a [top,left] array into a baseline value
17258	getBaseline: function( origin, original ) {
17259		var y, x;
17260
17261		switch ( origin[ 0 ] ) {
17262		case "top":
17263			y = 0;
17264			break;
17265		case "middle":
17266			y = 0.5;
17267			break;
17268		case "bottom":
17269			y = 1;
17270			break;
17271		default:
17272			y = origin[ 0 ] / original.height;
17273		}
17274
17275		switch ( origin[ 1 ] ) {
17276		case "left":
17277			x = 0;
17278			break;
17279		case "center":
17280			x = 0.5;
17281			break;
17282		case "right":
17283			x = 1;
17284			break;
17285		default:
17286			x = origin[ 1 ] / original.width;
17287		}
17288
17289		return {
17290			x: x,
17291			y: y
17292		};
17293	},
17294
17295	// Creates a placeholder element so that the original element can be made absolute
17296	createPlaceholder: function( element ) {
17297		var placeholder,
17298			cssPosition = element.css( "position" ),
17299			position = element.position();
17300
17301		// Lock in margins first to account for form elements, which
17302		// will change margin if you explicitly set height
17303		// see: http://jsfiddle.net/JZSMt/3/ https://bugs.webkit.org/show_bug.cgi?id=107380
17304		// Support: Safari
17305		element.css( {
17306			marginTop: element.css( "marginTop" ),
17307			marginBottom: element.css( "marginBottom" ),
17308			marginLeft: element.css( "marginLeft" ),
17309			marginRight: element.css( "marginRight" )
17310		} )
17311		.outerWidth( element.outerWidth() )
17312		.outerHeight( element.outerHeight() );
17313
17314		if ( /^(static|relative)/.test( cssPosition ) ) {
17315			cssPosition = "absolute";
17316
17317			placeholder = $( "<" + element[ 0 ].nodeName + ">" ).insertAfter( element ).css( {
17318
17319				// Convert inline to inline block to account for inline elements
17320				// that turn to inline block based on content (like img)
17321				display: /^(inline|ruby)/.test( element.css( "display" ) ) ?
17322					"inline-block" :
17323					"block",
17324				visibility: "hidden",
17325
17326				// Margins need to be set to account for margin collapse
17327				marginTop: element.css( "marginTop" ),
17328				marginBottom: element.css( "marginBottom" ),
17329				marginLeft: element.css( "marginLeft" ),
17330				marginRight: element.css( "marginRight" ),
17331				"float": element.css( "float" )
17332			} )
17333			.outerWidth( element.outerWidth() )
17334			.outerHeight( element.outerHeight() )
17335			.addClass( "ui-effects-placeholder" );
17336
17337			element.data( dataSpace + "placeholder", placeholder );
17338		}
17339
17340		element.css( {
17341			position: cssPosition,
17342			left: position.left,
17343			top: position.top
17344		} );
17345
17346		return placeholder;
17347	},
17348
17349	removePlaceholder: function( element ) {
17350		var dataKey = dataSpace + "placeholder",
17351				placeholder = element.data( dataKey );
17352
17353		if ( placeholder ) {
17354			placeholder.remove();
17355			element.removeData( dataKey );
17356		}
17357	},
17358
17359	// Removes a placeholder if it exists and restores
17360	// properties that were modified during placeholder creation
17361	cleanUp: function( element ) {
17362		$.effects.restoreStyle( element );
17363		$.effects.removePlaceholder( element );
17364	},
17365
17366	setTransition: function( element, list, factor, value ) {
17367		value = value || {};
17368		$.each( list, function( i, x ) {
17369			var unit = element.cssUnit( x );
17370			if ( unit[ 0 ] > 0 ) {
17371				value[ x ] = unit[ 0 ] * factor + unit[ 1 ];
17372			}
17373		} );
17374		return value;
17375	}
17376} );
17377
17378// Return an effect options object for the given parameters:
17379function _normalizeArguments( effect, options, speed, callback ) {
17380
17381	// Allow passing all options as the first parameter
17382	if ( $.isPlainObject( effect ) ) {
17383		options = effect;
17384		effect = effect.effect;
17385	}
17386
17387	// Convert to an object
17388	effect = { effect: effect };
17389
17390	// Catch (effect, null, ...)
17391	if ( options == null ) {
17392		options = {};
17393	}
17394
17395	// Catch (effect, callback)
17396	if ( $.isFunction( options ) ) {
17397		callback = options;
17398		speed = null;
17399		options = {};
17400	}
17401
17402	// Catch (effect, speed, ?)
17403	if ( typeof options === "number" || $.fx.speeds[ options ] ) {
17404		callback = speed;
17405		speed = options;
17406		options = {};
17407	}
17408
17409	// Catch (effect, options, callback)
17410	if ( $.isFunction( speed ) ) {
17411		callback = speed;
17412		speed = null;
17413	}
17414
17415	// Add options to effect
17416	if ( options ) {
17417		$.extend( effect, options );
17418	}
17419
17420	speed = speed || options.duration;
17421	effect.duration = $.fx.off ? 0 :
17422		typeof speed === "number" ? speed :
17423		speed in $.fx.speeds ? $.fx.speeds[ speed ] :
17424		$.fx.speeds._default;
17425
17426	effect.complete = callback || options.complete;
17427
17428	return effect;
17429}
17430
17431function standardAnimationOption( option ) {
17432
17433	// Valid standard speeds (nothing, number, named speed)
17434	if ( !option || typeof option === "number" || $.fx.speeds[ option ] ) {
17435		return true;
17436	}
17437
17438	// Invalid strings - treat as "normal" speed
17439	if ( typeof option === "string" && !$.effects.effect[ option ] ) {
17440		return true;
17441	}
17442
17443	// Complete callback
17444	if ( $.isFunction( option ) ) {
17445		return true;
17446	}
17447
17448	// Options hash (but not naming an effect)
17449	if ( typeof option === "object" && !option.effect ) {
17450		return true;
17451	}
17452
17453	// Didn't match any standard API
17454	return false;
17455}
17456
17457$.fn.extend( {
17458	effect: function( /* effect, options, speed, callback */ ) {
17459		var args = _normalizeArguments.apply( this, arguments ),
17460			effectMethod = $.effects.effect[ args.effect ],
17461			defaultMode = effectMethod.mode,
17462			queue = args.queue,
17463			queueName = queue || "fx",
17464			complete = args.complete,
17465			mode = args.mode,
17466			modes = [],
17467			prefilter = function( next ) {
17468				var el = $( this ),
17469					normalizedMode = $.effects.mode( el, mode ) || defaultMode;
17470
17471				// Sentinel for duck-punching the :animated psuedo-selector
17472				el.data( dataSpaceAnimated, true );
17473
17474				// Save effect mode for later use,
17475				// we can't just call $.effects.mode again later,
17476				// as the .show() below destroys the initial state
17477				modes.push( normalizedMode );
17478
17479				// See $.uiBackCompat inside of run() for removal of defaultMode in 1.13
17480				if ( defaultMode && ( normalizedMode === "show" ||
17481						( normalizedMode === defaultMode && normalizedMode === "hide" ) ) ) {
17482					el.show();
17483				}
17484
17485				if ( !defaultMode || normalizedMode !== "none" ) {
17486					$.effects.saveStyle( el );
17487				}
17488
17489				if ( $.isFunction( next ) ) {
17490					next();
17491				}
17492			};
17493
17494		if ( $.fx.off || !effectMethod ) {
17495
17496			// Delegate to the original method (e.g., .show()) if possible
17497			if ( mode ) {
17498				return this[ mode ]( args.duration, complete );
17499			} else {
17500				return this.each( function() {
17501					if ( complete ) {
17502						complete.call( this );
17503					}
17504				} );
17505			}
17506		}
17507
17508		function run( next ) {
17509			var elem = $( this );
17510
17511			function cleanup() {
17512				elem.removeData( dataSpaceAnimated );
17513
17514				$.effects.cleanUp( elem );
17515
17516				if ( args.mode === "hide" ) {
17517					elem.hide();
17518				}
17519
17520				done();
17521			}
17522
17523			function done() {
17524				if ( $.isFunction( complete ) ) {
17525					complete.call( elem[ 0 ] );
17526				}
17527
17528				if ( $.isFunction( next ) ) {
17529					next();
17530				}
17531			}
17532
17533			// Override mode option on a per element basis,
17534			// as toggle can be either show or hide depending on element state
17535			args.mode = modes.shift();
17536
17537			if ( $.uiBackCompat !== false && !defaultMode ) {
17538				if ( elem.is( ":hidden" ) ? mode === "hide" : mode === "show" ) {
17539
17540					// Call the core method to track "olddisplay" properly
17541					elem[ mode ]();
17542					done();
17543				} else {
17544					effectMethod.call( elem[ 0 ], args, done );
17545				}
17546			} else {
17547				if ( args.mode === "none" ) {
17548
17549					// Call the core method to track "olddisplay" properly
17550					elem[ mode ]();
17551					done();
17552				} else {
17553					effectMethod.call( elem[ 0 ], args, cleanup );
17554				}
17555			}
17556		}
17557
17558		// Run prefilter on all elements first to ensure that
17559		// any showing or hiding happens before placeholder creation,
17560		// which ensures that any layout changes are correctly captured.
17561		return queue === false ?
17562			this.each( prefilter ).each( run ) :
17563			this.queue( queueName, prefilter ).queue( queueName, run );
17564	},
17565
17566	show: ( function( orig ) {
17567		return function( option ) {
17568			if ( standardAnimationOption( option ) ) {
17569				return orig.apply( this, arguments );
17570			} else {
17571				var args = _normalizeArguments.apply( this, arguments );
17572				args.mode = "show";
17573				return this.effect.call( this, args );
17574			}
17575		};
17576	} )( $.fn.show ),
17577
17578	hide: ( function( orig ) {
17579		return function( option ) {
17580			if ( standardAnimationOption( option ) ) {
17581				return orig.apply( this, arguments );
17582			} else {
17583				var args = _normalizeArguments.apply( this, arguments );
17584				args.mode = "hide";
17585				return this.effect.call( this, args );
17586			}
17587		};
17588	} )( $.fn.hide ),
17589
17590	toggle: ( function( orig ) {
17591		return function( option ) {
17592			if ( standardAnimationOption( option ) || typeof option === "boolean" ) {
17593				return orig.apply( this, arguments );
17594			} else {
17595				var args = _normalizeArguments.apply( this, arguments );
17596				args.mode = "toggle";
17597				return this.effect.call( this, args );
17598			}
17599		};
17600	} )( $.fn.toggle ),
17601
17602	cssUnit: function( key ) {
17603		var style = this.css( key ),
17604			val = [];
17605
17606		$.each( [ "em", "px", "%", "pt" ], function( i, unit ) {
17607			if ( style.indexOf( unit ) > 0 ) {
17608				val = [ parseFloat( style ), unit ];
17609			}
17610		} );
17611		return val;
17612	},
17613
17614	cssClip: function( clipObj ) {
17615		if ( clipObj ) {
17616			return this.css( "clip", "rect(" + clipObj.top + "px " + clipObj.right + "px " +
17617				clipObj.bottom + "px " + clipObj.left + "px)" );
17618		}
17619		return parseClip( this.css( "clip" ), this );
17620	},
17621
17622	transfer: function( options, done ) {
17623		var element = $( this ),
17624			target = $( options.to ),
17625			targetFixed = target.css( "position" ) === "fixed",
17626			body = $( "body" ),
17627			fixTop = targetFixed ? body.scrollTop() : 0,
17628			fixLeft = targetFixed ? body.scrollLeft() : 0,
17629			endPosition = target.offset(),
17630			animation = {
17631				top: endPosition.top - fixTop,
17632				left: endPosition.left - fixLeft,
17633				height: target.innerHeight(),
17634				width: target.innerWidth()
17635			},
17636			startPosition = element.offset(),
17637			transfer = $( "<div class='ui-effects-transfer'></div>" )
17638				.appendTo( "body" )
17639				.addClass( options.className )
17640				.css( {
17641					top: startPosition.top - fixTop,
17642					left: startPosition.left - fixLeft,
17643					height: element.innerHeight(),
17644					width: element.innerWidth(),
17645					position: targetFixed ? "fixed" : "absolute"
17646				} )
17647				.animate( animation, options.duration, options.easing, function() {
17648					transfer.remove();
17649					if ( $.isFunction( done ) ) {
17650						done();
17651					}
17652				} );
17653	}
17654} );
17655
17656function parseClip( str, element ) {
17657		var outerWidth = element.outerWidth(),
17658			outerHeight = element.outerHeight(),
17659			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)\)$/,
17660			values = clipRegex.exec( str ) || [ "", 0, outerWidth, outerHeight, 0 ];
17661
17662		return {
17663			top: parseFloat( values[ 1 ] ) || 0,
17664			right: values[ 2 ] === "auto" ? outerWidth : parseFloat( values[ 2 ] ),
17665			bottom: values[ 3 ] === "auto" ? outerHeight : parseFloat( values[ 3 ] ),
17666			left: parseFloat( values[ 4 ] ) || 0
17667		};
17668}
17669
17670$.fx.step.clip = function( fx ) {
17671	if ( !fx.clipInit ) {
17672		fx.start = $( fx.elem ).cssClip();
17673		if ( typeof fx.end === "string" ) {
17674			fx.end = parseClip( fx.end, fx.elem );
17675		}
17676		fx.clipInit = true;
17677	}
17678
17679	$( fx.elem ).cssClip( {
17680		top: fx.pos * ( fx.end.top - fx.start.top ) + fx.start.top,
17681		right: fx.pos * ( fx.end.right - fx.start.right ) + fx.start.right,
17682		bottom: fx.pos * ( fx.end.bottom - fx.start.bottom ) + fx.start.bottom,
17683		left: fx.pos * ( fx.end.left - fx.start.left ) + fx.start.left
17684	} );
17685};
17686
17687} )();
17688
17689/******************************************************************************/
17690/*********************************** EASING ***********************************/
17691/******************************************************************************/
17692
17693( function() {
17694
17695// Based on easing equations from Robert Penner (http://www.robertpenner.com/easing)
17696
17697var baseEasings = {};
17698
17699$.each( [ "Quad", "Cubic", "Quart", "Quint", "Expo" ], function( i, name ) {
17700	baseEasings[ name ] = function( p ) {
17701		return Math.pow( p, i + 2 );
17702	};
17703} );
17704
17705$.extend( baseEasings, {
17706	Sine: function( p ) {
17707		return 1 - Math.cos( p * Math.PI / 2 );
17708	},
17709	Circ: function( p ) {
17710		return 1 - Math.sqrt( 1 - p * p );
17711	},
17712	Elastic: function( p ) {
17713		return p === 0 || p === 1 ? p :
17714			-Math.pow( 2, 8 * ( p - 1 ) ) * Math.sin( ( ( p - 1 ) * 80 - 7.5 ) * Math.PI / 15 );
17715	},
17716	Back: function( p ) {
17717		return p * p * ( 3 * p - 2 );
17718	},
17719	Bounce: function( p ) {
17720		var pow2,
17721			bounce = 4;
17722
17723		while ( p < ( ( pow2 = Math.pow( 2, --bounce ) ) - 1 ) / 11 ) {}
17724		return 1 / Math.pow( 4, 3 - bounce ) - 7.5625 * Math.pow( ( pow2 * 3 - 2 ) / 22 - p, 2 );
17725	}
17726} );
17727
17728$.each( baseEasings, function( name, easeIn ) {
17729	$.easing[ "easeIn" + name ] = easeIn;
17730	$.easing[ "easeOut" + name ] = function( p ) {
17731		return 1 - easeIn( 1 - p );
17732	};
17733	$.easing[ "easeInOut" + name ] = function( p ) {
17734		return p < 0.5 ?
17735			easeIn( p * 2 ) / 2 :
17736			1 - easeIn( p * -2 + 2 ) / 2;
17737	};
17738} );
17739
17740} )();
17741
17742var effect = $.effects;
17743
17744
17745/*!
17746 * jQuery UI Effects Blind 1.12.1
17747 * http://jqueryui.com
17748 *
17749 * Copyright jQuery Foundation and other contributors
17750 * Released under the MIT license.
17751 * http://jquery.org/license
17752 */
17753
17754//>>label: Blind Effect
17755//>>group: Effects
17756//>>description: Blinds the element.
17757//>>docs: http://api.jqueryui.com/blind-effect/
17758//>>demos: http://jqueryui.com/effect/
17759
17760
17761
17762var effectsEffectBlind = $.effects.define( "blind", "hide", function( options, done ) {
17763	var map = {
17764			up: [ "bottom", "top" ],
17765			vertical: [ "bottom", "top" ],
17766			down: [ "top", "bottom" ],
17767			left: [ "right", "left" ],
17768			horizontal: [ "right", "left" ],
17769			right: [ "left", "right" ]
17770		},
17771		element = $( this ),
17772		direction = options.direction || "up",
17773		start = element.cssClip(),
17774		animate = { clip: $.extend( {}, start ) },
17775		placeholder = $.effects.createPlaceholder( element );
17776
17777	animate.clip[ map[ direction ][ 0 ] ] = animate.clip[ map[ direction ][ 1 ] ];
17778
17779	if ( options.mode === "show" ) {
17780		element.cssClip( animate.clip );
17781		if ( placeholder ) {
17782			placeholder.css( $.effects.clipToBox( animate ) );
17783		}
17784
17785		animate.clip = start;
17786	}
17787
17788	if ( placeholder ) {
17789		placeholder.animate( $.effects.clipToBox( animate ), options.duration, options.easing );
17790	}
17791
17792	element.animate( animate, {
17793		queue: false,
17794		duration: options.duration,
17795		easing: options.easing,
17796		complete: done
17797	} );
17798} );
17799
17800
17801/*!
17802 * jQuery UI Effects Bounce 1.12.1
17803 * http://jqueryui.com
17804 *
17805 * Copyright jQuery Foundation and other contributors
17806 * Released under the MIT license.
17807 * http://jquery.org/license
17808 */
17809
17810//>>label: Bounce Effect
17811//>>group: Effects
17812//>>description: Bounces an element horizontally or vertically n times.
17813//>>docs: http://api.jqueryui.com/bounce-effect/
17814//>>demos: http://jqueryui.com/effect/
17815
17816
17817
17818var effectsEffectBounce = $.effects.define( "bounce", function( options, done ) {
17819	var upAnim, downAnim, refValue,
17820		element = $( this ),
17821
17822		// Defaults:
17823		mode = options.mode,
17824		hide = mode === "hide",
17825		show = mode === "show",
17826		direction = options.direction || "up",
17827		distance = options.distance,
17828		times = options.times || 5,
17829
17830		// Number of internal animations
17831		anims = times * 2 + ( show || hide ? 1 : 0 ),
17832		speed = options.duration / anims,
17833		easing = options.easing,
17834
17835		// Utility:
17836		ref = ( direction === "up" || direction === "down" ) ? "top" : "left",
17837		motion = ( direction === "up" || direction === "left" ),
17838		i = 0,
17839
17840		queuelen = element.queue().length;
17841
17842	$.effects.createPlaceholder( element );
17843
17844	refValue = element.css( ref );
17845
17846	// Default distance for the BIGGEST bounce is the outer Distance / 3
17847	if ( !distance ) {
17848		distance = element[ ref === "top" ? "outerHeight" : "outerWidth" ]() / 3;
17849	}
17850
17851	if ( show ) {
17852		downAnim = { opacity: 1 };
17853		downAnim[ ref ] = refValue;
17854
17855		// If we are showing, force opacity 0 and set the initial position
17856		// then do the "first" animation
17857		element
17858			.css( "opacity", 0 )
17859			.css( ref, motion ? -distance * 2 : distance * 2 )
17860			.animate( downAnim, speed, easing );
17861	}
17862
17863	// Start at the smallest distance if we are hiding
17864	if ( hide ) {
17865		distance = distance / Math.pow( 2, times - 1 );
17866	}
17867
17868	downAnim = {};
17869	downAnim[ ref ] = refValue;
17870
17871	// Bounces up/down/left/right then back to 0 -- times * 2 animations happen here
17872	for ( ; i < times; i++ ) {
17873		upAnim = {};
17874		upAnim[ ref ] = ( motion ? "-=" : "+=" ) + distance;
17875
17876		element
17877			.animate( upAnim, speed, easing )
17878			.animate( downAnim, speed, easing );
17879
17880		distance = hide ? distance * 2 : distance / 2;
17881	}
17882
17883	// Last Bounce when Hiding
17884	if ( hide ) {
17885		upAnim = { opacity: 0 };
17886		upAnim[ ref ] = ( motion ? "-=" : "+=" ) + distance;
17887
17888		element.animate( upAnim, speed, easing );
17889	}
17890
17891	element.queue( done );
17892
17893	$.effects.unshift( element, queuelen, anims + 1 );
17894} );
17895
17896
17897/*!
17898 * jQuery UI Effects Clip 1.12.1
17899 * http://jqueryui.com
17900 *
17901 * Copyright jQuery Foundation and other contributors
17902 * Released under the MIT license.
17903 * http://jquery.org/license
17904 */
17905
17906//>>label: Clip Effect
17907//>>group: Effects
17908//>>description: Clips the element on and off like an old TV.
17909//>>docs: http://api.jqueryui.com/clip-effect/
17910//>>demos: http://jqueryui.com/effect/
17911
17912
17913
17914var effectsEffectClip = $.effects.define( "clip", "hide", function( options, done ) {
17915	var start,
17916		animate = {},
17917		element = $( this ),
17918		direction = options.direction || "vertical",
17919		both = direction === "both",
17920		horizontal = both || direction === "horizontal",
17921		vertical = both || direction === "vertical";
17922
17923	start = element.cssClip();
17924	animate.clip = {
17925		top: vertical ? ( start.bottom - start.top ) / 2 : start.top,
17926		right: horizontal ? ( start.right - start.left ) / 2 : start.right,
17927		bottom: vertical ? ( start.bottom - start.top ) / 2 : start.bottom,
17928		left: horizontal ? ( start.right - start.left ) / 2 : start.left
17929	};
17930
17931	$.effects.createPlaceholder( element );
17932
17933	if ( options.mode === "show" ) {
17934		element.cssClip( animate.clip );
17935		animate.clip = start;
17936	}
17937
17938	element.animate( animate, {
17939		queue: false,
17940		duration: options.duration,
17941		easing: options.easing,
17942		complete: done
17943	} );
17944
17945} );
17946
17947
17948/*!
17949 * jQuery UI Effects Drop 1.12.1
17950 * http://jqueryui.com
17951 *
17952 * Copyright jQuery Foundation and other contributors
17953 * Released under the MIT license.
17954 * http://jquery.org/license
17955 */
17956
17957//>>label: Drop Effect
17958//>>group: Effects
17959//>>description: Moves an element in one direction and hides it at the same time.
17960//>>docs: http://api.jqueryui.com/drop-effect/
17961//>>demos: http://jqueryui.com/effect/
17962
17963
17964
17965var effectsEffectDrop = $.effects.define( "drop", "hide", function( options, done ) {
17966
17967	var distance,
17968		element = $( this ),
17969		mode = options.mode,
17970		show = mode === "show",
17971		direction = options.direction || "left",
17972		ref = ( direction === "up" || direction === "down" ) ? "top" : "left",
17973		motion = ( direction === "up" || direction === "left" ) ? "-=" : "+=",
17974		oppositeMotion = ( motion === "+=" ) ? "-=" : "+=",
17975		animation = {
17976			opacity: 0
17977		};
17978
17979	$.effects.createPlaceholder( element );
17980
17981	distance = options.distance ||
17982		element[ ref === "top" ? "outerHeight" : "outerWidth" ]( true ) / 2;
17983
17984	animation[ ref ] = motion + distance;
17985
17986	if ( show ) {
17987		element.css( animation );
17988
17989		animation[ ref ] = oppositeMotion + distance;
17990		animation.opacity = 1;
17991	}
17992
17993	// Animate
17994	element.animate( animation, {
17995		queue: false,
17996		duration: options.duration,
17997		easing: options.easing,
17998		complete: done
17999	} );
18000} );
18001
18002
18003/*!
18004 * jQuery UI Effects Explode 1.12.1
18005 * http://jqueryui.com
18006 *
18007 * Copyright jQuery Foundation and other contributors
18008 * Released under the MIT license.
18009 * http://jquery.org/license
18010 */
18011
18012//>>label: Explode Effect
18013//>>group: Effects
18014// jscs:disable maximumLineLength
18015//>>description: Explodes an element in all directions into n pieces. Implodes an element to its original wholeness.
18016// jscs:enable maximumLineLength
18017//>>docs: http://api.jqueryui.com/explode-effect/
18018//>>demos: http://jqueryui.com/effect/
18019
18020
18021
18022var effectsEffectExplode = $.effects.define( "explode", "hide", function( options, done ) {
18023
18024	var i, j, left, top, mx, my,
18025		rows = options.pieces ? Math.round( Math.sqrt( options.pieces ) ) : 3,
18026		cells = rows,
18027		element = $( this ),
18028		mode = options.mode,
18029		show = mode === "show",
18030
18031		// Show and then visibility:hidden the element before calculating offset
18032		offset = element.show().css( "visibility", "hidden" ).offset(),
18033
18034		// Width and height of a piece
18035		width = Math.ceil( element.outerWidth() / cells ),
18036		height = Math.ceil( element.outerHeight() / rows ),
18037		pieces = [];
18038
18039	// Children animate complete:
18040	function childComplete() {
18041		pieces.push( this );
18042		if ( pieces.length === rows * cells ) {
18043			animComplete();
18044		}
18045	}
18046
18047	// Clone the element for each row and cell.
18048	for ( i = 0; i < rows; i++ ) { // ===>
18049		top = offset.top + i * height;
18050		my = i - ( rows - 1 ) / 2;
18051
18052		for ( j = 0; j < cells; j++ ) { // |||
18053			left = offset.left + j * width;
18054			mx = j - ( cells - 1 ) / 2;
18055
18056			// Create a clone of the now hidden main element that will be absolute positioned
18057			// within a wrapper div off the -left and -top equal to size of our pieces
18058			element
18059				.clone()
18060				.appendTo( "body" )
18061				.wrap( "<div></div>" )
18062				.css( {
18063					position: "absolute",
18064					visibility: "visible",
18065					left: -j * width,
18066					top: -i * height
18067				} )
18068
18069				// Select the wrapper - make it overflow: hidden and absolute positioned based on
18070				// where the original was located +left and +top equal to the size of pieces
18071				.parent()
18072					.addClass( "ui-effects-explode" )
18073					.css( {
18074						position: "absolute",
18075						overflow: "hidden",
18076						width: width,
18077						height: height,
18078						left: left + ( show ? mx * width : 0 ),
18079						top: top + ( show ? my * height : 0 ),
18080						opacity: show ? 0 : 1
18081					} )
18082					.animate( {
18083						left: left + ( show ? 0 : mx * width ),
18084						top: top + ( show ? 0 : my * height ),
18085						opacity: show ? 1 : 0
18086					}, options.duration || 500, options.easing, childComplete );
18087		}
18088	}
18089
18090	function animComplete() {
18091		element.css( {
18092			visibility: "visible"
18093		} );
18094		$( pieces ).remove();
18095		done();
18096	}
18097} );
18098
18099
18100/*!
18101 * jQuery UI Effects Fade 1.12.1
18102 * http://jqueryui.com
18103 *
18104 * Copyright jQuery Foundation and other contributors
18105 * Released under the MIT license.
18106 * http://jquery.org/license
18107 */
18108
18109//>>label: Fade Effect
18110//>>group: Effects
18111//>>description: Fades the element.
18112//>>docs: http://api.jqueryui.com/fade-effect/
18113//>>demos: http://jqueryui.com/effect/
18114
18115
18116
18117var effectsEffectFade = $.effects.define( "fade", "toggle", function( options, done ) {
18118	var show = options.mode === "show";
18119
18120	$( this )
18121		.css( "opacity", show ? 0 : 1 )
18122		.animate( {
18123			opacity: show ? 1 : 0
18124		}, {
18125			queue: false,
18126			duration: options.duration,
18127			easing: options.easing,
18128			complete: done
18129		} );
18130} );
18131
18132
18133/*!
18134 * jQuery UI Effects Fold 1.12.1
18135 * http://jqueryui.com
18136 *
18137 * Copyright jQuery Foundation and other contributors
18138 * Released under the MIT license.
18139 * http://jquery.org/license
18140 */
18141
18142//>>label: Fold Effect
18143//>>group: Effects
18144//>>description: Folds an element first horizontally and then vertically.
18145//>>docs: http://api.jqueryui.com/fold-effect/
18146//>>demos: http://jqueryui.com/effect/
18147
18148
18149
18150var effectsEffectFold = $.effects.define( "fold", "hide", function( options, done ) {
18151
18152	// Create element
18153	var element = $( this ),
18154		mode = options.mode,
18155		show = mode === "show",
18156		hide = mode === "hide",
18157		size = options.size || 15,
18158		percent = /([0-9]+)%/.exec( size ),
18159		horizFirst = !!options.horizFirst,
18160		ref = horizFirst ? [ "right", "bottom" ] : [ "bottom", "right" ],
18161		duration = options.duration / 2,
18162
18163		placeholder = $.effects.createPlaceholder( element ),
18164
18165		start = element.cssClip(),
18166		animation1 = { clip: $.extend( {}, start ) },
18167		animation2 = { clip: $.extend( {}, start ) },
18168
18169		distance = [ start[ ref[ 0 ] ], start[ ref[ 1 ] ] ],
18170
18171		queuelen = element.queue().length;
18172
18173	if ( percent ) {
18174		size = parseInt( percent[ 1 ], 10 ) / 100 * distance[ hide ? 0 : 1 ];
18175	}
18176	animation1.clip[ ref[ 0 ] ] = size;
18177	animation2.clip[ ref[ 0 ] ] = size;
18178	animation2.clip[ ref[ 1 ] ] = 0;
18179
18180	if ( show ) {
18181		element.cssClip( animation2.clip );
18182		if ( placeholder ) {
18183			placeholder.css( $.effects.clipToBox( animation2 ) );
18184		}
18185
18186		animation2.clip = start;
18187	}
18188
18189	// Animate
18190	element
18191		.queue( function( next ) {
18192			if ( placeholder ) {
18193				placeholder
18194					.animate( $.effects.clipToBox( animation1 ), duration, options.easing )
18195					.animate( $.effects.clipToBox( animation2 ), duration, options.easing );
18196			}
18197
18198			next();
18199		} )
18200		.animate( animation1, duration, options.easing )
18201		.animate( animation2, duration, options.easing )
18202		.queue( done );
18203
18204	$.effects.unshift( element, queuelen, 4 );
18205} );
18206
18207
18208/*!
18209 * jQuery UI Effects Highlight 1.12.1
18210 * http://jqueryui.com
18211 *
18212 * Copyright jQuery Foundation and other contributors
18213 * Released under the MIT license.
18214 * http://jquery.org/license
18215 */
18216
18217//>>label: Highlight Effect
18218//>>group: Effects
18219//>>description: Highlights the background of an element in a defined color for a custom duration.
18220//>>docs: http://api.jqueryui.com/highlight-effect/
18221//>>demos: http://jqueryui.com/effect/
18222
18223
18224
18225var effectsEffectHighlight = $.effects.define( "highlight", "show", function( options, done ) {
18226	var element = $( this ),
18227		animation = {
18228			backgroundColor: element.css( "backgroundColor" )
18229		};
18230
18231	if ( options.mode === "hide" ) {
18232		animation.opacity = 0;
18233	}
18234
18235	$.effects.saveStyle( element );
18236
18237	element
18238		.css( {
18239			backgroundImage: "none",
18240			backgroundColor: options.color || "#ffff99"
18241		} )
18242		.animate( animation, {
18243			queue: false,
18244			duration: options.duration,
18245			easing: options.easing,
18246			complete: done
18247		} );
18248} );
18249
18250
18251/*!
18252 * jQuery UI Effects Size 1.12.1
18253 * http://jqueryui.com
18254 *
18255 * Copyright jQuery Foundation and other contributors
18256 * Released under the MIT license.
18257 * http://jquery.org/license
18258 */
18259
18260//>>label: Size Effect
18261//>>group: Effects
18262//>>description: Resize an element to a specified width and height.
18263//>>docs: http://api.jqueryui.com/size-effect/
18264//>>demos: http://jqueryui.com/effect/
18265
18266
18267
18268var effectsEffectSize = $.effects.define( "size", function( options, done ) {
18269
18270	// Create element
18271	var baseline, factor, temp,
18272		element = $( this ),
18273
18274		// Copy for children
18275		cProps = [ "fontSize" ],
18276		vProps = [ "borderTopWidth", "borderBottomWidth", "paddingTop", "paddingBottom" ],
18277		hProps = [ "borderLeftWidth", "borderRightWidth", "paddingLeft", "paddingRight" ],
18278
18279		// Set options
18280		mode = options.mode,
18281		restore = mode !== "effect",
18282		scale = options.scale || "both",
18283		origin = options.origin || [ "middle", "center" ],
18284		position = element.css( "position" ),
18285		pos = element.position(),
18286		original = $.effects.scaledDimensions( element ),
18287		from = options.from || original,
18288		to = options.to || $.effects.scaledDimensions( element, 0 );
18289
18290	$.effects.createPlaceholder( element );
18291
18292	if ( mode === "show" ) {
18293		temp = from;
18294		from = to;
18295		to = temp;
18296	}
18297
18298	// Set scaling factor
18299	factor = {
18300		from: {
18301			y: from.height / original.height,
18302			x: from.width / original.width
18303		},
18304		to: {
18305			y: to.height / original.height,
18306			x: to.width / original.width
18307		}
18308	};
18309
18310	// Scale the css box
18311	if ( scale === "box" || scale === "both" ) {
18312
18313		// Vertical props scaling
18314		if ( factor.from.y !== factor.to.y ) {
18315			from = $.effects.setTransition( element, vProps, factor.from.y, from );
18316			to = $.effects.setTransition( element, vProps, factor.to.y, to );
18317		}
18318
18319		// Horizontal props scaling
18320		if ( factor.from.x !== factor.to.x ) {
18321			from = $.effects.setTransition( element, hProps, factor.from.x, from );
18322			to = $.effects.setTransition( element, hProps, factor.to.x, to );
18323		}
18324	}
18325
18326	// Scale the content
18327	if ( scale === "content" || scale === "both" ) {
18328
18329		// Vertical props scaling
18330		if ( factor.from.y !== factor.to.y ) {
18331			from = $.effects.setTransition( element, cProps, factor.from.y, from );
18332			to = $.effects.setTransition( element, cProps, factor.to.y, to );
18333		}
18334	}
18335
18336	// Adjust the position properties based on the provided origin points
18337	if ( origin ) {
18338		baseline = $.effects.getBaseline( origin, original );
18339		from.top = ( original.outerHeight - from.outerHeight ) * baseline.y + pos.top;
18340		from.left = ( original.outerWidth - from.outerWidth ) * baseline.x + pos.left;
18341		to.top = ( original.outerHeight - to.outerHeight ) * baseline.y + pos.top;
18342		to.left = ( original.outerWidth - to.outerWidth ) * baseline.x + pos.left;
18343	}
18344	element.css( from );
18345
18346	// Animate the children if desired
18347	if ( scale === "content" || scale === "both" ) {
18348
18349		vProps = vProps.concat( [ "marginTop", "marginBottom" ] ).concat( cProps );
18350		hProps = hProps.concat( [ "marginLeft", "marginRight" ] );
18351
18352		// Only animate children with width attributes specified
18353		// TODO: is this right? should we include anything with css width specified as well
18354		element.find( "*[width]" ).each( function() {
18355			var child = $( this ),
18356				childOriginal = $.effects.scaledDimensions( child ),
18357				childFrom = {
18358					height: childOriginal.height * factor.from.y,
18359					width: childOriginal.width * factor.from.x,
18360					outerHeight: childOriginal.outerHeight * factor.from.y,
18361					outerWidth: childOriginal.outerWidth * factor.from.x
18362				},
18363				childTo = {
18364					height: childOriginal.height * factor.to.y,
18365					width: childOriginal.width * factor.to.x,
18366					outerHeight: childOriginal.height * factor.to.y,
18367					outerWidth: childOriginal.width * factor.to.x
18368				};
18369
18370			// Vertical props scaling
18371			if ( factor.from.y !== factor.to.y ) {
18372				childFrom = $.effects.setTransition( child, vProps, factor.from.y, childFrom );
18373				childTo = $.effects.setTransition( child, vProps, factor.to.y, childTo );
18374			}
18375
18376			// Horizontal props scaling
18377			if ( factor.from.x !== factor.to.x ) {
18378				childFrom = $.effects.setTransition( child, hProps, factor.from.x, childFrom );
18379				childTo = $.effects.setTransition( child, hProps, factor.to.x, childTo );
18380			}
18381
18382			if ( restore ) {
18383				$.effects.saveStyle( child );
18384			}
18385
18386			// Animate children
18387			child.css( childFrom );
18388			child.animate( childTo, options.duration, options.easing, function() {
18389
18390				// Restore children
18391				if ( restore ) {
18392					$.effects.restoreStyle( child );
18393				}
18394			} );
18395		} );
18396	}
18397
18398	// Animate
18399	element.animate( to, {
18400		queue: false,
18401		duration: options.duration,
18402		easing: options.easing,
18403		complete: function() {
18404
18405			var offset = element.offset();
18406
18407			if ( to.opacity === 0 ) {
18408				element.css( "opacity", from.opacity );
18409			}
18410
18411			if ( !restore ) {
18412				element
18413					.css( "position", position === "static" ? "relative" : position )
18414					.offset( offset );
18415
18416				// Need to save style here so that automatic style restoration
18417				// doesn't restore to the original styles from before the animation.
18418				$.effects.saveStyle( element );
18419			}
18420
18421			done();
18422		}
18423	} );
18424
18425} );
18426
18427
18428/*!
18429 * jQuery UI Effects Scale 1.12.1
18430 * http://jqueryui.com
18431 *
18432 * Copyright jQuery Foundation and other contributors
18433 * Released under the MIT license.
18434 * http://jquery.org/license
18435 */
18436
18437//>>label: Scale Effect
18438//>>group: Effects
18439//>>description: Grows or shrinks an element and its content.
18440//>>docs: http://api.jqueryui.com/scale-effect/
18441//>>demos: http://jqueryui.com/effect/
18442
18443
18444
18445var effectsEffectScale = $.effects.define( "scale", function( options, done ) {
18446
18447	// Create element
18448	var el = $( this ),
18449		mode = options.mode,
18450		percent = parseInt( options.percent, 10 ) ||
18451			( parseInt( options.percent, 10 ) === 0 ? 0 : ( mode !== "effect" ? 0 : 100 ) ),
18452
18453		newOptions = $.extend( true, {
18454			from: $.effects.scaledDimensions( el ),
18455			to: $.effects.scaledDimensions( el, percent, options.direction || "both" ),
18456			origin: options.origin || [ "middle", "center" ]
18457		}, options );
18458
18459	// Fade option to support puff
18460	if ( options.fade ) {
18461		newOptions.from.opacity = 1;
18462		newOptions.to.opacity = 0;
18463	}
18464
18465	$.effects.effect.size.call( this, newOptions, done );
18466} );
18467
18468
18469/*!
18470 * jQuery UI Effects Puff 1.12.1
18471 * http://jqueryui.com
18472 *
18473 * Copyright jQuery Foundation and other contributors
18474 * Released under the MIT license.
18475 * http://jquery.org/license
18476 */
18477
18478//>>label: Puff Effect
18479//>>group: Effects
18480//>>description: Creates a puff effect by scaling the element up and hiding it at the same time.
18481//>>docs: http://api.jqueryui.com/puff-effect/
18482//>>demos: http://jqueryui.com/effect/
18483
18484
18485
18486var effectsEffectPuff = $.effects.define( "puff", "hide", function( options, done ) {
18487	var newOptions = $.extend( true, {}, options, {
18488		fade: true,
18489		percent: parseInt( options.percent, 10 ) || 150
18490	} );
18491
18492	$.effects.effect.scale.call( this, newOptions, done );
18493} );
18494
18495
18496/*!
18497 * jQuery UI Effects Pulsate 1.12.1
18498 * http://jqueryui.com
18499 *
18500 * Copyright jQuery Foundation and other contributors
18501 * Released under the MIT license.
18502 * http://jquery.org/license
18503 */
18504
18505//>>label: Pulsate Effect
18506//>>group: Effects
18507//>>description: Pulsates an element n times by changing the opacity to zero and back.
18508//>>docs: http://api.jqueryui.com/pulsate-effect/
18509//>>demos: http://jqueryui.com/effect/
18510
18511
18512
18513var effectsEffectPulsate = $.effects.define( "pulsate", "show", function( options, done ) {
18514	var element = $( this ),
18515		mode = options.mode,
18516		show = mode === "show",
18517		hide = mode === "hide",
18518		showhide = show || hide,
18519
18520		// Showing or hiding leaves off the "last" animation
18521		anims = ( ( options.times || 5 ) * 2 ) + ( showhide ? 1 : 0 ),
18522		duration = options.duration / anims,
18523		animateTo = 0,
18524		i = 1,
18525		queuelen = element.queue().length;
18526
18527	if ( show || !element.is( ":visible" ) ) {
18528		element.css( "opacity", 0 ).show();
18529		animateTo = 1;
18530	}
18531
18532	// Anims - 1 opacity "toggles"
18533	for ( ; i < anims; i++ ) {
18534		element.animate( { opacity: animateTo }, duration, options.easing );
18535		animateTo = 1 - animateTo;
18536	}
18537
18538	element.animate( { opacity: animateTo }, duration, options.easing );
18539
18540	element.queue( done );
18541
18542	$.effects.unshift( element, queuelen, anims + 1 );
18543} );
18544
18545
18546/*!
18547 * jQuery UI Effects Shake 1.12.1
18548 * http://jqueryui.com
18549 *
18550 * Copyright jQuery Foundation and other contributors
18551 * Released under the MIT license.
18552 * http://jquery.org/license
18553 */
18554
18555//>>label: Shake Effect
18556//>>group: Effects
18557//>>description: Shakes an element horizontally or vertically n times.
18558//>>docs: http://api.jqueryui.com/shake-effect/
18559//>>demos: http://jqueryui.com/effect/
18560
18561
18562
18563var effectsEffectShake = $.effects.define( "shake", function( options, done ) {
18564
18565	var i = 1,
18566		element = $( this ),
18567		direction = options.direction || "left",
18568		distance = options.distance || 20,
18569		times = options.times || 3,
18570		anims = times * 2 + 1,
18571		speed = Math.round( options.duration / anims ),
18572		ref = ( direction === "up" || direction === "down" ) ? "top" : "left",
18573		positiveMotion = ( direction === "up" || direction === "left" ),
18574		animation = {},
18575		animation1 = {},
18576		animation2 = {},
18577
18578		queuelen = element.queue().length;
18579
18580	$.effects.createPlaceholder( element );
18581
18582	// Animation
18583	animation[ ref ] = ( positiveMotion ? "-=" : "+=" ) + distance;
18584	animation1[ ref ] = ( positiveMotion ? "+=" : "-=" ) + distance * 2;
18585	animation2[ ref ] = ( positiveMotion ? "-=" : "+=" ) + distance * 2;
18586
18587	// Animate
18588	element.animate( animation, speed, options.easing );
18589
18590	// Shakes
18591	for ( ; i < times; i++ ) {
18592		element
18593			.animate( animation1, speed, options.easing )
18594			.animate( animation2, speed, options.easing );
18595	}
18596
18597	element
18598		.animate( animation1, speed, options.easing )
18599		.animate( animation, speed / 2, options.easing )
18600		.queue( done );
18601
18602	$.effects.unshift( element, queuelen, anims + 1 );
18603} );
18604
18605
18606/*!
18607 * jQuery UI Effects Slide 1.12.1
18608 * http://jqueryui.com
18609 *
18610 * Copyright jQuery Foundation and other contributors
18611 * Released under the MIT license.
18612 * http://jquery.org/license
18613 */
18614
18615//>>label: Slide Effect
18616//>>group: Effects
18617//>>description: Slides an element in and out of the viewport.
18618//>>docs: http://api.jqueryui.com/slide-effect/
18619//>>demos: http://jqueryui.com/effect/
18620
18621
18622
18623var effectsEffectSlide = $.effects.define( "slide", "show", function( options, done ) {
18624	var startClip, startRef,
18625		element = $( this ),
18626		map = {
18627			up: [ "bottom", "top" ],
18628			down: [ "top", "bottom" ],
18629			left: [ "right", "left" ],
18630			right: [ "left", "right" ]
18631		},
18632		mode = options.mode,
18633		direction = options.direction || "left",
18634		ref = ( direction === "up" || direction === "down" ) ? "top" : "left",
18635		positiveMotion = ( direction === "up" || direction === "left" ),
18636		distance = options.distance ||
18637			element[ ref === "top" ? "outerHeight" : "outerWidth" ]( true ),
18638		animation = {};
18639
18640	$.effects.createPlaceholder( element );
18641
18642	startClip = element.cssClip();
18643	startRef = element.position()[ ref ];
18644
18645	// Define hide animation
18646	animation[ ref ] = ( positiveMotion ? -1 : 1 ) * distance + startRef;
18647	animation.clip = element.cssClip();
18648	animation.clip[ map[ direction ][ 1 ] ] = animation.clip[ map[ direction ][ 0 ] ];
18649
18650	// Reverse the animation if we're showing
18651	if ( mode === "show" ) {
18652		element.cssClip( animation.clip );
18653		element.css( ref, animation[ ref ] );
18654		animation.clip = startClip;
18655		animation[ ref ] = startRef;
18656	}
18657
18658	// Actually animate
18659	element.animate( animation, {
18660		queue: false,
18661		duration: options.duration,
18662		easing: options.easing,
vendor: 637 bytes, lines 18663-18696
18663		complete: done
18664	} );
18665} );
18666
18667
18668/*!
18669 * jQuery UI Effects Transfer 1.12.1
18670 * http://jqueryui.com
18671 *
18672 * Copyright jQuery Foundation and other contributors
18673 * Released under the MIT license.
18674 * http://jquery.org/license
18675 */
18676
18677//>>label: Transfer Effect
18678//>>group: Effects
18679//>>description: Displays a transfer effect from one element to another.
18680//>>docs: http://api.jqueryui.com/transfer-effect/
18681//>>demos: http://jqueryui.com/effect/
18682
18683
18684
18685var effect;
18686if ( $.uiBackCompat !== false ) {
18687	effect = $.effects.define( "transfer", function( options, done ) {
18688		$( this ).transfer( options, done );
18689	} );
18690}
18691var effectsEffectTransfer = effect;
18692
18693
18694
18695
18696}));

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.