PageSourceSearch

https://pitercomfort.ru/bitrix/templates/concept_phoenix_s1/js/jquery-ui.min.js?1744023087519734

js pitercomfort.ru collected 2026-09-30 11:54:39 UTC 519,734 bytes, 18,166 lines download raw bytes

vendor: 16,384 bytes, lines 1-680
1
2
3(function( factory ) {
4	if ( typeof define === "function" && define.amd ) {
5
6		
7		define([ "jquery" ], factory );
8	} else {
9
10		factory( jQuery );
11	}
12}(function( $ ) {
13
14$.ui = $.ui || {};
15
16var version = $.ui.version = "1.12.1";
17
18var widgetUuid = 0;
19var widgetSlice = Array.prototype.slice;
20
21$.cleanData = ( function( orig ) {
22	return function( elems ) {
23		var events, elem, i;
24		for ( i = 0; ( elem = elems[ i ] ) != null; i++ ) {
25			try {
26
27				
28				events = $._data( elem, "events" );
29				if ( events && events.remove ) {
30					$( elem ).triggerHandler( "remove" );
31				}
32
33			} catch ( e ) {}
34		}
35		orig( elems );
36	};
37} )( $.cleanData );
38
39$.widget = function( name, base, prototype ) {
40	var existingConstructor, constructor, basePrototype;
41
42	var proxiedPrototype = {};
43
44	var namespace = name.split( "." )[ 0 ];
45	name = name.split( "." )[ 1 ];
46	var fullName = namespace + "-" + name;
47
48	if ( !prototype ) {
49		prototype = base;
50		base = $.Widget;
51	}
52
53	if ( $.isArray( prototype ) ) {
54		prototype = $.extend.apply( null, [ {} ].concat( prototype ) );
55	}
56
57	
58	$.expr[ ":" ][ fullName.toLowerCase() ] = function( elem ) {
59		return !!$.data( elem, fullName );
60	};
61
62	$[ namespace ] = $[ namespace ] || {};
63	existingConstructor = $[ namespace ][ name ];
64	constructor = $[ namespace ][ name ] = function( options, element ) {
65
66		
67		if ( !this._createWidget ) {
68			return new constructor( options, element );
69		}
70
71		
72		if ( arguments.length ) {
73			this._createWidget( options, element );
74		}
75	};
76
77	
78	$.extend( constructor, existingConstructor, {
79		version: prototype.version,
80
81		
82		_proto: $.extend( {}, prototype ),
83
84		
85		_childConstructors: []
86	} );
87
88	basePrototype = new base();
89
90	
91	basePrototype.options = $.widget.extend( {}, basePrototype.options );
92	$.each( prototype, function( prop, value ) {
93		if ( !$.isFunction( value ) ) {
94			proxiedPrototype[ prop ] = value;
95			return;
96		}
97		proxiedPrototype[ prop ] = ( function() {
98			function _super() {
99				return base.prototype[ prop ].apply( this, arguments );
100			}
101
102			function _superApply( args ) {
103				return base.prototype[ prop ].apply( this, args );
104			}
105
106			return function() {
107				var __super = this._super;
108				var __superApply = this._superApply;
109				var returnValue;
110
111				this._super = _super;
112				this._superApply = _superApply;
113
114				returnValue = value.apply( this, arguments );
115
116				this._super = __super;
117				this._superApply = __superApply;
118
119				return returnValue;
120			};
121		} )();
122	} );
123	constructor.prototype = $.widget.extend( basePrototype, {
124
125		
126		widgetEventPrefix: existingConstructor ? ( basePrototype.widgetEventPrefix || name ) : name
127	}, proxiedPrototype, {
128		constructor: constructor,
129		namespace: namespace,
130		widgetName: name,
131		widgetFullName: fullName
132	} );
133
134	
135	if ( existingConstructor ) {
136		$.each( existingConstructor._childConstructors, function( i, child ) {
137			var childPrototype = child.prototype;
138
139			
140			$.widget( childPrototype.namespace + "." + childPrototype.widgetName, constructor,
141				child._proto );
142		} );
143
144		
145		delete existingConstructor._childConstructors;
146	} else {
147		base._childConstructors.push( constructor );
148	}
149
150	$.widget.bridge( name, constructor );
151
152	return constructor;
153};
154
155$.widget.extend = function( target ) {
156	var input = widgetSlice.call( arguments, 1 );
157	var inputIndex = 0;
158	var inputLength = input.length;
159	var key;
160	var value;
161
162	for ( ; inputIndex < inputLength; inputIndex++ ) {
163		for ( key in input[ inputIndex ] ) {
164			value = input[ inputIndex ][ key ];
165			if ( input[ inputIndex ].hasOwnProperty( key ) && value !== undefined ) {
166
167				
168				if ( $.isPlainObject( value ) ) {
169					target[ key ] = $.isPlainObject( target[ key ] ) ?
170						$.widget.extend( {}, target[ key ], value ) :
171
172						
173						$.widget.extend( {}, value );
174
175				
176				} else {
177					target[ key ] = value;
178				}
179			}
180		}
181	}
182	return target;
183};
184
185$.widget.bridge = function( name, object ) {
186	var fullName = object.prototype.widgetFullName || name;
187	$.fn[ name ] = function( options ) {
188		var isMethodCall = typeof options === "string";
189		var args = widgetSlice.call( arguments, 1 );
190		var returnValue = this;
191
192		if ( isMethodCall ) {
193
194			
195			if ( !this.length && options === "instance" ) {
196				returnValue = undefined;
197			} else {
198				this.each( function() {
199					var methodValue;
200					var instance = $.data( this, fullName );
201
202					if ( options === "instance" ) {
203						returnValue = instance;
204						return false;
205					}
206
207					if ( !instance ) {
208						return $.error( "cannot call methods on " + name +
209							" prior to initialization; " +
210							"attempted to call method '" + options + "'" );
211					}
212
213					if ( !$.isFunction( instance[ options ] ) || options.charAt( 0 ) === "_" ) {
214						return $.error( "no such method '" + options + "' for " + name +
215							" widget instance" );
216					}
217
218					methodValue = instance[ options ].apply( instance, args );
219
220					if ( methodValue !== instance && methodValue !== undefined ) {
221						returnValue = methodValue && methodValue.jquery ?
222							returnValue.pushStack( methodValue.get() ) :
223							methodValue;
224						return false;
225					}
226				} );
227			}
228		} else {
229
230			
231			if ( args.length ) {
232				options = $.widget.extend.apply( null, [ options ].concat( args ) );
233			}
234
235			this.each( function() {
236				var instance = $.data( this, fullName );
237				if ( instance ) {
238					instance.option( options || {} );
239					if ( instance._init ) {
240						instance._init();
241					}
242				} else {
243					$.data( this, fullName, new object( options, this ) );
244				}
245			} );
246		}
247
248		return returnValue;
249	};
250};
251
252$.Widget = function( /* options, element */ ) {};
253$.Widget._childConstructors = [];
254
255$.Widget.prototype = {
256	widgetName: "widget",
257	widgetEventPrefix: "",
258	defaultElement: "<div>",
259
260	options: {
261		classes: {},
262		disabled: false,
263
264		
265		create: null
266	},
267
268	_createWidget: function( options, element ) {
269		element = $( element || this.defaultElement || this )[ 0 ];
270		this.element = $( element );
271		this.uuid = widgetUuid++;
272		this.eventNamespace = "." + this.widgetName + this.uuid;
273
274		this.bindings = $();
275		this.hoverable = $();
276		this.focusable = $();
277		this.classesElementLookup = {};
278
279		if ( element !== this ) {
280			$.data( element, this.widgetFullName, this );
281			this._on( true, this.element, {
282				remove: function( event ) {
283					if ( event.target === element ) {
284						this.destroy();
285					}
286				}
287			} );
288			this.document = $( element.style ?
289
290				
291				element.ownerDocument :
292
293				
294				element.document || element );
295			this.window = $( this.document[ 0 ].defaultView || this.document[ 0 ].parentWindow );
296		}
297
298		this.options = $.widget.extend( {},
299			this.options,
300			this._getCreateOptions(),
301			options );
302
303		this._create();
304
305		if ( this.options.disabled ) {
306			this._setOptionDisabled( this.options.disabled );
307		}
308
309		this._trigger( "create", null, this._getCreateEventData() );
310		this._init();
311	},
312
313	_getCreateOptions: function() {
314		return {};
315	},
316
317	_getCreateEventData: $.noop,
318
319	_create: $.noop,
320
321	_init: $.noop,
322
323	destroy: function() {
324		var that = this;
325
326		this._destroy();
327		$.each( this.classesElementLookup, function( key, value ) {
328			that._removeClass( value, key );
329		} );
330
331		
332		this.element
333			.off( this.eventNamespace )
334			.removeData( this.widgetFullName );
335		this.widget()
336			.off( this.eventNamespace )
337			.removeAttr( "aria-disabled" );
338
339		
340		this.bindings.off( this.eventNamespace );
341	},
342
343	_destroy: $.noop,
344
345	widget: function() {
346		return this.element;
347	},
348
349	option: function( key, value ) {
350		var options = key;
351		var parts;
352		var curOption;
353		var i;
354
355		if ( arguments.length === 0 ) {
356
357			
358			return $.widget.extend( {}, this.options );
359		}
360
361		if ( typeof key === "string" ) {
362
363			
364			options = {};
365			parts = key.split( "." );
366			key = parts.shift();
367			if ( parts.length ) {
368				curOption = options[ key ] = $.widget.extend( {}, this.options[ key ] );
369				for ( i = 0; i < parts.length - 1; i++ ) {
370					curOption[ parts[ i ] ] = curOption[ parts[ i ] ] || {};
371					curOption = curOption[ parts[ i ] ];
372				}
373				key = parts.pop();
374				if ( arguments.length === 1 ) {
375					return curOption[ key ] === undefined ? null : curOption[ key ];
376				}
377				curOption[ key ] = value;
378			} else {
379				if ( arguments.length === 1 ) {
380					return this.options[ key ] === undefined ? null : this.options[ key ];
381				}
382				options[ key ] = value;
383			}
384		}
385
386		this._setOptions( options );
387
388		return this;
389	},
390
391	_setOptions: function( options ) {
392		var key;
393
394		for ( key in options ) {
395			this._setOption( key, options[ key ] );
396		}
397
398		return this;
399	},
400
401	_setOption: function( key, value ) {
402		if ( key === "classes" ) {
403			this._setOptionClasses( value );
404		}
405
406		this.options[ key ] = value;
407
408		if ( key === "disabled" ) {
409			this._setOptionDisabled( value );
410		}
411
412		return this;
413	},
414
415	_setOptionClasses: function( value ) {
416		var classKey, elements, currentElements;
417
418		for ( classKey in value ) {
419			currentElements = this.classesElementLookup[ classKey ];
420			if ( value[ classKey ] === this.options.classes[ classKey ] ||
421					!currentElements ||
422					!currentElements.length ) {
423				continue;
424			}
425
426			
427			elements = $( currentElements.get() );
428			this._removeClass( currentElements, classKey );
429
430			elements.addClass( this._classes( {
431				element: elements,
432				keys: classKey,
433				classes: value,
434				add: true
435			} ) );
436		}
437	},
438
439	_setOptionDisabled: function( value ) {
440		this._toggleClass( this.widget(), this.widgetFullName + "-disabled", null, !!value );
441
442		
443		if ( value ) {
444			this._removeClass( this.hoverable, null, "ui-state-hover" );
445			this._removeClass( this.focusable, null, "ui-state-focus" );
446		}
447	},
448
449	enable: function() {
450		return this._setOptions( { disabled: false } );
451	},
452
453	disable: function() {
454		return this._setOptions( { disabled: true } );
455	},
456
457	_classes: function( options ) {
458		var full = [];
459		var that = this;
460
461		options = $.extend( {
462			element: this.element,
463			classes: this.options.classes || {}
464		}, options );
465
466		function processClassString( classes, checkOption ) {
467			var current, i;
468			for ( i = 0; i < classes.length; i++ ) {
469				current = that.classesElementLookup[ classes[ i ] ] || $();
470				if ( options.add ) {
471					current = $( $.unique( current.get().concat( options.element.get() ) ) );
472				} else {
473					current = $( current.not( options.element ).get() );
474				}
475				that.classesElementLookup[ classes[ i ] ] = current;
476				full.push( classes[ i ] );
477				if ( checkOption && options.classes[ classes[ i ] ] ) {
478					full.push( options.classes[ classes[ i ] ] );
479				}
480			}
481		}
482
483		this._on( options.element, {
484			"remove": "_untrackClassesElement"
485		} );
486
487		if ( options.keys ) {
488			processClassString( options.keys.match( /\S+/g ) || [], true );
489		}
490		if ( options.extra ) {
491			processClassString( options.extra.match( /\S+/g ) || [] );
492		}
493
494		return full.join( " " );
495	},
496
497	_untrackClassesElement: function( event ) {
498		var that = this;
499		$.each( that.classesElementLookup, function( key, value ) {
500			if ( $.inArray( event.target, value ) !== -1 ) {
501				that.classesElementLookup[ key ] = $( value.not( event.target ).get() );
502			}
503		} );
504	},
505
506	_removeClass: function( element, keys, extra ) {
507		return this._toggleClass( element, keys, extra, false );
508	},
509
510	_addClass: function( element, keys, extra ) {
511		return this._toggleClass( element, keys, extra, true );
512	},
513
514	_toggleClass: function( element, keys, extra, add ) {
515		add = ( typeof add === "boolean" ) ? add : extra;
516		var shift = ( typeof element === "string" || element === null ),
517			options = {
518				extra: shift ? keys : extra,
519				keys: shift ? element : keys,
520				element: shift ? this.element : element,
521				add: add
522			};
523		options.element.toggleClass( this._classes( options ), add );
524		return this;
525	},
526
527	_on: function( suppressDisabledCheck, element, handlers ) {
528		var delegateElement;
529		var instance = this;
530
531		
532		if ( typeof suppressDisabledCheck !== "boolean" ) {
533			handlers = element;
534			element = suppressDisabledCheck;
535			suppressDisabledCheck = false;
536		}
537
538		
539		if ( !handlers ) {
540			handlers = element;
541			element = this.element;
542			delegateElement = this.widget();
543		} else {
544			element = delegateElement = $( element );
545			this.bindings = this.bindings.add( element );
546		}
547
548		$.each( handlers, function( event, handler ) {
549			function handlerProxy() {
550
551				
552				if ( !suppressDisabledCheck &&
553						( instance.options.disabled === true ||
554						$( this ).hasClass( "ui-state-disabled" ) ) ) {
555					return;
556				}
557				return ( typeof handler === "string" ? instance[ handler ] : handler )
558					.apply( instance, arguments );
559			}
560
561			
562			if ( typeof handler !== "string" ) {
563				handlerProxy.guid = handler.guid =
564					handler.guid || handlerProxy.guid || $.guid++;
565			}
566
567			var match = event.match( /^([\w:-]*)\s*(.*)$/ );
568			var eventName = match[ 1 ] + instance.eventNamespace;
569			var selector = match[ 2 ];
570
571			if ( selector ) {
572				delegateElement.on( eventName, selector, handlerProxy );
573			} else {
574				element.on( eventName, handlerProxy );
575			}
576		} );
577	},
578
579	_off: function( element, eventName ) {
580		eventName = ( eventName || "" ).split( " " ).join( this.eventNamespace + " " ) +
581			this.eventNamespace;
582		element.off( eventName ).off( eventName );
583
584		
585		this.bindings = $( this.bindings.not( element ).get() );
586		this.focusable = $( this.focusable.not( element ).get() );
587		this.hoverable = $( this.hoverable.not( element ).get() );
588	},
589
590	_delay: function( handler, delay ) {
591		function handlerProxy() {
592			return ( typeof handler === "string" ? instance[ handler ] : handler )
593				.apply( instance, arguments );
594		}
595		var instance = this;
596		return setTimeout( handlerProxy, delay || 0 );
597	},
598
599	_hoverable: function( element ) {
600		this.hoverable = this.hoverable.add( element );
601		this._on( element, {
602			mouseenter: function( event ) {
603				this._addClass( $( event.currentTarget ), null, "ui-state-hover" );
604			},
605			mouseleave: function( event ) {
606				this._removeClass( $( event.currentTarget ), null, "ui-state-hover" );
607			}
608		} );
609	},
610
611	_focusable: function( element ) {
612		this.focusable = this.focusable.add( element );
613		this._on( element, {
614			focusin: function( event ) {
615				this._addClass( $( event.currentTarget ), null, "ui-state-focus" );
616			},
617			focusout: function( event ) {
618				this._removeClass( $( event.currentTarget ), null, "ui-state-focus" );
619			}
620		} );
621	},
622
623	_trigger: function( type, event, data ) {
624		var prop, orig;
625		var callback = this.options[ type ];
626
627		data = data || {};
628		event = $.Event( event );
629		event.type = ( type === this.widgetEventPrefix ?
630			type :
631			this.widgetEventPrefix + type ).toLowerCase();
632
633		
634		event.target = this.element[ 0 ];
635
636		
637		orig = event.originalEvent;
638		if ( orig ) {
639			for ( prop in orig ) {
640				if ( !( prop in event ) ) {
641					event[ prop ] = orig[ prop ];
642				}
643			}
644		}
645
646		this.element.trigger( event, data );
647		return !( $.isFunction( callback ) &&
648			callback.apply( this.element[ 0 ], [ event ].concat( data ) ) === false ||
649			event.isDefaultPrevented() );
650	}
651};
652
653$.each( { show: "fadeIn", hide: "fadeOut" }, function( method, defaultEffect ) {
654	$.Widget.prototype[ "_" + method ] = function( element, options, callback ) {
655		if ( typeof options === "string" ) {
656			options = { effect: options };
657		}
658
659		var hasOptions;
660		var effectName = !options ?
661			method :
662			options === true || typeof options === "number" ?
663				defaultEffect :
664				options.effect || defaultEffect;
665
666		options = options || {};
667		if ( typeof options === "number" ) {
668			options = { duration: options };
669		}
670
671		hasOptions = !$.isEmptyObject( options );
672		options.complete = callback;
673
674		if ( options.delay ) {
675			element.delay( options.delay );
676		}
677
678		if ( hasOptions && $.effects && $.effects.effect[ effectName ] ) {
679			element[ method ]( options );
680		} else if ( effectName !
vendor: 4,515 bytes, lines 680-844
680== method && element[ effectName ] ) {
681			element[ effectName ]( options.duration, options.easing, callback );
682		} else {
683			element.queue( function( next ) {
684				$( this )[ method ]();
685				if ( callback ) {
686					callback.call( element[ 0 ] );
687				}
688				next();
689			} );
690		}
691	};
692} );
693
694var widget = $.widget;
695
696
697
698
699( function() {
700var cachedScrollbarWidth,
701	max = Math.max,
702	abs = Math.abs,
703	rhorizontal = /left|center|right/,
704	rvertical = /top|center|bottom/,
705	roffset = /[\+\-]\d+(\.[\d]+)?%?/,
706	rposition = /^\w+/,
707	rpercent = /%$/,
708	_position = $.fn.position;
709
710function getOffsets( offsets, width, height ) {
711	return [
712		parseFloat( offsets[ 0 ] ) * ( rpercent.test( offsets[ 0 ] ) ? width / 100 : 1 ),
713		parseFloat( offsets[ 1 ] ) * ( rpercent.test( offsets[ 1 ] ) ? height / 100 : 1 )
714	];
715}
716
717function parseCss( element, property ) {
718	return parseInt( $.css( element, property ), 10 ) || 0;
719}
720
721function getDimensions( elem ) {
722	var raw = elem[ 0 ];
723	if ( raw.nodeType === 9 ) {
724		return {
725			width: elem.width(),
726			height: elem.height(),
727			offset: { top: 0, left: 0 }
728		};
729	}
730	if ( $.isWindow( raw ) ) {
731		return {
732			width: elem.width(),
733			height: elem.height(),
734			offset: { top: elem.scrollTop(), left: elem.scrollLeft() }
735		};
736	}
737	if ( raw.preventDefault ) {
738		return {
739			width: 0,
740			height: 0,
741			offset: { top: raw.pageY, left: raw.pageX }
742		};
743	}
744	return {
745		width: elem.outerWidth(),
746		height: elem.outerHeight(),
747		offset: elem.offset()
748	};
749}
750
751$.position = {
752	scrollbarWidth: function() {
753		if ( cachedScrollbarWidth !== undefined ) {
754			return cachedScrollbarWidth;
755		}
756		var w1, w2,
757			div = $( "<div " +
758				"style='display:block;position:absolute;width:50px;height:50px;overflow:hidden;'>" +
759				"<div style='height:100px;width:auto;'></div></div>" ),
760			innerDiv = div.children()[ 0 ];
761
762		$( "body" ).append( div );
763		w1 = innerDiv.offsetWidth;
764		div.css( "overflow", "scroll" );
765
766		w2 = innerDiv.offsetWidth;
767
768		if ( w1 === w2 ) {
769			w2 = div[ 0 ].clientWidth;
770		}
771
772		div.remove();
773
774		return ( cachedScrollbarWidth = w1 - w2 );
775	},
776	getScrollInfo: function( within ) {
777		var overflowX = within.isWindow || within.isDocument ? "" :
778				within.element.css( "overflow-x" ),
779			overflowY = within.isWindow || within.isDocument ? "" :
780				within.element.css( "overflow-y" ),
781			hasOverflowX = overflowX === "scroll" ||
782				( overflowX === "auto" && within.width < within.element[ 0 ].scrollWidth ),
783			hasOverflowY = overflowY === "scroll" ||
784				( overflowY === "auto" && within.height < within.element[ 0 ].scrollHeight );
785		return {
786			width: hasOverflowY ? $.position.scrollbarWidth() : 0,
787			height: hasOverflowX ? $.position.scrollbarWidth() : 0
788		};
789	},
790	getWithinInfo: function( element ) {
791		var withinElement = $( element || window ),
792			isWindow = $.isWindow( withinElement[ 0 ] ),
793			isDocument = !!withinElement[ 0 ] && withinElement[ 0 ].nodeType === 9,
794			hasOffset = !isWindow && !isDocument;
795		return {
796			element: withinElement,
797			isWindow: isWindow,
798			isDocument: isDocument,
799			offset: hasOffset ? $( element ).offset() : { left: 0, top: 0 },
800			scrollLeft: withinElement.scrollLeft(),
801			scrollTop: withinElement.scrollTop(),
802			width: withinElement.outerWidth(),
803			height: withinElement.outerHeight()
804		};
805	}
806};
807
808$.fn.position = function( options ) {
809	if ( !options || !options.of ) {
810		return _position.apply( this, arguments );
811	}
812
813	
814	options = $.extend( {}, options );
815
816	var atOffset, targetWidth, targetHeight, targetOffset, basePosition, dimensions,
817		target = $( options.of ),
818		within = $.position.getWithinInfo( options.within ),
819		scrollInfo = $.position.getScrollInfo( within ),
820		collision = ( options.collision || "flip" ).split( " " ),
821		offsets = {};
822
823	dimensions = getDimensions( target );
824	if ( target[ 0 ].preventDefault ) {
825
826		
827		options.at = "left top";
828	}
829	targetWidth = dimensions.width;
830	targetHeight = dimensions.height;
831	targetOffset = dimensions.offset;
832
833	// Clone to reuse original targetOffset later
834	basePosition = $.extend( {}, targetOffset );
835
836	// Force my and at to have valid horizontal and vertical positions
837	// if a value is missing or invalid, it will be converted to center
838	$.each( [ "my", "at" ], function() {
839		var pos = ( options[ this ] || "" ).split( " " ),
840			horizontalOffset,
841			verticalOffset;
842
843		if ( pos.length === 1 ) {
844			pos = rhorizontal.test( pos[ 0 ] ) ?
vendor: 10,483 bytes, lines 845-1171
845				pos.concat( [ "center" ] ) :
846				rvertical.test( pos[ 0 ] ) ?
847					[ "center" ].concat( pos ) :
848					[ "center", "center" ];
849		}
850		pos[ 0 ] = rhorizontal.test( pos[ 0 ] ) ? pos[ 0 ] : "center";
851		pos[ 1 ] = rvertical.test( pos[ 1 ] ) ? pos[ 1 ] : "center";
852
853		// Calculate offsets
854		horizontalOffset = roffset.exec( pos[ 0 ] );
855		verticalOffset = roffset.exec( pos[ 1 ] );
856		offsets[ this ] = [
857			horizontalOffset ? horizontalOffset[ 0 ] : 0,
858			verticalOffset ? verticalOffset[ 0 ] : 0
859		];
860
861		// Reduce to just the positions without the offsets
862		options[ this ] = [
863			rposition.exec( pos[ 0 ] )[ 0 ],
864			rposition.exec( pos[ 1 ] )[ 0 ]
865		];
866	} );
867
868	// Normalize collision option
869	if ( collision.length === 1 ) {
870		collision[ 1 ] = collision[ 0 ];
871	}
872
873	if ( options.at[ 0 ] === "right" ) {
874		basePosition.left += targetWidth;
875	} else if ( options.at[ 0 ] === "center" ) {
876		basePosition.left += targetWidth / 2;
877	}
878
879	if ( options.at[ 1 ] === "bottom" ) {
880		basePosition.top += targetHeight;
881	} else if ( options.at[ 1 ] === "center" ) {
882		basePosition.top += targetHeight / 2;
883	}
884
885	atOffset = getOffsets( offsets.at, targetWidth, targetHeight );
886	basePosition.left += atOffset[ 0 ];
887	basePosition.top += atOffset[ 1 ];
888
889	return this.each( function() {
890		var collisionPosition, using,
891			elem = $( this ),
892			elemWidth = elem.outerWidth(),
893			elemHeight = elem.outerHeight(),
894			marginLeft = parseCss( this, "marginLeft" ),
895			marginTop = parseCss( this, "marginTop" ),
896			collisionWidth = elemWidth + marginLeft + parseCss( this, "marginRight" ) +
897				scrollInfo.width,
898			collisionHeight = elemHeight + marginTop + parseCss( this, "marginBottom" ) +
899				scrollInfo.height,
900			position = $.extend( {}, basePosition ),
901			myOffset = getOffsets( offsets.my, elem.outerWidth(), elem.outerHeight() );
902
903		if ( options.my[ 0 ] === "right" ) {
904			position.left -= elemWidth;
905		} else if ( options.my[ 0 ] === "center" ) {
906			position.left -= elemWidth / 2;
907		}
908
909		if ( options.my[ 1 ] === "bottom" ) {
910			position.top -= elemHeight;
911		} else if ( options.my[ 1 ] === "center" ) {
912			position.top -= elemHeight / 2;
913		}
914
915		position.left += myOffset[ 0 ];
916		position.top += myOffset[ 1 ];
917
918		collisionPosition = {
919			marginLeft: marginLeft,
920			marginTop: marginTop
921		};
922
923		$.each( [ "left", "top" ], function( i, dir ) {
924			if ( $.ui.position[ collision[ i ] ] ) {
925				$.ui.position[ collision[ i ] ][ dir ]( position, {
926					targetWidth: targetWidth,
927					targetHeight: targetHeight,
928					elemWidth: elemWidth,
929					elemHeight: elemHeight,
930					collisionPosition: collisionPosition,
931					collisionWidth: collisionWidth,
932					collisionHeight: collisionHeight,
933					offset: [ atOffset[ 0 ] + myOffset[ 0 ], atOffset [ 1 ] + myOffset[ 1 ] ],
934					my: options.my,
935					at: options.at,
936					within: within,
937					elem: elem
938				} );
939			}
940		} );
941
942		if ( options.using ) {
943
944			// Adds feedback as second argument to using callback, if present
945			using = function( props ) {
946				var left = targetOffset.left - position.left,
947					right = left + targetWidth - elemWidth,
948					top = targetOffset.top - position.top,
949					bottom = top + targetHeight - elemHeight,
950					feedback = {
951						target: {
952							element: target,
953							left: targetOffset.left,
954							top: targetOffset.top,
955							width: targetWidth,
956							height: targetHeight
957						},
958						element: {
959							element: elem,
960							left: position.left,
961							top: position.top,
962							width: elemWidth,
963							height: elemHeight
964						},
965						horizontal: right < 0 ? "left" : left > 0 ? "right" : "center",
966						vertical: bottom < 0 ? "top" : top > 0 ? "bottom" : "middle"
967					};
968				if ( targetWidth < elemWidth && abs( left + right ) < targetWidth ) {
969					feedback.horizontal = "center";
970				}
971				if ( targetHeight < elemHeight && abs( top + bottom ) < targetHeight ) {
972					feedback.vertical = "middle";
973				}
974				if ( max( abs( left ), abs( right ) ) > max( abs( top ), abs( bottom ) ) ) {
975					feedback.important = "horizontal";
976				} else {
977					feedback.important = "vertical";
978				}
979				options.using.call( this, props, feedback );
980			};
981		}
982
983		elem.offset( $.extend( position, { using: using } ) );
984	} );
985};
986
987$.ui.position = {
988	fit: {
989		left: function( position, data ) {
990			var within = data.within,
991				withinOffset = within.isWindow ? within.scrollLeft : within.offset.left,
992				outerWidth = within.width,
993				collisionPosLeft = position.left - data.collisionPosition.marginLeft,
994				overLeft = withinOffset - collisionPosLeft,
995				overRight = collisionPosLeft + data.collisionWidth - outerWidth - withinOffset,
996				newOverRight;
997
998			// Element is wider than within
999			if ( data.collisionWidth > outerWidth ) {
1000
1001				// Element is initially over the left side of within
1002				if ( overLeft > 0 && overRight <= 0 ) {
1003					newOverRight = position.left + overLeft + data.collisionWidth - outerWidth -
1004						withinOffset;
1005					position.left += overLeft - newOverRight;
1006
1007				// Element is initially over right side of within
1008				} else if ( overRight > 0 && overLeft <= 0 ) {
1009					position.left = withinOffset;
1010
1011				// Element is initially over both left and right sides of within
1012				} else {
1013					if ( overLeft > overRight ) {
1014						position.left = withinOffset + outerWidth - data.collisionWidth;
1015					} else {
1016						position.left = withinOffset;
1017					}
1018				}
1019
1020			// Too far left -> align with left edge
1021			} else if ( overLeft > 0 ) {
1022				position.left += overLeft;
1023
1024			// Too far right -> align with right edge
1025			} else if ( overRight > 0 ) {
1026				position.left -= overRight;
1027
1028			// Adjust based on position and margin
1029			} else {
1030				position.left = max( position.left - collisionPosLeft, position.left );
1031			}
1032		},
1033		top: function( position, data ) {
1034			var within = data.within,
1035				withinOffset = within.isWindow ? within.scrollTop : within.offset.top,
1036				outerHeight = data.within.height,
1037				collisionPosTop = position.top - data.collisionPosition.marginTop,
1038				overTop = withinOffset - collisionPosTop,
1039				overBottom = collisionPosTop + data.collisionHeight - outerHeight - withinOffset,
1040				newOverBottom;
1041
1042			// Element is taller than within
1043			if ( data.collisionHeight > outerHeight ) {
1044
1045				// Element is initially over the top of within
1046				if ( overTop > 0 && overBottom <= 0 ) {
1047					newOverBottom = position.top + overTop + data.collisionHeight - outerHeight -
1048						withinOffset;
1049					position.top += overTop - newOverBottom;
1050
1051				// Element is initially over bottom of within
1052				} else if ( overBottom > 0 && overTop <= 0 ) {
1053					position.top = withinOffset;
1054
1055				// Element is initially over both top and bottom of within
1056				} else {
1057					if ( overTop > overBottom ) {
1058						position.top = withinOffset + outerHeight - data.collisionHeight;
1059					} else {
1060						position.top = withinOffset;
1061					}
1062				}
1063
1064			// Too far up -> align with top
1065			} else if ( overTop > 0 ) {
1066				position.top += overTop;
1067
1068			// Too far down -> align with bottom edge
1069			} else if ( overBottom > 0 ) {
1070				position.top -= overBottom;
1071
1072			// Adjust based on position and margin
1073			} else {
1074				position.top = max( position.top - collisionPosTop, position.top );
1075			}
1076		}
1077	},
1078	flip: {
1079		left: function( position, data ) {
1080			var within = data.within,
1081				withinOffset = within.offset.left + within.scrollLeft,
1082				outerWidth = within.width,
1083				offsetLeft = within.isWindow ? within.scrollLeft : within.offset.left,
1084				collisionPosLeft = position.left - data.collisionPosition.marginLeft,
1085				overLeft = collisionPosLeft - offsetLeft,
1086				overRight = collisionPosLeft + data.collisionWidth - outerWidth - offsetLeft,
1087				myOffset = data.my[ 0 ] === "left" ?
1088					-data.elemWidth :
1089					data.my[ 0 ] === "right" ?
1090						data.elemWidth :
1091						0,
1092				atOffset = data.at[ 0 ] === "left" ?
1093					data.targetWidth :
1094					data.at[ 0 ] === "right" ?
1095						-data.targetWidth :
1096						0,
1097				offset = -2 * data.offset[ 0 ],
1098				newOverRight,
1099				newOverLeft;
1100
1101			if ( overLeft < 0 ) {
1102				newOverRight = position.left + myOffset + atOffset + offset + data.collisionWidth -
1103					outerWidth - withinOffset;
1104				if ( newOverRight < 0 || newOverRight < abs( overLeft ) ) {
1105					position.left += myOffset + atOffset + offset;
1106				}
1107			} else if ( overRight > 0 ) {
1108				newOverLeft = position.left - data.collisionPosition.marginLeft + myOffset +
1109					atOffset + offset - offsetLeft;
1110				if ( newOverLeft > 0 || abs( newOverLeft ) < overRight ) {
1111					position.left += myOffset + atOffset + offset;
1112				}
1113			}
1114		},
1115		top: function( position, data ) {
1116			var within = data.within,
1117				withinOffset = within.offset.top + within.scrollTop,
1118				outerHeight = within.height,
1119				offsetTop = within.isWindow ? within.scrollTop : within.offset.top,
1120				collisionPosTop = position.top - data.collisionPosition.marginTop,
1121				overTop = collisionPosTop - offsetTop,
1122				overBottom = collisionPosTop + data.collisionHeight - outerHeight - offsetTop,
1123				top = data.my[ 1 ] === "top",
1124				myOffset = top ?
1125					-data.elemHeight :
1126					data.my[ 1 ] === "bottom" ?
1127						data.elemHeight :
1128						0,
1129				atOffset = data.at[ 1 ] === "top" ?
1130					data.targetHeight :
1131					data.at[ 1 ] === "bottom" ?
1132						-data.targetHeight :
1133						0,
1134				offset = -2 * data.offset[ 1 ],
1135				newOverTop,
1136				newOverBottom;
1137			if ( overTop < 0 ) {
1138				newOverBottom = position.top + myOffset + atOffset + offset + data.collisionHeight -
1139					outerHeight - withinOffset;
1140				if ( newOverBottom < 0 || newOverBottom < abs( overTop ) ) {
1141					position.top += myOffset + atOffset + offset;
1142				}
1143			} else if ( overBottom > 0 ) {
1144				newOverTop = position.top - data.collisionPosition.marginTop + myOffset + atOffset +
1145					offset - offsetTop;
1146				if ( newOverTop > 0 || abs( newOverTop ) < overBottom ) {
1147					position.top += myOffset + atOffset + offset;
1148				}
1149			}
1150		}
1151	},
1152	flipfit: {
1153		left: function() {
1154			$.ui.position.flip.left.apply( this, arguments );
1155			$.ui.position.fit.left.apply( this, arguments );
1156		},
1157		top: function() {
1158			$.ui.position.flip.top.apply( this, arguments );
1159			$.ui.position.fit.top.apply( this, arguments );
1160		}
1161	}
1162};
1163
1164} )();
1165
1166var position = $.ui.position;
1167
1168
1169/*!
1170 * jQuery UI :data 1.12.1
1171 * http://jqueryui.com
vendor: 5,137 bytes, lines 1172-1377
1172 *
1173 * Copyright jQuery Foundation and other contributors
1174 * Released under the MIT license.
1175 * http://jquery.org/license
1176 */
1177
1178//>>label: :data Selector
1179//>>group: Core
1180//>>description: Selects elements which have data stored under the specified key.
1181//>>docs: http://api.jqueryui.com/data-selector/
1182
1183
1184var data = $.extend( $.expr[ ":" ], {
1185	data: $.expr.createPseudo ?
1186		$.expr.createPseudo( function( dataName ) {
1187			return function( elem ) {
1188				return !!$.data( elem, dataName );
1189			};
1190		} ) :
1191
1192		// Support: jQuery <1.8
1193		function( elem, i, match ) {
1194			return !!$.data( elem, match[ 3 ] );
1195		}
1196} );
1197
1198/*!
1199 * jQuery UI Disable Selection 1.12.1
1200 * http://jqueryui.com
1201 *
1202 * Copyright jQuery Foundation and other contributors
1203 * Released under the MIT license.
1204 * http://jquery.org/license
1205 */
1206
1207//>>label: disableSelection
1208//>>group: Core
1209//>>description: Disable selection of text content within the set of matched elements.
1210//>>docs: http://api.jqueryui.com/disableSelection/
1211
1212// This file is deprecated
1213
1214
1215var disableSelection = $.fn.extend( {
1216	disableSelection: ( function() {
1217		var eventType = "onselectstart" in document.createElement( "div" ) ?
1218			"selectstart" :
1219			"mousedown";
1220
1221		return function() {
1222			return this.on( eventType + ".ui-disableSelection", function( event ) {
1223				event.preventDefault();
1224			} );
1225		};
1226	} )(),
1227
1228	enableSelection: function() {
1229		return this.off( ".ui-disableSelection" );
1230	}
1231} );
1232
1233
1234/*!
1235 * jQuery UI Effects 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: Effects Core
1244//>>group: Effects
1245// jscs:disable maximumLineLength
1246//>>description: Extends the internal jQuery effects. Includes morphing and easing. Required by all other effects.
1247// jscs:enable maximumLineLength
1248//>>docs: http://api.jqueryui.com/category/effects-core/
1249//>>demos: http://jqueryui.com/effect/
1250
1251
1252
1253var dataSpace = "ui-effects-",
1254	dataSpaceStyle = "ui-effects-style",
1255	dataSpaceAnimated = "ui-effects-animated",
1256
1257	// Create a local jQuery because jQuery Color relies on it and the
1258	// global may not exist with AMD and a custom build (#10199)
1259	jQuery = $;
1260
1261$.effects = {
1262	effect: {}
1263};
1264
1265/*!
1266 * jQuery Color Animations v2.1.2
1267 * https://github.com/jquery/jquery-color
1268 *
1269 * Copyright 2014 jQuery Foundation and other contributors
1270 * Released under the MIT license.
1271 * http://jquery.org/license
1272 *
1273 * Date: Wed Jan 16 08:47:09 2013 -0600
1274 */
1275( function( jQuery, undefined ) {
1276
1277	var stepHooks = "backgroundColor borderBottomColor borderLeftColor borderRightColor " +
1278		"borderTopColor color columnRuleColor outlineColor textDecorationColor textEmphasisColor",
1279
1280	// Plusequals test for += 100 -= 100
1281	rplusequals = /^([\-+])=\s*(\d+\.?\d*)/,
1282
1283	// A set of RE's that can match strings and generate color tuples.
1284	stringParsers = [ {
1285			re: /rgba?\(\s*(\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(\d{1,3})\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/,
1286			parse: function( execResult ) {
1287				return [
1288					execResult[ 1 ],
1289					execResult[ 2 ],
1290					execResult[ 3 ],
1291					execResult[ 4 ]
1292				];
1293			}
1294		}, {
1295			re: /rgba?\(\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/,
1296			parse: function( execResult ) {
1297				return [
1298					execResult[ 1 ] * 2.55,
1299					execResult[ 2 ] * 2.55,
1300					execResult[ 3 ] * 2.55,
1301					execResult[ 4 ]
1302				];
1303			}
1304		}, {
1305
1306			// This regex ignores A-F because it's compared against an already lowercased string
1307			re: /#([a-f0-9]{2})([a-f0-9]{2})([a-f0-9]{2})/,
1308			parse: function( execResult ) {
1309				return [
1310					parseInt( execResult[ 1 ], 16 ),
1311					parseInt( execResult[ 2 ], 16 ),
1312					parseInt( execResult[ 3 ], 16 )
1313				];
1314			}
1315		}, {
1316
1317			// This regex ignores A-F because it's compared against an already lowercased string
1318			re: /#([a-f0-9])([a-f0-9])([a-f0-9])/,
1319			parse: function( execResult ) {
1320				return [
1321					parseInt( execResult[ 1 ] + execResult[ 1 ], 16 ),
1322					parseInt( execResult[ 2 ] + execResult[ 2 ], 16 ),
1323					parseInt( execResult[ 3 ] + execResult[ 3 ], 16 )
1324				];
1325			}
1326		}, {
1327			re: /hsla?\(\s*(\d+(?:\.\d+)?)\s*,\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/,
1328			space: "hsla",
1329			parse: function( execResult ) {
1330				return [
1331					execResult[ 1 ],
1332					execResult[ 2 ] / 100,
1333					execResult[ 3 ] / 100,
1334					execResult[ 4 ]
1335				];
1336			}
1337		} ],
1338
1339	// JQuery.Color( )
1340	color = jQuery.Color = function( color, green, blue, alpha ) {
1341		return new jQuery.Color.fn.parse( color, green, blue, alpha );
1342	},
1343	spaces = {
1344		rgba: {
1345			props: {
1346				red: {
1347					idx: 0,
1348					type: "byte"
1349				},
1350				green: {
1351					idx: 1,
1352					type: "byte"
1353				},
1354				blue: {
1355					idx: 2,
1356					type: "byte"
1357				}
1358			}
1359		},
1360
1361		hsla: {
1362			props: {
1363				hue: {
1364					idx: 0,
1365					type: "degrees"
1366				},
1367				saturation: {
1368					idx: 1,
1369					type: "percent"
1370				},
1371				lightness: {
1372					idx: 2,
1373					type: "percent"
1374				}
1375			}
1376		}
1377	},
vendor: 18,301 bytes, lines 1378-2100
1378	propTypes = {
1379		"byte": {
1380			floor: true,
1381			max: 255
1382		},
1383		"percent": {
1384			max: 1
1385		},
1386		"degrees": {
1387			mod: 360,
1388			floor: true
1389		}
1390	},
1391	support = color.support = {},
1392
1393	// Element for support tests
1394	supportElem = jQuery( "<p>" )[ 0 ],
1395
1396	// Colors = jQuery.Color.names
1397	colors,
1398
1399	// Local aliases of functions called often
1400	each = jQuery.each;
1401
1402// Determine rgba support immediately
1403supportElem.style.cssText = "background-color:rgba(1,1,1,.5)";
1404support.rgba = supportElem.style.backgroundColor.indexOf( "rgba" ) > -1;
1405
1406// Define cache name and alpha properties
1407// for rgba and hsla spaces
1408each( spaces, function( spaceName, space ) {
1409	space.cache = "_" + spaceName;
1410	space.props.alpha = {
1411		idx: 3,
1412		type: "percent",
1413		def: 1
1414	};
1415} );
1416
1417function clamp( value, prop, allowEmpty ) {
1418	var type = propTypes[ prop.type ] || {};
1419
1420	if ( value == null ) {
1421		return ( allowEmpty || !prop.def ) ? null : prop.def;
1422	}
1423
1424	// ~~ is an short way of doing floor for positive numbers
1425	value = type.floor ? ~~value : parseFloat( value );
1426
1427	// IE will pass in empty strings as value for alpha,
1428	// which will hit this case
1429	if ( isNaN( value ) ) {
1430		return prop.def;
1431	}
1432
1433	if ( type.mod ) {
1434
1435		// We add mod before modding to make sure that negatives values
1436		// get converted properly: -10 -> 350
1437		return ( value + type.mod ) % type.mod;
1438	}
1439
1440	// For now all property types without mod have min and max
1441	return 0 > value ? 0 : type.max < value ? type.max : value;
1442}
1443
1444function stringParse( string ) {
1445	var inst = color(),
1446		rgba = inst._rgba = [];
1447
1448	string = string.toLowerCase();
1449
1450	each( stringParsers, function( i, parser ) {
1451		var parsed,
1452			match = parser.re.exec( string ),
1453			values = match && parser.parse( match ),
1454			spaceName = parser.space || "rgba";
1455
1456		if ( values ) {
1457			parsed = inst[ spaceName ]( values );
1458
1459			// If this was an rgba parse the assignment might happen twice
1460			// oh well....
1461			inst[ spaces[ spaceName ].cache ] = parsed[ spaces[ spaceName ].cache ];
1462			rgba = inst._rgba = parsed._rgba;
1463
1464			// Exit each( stringParsers ) here because we matched
1465			return false;
1466		}
1467	} );
1468
1469	// Found a stringParser that handled it
1470	if ( rgba.length ) {
1471
1472		// If this came from a parsed string, force "transparent" when alpha is 0
1473		// chrome, (and maybe others) return "transparent" as rgba(0,0,0,0)
1474		if ( rgba.join() === "0,0,0,0" ) {
1475			jQuery.extend( rgba, colors.transparent );
1476		}
1477		return inst;
1478	}
1479
1480	// Named colors
1481	return colors[ string ];
1482}
1483
1484color.fn = jQuery.extend( color.prototype, {
1485	parse: function( red, green, blue, alpha ) {
1486		if ( red === undefined ) {
1487			this._rgba = [ null, null, null, null ];
1488			return this;
1489		}
1490		if ( red.jquery || red.nodeType ) {
1491			red = jQuery( red ).css( green );
1492			green = undefined;
1493		}
1494
1495		var inst = this,
1496			type = jQuery.type( red ),
1497			rgba = this._rgba = [];
1498
1499		// More than 1 argument specified - assume ( red, green, blue, alpha )
1500		if ( green !== undefined ) {
1501			red = [ red, green, blue, alpha ];
1502			type = "array";
1503		}
1504
1505		if ( type === "string" ) {
1506			return this.parse( stringParse( red ) || colors._default );
1507		}
1508
1509		if ( type === "array" ) {
1510			each( spaces.rgba.props, function( key, prop ) {
1511				rgba[ prop.idx ] = clamp( red[ prop.idx ], prop );
1512			} );
1513			return this;
1514		}
1515
1516		if ( type === "object" ) {
1517			if ( red instanceof color ) {
1518				each( spaces, function( spaceName, space ) {
1519					if ( red[ space.cache ] ) {
1520						inst[ space.cache ] = red[ space.cache ].slice();
1521					}
1522				} );
1523			} else {
1524				each( spaces, function( spaceName, space ) {
1525					var cache = space.cache;
1526					each( space.props, function( key, prop ) {
1527
1528						// If the cache doesn't exist, and we know how to convert
1529						if ( !inst[ cache ] && space.to ) {
1530
1531							// If the value was null, we don't need to copy it
1532							// if the key was alpha, we don't need to copy it either
1533							if ( key === "alpha" || red[ key ] == null ) {
1534								return;
1535							}
1536							inst[ cache ] = space.to( inst._rgba );
1537						}
1538
1539						// This is the only case where we allow nulls for ALL properties.
1540						// call clamp with alwaysAllowEmpty
1541						inst[ cache ][ prop.idx ] = clamp( red[ key ], prop, true );
1542					} );
1543
1544					// Everything defined but alpha?
1545					if ( inst[ cache ] &&
1546							jQuery.inArray( null, inst[ cache ].slice( 0, 3 ) ) < 0 ) {
1547
1548						// Use the default of 1
1549						inst[ cache ][ 3 ] = 1;
1550						if ( space.from ) {
1551							inst._rgba = space.from( inst[ cache ] );
1552						}
1553					}
1554				} );
1555			}
1556			return this;
1557		}
1558	},
1559	is: function( compare ) {
1560		var is = color( compare ),
1561			same = true,
1562			inst = this;
1563
1564		each( spaces, function( _, space ) {
1565			var localCache,
1566				isCache = is[ space.cache ];
1567			if ( isCache ) {
1568				localCache = inst[ space.cache ] || space.to && space.to( inst._rgba ) || [];
1569				each( space.props, function( _, prop ) {
1570					if ( isCache[ prop.idx ] != null ) {
1571						same = ( isCache[ prop.idx ] === localCache[ prop.idx ] );
1572						return same;
1573					}
1574				} );
1575			}
1576			return same;
1577		} );
1578		return same;
1579	},
1580	_space: function() {
1581		var used = [],
1582			inst = this;
1583		each( spaces, function( spaceName, space ) {
1584			if ( inst[ space.cache ] ) {
1585				used.push( spaceName );
1586			}
1587		} );
1588		return used.pop();
1589	},
1590	transition: function( other, distance ) {
1591		var end = color( other ),
1592			spaceName = end._space(),
1593			space = spaces[ spaceName ],
1594			startColor = this.alpha() === 0 ? color( "transparent" ) : this,
1595			start = startColor[ space.cache ] || space.to( startColor._rgba ),
1596			result = start.slice();
1597
1598		end = end[ space.cache ];
1599		each( space.props, function( key, prop ) {
1600			var index = prop.idx,
1601				startValue = start[ index ],
1602				endValue = end[ index ],
1603				type = propTypes[ prop.type ] || {};
1604
1605			// If null, don't override start value
1606			if ( endValue === null ) {
1607				return;
1608			}
1609
1610			// If null - use end
1611			if ( startValue === null ) {
1612				result[ index ] = endValue;
1613			} else {
1614				if ( type.mod ) {
1615					if ( endValue - startValue > type.mod / 2 ) {
1616						startValue += type.mod;
1617					} else if ( startValue - endValue > type.mod / 2 ) {
1618						startValue -= type.mod;
1619					}
1620				}
1621				result[ index ] = clamp( ( endValue - startValue ) * distance + startValue, prop );
1622			}
1623		} );
1624		return this[ spaceName ]( result );
1625	},
1626	blend: function( opaque ) {
1627
1628		// If we are already opaque - return ourself
1629		if ( this._rgba[ 3 ] === 1 ) {
1630			return this;
1631		}
1632
1633		var rgb = this._rgba.slice(),
1634			a = rgb.pop(),
1635			blend = color( opaque )._rgba;
1636
1637		return color( jQuery.map( rgb, function( v, i ) {
1638			return ( 1 - a ) * blend[ i ] + a * v;
1639		} ) );
1640	},
1641	toRgbaString: function() {
1642		var prefix = "rgba(",
1643			rgba = jQuery.map( this._rgba, function( v, i ) {
1644				return v == null ? ( i > 2 ? 1 : 0 ) : v;
1645			} );
1646
1647		if ( rgba[ 3 ] === 1 ) {
1648			rgba.pop();
1649			prefix = "rgb(";
1650		}
1651
1652		return prefix + rgba.join() + ")";
1653	},
1654	toHslaString: function() {
1655		var prefix = "hsla(",
1656			hsla = jQuery.map( this.hsla(), function( v, i ) {
1657				if ( v == null ) {
1658					v = i > 2 ? 1 : 0;
1659				}
1660
1661				// Catch 1 and 2
1662				if ( i && i < 3 ) {
1663					v = Math.round( v * 100 ) + "%";
1664				}
1665				return v;
1666			} );
1667
1668		if ( hsla[ 3 ] === 1 ) {
1669			hsla.pop();
1670			prefix = "hsl(";
1671		}
1672		return prefix + hsla.join() + ")";
1673	},
1674	toHexString: function( includeAlpha ) {
1675		var rgba = this._rgba.slice(),
1676			alpha = rgba.pop();
1677
1678		if ( includeAlpha ) {
1679			rgba.push( ~~( alpha * 255 ) );
1680		}
1681
1682		return "#" + jQuery.map( rgba, function( v ) {
1683
1684			// Default to 0 when nulls exist
1685			v = ( v || 0 ).toString( 16 );
1686			return v.length === 1 ? "0" + v : v;
1687		} ).join( "" );
1688	},
1689	toString: function() {
1690		return this._rgba[ 3 ] === 0 ? "transparent" : this.toRgbaString();
1691	}
1692} );
1693color.fn.parse.prototype = color.fn;
1694
1695// Hsla conversions adapted from:
1696// https://code.google.com/p/maashaack/source/browse/packages/graphics/trunk/src/graphics/colors/HUE2RGB.as?r=5021
1697
1698function hue2rgb( p, q, h ) {
1699	h = ( h + 1 ) % 1;
1700	if ( h * 6 < 1 ) {
1701		return p + ( q - p ) * h * 6;
1702	}
1703	if ( h * 2 < 1 ) {
1704		return q;
1705	}
1706	if ( h * 3 < 2 ) {
1707		return p + ( q - p ) * ( ( 2 / 3 ) - h ) * 6;
1708	}
1709	return p;
1710}
1711
1712spaces.hsla.to = function( rgba ) {
1713	if ( rgba[ 0 ] == null || rgba[ 1 ] == null || rgba[ 2 ] == null ) {
1714		return [ null, null, null, rgba[ 3 ] ];
1715	}
1716	var r = rgba[ 0 ] / 255,
1717		g = rgba[ 1 ] / 255,
1718		b = rgba[ 2 ] / 255,
1719		a = rgba[ 3 ],
1720		max = Math.max( r, g, b ),
1721		min = Math.min( r, g, b ),
1722		diff = max - min,
1723		add = max + min,
1724		l = add * 0.5,
1725		h, s;
1726
1727	if ( min === max ) {
1728		h = 0;
1729	} else if ( r === max ) {
1730		h = ( 60 * ( g - b ) / diff ) + 360;
1731	} else if ( g === max ) {
1732		h = ( 60 * ( b - r ) / diff ) + 120;
1733	} else {
1734		h = ( 60 * ( r - g ) / diff ) + 240;
1735	}
1736
1737	// Chroma (diff) == 0 means greyscale which, by definition, saturation = 0%
1738	// otherwise, saturation is based on the ratio of chroma (diff) to lightness (add)
1739	if ( diff === 0 ) {
1740		s = 0;
1741	} else if ( l <= 0.5 ) {
1742		s = diff / add;
1743	} else {
1744		s = diff / ( 2 - add );
1745	}
1746	return [ Math.round( h ) % 360, s, l, a == null ? 1 : a ];
1747};
1748
1749spaces.hsla.from = function( hsla ) {
1750	if ( hsla[ 0 ] == null || hsla[ 1 ] == null || hsla[ 2 ] == null ) {
1751		return [ null, null, null, hsla[ 3 ] ];
1752	}
1753	var h = hsla[ 0 ] / 360,
1754		s = hsla[ 1 ],
1755		l = hsla[ 2 ],
1756		a = hsla[ 3 ],
1757		q = l <= 0.5 ? l * ( 1 + s ) : l + s - l * s,
1758		p = 2 * l - q;
1759
1760	return [
1761		Math.round( hue2rgb( p, q, h + ( 1 / 3 ) ) * 255 ),
1762		Math.round( hue2rgb( p, q, h ) * 255 ),
1763		Math.round( hue2rgb( p, q, h - ( 1 / 3 ) ) * 255 ),
1764		a
1765	];
1766};
1767
1768each( spaces, function( spaceName, space ) {
1769	var props = space.props,
1770		cache = space.cache,
1771		to = space.to,
1772		from = space.from;
1773
1774	// Makes rgba() and hsla()
1775	color.fn[ spaceName ] = function( value ) {
1776
1777		// Generate a cache for this space if it doesn't exist
1778		if ( to && !this[ cache ] ) {
1779			this[ cache ] = to( this._rgba );
1780		}
1781		if ( value === undefined ) {
1782			return this[ cache ].slice();
1783		}
1784
1785		var ret,
1786			type = jQuery.type( value ),
1787			arr = ( type === "array" || type === "object" ) ? value : arguments,
1788			local = this[ cache ].slice();
1789
1790		each( props, function( key, prop ) {
1791			var val = arr[ type === "object" ? key : prop.idx ];
1792			if ( val == null ) {
1793				val = local[ prop.idx ];
1794			}
1795			local[ prop.idx ] = clamp( val, prop );
1796		} );
1797
1798		if ( from ) {
1799			ret = color( from( local ) );
1800			ret[ cache ] = local;
1801			return ret;
1802		} else {
1803			return color( local );
1804		}
1805	};
1806
1807	// Makes red() green() blue() alpha() hue() saturation() lightness()
1808	each( props, function( key, prop ) {
1809
1810		// Alpha is included in more than one space
1811		if ( color.fn[ key ] ) {
1812			return;
1813		}
1814		color.fn[ key ] = function( value ) {
1815			var vtype = jQuery.type( value ),
1816				fn = ( key === "alpha" ? ( this._hsla ? "hsla" : "rgba" ) : spaceName ),
1817				local = this[ fn ](),
1818				cur = local[ prop.idx ],
1819				match;
1820
1821			if ( vtype === "undefined" ) {
1822				return cur;
1823			}
1824
1825			if ( vtype === "function" ) {
1826				value = value.call( this, cur );
1827				vtype = jQuery.type( value );
1828			}
1829			if ( value == null && prop.empty ) {
1830				return this;
1831			}
1832			if ( vtype === "string" ) {
1833				match = rplusequals.exec( value );
1834				if ( match ) {
1835					value = cur + parseFloat( match[ 2 ] ) * ( match[ 1 ] === "+" ? 1 : -1 );
1836				}
1837			}
1838			local[ prop.idx ] = value;
1839			return this[ fn ]( local );
1840		};
1841	} );
1842} );
1843
1844// Add cssHook and .fx.step function for each named hook.
1845// accept a space separated string of properties
1846color.hook = function( hook ) {
1847	var hooks = hook.split( " " );
1848	each( hooks, function( i, hook ) {
1849		jQuery.cssHooks[ hook ] = {
1850			set: function( elem, value ) {
1851				var parsed, curElem,
1852					backgroundColor = "";
1853
1854				if ( value !== "transparent" && ( jQuery.type( value ) !== "string" ||
1855						( parsed = stringParse( value ) ) ) ) {
1856					value = color( parsed || value );
1857					if ( !support.rgba && value._rgba[ 3 ] !== 1 ) {
1858						curElem = hook === "backgroundColor" ? elem.parentNode : elem;
1859						while (
1860							( backgroundColor === "" || backgroundColor === "transparent" ) &&
1861							curElem && curElem.style
1862						) {
1863							try {
1864								backgroundColor = jQuery.css( curElem, "backgroundColor" );
1865								curElem = curElem.parentNode;
1866							} catch ( e ) {
1867							}
1868						}
1869
1870						value = value.blend( backgroundColor && backgroundColor !== "transparent" ?
1871							backgroundColor :
1872							"_default" );
1873					}
1874
1875					value = value.toRgbaString();
1876				}
1877				try {
1878					elem.style[ hook ] = value;
1879				} catch ( e ) {
1880
1881					// Wrapped to prevent IE from throwing errors on "invalid" values like
1882					// 'auto' or 'inherit'
1883				}
1884			}
1885		};
1886		jQuery.fx.step[ hook ] = function( fx ) {
1887			if ( !fx.colorInit ) {
1888				fx.start = color( fx.elem, hook );
1889				fx.end = color( fx.end );
1890				fx.colorInit = true;
1891			}
1892			jQuery.cssHooks[ hook ].set( fx.elem, fx.start.transition( fx.end, fx.pos ) );
1893		};
1894	} );
1895
1896};
1897
1898color.hook( stepHooks );
1899
1900jQuery.cssHooks.borderColor = {
1901	expand: function( value ) {
1902		var expanded = {};
1903
1904		each( [ "Top", "Right", "Bottom", "Left" ], function( i, part ) {
1905			expanded[ "border" + part + "Color" ] = value;
1906		} );
1907		return expanded;
1908	}
1909};
1910
1911// Basic color names only.
1912// Usage of any of the other color names requires adding yourself or including
1913// jquery.color.svg-names.js.
1914colors = jQuery.Color.names = {
1915
1916	// 4.1. Basic color keywords
1917	aqua: "#00ffff",
1918	black: "#000000",
1919	blue: "#0000ff",
1920	fuchsia: "#ff00ff",
1921	gray: "#808080",
1922	green: "#008000",
1923	lime: "#00ff00",
1924	maroon: "#800000",
1925	navy: "#000080",
1926	olive: "#808000",
1927	purple: "#800080",
1928	red: "#ff0000",
1929	silver: "#c0c0c0",
1930	teal: "#008080",
1931	white: "#ffffff",
1932	yellow: "#ffff00",
1933
1934	// 4.2.3. "transparent" color keyword
1935	transparent: [ null, null, null, 0 ],
1936
1937	_default: "#ffffff"
1938};
1939
1940} )( jQuery );
1941
1942/******************************************************************************/
1943/****************************** CLASS ANIMATIONS ******************************/
1944/******************************************************************************/
1945( function() {
1946
1947var classAnimationActions = [ "add", "remove", "toggle" ],
1948	shorthandStyles = {
1949		border: 1,
1950		borderBottom: 1,
1951		borderColor: 1,
1952		borderLeft: 1,
1953		borderRight: 1,
1954		borderTop: 1,
1955		borderWidth: 1,
1956		margin: 1,
1957		padding: 1
1958	};
1959
1960$.each(
1961	[ "borderLeftStyle", "borderRightStyle", "borderBottomStyle", "borderTopStyle" ],
1962	function( _, prop ) {
1963		$.fx.step[ prop ] = function( fx ) {
1964			if ( fx.end !== "none" && !fx.setAttr || fx.pos === 1 && !fx.setAttr ) {
1965				jQuery.style( fx.elem, prop, fx.end );
1966				fx.setAttr = true;
1967			}
1968		};
1969	}
1970);
1971
1972function getElementStyles( elem ) {
1973	var key, len,
1974		style = elem.ownerDocument.defaultView ?
1975			elem.ownerDocument.defaultView.getComputedStyle( elem, null ) :
1976			elem.currentStyle,
1977		styles = {};
1978
1979	if ( style && style.length && style[ 0 ] && style[ style[ 0 ] ] ) {
1980		len = style.length;
1981		while ( len-- ) {
1982			key = style[ len ];
1983			if ( typeof style[ key ] === "string" ) {
1984				styles[ $.camelCase( key ) ] = style[ key ];
1985			}
1986		}
1987
1988	// Support: Opera, IE <9
1989	} else {
1990		for ( key in style ) {
1991			if ( typeof style[ key ] === "string" ) {
1992				styles[ key ] = style[ key ];
1993			}
1994		}
1995	}
1996
1997	return styles;
1998}
1999
2000function styleDifference( oldStyle, newStyle ) {
2001	var diff = {},
2002		name, value;
2003
2004	for ( name in newStyle ) {
2005		value = newStyle[ name ];
2006		if ( oldStyle[ name ] !== value ) {
2007			if ( !shorthandStyles[ name ] ) {
2008				if ( $.fx.step[ name ] || !isNaN( parseFloat( value ) ) ) {
2009					diff[ name ] = value;
2010				}
2011			}
2012		}
2013	}
2014
2015	return diff;
2016}
2017
2018// Support: jQuery <1.8
2019if ( !$.fn.addBack ) {
2020	$.fn.addBack = function( selector ) {
2021		return this.add( selector == null ?
2022			this.prevObject : this.prevObject.filter( selector )
2023		);
2024	};
2025}
2026
2027$.effects.animateClass = function( value, duration, easing, callback ) {
2028	var o = $.speed( duration, easing, callback );
2029
2030	return this.queue( function() {
2031		var animated = $( this ),
2032			baseClass = animated.attr( "class" ) || "",
2033			applyClassChange,
2034			allAnimations = o.children ? animated.find( "*" ).addBack() : animated;
2035
2036		// Map the animated objects to store the original styles.
2037		allAnimations = allAnimations.map( function() {
2038			var el = $( this );
2039			return {
2040				el: el,
2041				start: getElementStyles( this )
2042			};
2043		} );
2044
2045		// Apply class change
2046		applyClassChange = function() {
2047			$.each( classAnimationActions, function( i, action ) {
2048				if ( value[ action ] ) {
2049					animated[ action + "Class" ]( value[ action ] );
2050				}
2051			} );
2052		};
2053		applyClassChange();
2054
2055		// Map all animated objects again - calculate new styles and diff
2056		allAnimations = allAnimations.map( function() {
2057			this.end = getElementStyles( this.el[ 0 ] );
2058			this.diff = styleDifference( this.start, this.end );
2059			return this;
2060		} );
2061
2062		// Apply original class
2063		animated.attr( "class", baseClass );
2064
2065		// Map all animated objects again - this time collecting a promise
2066		allAnimations = allAnimations.map( function() {
2067			var styleInfo = this,
2068				dfd = $.Deferred(),
2069				opts = $.extend( {}, o, {
2070					queue: false,
2071					complete: function() {
2072						dfd.resolve( styleInfo );
2073					}
2074				} );
2075
2076			this.el.animate( this.diff, opts );
2077			return dfd.promise();
2078		} );
2079
2080		// Once all animations have completed:
2081		$.when.apply( $, allAnimations.get() ).done( function() {
2082
2083			// Set the final class
2084			applyClassChange();
2085
2086			// For each animated element,
2087			// clear all css properties that were animated
2088			$.each( arguments, function() {
2089				var el = this.el;
2090				$.each( this.diff, function( key ) {
2091					el.css( key, "" );
2092				} );
2093			} );
2094
2095			// This is guarnteed to be there if you use jQuery.speed()
2096			// it also handles dequeuing the next anim...
2097			o.complete.call( animated[ 0 ] );
2098		} );
2099	} );
2100};
vendor: 5,123 bytes, lines 2101-2281
2101
2102$.fn.extend( {
2103	addClass: ( function( orig ) {
2104		return function( classNames, speed, easing, callback ) {
2105			return speed ?
2106				$.effects.animateClass.call( this,
2107					{ add: classNames }, speed, easing, callback ) :
2108				orig.apply( this, arguments );
2109		};
2110	} )( $.fn.addClass ),
2111
2112	removeClass: ( function( orig ) {
2113		return function( classNames, speed, easing, callback ) {
2114			return arguments.length > 1 ?
2115				$.effects.animateClass.call( this,
2116					{ remove: classNames }, speed, easing, callback ) :
2117				orig.apply( this, arguments );
2118		};
2119	} )( $.fn.removeClass ),
2120
2121	toggleClass: ( function( orig ) {
2122		return function( classNames, force, speed, easing, callback ) {
2123			if ( typeof force === "boolean" || force === undefined ) {
2124				if ( !speed ) {
2125
2126					// Without speed parameter
2127					return orig.apply( this, arguments );
2128				} else {
2129					return $.effects.animateClass.call( this,
2130						( force ? { add: classNames } : { remove: classNames } ),
2131						speed, easing, callback );
2132				}
2133			} else {
2134
2135				// Without force parameter
2136				return $.effects.animateClass.call( this,
2137					{ toggle: classNames }, force, speed, easing );
2138			}
2139		};
2140	} )( $.fn.toggleClass ),
2141
2142	switchClass: function( remove, add, speed, easing, callback ) {
2143		return $.effects.animateClass.call( this, {
2144			add: add,
2145			remove: remove
2146		}, speed, easing, callback );
2147	}
2148} );
2149
2150} )();
2151
2152/******************************************************************************/
2153/*********************************** EFFECTS **********************************/
2154/******************************************************************************/
2155
2156( function() {
2157
2158if ( $.expr && $.expr.filters && $.expr.filters.animated ) {
2159	$.expr.filters.animated = ( function( orig ) {
2160		return function( elem ) {
2161			return !!$( elem ).data( dataSpaceAnimated ) || orig( elem );
2162		};
2163	} )( $.expr.filters.animated );
2164}
2165
2166if ( $.uiBackCompat !== false ) {
2167	$.extend( $.effects, {
2168
2169		// Saves a set of properties in a data storage
2170		save: function( element, set ) {
2171			var i = 0, length = set.length;
2172			for ( ; i < length; i++ ) {
2173				if ( set[ i ] !== null ) {
2174					element.data( dataSpace + set[ i ], element[ 0 ].style[ set[ i ] ] );
2175				}
2176			}
2177		},
2178
2179		// Restores a set of previously saved properties from a data storage
2180		restore: function( element, set ) {
2181			var val, i = 0, length = set.length;
2182			for ( ; i < length; i++ ) {
2183				if ( set[ i ] !== null ) {
2184					val = element.data( dataSpace + set[ i ] );
2185					element.css( set[ i ], val );
2186				}
2187			}
2188		},
2189
2190		setMode: function( el, mode ) {
2191			if ( mode === "toggle" ) {
2192				mode = el.is( ":hidden" ) ? "show" : "hide";
2193			}
2194			return mode;
2195		},
2196
2197		// Wraps the element around a wrapper that copies position properties
2198		createWrapper: function( element ) {
2199
2200			// If the element is already wrapped, return it
2201			if ( element.parent().is( ".ui-effects-wrapper" ) ) {
2202				return element.parent();
2203			}
2204
2205			// Wrap the element
2206			var props = {
2207					width: element.outerWidth( true ),
2208					height: element.outerHeight( true ),
2209					"float": element.css( "float" )
2210				},
2211				wrapper = $( "<div></div>" )
2212					.addClass( "ui-effects-wrapper" )
2213					.css( {
2214						fontSize: "100%",
2215						background: "transparent",
2216						border: "none",
2217						margin: 0,
2218						padding: 0
2219					} ),
2220
2221				// Store the size in case width/height are defined in % - Fixes #5245
2222				size = {
2223					width: element.width(),
2224					height: element.height()
2225				},
2226				active = document.activeElement;
2227
2228			// Support: Firefox
2229			// Firefox incorrectly exposes anonymous content
2230			// https://bugzilla.mozilla.org/show_bug.cgi?id=561664
2231			try {
2232				active.id;
2233			} catch ( e ) {
2234				active = document.body;
2235			}
2236
2237			element.wrap( wrapper );
2238
2239			// Fixes #7595 - Elements lose focus when wrapped.
2240			if ( element[ 0 ] === active || $.contains( element[ 0 ], active ) ) {
2241				$( active ).trigger( "focus" );
2242			}
2243
2244			// Hotfix for jQuery 1.4 since some change in wrap() seems to actually
2245			// lose the reference to the wrapped element
2246			wrapper = element.parent();
2247
2248			// Transfer positioning properties to the wrapper
2249			if ( element.css( "position" ) === "static" ) {
2250				wrapper.css( { position: "relative" } );
2251				element.css( { position: "relative" } );
2252			} else {
2253				$.extend( props, {
2254					position: element.css( "position" ),
2255					zIndex: element.css( "z-index" )
2256				} );
2257				$.each( [ "top", "left", "bottom", "right" ], function( i, pos ) {
2258					props[ pos ] = element.css( pos );
2259					if ( isNaN( parseInt( props[ pos ], 10 ) ) ) {
2260						props[ pos ] = "auto";
2261					}
2262				} );
2263				element.css( {
2264					position: "relative",
2265					top: 0,
2266					left: 0,
2267					right: "auto",
2268					bottom: "auto"
2269				} );
2270			}
2271			element.css( size );
2272
2273			return wrapper.css( props ).show();
2274		},
2275
2276		removeWrapper: function( element ) {
2277			var active = document.activeElement;
2278
2279			if ( element.parent().is( ".ui-effects-wrapper" ) ) {
2280				element.parent().replaceWith( element );
2281
vendor: 16,570 bytes, lines 2282-2917
2282				// Fixes #7595 - Elements lose focus when wrapped.
2283				if ( element[ 0 ] === active || $.contains( element[ 0 ], active ) ) {
2284					$( active ).trigger( "focus" );
2285				}
2286			}
2287
2288			return element;
2289		}
2290	} );
2291}
2292
2293$.extend( $.effects, {
2294	version: "1.12.1",
2295
2296	define: function( name, mode, effect ) {
2297		if ( !effect ) {
2298			effect = mode;
2299			mode = "effect";
2300		}
2301
2302		$.effects.effect[ name ] = effect;
2303		$.effects.effect[ name ].mode = mode;
2304
2305		return effect;
2306	},
2307
2308	scaledDimensions: function( element, percent, direction ) {
2309		if ( percent === 0 ) {
2310			return {
2311				height: 0,
2312				width: 0,
2313				outerHeight: 0,
2314				outerWidth: 0
2315			};
2316		}
2317
2318		var x = direction !== "horizontal" ? ( ( percent || 100 ) / 100 ) : 1,
2319			y = direction !== "vertical" ? ( ( percent || 100 ) / 100 ) : 1;
2320
2321		return {
2322			height: element.height() * y,
2323			width: element.width() * x,
2324			outerHeight: element.outerHeight() * y,
2325			outerWidth: element.outerWidth() * x
2326		};
2327
2328	},
2329
2330	clipToBox: function( animation ) {
2331		return {
2332			width: animation.clip.right - animation.clip.left,
2333			height: animation.clip.bottom - animation.clip.top,
2334			left: animation.clip.left,
2335			top: animation.clip.top
2336		};
2337	},
2338
2339	// Injects recently queued functions to be first in line (after "inprogress")
2340	unshift: function( element, queueLength, count ) {
2341		var queue = element.queue();
2342
2343		if ( queueLength > 1 ) {
2344			queue.splice.apply( queue,
2345				[ 1, 0 ].concat( queue.splice( queueLength, count ) ) );
2346		}
2347		element.dequeue();
2348	},
2349
2350	saveStyle: function( element ) {
2351		element.data( dataSpaceStyle, element[ 0 ].style.cssText );
2352	},
2353
2354	restoreStyle: function( element ) {
2355		element[ 0 ].style.cssText = element.data( dataSpaceStyle ) || "";
2356		element.removeData( dataSpaceStyle );
2357	},
2358
2359	mode: function( element, mode ) {
2360		var hidden = element.is( ":hidden" );
2361
2362		if ( mode === "toggle" ) {
2363			mode = hidden ? "show" : "hide";
2364		}
2365		if ( hidden ? mode === "hide" : mode === "show" ) {
2366			mode = "none";
2367		}
2368		return mode;
2369	},
2370
2371	// Translates a [top,left] array into a baseline value
2372	getBaseline: function( origin, original ) {
2373		var y, x;
2374
2375		switch ( origin[ 0 ] ) {
2376		case "top":
2377			y = 0;
2378			break;
2379		case "middle":
2380			y = 0.5;
2381			break;
2382		case "bottom":
2383			y = 1;
2384			break;
2385		default:
2386			y = origin[ 0 ] / original.height;
2387		}
2388
2389		switch ( origin[ 1 ] ) {
2390		case "left":
2391			x = 0;
2392			break;
2393		case "center":
2394			x = 0.5;
2395			break;
2396		case "right":
2397			x = 1;
2398			break;
2399		default:
2400			x = origin[ 1 ] / original.width;
2401		}
2402
2403		return {
2404			x: x,
2405			y: y
2406		};
2407	},
2408
2409	// Creates a placeholder element so that the original element can be made absolute
2410	createPlaceholder: function( element ) {
2411		var placeholder,
2412			cssPosition = element.css( "position" ),
2413			position = element.position();
2414
2415		// Lock in margins first to account for form elements, which
2416		// will change margin if you explicitly set height
2417		// see: http://jsfiddle.net/JZSMt/3/ https://bugs.webkit.org/show_bug.cgi?id=107380
2418		// Support: Safari
2419		element.css( {
2420			marginTop: element.css( "marginTop" ),
2421			marginBottom: element.css( "marginBottom" ),
2422			marginLeft: element.css( "marginLeft" ),
2423			marginRight: element.css( "marginRight" )
2424		} )
2425		.outerWidth( element.outerWidth() )
2426		.outerHeight( element.outerHeight() );
2427
2428		if ( /^(static|relative)/.test( cssPosition ) ) {
2429			cssPosition = "absolute";
2430
2431			placeholder = $( "<" + element[ 0 ].nodeName + ">" ).insertAfter( element ).css( {
2432
2433				// Convert inline to inline block to account for inline elements
2434				// that turn to inline block based on content (like img)
2435				display: /^(inline|ruby)/.test( element.css( "display" ) ) ?
2436					"inline-block" :
2437					"block",
2438				visibility: "hidden",
2439
2440				// Margins need to be set to account for margin collapse
2441				marginTop: element.css( "marginTop" ),
2442				marginBottom: element.css( "marginBottom" ),
2443				marginLeft: element.css( "marginLeft" ),
2444				marginRight: element.css( "marginRight" ),
2445				"float": element.css( "float" )
2446			} )
2447			.outerWidth( element.outerWidth() )
2448			.outerHeight( element.outerHeight() )
2449			.addClass( "ui-effects-placeholder" );
2450
2451			element.data( dataSpace + "placeholder", placeholder );
2452		}
2453
2454		element.css( {
2455			position: cssPosition,
2456			left: position.left,
2457			top: position.top
2458		} );
2459
2460		return placeholder;
2461	},
2462
2463	removePlaceholder: function( element ) {
2464		var dataKey = dataSpace + "placeholder",
2465				placeholder = element.data( dataKey );
2466
2467		if ( placeholder ) {
2468			placeholder.remove();
2469			element.removeData( dataKey );
2470		}
2471	},
2472
2473	// Removes a placeholder if it exists and restores
2474	// properties that were modified during placeholder creation
2475	cleanUp: function( element ) {
2476		$.effects.restoreStyle( element );
2477		$.effects.removePlaceholder( element );
2478	},
2479
2480	setTransition: function( element, list, factor, value ) {
2481		value = value || {};
2482		$.each( list, function( i, x ) {
2483			var unit = element.cssUnit( x );
2484			if ( unit[ 0 ] > 0 ) {
2485				value[ x ] = unit[ 0 ] * factor + unit[ 1 ];
2486			}
2487		} );
2488		return value;
2489	}
2490} );
2491
2492// Return an effect options object for the given parameters:
2493function _normalizeArguments( effect, options, speed, callback ) {
2494
2495	// Allow passing all options as the first parameter
2496	if ( $.isPlainObject( effect ) ) {
2497		options = effect;
2498		effect = effect.effect;
2499	}
2500
2501	// Convert to an object
2502	effect = { effect: effect };
2503
2504	// Catch (effect, null, ...)
2505	if ( options == null ) {
2506		options = {};
2507	}
2508
2509	// Catch (effect, callback)
2510	if ( $.isFunction( options ) ) {
2511		callback = options;
2512		speed = null;
2513		options = {};
2514	}
2515
2516	// Catch (effect, speed, ?)
2517	if ( typeof options === "number" || $.fx.speeds[ options ] ) {
2518		callback = speed;
2519		speed = options;
2520		options = {};
2521	}
2522
2523	// Catch (effect, options, callback)
2524	if ( $.isFunction( speed ) ) {
2525		callback = speed;
2526		speed = null;
2527	}
2528
2529	// Add options to effect
2530	if ( options ) {
2531		$.extend( effect, options );
2532	}
2533
2534	speed = speed || options.duration;
2535	effect.duration = $.fx.off ? 0 :
2536		typeof speed === "number" ? speed :
2537		speed in $.fx.speeds ? $.fx.speeds[ speed ] :
2538		$.fx.speeds._default;
2539
2540	effect.complete = callback || options.complete;
2541
2542	return effect;
2543}
2544
2545function standardAnimationOption( option ) {
2546
2547	// Valid standard speeds (nothing, number, named speed)
2548	if ( !option || typeof option === "number" || $.fx.speeds[ option ] ) {
2549		return true;
2550	}
2551
2552	// Invalid strings - treat as "normal" speed
2553	if ( typeof option === "string" && !$.effects.effect[ option ] ) {
2554		return true;
2555	}
2556
2557	// Complete callback
2558	if ( $.isFunction( option ) ) {
2559		return true;
2560	}
2561
2562	// Options hash (but not naming an effect)
2563	if ( typeof option === "object" && !option.effect ) {
2564		return true;
2565	}
2566
2567	// Didn't match any standard API
2568	return false;
2569}
2570
2571$.fn.extend( {
2572	effect: function( /* effect, options, speed, callback */ ) {
2573		var args = _normalizeArguments.apply( this, arguments ),
2574			effectMethod = $.effects.effect[ args.effect ],
2575			defaultMode = effectMethod.mode,
2576			queue = args.queue,
2577			queueName = queue || "fx",
2578			complete = args.complete,
2579			mode = args.mode,
2580			modes = [],
2581			prefilter = function( next ) {
2582				var el = $( this ),
2583					normalizedMode = $.effects.mode( el, mode ) || defaultMode;
2584
2585				// Sentinel for duck-punching the :animated psuedo-selector
2586				el.data( dataSpaceAnimated, true );
2587
2588				// Save effect mode for later use,
2589				// we can't just call $.effects.mode again later,
2590				// as the .show() below destroys the initial state
2591				modes.push( normalizedMode );
2592
2593				// See $.uiBackCompat inside of run() for removal of defaultMode in 1.13
2594				if ( defaultMode && ( normalizedMode === "show" ||
2595						( normalizedMode === defaultMode && normalizedMode === "hide" ) ) ) {
2596					el.show();
2597				}
2598
2599				if ( !defaultMode || normalizedMode !== "none" ) {
2600					$.effects.saveStyle( el );
2601				}
2602
2603				if ( $.isFunction( next ) ) {
2604					next();
2605				}
2606			};
2607
2608		if ( $.fx.off || !effectMethod ) {
2609
2610			// Delegate to the original method (e.g., .show()) if possible
2611			if ( mode ) {
2612				return this[ mode ]( args.duration, complete );
2613			} else {
2614				return this.each( function() {
2615					if ( complete ) {
2616						complete.call( this );
2617					}
2618				} );
2619			}
2620		}
2621
2622		function run( next ) {
2623			var elem = $( this );
2624
2625			function cleanup() {
2626				elem.removeData( dataSpaceAnimated );
2627
2628				$.effects.cleanUp( elem );
2629
2630				if ( args.mode === "hide" ) {
2631					elem.hide();
2632				}
2633
2634				done();
2635			}
2636
2637			function done() {
2638				if ( $.isFunction( complete ) ) {
2639					complete.call( elem[ 0 ] );
2640				}
2641
2642				if ( $.isFunction( next ) ) {
2643					next();
2644				}
2645			}
2646
2647			// Override mode option on a per element basis,
2648			// as toggle can be either show or hide depending on element state
2649			args.mode = modes.shift();
2650
2651			if ( $.uiBackCompat !== false && !defaultMode ) {
2652				if ( elem.is( ":hidden" ) ? mode === "hide" : mode === "show" ) {
2653
2654					// Call the core method to track "olddisplay" properly
2655					elem[ mode ]();
2656					done();
2657				} else {
2658					effectMethod.call( elem[ 0 ], args, done );
2659				}
2660			} else {
2661				if ( args.mode === "none" ) {
2662
2663					// Call the core method to track "olddisplay" properly
2664					elem[ mode ]();
2665					done();
2666				} else {
2667					effectMethod.call( elem[ 0 ], args, cleanup );
2668				}
2669			}
2670		}
2671
2672		// Run prefilter on all elements first to ensure that
2673		// any showing or hiding happens before placeholder creation,
2674		// which ensures that any layout changes are correctly captured.
2675		return queue === false ?
2676			this.each( prefilter ).each( run ) :
2677			this.queue( queueName, prefilter ).queue( queueName, run );
2678	},
2679
2680	show: ( function( orig ) {
2681		return function( option ) {
2682			if ( standardAnimationOption( option ) ) {
2683				return orig.apply( this, arguments );
2684			} else {
2685				var args = _normalizeArguments.apply( this, arguments );
2686				args.mode = "show";
2687				return this.effect.call( this, args );
2688			}
2689		};
2690	} )( $.fn.show ),
2691
2692	hide: ( function( orig ) {
2693		return function( option ) {
2694			if ( standardAnimationOption( option ) ) {
2695				return orig.apply( this, arguments );
2696			} else {
2697				var args = _normalizeArguments.apply( this, arguments );
2698				args.mode = "hide";
2699				return this.effect.call( this, args );
2700			}
2701		};
2702	} )( $.fn.hide ),
2703
2704	toggle: ( function( orig ) {
2705		return function( option ) {
2706			if ( standardAnimationOption( option ) || typeof option === "boolean" ) {
2707				return orig.apply( this, arguments );
2708			} else {
2709				var args = _normalizeArguments.apply( this, arguments );
2710				args.mode = "toggle";
2711				return this.effect.call( this, args );
2712			}
2713		};
2714	} )( $.fn.toggle ),
2715
2716	cssUnit: function( key ) {
2717		var style = this.css( key ),
2718			val = [];
2719
2720		$.each( [ "em", "px", "%", "pt" ], function( i, unit ) {
2721			if ( style.indexOf( unit ) > 0 ) {
2722				val = [ parseFloat( style ), unit ];
2723			}
2724		} );
2725		return val;
2726	},
2727
2728	cssClip: function( clipObj ) {
2729		if ( clipObj ) {
2730			return this.css( "clip", "rect(" + clipObj.top + "px " + clipObj.right + "px " +
2731				clipObj.bottom + "px " + clipObj.left + "px)" );
2732		}
2733		return parseClip( this.css( "clip" ), this );
2734	},
2735
2736	transfer: function( options, done ) {
2737		var element = $( this ),
2738			target = $( options.to ),
2739			targetFixed = target.css( "position" ) === "fixed",
2740			body = $( "body" ),
2741			fixTop = targetFixed ? body.scrollTop() : 0,
2742			fixLeft = targetFixed ? body.scrollLeft() : 0,
2743			endPosition = target.offset(),
2744			animation = {
2745				top: endPosition.top - fixTop,
2746				left: endPosition.left - fixLeft,
2747				height: target.innerHeight(),
2748				width: target.innerWidth()
2749			},
2750			startPosition = element.offset(),
2751			transfer = $( "<div class='ui-effects-transfer'></div>" )
2752				.appendTo( "body" )
2753				.addClass( options.className )
2754				.css( {
2755					top: startPosition.top - fixTop,
2756					left: startPosition.left - fixLeft,
2757					height: element.innerHeight(),
2758					width: element.innerWidth(),
2759					position: targetFixed ? "fixed" : "absolute"
2760				} )
2761				.animate( animation, options.duration, options.easing, function() {
2762					transfer.remove();
2763					if ( $.isFunction( done ) ) {
2764						done();
2765					}
2766				} );
2767	}
2768} );
2769
2770function parseClip( str, element ) {
2771		var outerWidth = element.outerWidth(),
2772			outerHeight = element.outerHeight(),
2773			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)\)$/,
2774			values = clipRegex.exec( str ) || [ "", 0, outerWidth, outerHeight, 0 ];
2775
2776		return {
2777			top: parseFloat( values[ 1 ] ) || 0,
2778			right: values[ 2 ] === "auto" ? outerWidth : parseFloat( values[ 2 ] ),
2779			bottom: values[ 3 ] === "auto" ? outerHeight : parseFloat( values[ 3 ] ),
2780			left: parseFloat( values[ 4 ] ) || 0
2781		};
2782}
2783
2784$.fx.step.clip = function( fx ) {
2785	if ( !fx.clipInit ) {
2786		fx.start = $( fx.elem ).cssClip();
2787		if ( typeof fx.end === "string" ) {
2788			fx.end = parseClip( fx.end, fx.elem );
2789		}
2790		fx.clipInit = true;
2791	}
2792
2793	$( fx.elem ).cssClip( {
2794		top: fx.pos * ( fx.end.top - fx.start.top ) + fx.start.top,
2795		right: fx.pos * ( fx.end.right - fx.start.right ) + fx.start.right,
2796		bottom: fx.pos * ( fx.end.bottom - fx.start.bottom ) + fx.start.bottom,
2797		left: fx.pos * ( fx.end.left - fx.start.left ) + fx.start.left
2798	} );
2799};
2800
2801} )();
2802
2803/******************************************************************************/
2804/*********************************** EASING ***********************************/
2805/******************************************************************************/
2806
2807( function() {
2808
2809// Based on easing equations from Robert Penner (http://www.robertpenner.com/easing)
2810
2811var baseEasings = {};
2812
2813$.each( [ "Quad", "Cubic", "Quart", "Quint", "Expo" ], function( i, name ) {
2814	baseEasings[ name ] = function( p ) {
2815		return Math.pow( p, i + 2 );
2816	};
2817} );
2818
2819$.extend( baseEasings, {
2820	Sine: function( p ) {
2821		return 1 - Math.cos( p * Math.PI / 2 );
2822	},
2823	Circ: function( p ) {
2824		return 1 - Math.sqrt( 1 - p * p );
2825	},
2826	Elastic: function( p ) {
2827		return p === 0 || p === 1 ? p :
2828			-Math.pow( 2, 8 * ( p - 1 ) ) * Math.sin( ( ( p - 1 ) * 80 - 7.5 ) * Math.PI / 15 );
2829	},
2830	Back: function( p ) {
2831		return p * p * ( 3 * p - 2 );
2832	},
2833	Bounce: function( p ) {
2834		var pow2,
2835			bounce = 4;
2836
2837		while ( p < ( ( pow2 = Math.pow( 2, --bounce ) ) - 1 ) / 11 ) {}
2838		return 1 / Math.pow( 4, 3 - bounce ) - 7.5625 * Math.pow( ( pow2 * 3 - 2 ) / 22 - p, 2 );
2839	}
2840} );
2841
2842$.each( baseEasings, function( name, easeIn ) {
2843	$.easing[ "easeIn" + name ] = easeIn;
2844	$.easing[ "easeOut" + name ] = function( p ) {
2845		return 1 - easeIn( 1 - p );
2846	};
2847	$.easing[ "easeInOut" + name ] = function( p ) {
2848		return p < 0.5 ?
2849			easeIn( p * 2 ) / 2 :
2850			1 - easeIn( p * -2 + 2 ) / 2;
2851	};
2852} );
2853
2854} )();
2855
2856var effect = $.effects;
2857
2858
2859/*!
2860 * jQuery UI Effects Blind 1.12.1
2861 * http://jqueryui.com
2862 *
2863 * Copyright jQuery Foundation and other contributors
2864 * Released under the MIT license.
2865 * http://jquery.org/license
2866 */
2867
2868//>>label: Blind Effect
2869//>>group: Effects
2870//>>description: Blinds the element.
2871//>>docs: http://api.jqueryui.com/blind-effect/
2872//>>demos: http://jqueryui.com/effect/
2873
2874
2875
2876var effectsEffectBlind = $.effects.define( "blind", "hide", function( options, done ) {
2877	var map = {
2878			up: [ "bottom", "top" ],
2879			vertical: [ "bottom", "top" ],
2880			down: [ "top", "bottom" ],
2881			left: [ "right", "left" ],
2882			horizontal: [ "right", "left" ],
2883			right: [ "left", "right" ]
2884		},
2885		element = $( this ),
2886		direction = options.direction || "up",
2887		start = element.cssClip(),
2888		animate = { clip: $.extend( {}, start ) },
2889		placeholder = $.effects.createPlaceholder( element );
2890
2891	animate.clip[ map[ direction ][ 0 ] ] = animate.clip[ map[ direction ][ 1 ] ];
2892
2893	if ( options.mode === "show" ) {
2894		element.cssClip( animate.clip );
2895		if ( placeholder ) {
2896			placeholder.css( $.effects.clipToBox( animate ) );
2897		}
2898
2899		animate.clip = start;
2900	}
2901
2902	if ( placeholder ) {
2903		placeholder.animate( $.effects.clipToBox( animate ), options.duration, options.easing );
2904	}
2905
2906	element.animate( animate, {
2907		queue: false,
2908		duration: options.duration,
2909		easing: options.easing,
2910		complete: done
2911	} );
2912} );
2913
2914
2915/*!
2916 * jQuery UI Effects Bounce 1.12.1
2917 * http://jqueryui.com
vendor: 10,588 bytes, lines 2918-3324
2918 *
2919 * Copyright jQuery Foundation and other contributors
2920 * Released under the MIT license.
2921 * http://jquery.org/license
2922 */
2923
2924//>>label: Bounce Effect
2925//>>group: Effects
2926//>>description: Bounces an element horizontally or vertically n times.
2927//>>docs: http://api.jqueryui.com/bounce-effect/
2928//>>demos: http://jqueryui.com/effect/
2929
2930
2931
2932var effectsEffectBounce = $.effects.define( "bounce", function( options, done ) {
2933	var upAnim, downAnim, refValue,
2934		element = $( this ),
2935
2936		// Defaults:
2937		mode = options.mode,
2938		hide = mode === "hide",
2939		show = mode === "show",
2940		direction = options.direction || "up",
2941		distance = options.distance,
2942		times = options.times || 5,
2943
2944		// Number of internal animations
2945		anims = times * 2 + ( show || hide ? 1 : 0 ),
2946		speed = options.duration / anims,
2947		easing = options.easing,
2948
2949		// Utility:
2950		ref = ( direction === "up" || direction === "down" ) ? "top" : "left",
2951		motion = ( direction === "up" || direction === "left" ),
2952		i = 0,
2953
2954		queuelen = element.queue().length;
2955
2956	$.effects.createPlaceholder( element );
2957
2958	refValue = element.css( ref );
2959
2960	// Default distance for the BIGGEST bounce is the outer Distance / 3
2961	if ( !distance ) {
2962		distance = element[ ref === "top" ? "outerHeight" : "outerWidth" ]() / 3;
2963	}
2964
2965	if ( show ) {
2966		downAnim = { opacity: 1 };
2967		downAnim[ ref ] = refValue;
2968
2969		// If we are showing, force opacity 0 and set the initial position
2970		// then do the "first" animation
2971		element
2972			.css( "opacity", 0 )
2973			.css( ref, motion ? -distance * 2 : distance * 2 )
2974			.animate( downAnim, speed, easing );
2975	}
2976
2977	// Start at the smallest distance if we are hiding
2978	if ( hide ) {
2979		distance = distance / Math.pow( 2, times - 1 );
2980	}
2981
2982	downAnim = {};
2983	downAnim[ ref ] = refValue;
2984
2985	// Bounces up/down/left/right then back to 0 -- times * 2 animations happen here
2986	for ( ; i < times; i++ ) {
2987		upAnim = {};
2988		upAnim[ ref ] = ( motion ? "-=" : "+=" ) + distance;
2989
2990		element
2991			.animate( upAnim, speed, easing )
2992			.animate( downAnim, speed, easing );
2993
2994		distance = hide ? distance * 2 : distance / 2;
2995	}
2996
2997	// Last Bounce when Hiding
2998	if ( hide ) {
2999		upAnim = { opacity: 0 };
3000		upAnim[ ref ] = ( motion ? "-=" : "+=" ) + distance;
3001
3002		element.animate( upAnim, speed, easing );
3003	}
3004
3005	element.queue( done );
3006
3007	$.effects.unshift( element, queuelen, anims + 1 );
3008} );
3009
3010
3011/*!
3012 * jQuery UI Effects Clip 1.12.1
3013 * http://jqueryui.com
3014 *
3015 * Copyright jQuery Foundation and other contributors
3016 * Released under the MIT license.
3017 * http://jquery.org/license
3018 */
3019
3020//>>label: Clip Effect
3021//>>group: Effects
3022//>>description: Clips the element on and off like an old TV.
3023//>>docs: http://api.jqueryui.com/clip-effect/
3024//>>demos: http://jqueryui.com/effect/
3025
3026
3027
3028var effectsEffectClip = $.effects.define( "clip", "hide", function( options, done ) {
3029	var start,
3030		animate = {},
3031		element = $( this ),
3032		direction = options.direction || "vertical",
3033		both = direction === "both",
3034		horizontal = both || direction === "horizontal",
3035		vertical = both || direction === "vertical";
3036
3037	start = element.cssClip();
3038	animate.clip = {
3039		top: vertical ? ( start.bottom - start.top ) / 2 : start.top,
3040		right: horizontal ? ( start.right - start.left ) / 2 : start.right,
3041		bottom: vertical ? ( start.bottom - start.top ) / 2 : start.bottom,
3042		left: horizontal ? ( start.right - start.left ) / 2 : start.left
3043	};
3044
3045	$.effects.createPlaceholder( element );
3046
3047	if ( options.mode === "show" ) {
3048		element.cssClip( animate.clip );
3049		animate.clip = start;
3050	}
3051
3052	element.animate( animate, {
3053		queue: false,
3054		duration: options.duration,
3055		easing: options.easing,
3056		complete: done
3057	} );
3058
3059} );
3060
3061
3062/*!
3063 * jQuery UI Effects Drop 1.12.1
3064 * http://jqueryui.com
3065 *
3066 * Copyright jQuery Foundation and other contributors
3067 * Released under the MIT license.
3068 * http://jquery.org/license
3069 */
3070
3071//>>label: Drop Effect
3072//>>group: Effects
3073//>>description: Moves an element in one direction and hides it at the same time.
3074//>>docs: http://api.jqueryui.com/drop-effect/
3075//>>demos: http://jqueryui.com/effect/
3076
3077
3078
3079var effectsEffectDrop = $.effects.define( "drop", "hide", function( options, done ) {
3080
3081	var distance,
3082		element = $( this ),
3083		mode = options.mode,
3084		show = mode === "show",
3085		direction = options.direction || "left",
3086		ref = ( direction === "up" || direction === "down" ) ? "top" : "left",
3087		motion = ( direction === "up" || direction === "left" ) ? "-=" : "+=",
3088		oppositeMotion = ( motion === "+=" ) ? "-=" : "+=",
3089		animation = {
3090			opacity: 0
3091		};
3092
3093	$.effects.createPlaceholder( element );
3094
3095	distance = options.distance ||
3096		element[ ref === "top" ? "outerHeight" : "outerWidth" ]( true ) / 2;
3097
3098	animation[ ref ] = motion + distance;
3099
3100	if ( show ) {
3101		element.css( animation );
3102
3103		animation[ ref ] = oppositeMotion + distance;
3104		animation.opacity = 1;
3105	}
3106
3107	// Animate
3108	element.animate( animation, {
3109		queue: false,
3110		duration: options.duration,
3111		easing: options.easing,
3112		complete: done
3113	} );
3114} );
3115
3116
3117/*!
3118 * jQuery UI Effects Explode 1.12.1
3119 * http://jqueryui.com
3120 *
3121 * Copyright jQuery Foundation and other contributors
3122 * Released under the MIT license.
3123 * http://jquery.org/license
3124 */
3125
3126//>>label: Explode Effect
3127//>>group: Effects
3128// jscs:disable maximumLineLength
3129//>>description: Explodes an element in all directions into n pieces. Implodes an element to its original wholeness.
3130// jscs:enable maximumLineLength
3131//>>docs: http://api.jqueryui.com/explode-effect/
3132//>>demos: http://jqueryui.com/effect/
3133
3134
3135
3136var effectsEffectExplode = $.effects.define( "explode", "hide", function( options, done ) {
3137
3138	var i, j, left, top, mx, my,
3139		rows = options.pieces ? Math.round( Math.sqrt( options.pieces ) ) : 3,
3140		cells = rows,
3141		element = $( this ),
3142		mode = options.mode,
3143		show = mode === "show",
3144
3145		// Show and then visibility:hidden the element before calculating offset
3146		offset = element.show().css( "visibility", "hidden" ).offset(),
3147
3148		// Width and height of a piece
3149		width = Math.ceil( element.outerWidth() / cells ),
3150		height = Math.ceil( element.outerHeight() / rows ),
3151		pieces = [];
3152
3153	// Children animate complete:
3154	function childComplete() {
3155		pieces.push( this );
3156		if ( pieces.length === rows * cells ) {
3157			animComplete();
3158		}
3159	}
3160
3161	// Clone the element for each row and cell.
3162	for ( i = 0; i < rows; i++ ) { // ===>
3163		top = offset.top + i * height;
3164		my = i - ( rows - 1 ) / 2;
3165
3166		for ( j = 0; j < cells; j++ ) { // |||
3167			left = offset.left + j * width;
3168			mx = j - ( cells - 1 ) / 2;
3169
3170			// Create a clone of the now hidden main element that will be absolute positioned
3171			// within a wrapper div off the -left and -top equal to size of our pieces
3172			element
3173				.clone()
3174				.appendTo( "body" )
3175				.wrap( "<div></div>" )
3176				.css( {
3177					position: "absolute",
3178					visibility: "visible",
3179					left: -j * width,
3180					top: -i * height
3181				} )
3182
3183				// Select the wrapper - make it overflow: hidden and absolute positioned based on
3184				// where the original was located +left and +top equal to the size of pieces
3185				.parent()
3186					.addClass( "ui-effects-explode" )
3187					.css( {
3188						position: "absolute",
3189						overflow: "hidden",
3190						width: width,
3191						height: height,
3192						left: left + ( show ? mx * width : 0 ),
3193						top: top + ( show ? my * height : 0 ),
3194						opacity: show ? 0 : 1
3195					} )
3196					.animate( {
3197						left: left + ( show ? 0 : mx * width ),
3198						top: top + ( show ? 0 : my * height ),
3199						opacity: show ? 1 : 0
3200					}, options.duration || 500, options.easing, childComplete );
3201		}
3202	}
3203
3204	function animComplete() {
3205		element.css( {
3206			visibility: "visible"
3207		} );
3208		$( pieces ).remove();
3209		done();
3210	}
3211} );
3212
3213
3214/*!
3215 * jQuery UI Effects Fade 1.12.1
3216 * http://jqueryui.com
3217 *
3218 * Copyright jQuery Foundation and other contributors
3219 * Released under the MIT license.
3220 * http://jquery.org/license
3221 */
3222
3223//>>label: Fade Effect
3224//>>group: Effects
3225//>>description: Fades the element.
3226//>>docs: http://api.jqueryui.com/fade-effect/
3227//>>demos: http://jqueryui.com/effect/
3228
3229
3230
3231var effectsEffectFade = $.effects.define( "fade", "toggle", function( options, done ) {
3232	var show = options.mode === "show";
3233
3234	$( this )
3235		.css( "opacity", show ? 0 : 1 )
3236		.animate( {
3237			opacity: show ? 1 : 0
3238		}, {
3239			queue: false,
3240			duration: options.duration,
3241			easing: options.easing,
3242			complete: done
3243		} );
3244} );
3245
3246
3247/*!
3248 * jQuery UI Effects Fold 1.12.1
3249 * http://jqueryui.com
3250 *
3251 * Copyright jQuery Foundation and other contributors
3252 * Released under the MIT license.
3253 * http://jquery.org/license
3254 */
3255
3256//>>label: Fold Effect
3257//>>group: Effects
3258//>>description: Folds an element first horizontally and then vertically.
3259//>>docs: http://api.jqueryui.com/fold-effect/
3260//>>demos: http://jqueryui.com/effect/
3261
3262
3263
3264var effectsEffectFold = $.effects.define( "fold", "hide", function( options, done ) {
3265
3266	// Create element
3267	var element = $( this ),
3268		mode = options.mode,
3269		show = mode === "show",
3270		hide = mode === "hide",
3271		size = options.size || 15,
3272		percent = /([0-9]+)%/.exec( size ),
3273		horizFirst = !!options.horizFirst,
3274		ref = horizFirst ? [ "right", "bottom" ] : [ "bottom", "right" ],
3275		duration = options.duration / 2,
3276
3277		placeholder = $.effects.createPlaceholder( element ),
3278
3279		start = element.cssClip(),
3280		animation1 = { clip: $.extend( {}, start ) },
3281		animation2 = { clip: $.extend( {}, start ) },
3282
3283		distance = [ start[ ref[ 0 ] ], start[ ref[ 1 ] ] ],
3284
3285		queuelen = element.queue().length;
3286
3287	if ( percent ) {
3288		size = parseInt( percent[ 1 ], 10 ) / 100 * distance[ hide ? 0 : 1 ];
3289	}
3290	animation1.clip[ ref[ 0 ] ] = size;
3291	animation2.clip[ ref[ 0 ] ] = size;
3292	animation2.clip[ ref[ 1 ] ] = 0;
3293
3294	if ( show ) {
3295		element.cssClip( animation2.clip );
3296		if ( placeholder ) {
3297			placeholder.css( $.effects.clipToBox( animation2 ) );
3298		}
3299
3300		animation2.clip = start;
3301	}
3302
3303	// Animate
3304	element
3305		.queue( function( next ) {
3306			if ( placeholder ) {
3307				placeholder
3308					.animate( $.effects.clipToBox( animation1 ), duration, options.easing )
3309					.animate( $.effects.clipToBox( animation2 ), duration, options.easing );
3310			}
3311
3312			next();
3313		} )
3314		.animate( animation1, duration, options.easing )
3315		.animate( animation2, duration, options.easing )
3316		.queue( done );
3317
3318	$.effects.unshift( element, queuelen, 4 );
3319} );
3320
3321
3322/*!
3323 * jQuery UI Effects Highlight 1.12.1
3324 * http://jqueryui.com
vendor: 6,249 bytes, lines 3325-3544
3325 *
3326 * Copyright jQuery Foundation and other contributors
3327 * Released under the MIT license.
3328 * http://jquery.org/license
3329 */
3330
3331//>>label: Highlight Effect
3332//>>group: Effects
3333//>>description: Highlights the background of an element in a defined color for a custom duration.
3334//>>docs: http://api.jqueryui.com/highlight-effect/
3335//>>demos: http://jqueryui.com/effect/
3336
3337
3338
3339var effectsEffectHighlight = $.effects.define( "highlight", "show", function( options, done ) {
3340	var element = $( this ),
3341		animation = {
3342			backgroundColor: element.css( "backgroundColor" )
3343		};
3344
3345	if ( options.mode === "hide" ) {
3346		animation.opacity = 0;
3347	}
3348
3349	$.effects.saveStyle( element );
3350
3351	element
3352		.css( {
3353			backgroundImage: "none",
3354			backgroundColor: options.color || "#ffff99"
3355		} )
3356		.animate( animation, {
3357			queue: false,
3358			duration: options.duration,
3359			easing: options.easing,
3360			complete: done
3361		} );
3362} );
3363
3364
3365/*!
3366 * jQuery UI Effects Size 1.12.1
3367 * http://jqueryui.com
3368 *
3369 * Copyright jQuery Foundation and other contributors
3370 * Released under the MIT license.
3371 * http://jquery.org/license
3372 */
3373
3374//>>label: Size Effect
3375//>>group: Effects
3376//>>description: Resize an element to a specified width and height.
3377//>>docs: http://api.jqueryui.com/size-effect/
3378//>>demos: http://jqueryui.com/effect/
3379
3380
3381
3382var effectsEffectSize = $.effects.define( "size", function( options, done ) {
3383
3384	// Create element
3385	var baseline, factor, temp,
3386		element = $( this ),
3387
3388		// Copy for children
3389		cProps = [ "fontSize" ],
3390		vProps = [ "borderTopWidth", "borderBottomWidth", "paddingTop", "paddingBottom" ],
3391		hProps = [ "borderLeftWidth", "borderRightWidth", "paddingLeft", "paddingRight" ],
3392
3393		// Set options
3394		mode = options.mode,
3395		restore = mode !== "effect",
3396		scale = options.scale || "both",
3397		origin = options.origin || [ "middle", "center" ],
3398		position = element.css( "position" ),
3399		pos = element.position(),
3400		original = $.effects.scaledDimensions( element ),
3401		from = options.from || original,
3402		to = options.to || $.effects.scaledDimensions( element, 0 );
3403
3404	$.effects.createPlaceholder( element );
3405
3406	if ( mode === "show" ) {
3407		temp = from;
3408		from = to;
3409		to = temp;
3410	}
3411
3412	// Set scaling factor
3413	factor = {
3414		from: {
3415			y: from.height / original.height,
3416			x: from.width / original.width
3417		},
3418		to: {
3419			y: to.height / original.height,
3420			x: to.width / original.width
3421		}
3422	};
3423
3424	// Scale the css box
3425	if ( scale === "box" || scale === "both" ) {
3426
3427		// Vertical props scaling
3428		if ( factor.from.y !== factor.to.y ) {
3429			from = $.effects.setTransition( element, vProps, factor.from.y, from );
3430			to = $.effects.setTransition( element, vProps, factor.to.y, to );
3431		}
3432
3433		// Horizontal props scaling
3434		if ( factor.from.x !== factor.to.x ) {
3435			from = $.effects.setTransition( element, hProps, factor.from.x, from );
3436			to = $.effects.setTransition( element, hProps, factor.to.x, to );
3437		}
3438	}
3439
3440	// Scale the content
3441	if ( scale === "content" || scale === "both" ) {
3442
3443		// Vertical props scaling
3444		if ( factor.from.y !== factor.to.y ) {
3445			from = $.effects.setTransition( element, cProps, factor.from.y, from );
3446			to = $.effects.setTransition( element, cProps, factor.to.y, to );
3447		}
3448	}
3449
3450	// Adjust the position properties based on the provided origin points
3451	if ( origin ) {
3452		baseline = $.effects.getBaseline( origin, original );
3453		from.top = ( original.outerHeight - from.outerHeight ) * baseline.y + pos.top;
3454		from.left = ( original.outerWidth - from.outerWidth ) * baseline.x + pos.left;
3455		to.top = ( original.outerHeight - to.outerHeight ) * baseline.y + pos.top;
3456		to.left = ( original.outerWidth - to.outerWidth ) * baseline.x + pos.left;
3457	}
3458	element.css( from );
3459
3460	// Animate the children if desired
3461	if ( scale === "content" || scale === "both" ) {
3462
3463		vProps = vProps.concat( [ "marginTop", "marginBottom" ] ).concat( cProps );
3464		hProps = hProps.concat( [ "marginLeft", "marginRight" ] );
3465
3466		// Only animate children with width attributes specified
3467		// TODO: is this right? should we include anything with css width specified as well
3468		element.find( "*[width]" ).each( function() {
3469			var child = $( this ),
3470				childOriginal = $.effects.scaledDimensions( child ),
3471				childFrom = {
3472					height: childOriginal.height * factor.from.y,
3473					width: childOriginal.width * factor.from.x,
3474					outerHeight: childOriginal.outerHeight * factor.from.y,
3475					outerWidth: childOriginal.outerWidth * factor.from.x
3476				},
3477				childTo = {
3478					height: childOriginal.height * factor.to.y,
3479					width: childOriginal.width * factor.to.x,
3480					outerHeight: childOriginal.height * factor.to.y,
3481					outerWidth: childOriginal.width * factor.to.x
3482				};
3483
3484			// Vertical props scaling
3485			if ( factor.from.y !== factor.to.y ) {
3486				childFrom = $.effects.setTransition( child, vProps, factor.from.y, childFrom );
3487				childTo = $.effects.setTransition( child, vProps, factor.to.y, childTo );
3488			}
3489
3490			// Horizontal props scaling
3491			if ( factor.from.x !== factor.to.x ) {
3492				childFrom = $.effects.setTransition( child, hProps, factor.from.x, childFrom );
3493				childTo = $.effects.setTransition( child, hProps, factor.to.x, childTo );
3494			}
3495
3496			if ( restore ) {
3497				$.effects.saveStyle( child );
3498			}
3499
3500			// Animate children
3501			child.css( childFrom );
3502			child.animate( childTo, options.duration, options.easing, function() {
3503
3504				// Restore children
3505				if ( restore ) {
3506					$.effects.restoreStyle( child );
3507				}
3508			} );
3509		} );
3510	}
3511
3512	// Animate
3513	element.animate( to, {
3514		queue: false,
3515		duration: options.duration,
3516		easing: options.easing,
3517		complete: function() {
3518
3519			var offset = element.offset();
3520
3521			if ( to.opacity === 0 ) {
3522				element.css( "opacity", from.opacity );
3523			}
3524
3525			if ( !restore ) {
3526				element
3527					.css( "position", position === "static" ? "relative" : position )
3528					.offset( offset );
3529
3530				// Need to save style here so that automatic style restoration
3531				// doesn't restore to the original styles from before the animation.
3532				$.effects.saveStyle( element );
3533			}
3534
3535			done();
3536		}
3537	} );
3538
3539} );
3540
3541
3542/*!
3543 * jQuery UI Effects Scale 1.12.1
3544 * http://jqueryui.com
vendor: 4,797 bytes, lines 3545-3722
3545 *
3546 * Copyright jQuery Foundation and other contributors
3547 * Released under the MIT license.
3548 * http://jquery.org/license
3549 */
3550
3551//>>label: Scale Effect
3552//>>group: Effects
3553//>>description: Grows or shrinks an element and its content.
3554//>>docs: http://api.jqueryui.com/scale-effect/
3555//>>demos: http://jqueryui.com/effect/
3556
3557
3558
3559var effectsEffectScale = $.effects.define( "scale", function( options, done ) {
3560
3561	// Create element
3562	var el = $( this ),
3563		mode = options.mode,
3564		percent = parseInt( options.percent, 10 ) ||
3565			( parseInt( options.percent, 10 ) === 0 ? 0 : ( mode !== "effect" ? 0 : 100 ) ),
3566
3567		newOptions = $.extend( true, {
3568			from: $.effects.scaledDimensions( el ),
3569			to: $.effects.scaledDimensions( el, percent, options.direction || "both" ),
3570			origin: options.origin || [ "middle", "center" ]
3571		}, options );
3572
3573	// Fade option to support puff
3574	if ( options.fade ) {
3575		newOptions.from.opacity = 1;
3576		newOptions.to.opacity = 0;
3577	}
3578
3579	$.effects.effect.size.call( this, newOptions, done );
3580} );
3581
3582
3583/*!
3584 * jQuery UI Effects Puff 1.12.1
3585 * http://jqueryui.com
3586 *
3587 * Copyright jQuery Foundation and other contributors
3588 * Released under the MIT license.
3589 * http://jquery.org/license
3590 */
3591
3592//>>label: Puff Effect
3593//>>group: Effects
3594//>>description: Creates a puff effect by scaling the element up and hiding it at the same time.
3595//>>docs: http://api.jqueryui.com/puff-effect/
3596//>>demos: http://jqueryui.com/effect/
3597
3598
3599
3600var effectsEffectPuff = $.effects.define( "puff", "hide", function( options, done ) {
3601	var newOptions = $.extend( true, {}, options, {
3602		fade: true,
3603		percent: parseInt( options.percent, 10 ) || 150
3604	} );
3605
3606	$.effects.effect.scale.call( this, newOptions, done );
3607} );
3608
3609
3610/*!
3611 * jQuery UI Effects Pulsate 1.12.1
3612 * http://jqueryui.com
3613 *
3614 * Copyright jQuery Foundation and other contributors
3615 * Released under the MIT license.
3616 * http://jquery.org/license
3617 */
3618
3619//>>label: Pulsate Effect
3620//>>group: Effects
3621//>>description: Pulsates an element n times by changing the opacity to zero and back.
3622//>>docs: http://api.jqueryui.com/pulsate-effect/
3623//>>demos: http://jqueryui.com/effect/
3624
3625
3626
3627var effectsEffectPulsate = $.effects.define( "pulsate", "show", function( options, done ) {
3628	var element = $( this ),
3629		mode = options.mode,
3630		show = mode === "show",
3631		hide = mode === "hide",
3632		showhide = show || hide,
3633
3634		// Showing or hiding leaves off the "last" animation
3635		anims = ( ( options.times || 5 ) * 2 ) + ( showhide ? 1 : 0 ),
3636		duration = options.duration / anims,
3637		animateTo = 0,
3638		i = 1,
3639		queuelen = element.queue().length;
3640
3641	if ( show || !element.is( ":visible" ) ) {
3642		element.css( "opacity", 0 ).show();
3643		animateTo = 1;
3644	}
3645
3646	// Anims - 1 opacity "toggles"
3647	for ( ; i < anims; i++ ) {
3648		element.animate( { opacity: animateTo }, duration, options.easing );
3649		animateTo = 1 - animateTo;
3650	}
3651
3652	element.animate( { opacity: animateTo }, duration, options.easing );
3653
3654	element.queue( done );
3655
3656	$.effects.unshift( element, queuelen, anims + 1 );
3657} );
3658
3659
3660/*!
3661 * jQuery UI Effects Shake 1.12.1
3662 * http://jqueryui.com
3663 *
3664 * Copyright jQuery Foundation and other contributors
3665 * Released under the MIT license.
3666 * http://jquery.org/license
3667 */
3668
3669//>>label: Shake Effect
3670//>>group: Effects
3671//>>description: Shakes an element horizontally or vertically n times.
3672//>>docs: http://api.jqueryui.com/shake-effect/
3673//>>demos: http://jqueryui.com/effect/
3674
3675
3676
3677var effectsEffectShake = $.effects.define( "shake", function( options, done ) {
3678
3679	var i = 1,
3680		element = $( this ),
3681		direction = options.direction || "left",
3682		distance = options.distance || 20,
3683		times = options.times || 3,
3684		anims = times * 2 + 1,
3685		speed = Math.round( options.duration / anims ),
3686		ref = ( direction === "up" || direction === "down" ) ? "top" : "left",
3687		positiveMotion = ( direction === "up" || direction === "left" ),
3688		animation = {},
3689		animation1 = {},
3690		animation2 = {},
3691
3692		queuelen = element.queue().length;
3693
3694	$.effects.createPlaceholder( element );
3695
3696	// Animation
3697	animation[ ref ] = ( positiveMotion ? "-=" : "+=" ) + distance;
3698	animation1[ ref ] = ( positiveMotion ? "+=" : "-=" ) + distance * 2;
3699	animation2[ ref ] = ( positiveMotion ? "-=" : "+=" ) + distance * 2;
3700
3701	// Animate
3702	element.animate( animation, speed, options.easing );
3703
3704	// Shakes
3705	for ( ; i < times; i++ ) {
3706		element
3707			.animate( animation1, speed, options.easing )
3708			.animate( animation2, speed, options.easing );
3709	}
3710
3711	element
3712		.animate( animation1, speed, options.easing )
3713		.animate( animation, speed / 2, options.easing )
3714		.queue( done );
3715
3716	$.effects.unshift( element, queuelen, anims + 1 );
3717} );
3718
3719
3720/*!
3721 * jQuery UI Effects Slide 1.12.1
3722 * http://jqueryui.com
vendor: 4,781 bytes, lines 3723-3894
3723 *
3724 * Copyright jQuery Foundation and other contributors
3725 * Released under the MIT license.
3726 * http://jquery.org/license
3727 */
3728
3729//>>label: Slide Effect
3730//>>group: Effects
3731//>>description: Slides an element in and out of the viewport.
3732//>>docs: http://api.jqueryui.com/slide-effect/
3733//>>demos: http://jqueryui.com/effect/
3734
3735
3736
3737var effectsEffectSlide = $.effects.define( "slide", "show", function( options, done ) {
3738	var startClip, startRef,
3739		element = $( this ),
3740		map = {
3741			up: [ "bottom", "top" ],
3742			down: [ "top", "bottom" ],
3743			left: [ "right", "left" ],
3744			right: [ "left", "right" ]
3745		},
3746		mode = options.mode,
3747		direction = options.direction || "left",
3748		ref = ( direction === "up" || direction === "down" ) ? "top" : "left",
3749		positiveMotion = ( direction === "up" || direction === "left" ),
3750		distance = options.distance ||
3751			element[ ref === "top" ? "outerHeight" : "outerWidth" ]( true ),
3752		animation = {};
3753
3754	$.effects.createPlaceholder( element );
3755
3756	startClip = element.cssClip();
3757	startRef = element.position()[ ref ];
3758
3759	// Define hide animation
3760	animation[ ref ] = ( positiveMotion ? -1 : 1 ) * distance + startRef;
3761	animation.clip = element.cssClip();
3762	animation.clip[ map[ direction ][ 1 ] ] = animation.clip[ map[ direction ][ 0 ] ];
3763
3764	// Reverse the animation if we're showing
3765	if ( mode === "show" ) {
3766		element.cssClip( animation.clip );
3767		element.css( ref, animation[ ref ] );
3768		animation.clip = startClip;
3769		animation[ ref ] = startRef;
3770	}
3771
3772	// Actually animate
3773	element.animate( animation, {
3774		queue: false,
3775		duration: options.duration,
3776		easing: options.easing,
3777		complete: done
3778	} );
3779} );
3780
3781
3782/*!
3783 * jQuery UI Effects Transfer 1.12.1
3784 * http://jqueryui.com
3785 *
3786 * Copyright jQuery Foundation and other contributors
3787 * Released under the MIT license.
3788 * http://jquery.org/license
3789 */
3790
3791//>>label: Transfer Effect
3792//>>group: Effects
3793//>>description: Displays a transfer effect from one element to another.
3794//>>docs: http://api.jqueryui.com/transfer-effect/
3795//>>demos: http://jqueryui.com/effect/
3796
3797
3798
3799var effect;
3800if ( $.uiBackCompat !== false ) {
3801	effect = $.effects.define( "transfer", function( options, done ) {
3802		$( this ).transfer( options, done );
3803	} );
3804}
3805var effectsEffectTransfer = effect;
3806
3807
3808/*!
3809 * jQuery UI Focusable 1.12.1
3810 * http://jqueryui.com
3811 *
3812 * Copyright jQuery Foundation and other contributors
3813 * Released under the MIT license.
3814 * http://jquery.org/license
3815 */
3816
3817//>>label: :focusable Selector
3818//>>group: Core
3819//>>description: Selects elements which can be focused.
3820//>>docs: http://api.jqueryui.com/focusable-selector/
3821
3822
3823
3824// Selectors
3825$.ui.focusable = function( element, hasTabindex ) {
3826	var map, mapName, img, focusableIfVisible, fieldset,
3827		nodeName = element.nodeName.toLowerCase();
3828
3829	if ( "area" === nodeName ) {
3830		map = element.parentNode;
3831		mapName = map.name;
3832		if ( !element.href || !mapName || map.nodeName.toLowerCase() !== "map" ) {
3833			return false;
3834		}
3835		img = $( "img[usemap='#" + mapName + "']" );
3836		return img.length > 0 && img.is( ":visible" );
3837	}
3838
3839	if ( /^(input|select|textarea|button|object)$/.test( nodeName ) ) {
3840		focusableIfVisible = !element.disabled;
3841
3842		if ( focusableIfVisible ) {
3843
3844			// Form controls within a disabled fieldset are disabled.
3845			// However, controls within the fieldset's legend do not get disabled.
3846			// Since controls generally aren't placed inside legends, we skip
3847			// this portion of the check.
3848			fieldset = $( element ).closest( "fieldset" )[ 0 ];
3849			if ( fieldset ) {
3850				focusableIfVisible = !fieldset.disabled;
3851			}
3852		}
3853	} else if ( "a" === nodeName ) {
3854		focusableIfVisible = element.href || hasTabindex;
3855	} else {
3856		focusableIfVisible = hasTabindex;
3857	}
3858
3859	return focusableIfVisible && $( element ).is( ":visible" ) && visible( $( element ) );
3860};
3861
3862// Support: IE 8 only
3863// IE 8 doesn't resolve inherit to visible/hidden for computed values
3864function visible( element ) {
3865	var visibility = element.css( "visibility" );
3866	while ( visibility === "inherit" ) {
3867		element = element.parent();
3868		visibility = element.css( "visibility" );
3869	}
3870	return visibility !== "hidden";
3871}
3872
3873$.extend( $.expr[ ":" ], {
3874	focusable: function( element ) {
3875		return $.ui.focusable( element, $.attr( element, "tabindex" ) != null );
3876	}
3877} );
3878
3879var focusable = $.ui.focusable;
3880
3881
3882
3883
3884// Support: IE8 Only
3885// IE8 does not support the form attribute and when it is supplied. It overwrites the form prop
3886// with a string, so we need to find the proper form.
3887var form = $.fn.form = function() {
3888	return typeof this[ 0 ].form === "string" ? this.closest( "form" ) : $( this[ 0 ].form );
3889};
3890
3891
3892/*!
3893 * jQuery UI Form Reset Mixin 1.12.1
3894 * http://jqueryui.com
vendor: 4,779 bytes, lines 3895-4082
3895 *
3896 * Copyright jQuery Foundation and other contributors
3897 * Released under the MIT license.
3898 * http://jquery.org/license
3899 */
3900
3901//>>label: Form Reset Mixin
3902//>>group: Core
3903//>>description: Refresh input widgets when their form is reset
3904//>>docs: http://api.jqueryui.com/form-reset-mixin/
3905
3906
3907
3908var formResetMixin = $.ui.formResetMixin = {
3909	_formResetHandler: function() {
3910		var form = $( this );
3911
3912		// Wait for the form reset to actually happen before refreshing
3913		setTimeout( function() {
3914			var instances = form.data( "ui-form-reset-instances" );
3915			$.each( instances, function() {
3916				this.refresh();
3917			} );
3918		} );
3919	},
3920
3921	_bindFormResetHandler: function() {
3922		this.form = this.element.form();
3923		if ( !this.form.length ) {
3924			return;
3925		}
3926
3927		var instances = this.form.data( "ui-form-reset-instances" ) || [];
3928		if ( !instances.length ) {
3929
3930			// We don't use _on() here because we use a single event handler per form
3931			this.form.on( "reset.ui-form-reset", this._formResetHandler );
3932		}
3933		instances.push( this );
3934		this.form.data( "ui-form-reset-instances", instances );
3935	},
3936
3937	_unbindFormResetHandler: function() {
3938		if ( !this.form.length ) {
3939			return;
3940		}
3941
3942		var instances = this.form.data( "ui-form-reset-instances" );
3943		instances.splice( $.inArray( this, instances ), 1 );
3944		if ( instances.length ) {
3945			this.form.data( "ui-form-reset-instances", instances );
3946		} else {
3947			this.form
3948				.removeData( "ui-form-reset-instances" )
3949				.off( "reset.ui-form-reset" );
3950		}
3951	}
3952};
3953
3954
3955/*!
3956 * jQuery UI Support for jQuery core 1.7.x 1.12.1
3957 * http://jqueryui.com
3958 *
3959 * Copyright jQuery Foundation and other contributors
3960 * Released under the MIT license.
3961 * http://jquery.org/license
3962 *
3963 */
3964
3965//>>label: jQuery 1.7 Support
3966//>>group: Core
3967//>>description: Support version 1.7.x of jQuery core
3968
3969
3970
3971// Support: jQuery 1.7 only
3972// Not a great way to check versions, but since we only support 1.7+ and only
3973// need to detect <1.8, this is a simple check that should suffice. Checking
3974// for "1.7." would be a bit safer, but the version string is 1.7, not 1.7.0
3975// and we'll never reach 1.70.0 (if we do, we certainly won't be supporting
3976// 1.7 anymore). See #11197 for why we're not using feature detection.
3977if ( $.fn.jquery.substring( 0, 3 ) === "1.7" ) {
3978
3979	// Setters for .innerWidth(), .innerHeight(), .outerWidth(), .outerHeight()
3980	// Unlike jQuery Core 1.8+, these only support numeric values to set the
3981	// dimensions in pixels
3982	$.each( [ "Width", "Height" ], function( i, name ) {
3983		var side = name === "Width" ? [ "Left", "Right" ] : [ "Top", "Bottom" ],
3984			type = name.toLowerCase(),
3985			orig = {
3986				innerWidth: $.fn.innerWidth,
3987				innerHeight: $.fn.innerHeight,
3988				outerWidth: $.fn.outerWidth,
3989				outerHeight: $.fn.outerHeight
3990			};
3991
3992		function reduce( elem, size, border, margin ) {
3993			$.each( side, function() {
3994				size -= parseFloat( $.css( elem, "padding" + this ) ) || 0;
3995				if ( border ) {
3996					size -= parseFloat( $.css( elem, "border" + this + "Width" ) ) || 0;
3997				}
3998				if ( margin ) {
3999					size -= parseFloat( $.css( elem, "margin" + this ) ) || 0;
4000				}
4001			} );
4002			return size;
4003		}
4004
4005		$.fn[ "inner" + name ] = function( size ) {
4006			if ( size === undefined ) {
4007				return orig[ "inner" + name ].call( this );
4008			}
4009
4010			return this.each( function() {
4011				$( this ).css( type, reduce( this, size ) + "px" );
4012			} );
4013		};
4014
4015		$.fn[ "outer" + name ] = function( size, margin ) {
4016			if ( typeof size !== "number" ) {
4017				return orig[ "outer" + name ].call( this, size );
4018			}
4019
4020			return this.each( function() {
4021				$( this ).css( type, reduce( this, size, true, margin ) + "px" );
4022			} );
4023		};
4024	} );
4025
4026	$.fn.addBack = function( selector ) {
4027		return this.add( selector == null ?
4028			this.prevObject : this.prevObject.filter( selector )
4029		);
4030	};
4031}
4032
4033;
4034/*!
4035 * jQuery UI Keycode 1.12.1
4036 * http://jqueryui.com
4037 *
4038 * Copyright jQuery Foundation and other contributors
4039 * Released under the MIT license.
4040 * http://jquery.org/license
4041 */
4042
4043//>>label: Keycode
4044//>>group: Core
4045//>>description: Provide keycodes as keynames
4046//>>docs: http://api.jqueryui.com/jQuery.ui.keyCode/
4047
4048
4049var keycode = $.ui.keyCode = {
4050	BACKSPACE: 8,
4051	COMMA: 188,
4052	DELETE: 46,
4053	DOWN: 40,
4054	END: 35,
4055	ENTER: 13,
4056	ESCAPE: 27,
4057	HOME: 36,
4058	LEFT: 37,
4059	PAGE_DOWN: 34,
4060	PAGE_UP: 33,
4061	PERIOD: 190,
4062	RIGHT: 39,
4063	SPACE: 32,
4064	TAB: 9,
4065	UP: 38
4066};
4067
4068
4069
4070
4071// Internal use only
4072var escapeSelector = $.ui.escapeSelector = ( function() {
4073	var selectorEscape = /([!"#$%&'()*+,./:;<=>?@[\]^`{|}~])/g;
4074	return function( selector ) {
4075		return selector.replace( selectorEscape, "\\$1" );
4076	};
4077} )();
4078
4079
4080/*!
4081 * jQuery UI Labels 1.12.1
4082 * http://jqueryui.com
vendor: 5,256 bytes, lines 4083-4286
4083 *
4084 * Copyright jQuery Foundation and other contributors
4085 * Released under the MIT license.
4086 * http://jquery.org/license
4087 */
4088
4089//>>label: labels
4090//>>group: Core
4091//>>description: Find all the labels associated with a given input
4092//>>docs: http://api.jqueryui.com/labels/
4093
4094
4095
4096var labels = $.fn.labels = function() {
4097	var ancestor, selector, id, labels, ancestors;
4098
4099	// Check control.labels first
4100	if ( this[ 0 ].labels && this[ 0 ].labels.length ) {
4101		return this.pushStack( this[ 0 ].labels );
4102	}
4103
4104	// Support: IE <= 11, FF <= 37, Android <= 2.3 only
4105	// Above browsers do not support control.labels. Everything below is to support them
4106	// as well as document fragments. control.labels does not work on document fragments
4107	labels = this.eq( 0 ).parents( "label" );
4108
4109	// Look for the label based on the id
4110	id = this.attr( "id" );
4111	if ( id ) {
4112
4113		// We don't search against the document in case the element
4114		// is disconnected from the DOM
4115		ancestor = this.eq( 0 ).parents().last();
4116
4117		// Get a full set of top level ancestors
4118		ancestors = ancestor.add( ancestor.length ? ancestor.siblings() : this.siblings() );
4119
4120		// Create a selector for the label based on the id
4121		selector = "label[for='" + $.ui.escapeSelector( id ) + "']";
4122
4123		labels = labels.add( ancestors.find( selector ).addBack( selector ) );
4124
4125	}
4126
4127	// Return whatever we have found for labels
4128	return this.pushStack( labels );
4129};
4130
4131
4132/*!
4133 * jQuery UI Scroll Parent 1.12.1
4134 * http://jqueryui.com
4135 *
4136 * Copyright jQuery Foundation and other contributors
4137 * Released under the MIT license.
4138 * http://jquery.org/license
4139 */
4140
4141//>>label: scrollParent
4142//>>group: Core
4143//>>description: Get the closest ancestor element that is scrollable.
4144//>>docs: http://api.jqueryui.com/scrollParent/
4145
4146
4147
4148var scrollParent = $.fn.scrollParent = function( includeHidden ) {
4149	var position = this.css( "position" ),
4150		excludeStaticParent = position === "absolute",
4151		overflowRegex = includeHidden ? /(auto|scroll|hidden)/ : /(auto|scroll)/,
4152		scrollParent = this.parents().filter( function() {
4153			var parent = $( this );
4154			if ( excludeStaticParent && parent.css( "position" ) === "static" ) {
4155				return false;
4156			}
4157			return overflowRegex.test( parent.css( "overflow" ) + parent.css( "overflow-y" ) +
4158				parent.css( "overflow-x" ) );
4159		} ).eq( 0 );
4160
4161	return position === "fixed" || !scrollParent.length ?
4162		$( this[ 0 ].ownerDocument || document ) :
4163		scrollParent;
4164};
4165
4166
4167/*!
4168 * jQuery UI Tabbable 1.12.1
4169 * http://jqueryui.com
4170 *
4171 * Copyright jQuery Foundation and other contributors
4172 * Released under the MIT license.
4173 * http://jquery.org/license
4174 */
4175
4176//>>label: :tabbable Selector
4177//>>group: Core
4178//>>description: Selects elements which can be tabbed to.
4179//>>docs: http://api.jqueryui.com/tabbable-selector/
4180
4181
4182
4183var tabbable = $.extend( $.expr[ ":" ], {
4184	tabbable: function( element ) {
4185		var tabIndex = $.attr( element, "tabindex" ),
4186			hasTabindex = tabIndex != null;
4187		return ( !hasTabindex || tabIndex >= 0 ) && $.ui.focusable( element, hasTabindex );
4188	}
4189} );
4190
4191
4192/*!
4193 * jQuery UI Unique ID 1.12.1
4194 * http://jqueryui.com
4195 *
4196 * Copyright jQuery Foundation and other contributors
4197 * Released under the MIT license.
4198 * http://jquery.org/license
4199 */
4200
4201//>>label: uniqueId
4202//>>group: Core
4203//>>description: Functions to generate and remove uniqueId's
4204//>>docs: http://api.jqueryui.com/uniqueId/
4205
4206
4207
4208var uniqueId = $.fn.extend( {
4209	uniqueId: ( function() {
4210		var uuid = 0;
4211
4212		return function() {
4213			return this.each( function() {
4214				if ( !this.id ) {
4215					this.id = "ui-id-" + ( ++uuid );
4216				}
4217			} );
4218		};
4219	} )(),
4220
4221	removeUniqueId: function() {
4222		return this.each( function() {
4223			if ( /^ui-id-\d+$/.test( this.id ) ) {
4224				$( this ).removeAttr( "id" );
4225			}
4226		} );
4227	}
4228} );
4229
4230
4231/*!
4232 * jQuery UI Accordion 1.12.1
4233 * http://jqueryui.com
4234 *
4235 * Copyright jQuery Foundation and other contributors
4236 * Released under the MIT license.
4237 * http://jquery.org/license
4238 */
4239
4240//>>label: Accordion
4241//>>group: Widgets
4242// jscs:disable maximumLineLength
4243//>>description: Displays collapsible content panels for presenting information in a limited amount of space.
4244// jscs:enable maximumLineLength
4245//>>docs: http://api.jqueryui.com/accordion/
4246//>>demos: http://jqueryui.com/accordion/
4247//>>css.structure: ../../themes/base/core.css
4248//>>css.structure: ../../themes/base/accordion.css
4249//>>css.theme: ../../themes/base/theme.css
4250
4251
4252
4253var widgetsAccordion = $.widget( "ui.accordion", {
4254	version: "1.12.1",
4255	options: {
4256		active: 0,
4257		animate: {},
4258		classes: {
4259			"ui-accordion-header": "ui-corner-top",
4260			"ui-accordion-header-collapsed": "ui-corner-all",
4261			"ui-accordion-content": "ui-corner-bottom"
4262		},
4263		collapsible: false,
4264		event: "click",
4265		header: "> li > :first-child, > :not(li):even",
4266		heightStyle: "auto",
4267		icons: {
4268			activeHeader: "ui-icon-triangle-1-s",
4269			header: "ui-icon-triangle-1-e"
4270		},
4271
4272		// Callbacks
4273		activate: null,
4274		beforeActivate: null
4275	},
4276
4277	hideProps: {
4278		borderTopWidth: "hide",
4279		borderBottomWidth: "hide",
4280		paddingTop: "hide",
4281		paddingBottom: "hide",
4282		height: "hide"
4283	},
4284
4285	showProps: {
4286		borderTopWidth: "show",
vendor: 5,248 bytes, lines 4287-4489
4287		borderBottomWidth: "show",
4288		paddingTop: "show",
4289		paddingBottom: "show",
4290		height: "show"
4291	},
4292
4293	_create: function() {
4294		var options = this.options;
4295
4296		this.prevShow = this.prevHide = $();
4297		this._addClass( "ui-accordion", "ui-widget ui-helper-reset" );
4298		this.element.attr( "role", "tablist" );
4299
4300		// Don't allow collapsible: false and active: false / null
4301		if ( !options.collapsible && ( options.active === false || options.active == null ) ) {
4302			options.active = 0;
4303		}
4304
4305		this._processPanels();
4306
4307		// handle negative values
4308		if ( options.active < 0 ) {
4309			options.active += this.headers.length;
4310		}
4311		this._refresh();
4312	},
4313
4314	_getCreateEventData: function() {
4315		return {
4316			header: this.active,
4317			panel: !this.active.length ? $() : this.active.next()
4318		};
4319	},
4320
4321	_createIcons: function() {
4322		var icon, children,
4323			icons = this.options.icons;
4324
4325		if ( icons ) {
4326			icon = $( "<span>" );
4327			this._addClass( icon, "ui-accordion-header-icon", "ui-icon " + icons.header );
4328			icon.prependTo( this.headers );
4329			children = this.active.children( ".ui-accordion-header-icon" );
4330			this._removeClass( children, icons.header )
4331				._addClass( children, null, icons.activeHeader )
4332				._addClass( this.headers, "ui-accordion-icons" );
4333		}
4334	},
4335
4336	_destroyIcons: function() {
4337		this._removeClass( this.headers, "ui-accordion-icons" );
4338		this.headers.children( ".ui-accordion-header-icon" ).remove();
4339	},
4340
4341	_destroy: function() {
4342		var contents;
4343
4344		// Clean up main element
4345		this.element.removeAttr( "role" );
4346
4347		// Clean up headers
4348		this.headers
4349			.removeAttr( "role aria-expanded aria-selected aria-controls tabIndex" )
4350			.removeUniqueId();
4351
4352		this._destroyIcons();
4353
4354		// Clean up content panels
4355		contents = this.headers.next()
4356			.css( "display", "" )
4357			.removeAttr( "role aria-hidden aria-labelledby" )
4358			.removeUniqueId();
4359
4360		if ( this.options.heightStyle !== "content" ) {
4361			contents.css( "height", "" );
4362		}
4363	},
4364
4365	_setOption: function( key, value ) {
4366		if ( key === "active" ) {
4367
4368			// _activate() will handle invalid values and update this.options
4369			this._activate( value );
4370			return;
4371		}
4372
4373		if ( key === "event" ) {
4374			if ( this.options.event ) {
4375				this._off( this.headers, this.options.event );
4376			}
4377			this._setupEvents( value );
4378		}
4379
4380		this._super( key, value );
4381
4382		// Setting collapsible: false while collapsed; open first panel
4383		if ( key === "collapsible" && !value && this.options.active === false ) {
4384			this._activate( 0 );
4385		}
4386
4387		if ( key === "icons" ) {
4388			this._destroyIcons();
4389			if ( value ) {
4390				this._createIcons();
4391			}
4392		}
4393	},
4394
4395	_setOptionDisabled: function( value ) {
4396		this._super( value );
4397
4398		this.element.attr( "aria-disabled", value );
4399
4400		// Support: IE8 Only
4401		// #5332 / #6059 - opacity doesn't cascade to positioned elements in IE
4402		// so we need to add the disabled class to the headers and panels
4403		this._toggleClass( null, "ui-state-disabled", !!value );
4404		this._toggleClass( this.headers.add( this.headers.next() ), null, "ui-state-disabled",
4405			!!value );
4406	},
4407
4408	_keydown: function( event ) {
4409		if ( event.altKey || event.ctrlKey ) {
4410			return;
4411		}
4412
4413		var keyCode = $.ui.keyCode,
4414			length = this.headers.length,
4415			currentIndex = this.headers.index( event.target ),
4416			toFocus = false;
4417
4418		switch ( event.keyCode ) {
4419		case keyCode.RIGHT:
4420		case keyCode.DOWN:
4421			toFocus = this.headers[ ( currentIndex + 1 ) % length ];
4422			break;
4423		case keyCode.LEFT:
4424		case keyCode.UP:
4425			toFocus = this.headers[ ( currentIndex - 1 + length ) % length ];
4426			break;
4427		case keyCode.SPACE:
4428		case keyCode.ENTER:
4429			this._eventHandler( event );
4430			break;
4431		case keyCode.HOME:
4432			toFocus = this.headers[ 0 ];
4433			break;
4434		case keyCode.END:
4435			toFocus = this.headers[ length - 1 ];
4436			break;
4437		}
4438
4439		if ( toFocus ) {
4440			$( event.target ).attr( "tabIndex", -1 );
4441			$( toFocus ).attr( "tabIndex", 0 );
4442			$( toFocus ).trigger( "focus" );
4443			event.preventDefault();
4444		}
4445	},
4446
4447	_panelKeyDown: function( event ) {
4448		if ( event.keyCode === $.ui.keyCode.UP && event.ctrlKey ) {
4449			$( event.currentTarget ).prev().trigger( "focus" );
4450		}
4451	},
4452
4453	refresh: function() {
4454		var options = this.options;
4455		this._processPanels();
4456
4457		// Was collapsed or no panel
4458		if ( ( options.active === false && options.collapsible === true ) ||
4459				!this.headers.length ) {
4460			options.active = false;
4461			this.active = $();
4462
4463		// active false only when collapsible is true
4464		} else if ( options.active === false ) {
4465			this._activate( 0 );
4466
4467		// was active, but active panel is gone
4468		} else if ( this.active.length && !$.contains( this.element[ 0 ], this.active[ 0 ] ) ) {
4469
4470			// all remaining panel are disabled
4471			if ( this.headers.length === this.headers.find( ".ui-state-disabled" ).length ) {
4472				options.active = false;
4473				this.active = $();
4474
4475			// activate previous panel
4476			} else {
4477				this._activate( Math.max( 0, options.active - 1 ) );
4478			}
4479
4480		// was active, active panel still exists
4481		} else {
4482
4483			// make sure active index is correct
4484			options.active = this.headers.index( this.active );
4485		}
4486
4487		this._destroyIcons();
4488
4489		this._refresh();
vendor: 6,800 bytes, lines 4490-4727
4490	},
4491
4492	_processPanels: function() {
4493		var prevHeaders = this.headers,
4494			prevPanels = this.panels;
4495
4496		this.headers = this.element.find( this.options.header );
4497		this._addClass( this.headers, "ui-accordion-header ui-accordion-header-collapsed",
4498			"ui-state-default" );
4499
4500		this.panels = this.headers.next().filter( ":not(.ui-accordion-content-active)" ).hide();
4501		this._addClass( this.panels, "ui-accordion-content", "ui-helper-reset ui-widget-content" );
4502
4503		// Avoid memory leaks (#10056)
4504		if ( prevPanels ) {
4505			this._off( prevHeaders.not( this.headers ) );
4506			this._off( prevPanels.not( this.panels ) );
4507		}
4508	},
4509
4510	_refresh: function() {
4511		var maxHeight,
4512			options = this.options,
4513			heightStyle = options.heightStyle,
4514			parent = this.element.parent();
4515
4516		this.active = this._findActive( options.active );
4517		this._addClass( this.active, "ui-accordion-header-active", "ui-state-active" )
4518			._removeClass( this.active, "ui-accordion-header-collapsed" );
4519		this._addClass( this.active.next(), "ui-accordion-content-active" );
4520		this.active.next().show();
4521
4522		this.headers
4523			.attr( "role", "tab" )
4524			.each( function() {
4525				var header = $( this ),
4526					headerId = header.uniqueId().attr( "id" ),
4527					panel = header.next(),
4528					panelId = panel.uniqueId().attr( "id" );
4529				header.attr( "aria-controls", panelId );
4530				panel.attr( "aria-labelledby", headerId );
4531			} )
4532			.next()
4533				.attr( "role", "tabpanel" );
4534
4535		this.headers
4536			.not( this.active )
4537				.attr( {
4538					"aria-selected": "false",
4539					"aria-expanded": "false",
4540					tabIndex: -1
4541				} )
4542				.next()
4543					.attr( {
4544						"aria-hidden": "true"
4545					} )
4546					.hide();
4547
4548		// Make sure at least one header is in the tab order
4549		if ( !this.active.length ) {
4550			this.headers.eq( 0 ).attr( "tabIndex", 0 );
4551		} else {
4552			this.active.attr( {
4553				"aria-selected": "true",
4554				"aria-expanded": "true",
4555				tabIndex: 0
4556			} )
4557				.next()
4558					.attr( {
4559						"aria-hidden": "false"
4560					} );
4561		}
4562
4563		this._createIcons();
4564
4565		this._setupEvents( options.event );
4566
4567		if ( heightStyle === "fill" ) {
4568			maxHeight = parent.height();
4569			this.element.siblings( ":visible" ).each( function() {
4570				var elem = $( this ),
4571					position = elem.css( "position" );
4572
4573				if ( position === "absolute" || position === "fixed" ) {
4574					return;
4575				}
4576				maxHeight -= elem.outerHeight( true );
4577			} );
4578
4579			this.headers.each( function() {
4580				maxHeight -= $( this ).outerHeight( true );
4581			} );
4582
4583			this.headers.next()
4584				.each( function() {
4585					$( this ).height( Math.max( 0, maxHeight -
4586						$( this ).innerHeight() + $( this ).height() ) );
4587				} )
4588				.css( "overflow", "auto" );
4589		} else if ( heightStyle === "auto" ) {
4590			maxHeight = 0;
4591			this.headers.next()
4592				.each( function() {
4593					var isVisible = $( this ).is( ":visible" );
4594					if ( !isVisible ) {
4595						$( this ).show();
4596					}
4597					maxHeight = Math.max( maxHeight, $( this ).css( "height", "" ).height() );
4598					if ( !isVisible ) {
4599						$( this ).hide();
4600					}
4601				} )
4602				.height( maxHeight );
4603		}
4604	},
4605
4606	_activate: function( index ) {
4607		var active = this._findActive( index )[ 0 ];
4608
4609		// Trying to activate the already active panel
4610		if ( active === this.active[ 0 ] ) {
4611			return;
4612		}
4613
4614		// Trying to collapse, simulate a click on the currently active header
4615		active = active || this.active[ 0 ];
4616
4617		this._eventHandler( {
4618			target: active,
4619			currentTarget: active,
4620			preventDefault: $.noop
4621		} );
4622	},
4623
4624	_findActive: function( selector ) {
4625		return typeof selector === "number" ? this.headers.eq( selector ) : $();
4626	},
4627
4628	_setupEvents: function( event ) {
4629		var events = {
4630			keydown: "_keydown"
4631		};
4632		if ( event ) {
4633			$.each( event.split( " " ), function( index, eventName ) {
4634				events[ eventName ] = "_eventHandler";
4635			} );
4636		}
4637
4638		this._off( this.headers.add( this.headers.next() ) );
4639		this._on( this.headers, events );
4640		this._on( this.headers.next(), { keydown: "_panelKeyDown" } );
4641		this._hoverable( this.headers );
4642		this._focusable( this.headers );
4643	},
4644
4645	_eventHandler: function( event ) {
4646		var activeChildren, clickedChildren,
4647			options = this.options,
4648			active = this.active,
4649			clicked = $( event.currentTarget ),
4650			clickedIsActive = clicked[ 0 ] === active[ 0 ],
4651			collapsing = clickedIsActive && options.collapsible,
4652			toShow = collapsing ? $() : clicked.next(),
4653			toHide = active.next(),
4654			eventData = {
4655				oldHeader: active,
4656				oldPanel: toHide,
4657				newHeader: collapsing ? $() : clicked,
4658				newPanel: toShow
4659			};
4660
4661		event.preventDefault();
4662
4663		if (
4664
4665				// click on active header, but not collapsible
4666				( clickedIsActive && !options.collapsible ) ||
4667
4668				// allow canceling activation
4669				( this._trigger( "beforeActivate", event, eventData ) === false ) ) {
4670			return;
4671		}
4672
4673		options.active = collapsing ? false : this.headers.index( clicked );
4674
4675		// When the call to ._toggle() comes after the class changes
4676		// it causes a very odd bug in IE 8 (see #6720)
4677		this.active = clickedIsActive ? $() : clicked;
4678		this._toggle( eventData );
4679
4680		// Switch classes
4681		// corner classes on the previously active header stay after the animation
4682		this._removeClass( active, "ui-accordion-header-active", "ui-state-active" );
4683		if ( options.icons ) {
4684			activeChildren = active.children( ".ui-accordion-header-icon" );
4685			this._removeClass( activeChildren, null, options.icons.activeHeader )
4686				._addClass( activeChildren, null, options.icons.header );
4687		}
4688
4689		if ( !clickedIsActive ) {
4690			this._removeClass( clicked, "ui-accordion-header-collapsed" )
4691				._addClass( clicked, "ui-accordion-header-active", "ui-state-active" );
4692			if ( options.icons ) {
4693				clickedChildren = clicked.children( ".ui-accordion-header-icon" );
4694				this._removeClass( clickedChildren, null, options.icons.header )
4695					._addClass( clickedChildren, null, options.icons.activeHeader );
4696			}
4697
4698			this._addClass( clicked.next(), "ui-accordion-content-active" );
4699		}
4700	},
4701
4702	_toggle: function( data ) {
4703		var toShow = data.newPanel,
4704			toHide = this.prevShow.length ? this.prevShow : data.oldPanel;
4705
4706		// Handle activating a panel during the animation for another activation
4707		this.prevShow.add( this.prevHide ).stop( true, true );
4708		this.prevShow = toShow;
4709		this.prevHide = toHide;
4710
4711		if ( this.options.animate ) {
4712			this._animate( toShow, toHide, data );
4713		} else {
4714			toHide.hide();
4715			toShow.show();
4716			this._toggleComplete( data );
4717		}
4718
4719		toHide.attr( {
4720			"aria-hidden": "true"
4721		} );
4722		toHide.prev().attr( {
4723			"aria-selected": "false",
4724			"aria-expanded": "false"
4725		} );
4726
4727		// if we're switching panels, remove the old header from the tab order
vendor: 7,571 bytes, lines 4728-4998
4728		// if we're opening from collapsed state, remove the previous header from the tab order
4729		// if we're collapsing, then keep the collapsing header in the tab order
4730		if ( toShow.length && toHide.length ) {
4731			toHide.prev().attr( {
4732				"tabIndex": -1,
4733				"aria-expanded": "false"
4734			} );
4735		} else if ( toShow.length ) {
4736			this.headers.filter( function() {
4737				return parseInt( $( this ).attr( "tabIndex" ), 10 ) === 0;
4738			} )
4739				.attr( "tabIndex", -1 );
4740		}
4741
4742		toShow
4743			.attr( "aria-hidden", "false" )
4744			.prev()
4745				.attr( {
4746					"aria-selected": "true",
4747					"aria-expanded": "true",
4748					tabIndex: 0
4749				} );
4750	},
4751
4752	_animate: function( toShow, toHide, data ) {
4753		var total, easing, duration,
4754			that = this,
4755			adjust = 0,
4756			boxSizing = toShow.css( "box-sizing" ),
4757			down = toShow.length &&
4758				( !toHide.length || ( toShow.index() < toHide.index() ) ),
4759			animate = this.options.animate || {},
4760			options = down && animate.down || animate,
4761			complete = function() {
4762				that._toggleComplete( data );
4763			};
4764
4765		if ( typeof options === "number" ) {
4766			duration = options;
4767		}
4768		if ( typeof options === "string" ) {
4769			easing = options;
4770		}
4771
4772		// fall back from options to animation in case of partial down settings
4773		easing = easing || options.easing || animate.easing;
4774		duration = duration || options.duration || animate.duration;
4775
4776		if ( !toHide.length ) {
4777			return toShow.animate( this.showProps, duration, easing, complete );
4778		}
4779		if ( !toShow.length ) {
4780			return toHide.animate( this.hideProps, duration, easing, complete );
4781		}
4782
4783		total = toShow.show().outerHeight();
4784		toHide.animate( this.hideProps, {
4785			duration: duration,
4786			easing: easing,
4787			step: function( now, fx ) {
4788				fx.now = Math.round( now );
4789			}
4790		} );
4791		toShow
4792			.hide()
4793			.animate( this.showProps, {
4794				duration: duration,
4795				easing: easing,
4796				complete: complete,
4797				step: function( now, fx ) {
4798					fx.now = Math.round( now );
4799					if ( fx.prop !== "height" ) {
4800						if ( boxSizing === "content-box" ) {
4801							adjust += fx.now;
4802						}
4803					} else if ( that.options.heightStyle !== "content" ) {
4804						fx.now = Math.round( total - toHide.outerHeight() - adjust );
4805						adjust = 0;
4806					}
4807				}
4808			} );
4809	},
4810
4811	_toggleComplete: function( data ) {
4812		var toHide = data.oldPanel,
4813			prev = toHide.prev();
4814
4815		this._removeClass( toHide, "ui-accordion-content-active" );
4816		this._removeClass( prev, "ui-accordion-header-active" )
4817			._addClass( prev, "ui-accordion-header-collapsed" );
4818
4819		// Work around for rendering bug in IE (#5421)
4820		if ( toHide.length ) {
4821			toHide.parent()[ 0 ].className = toHide.parent()[ 0 ].className;
4822		}
4823		this._trigger( "activate", null, data );
4824	}
4825} );
4826
4827
4828
4829var safeActiveElement = $.ui.safeActiveElement = function( document ) {
4830	var activeElement;
4831
4832	// Support: IE 9 only
4833	// IE9 throws an "Unspecified error" accessing document.activeElement from an <iframe>
4834	try {
4835		activeElement = document.activeElement;
4836	} catch ( error ) {
4837		activeElement = document.body;
4838	}
4839
4840	// Support: IE 9 - 11 only
4841	// IE may return null instead of an element
4842	// Interestingly, this only seems to occur when NOT in an iframe
4843	if ( !activeElement ) {
4844		activeElement = document.body;
4845	}
4846
4847	// Support: IE 11 only
4848	// IE11 returns a seemingly empty object in some cases when accessing
4849	// document.activeElement from an <iframe>
4850	if ( !activeElement.nodeName ) {
4851		activeElement = document.body;
4852	}
4853
4854	return activeElement;
4855};
4856
4857
4858/*!
4859 * jQuery UI Menu 1.12.1
4860 * http://jqueryui.com
4861 *
4862 * Copyright jQuery Foundation and other contributors
4863 * Released under the MIT license.
4864 * http://jquery.org/license
4865 */
4866
4867//>>label: Menu
4868//>>group: Widgets
4869//>>description: Creates nestable menus.
4870//>>docs: http://api.jqueryui.com/menu/
4871//>>demos: http://jqueryui.com/menu/
4872//>>css.structure: ../../themes/base/core.css
4873//>>css.structure: ../../themes/base/menu.css
4874//>>css.theme: ../../themes/base/theme.css
4875
4876
4877
4878var widgetsMenu = $.widget( "ui.menu", {
4879	version: "1.12.1",
4880	defaultElement: "<ul>",
4881	delay: 300,
4882	options: {
4883		icons: {
4884			submenu: "ui-icon-caret-1-e"
4885		},
4886		items: "> *",
4887		menus: "ul",
4888		position: {
4889			my: "left top",
4890			at: "right top"
4891		},
4892		role: "menu",
4893
4894		// Callbacks
4895		blur: null,
4896		focus: null,
4897		select: null
4898	},
4899
4900	_create: function() {
4901		this.activeMenu = this.element;
4902
4903		// Flag used to prevent firing of the click handler
4904		// as the event bubbles up through nested menus
4905		this.mouseHandled = false;
4906		this.element
4907			.uniqueId()
4908			.attr( {
4909				role: this.options.role,
4910				tabIndex: 0
4911			} );
4912
4913		this._addClass( "ui-menu", "ui-widget ui-widget-content" );
4914		this._on( {
4915
4916			// Prevent focus from sticking to links inside menu after clicking
4917			// them (focus should always stay on UL during navigation).
4918			"mousedown .ui-menu-item": function( event ) {
4919				event.preventDefault();
4920			},
4921			"click .ui-menu-item": function( event ) {
4922				var target = $( event.target );
4923				var active = $( $.ui.safeActiveElement( this.document[ 0 ] ) );
4924				if ( !this.mouseHandled && target.not( ".ui-state-disabled" ).length ) {
4925					this.select( event );
4926
4927					// Only set the mouseHandled flag if the event will bubble, see #9469.
4928					if ( !event.isPropagationStopped() ) {
4929						this.mouseHandled = true;
4930					}
4931
4932					// Open submenu on click
4933					if ( target.has( ".ui-menu" ).length ) {
4934						this.expand( event );
4935					} else if ( !this.element.is( ":focus" ) &&
4936							active.closest( ".ui-menu" ).length ) {
4937
4938						// Redirect focus to the menu
4939						this.element.trigger( "focus", [ true ] );
4940
4941						// If the active item is on the top level, let it stay active.
4942						// Otherwise, blur the active item since it is no longer visible.
4943						if ( this.active && this.active.parents( ".ui-menu" ).length === 1 ) {
4944							clearTimeout( this.timer );
4945						}
4946					}
4947				}
4948			},
4949			"mouseenter .ui-menu-item": function( event ) {
4950
4951				// Ignore mouse events while typeahead is active, see #10458.
4952				// Prevents focusing the wrong item when typeahead causes a scroll while the mouse
4953				// is over an item in the menu
4954				if ( this.previousFilter ) {
4955					return;
4956				}
4957
4958				var actualTarget = $( event.target ).closest( ".ui-menu-item" ),
4959					target = $( event.currentTarget );
4960
4961				// Ignore bubbled events on parent items, see #11641
4962				if ( actualTarget[ 0 ] !== target[ 0 ] ) {
4963					return;
4964				}
4965
4966				// Remove ui-state-active class from siblings of the newly focused menu item
4967				// to avoid a jump caused by adjacent elements both having a class with a border
4968				this._removeClass( target.siblings().children( ".ui-state-active" ),
4969					null, "ui-state-active" );
4970				this.focus( event, target );
4971			},
4972			mouseleave: "collapseAll",
4973			"mouseleave .ui-menu": "collapseAll",
4974			focus: function( event, keepActiveItem ) {
4975
4976				// If there's already an active item, keep it active
4977				// If not, activate the first item
4978				var item = this.active || this.element.find( this.options.items ).eq( 0 );
4979
4980				if ( !keepActiveItem ) {
4981					this.focus( event, item );
4982				}
4983			},
4984			blur: function( event ) {
4985				this._delay( function() {
4986					var notContained = !$.contains(
4987						this.element[ 0 ],
4988						$.ui.safeActiveElement( this.document[ 0 ] )
4989					);
4990					if ( notContained ) {
4991						this.collapseAll( event );
4992					}
4993				} );
4994			},
4995			keydown: "_keydown"
4996		} );
4997
4998		this.refresh();
vendor: 4,401 bytes, lines 4999-5162
4999
5000		// Clicks outside of a menu collapse any open menus
5001		this._on( this.document, {
5002			click: function( event ) {
5003				if ( this._closeOnDocumentClick( event ) ) {
5004					this.collapseAll( event );
5005				}
5006
5007				// Reset the mouseHandled flag
5008				this.mouseHandled = false;
5009			}
5010		} );
5011	},
5012
5013	_destroy: function() {
5014		var items = this.element.find( ".ui-menu-item" )
5015				.removeAttr( "role aria-disabled" ),
5016			submenus = items.children( ".ui-menu-item-wrapper" )
5017				.removeUniqueId()
5018				.removeAttr( "tabIndex role aria-haspopup" );
5019
5020		// Destroy (sub)menus
5021		this.element
5022			.removeAttr( "aria-activedescendant" )
5023			.find( ".ui-menu" ).addBack()
5024				.removeAttr( "role aria-labelledby aria-expanded aria-hidden aria-disabled " +
5025					"tabIndex" )
5026				.removeUniqueId()
5027				.show();
5028
5029		submenus.children().each( function() {
5030			var elem = $( this );
5031			if ( elem.data( "ui-menu-submenu-caret" ) ) {
5032				elem.remove();
5033			}
5034		} );
5035	},
5036
5037	_keydown: function( event ) {
5038		var match, prev, character, skip,
5039			preventDefault = true;
5040
5041		switch ( event.keyCode ) {
5042		case $.ui.keyCode.PAGE_UP:
5043			this.previousPage( event );
5044			break;
5045		case $.ui.keyCode.PAGE_DOWN:
5046			this.nextPage( event );
5047			break;
5048		case $.ui.keyCode.HOME:
5049			this._move( "first", "first", event );
5050			break;
5051		case $.ui.keyCode.END:
5052			this._move( "last", "last", event );
5053			break;
5054		case $.ui.keyCode.UP:
5055			this.previous( event );
5056			break;
5057		case $.ui.keyCode.DOWN:
5058			this.next( event );
5059			break;
5060		case $.ui.keyCode.LEFT:
5061			this.collapse( event );
5062			break;
5063		case $.ui.keyCode.RIGHT:
5064			if ( this.active && !this.active.is( ".ui-state-disabled" ) ) {
5065				this.expand( event );
5066			}
5067			break;
5068		case $.ui.keyCode.ENTER:
5069		case $.ui.keyCode.SPACE:
5070			this._activate( event );
5071			break;
5072		case $.ui.keyCode.ESCAPE:
5073			this.collapse( event );
5074			break;
5075		default:
5076			preventDefault = false;
5077			prev = this.previousFilter || "";
5078			skip = false;
5079
5080			// Support number pad values
5081			character = event.keyCode >= 96 && event.keyCode <= 105 ?
5082				( event.keyCode - 96 ).toString() : String.fromCharCode( event.keyCode );
5083
5084			clearTimeout( this.filterTimer );
5085
5086			if ( character === prev ) {
5087				skip = true;
5088			} else {
5089				character = prev + character;
5090			}
5091
5092			match = this._filterMenuItems( character );
5093			match = skip && match.index( this.active.next() ) !== -1 ?
5094				this.active.nextAll( ".ui-menu-item" ) :
5095				match;
5096
5097			// If no matches on the current filter, reset to the last character pressed
5098			// to move down the menu to the first item that starts with that character
5099			if ( !match.length ) {
5100				character = String.fromCharCode( event.keyCode );
5101				match = this._filterMenuItems( character );
5102			}
5103
5104			if ( match.length ) {
5105				this.focus( event, match );
5106				this.previousFilter = character;
5107				this.filterTimer = this._delay( function() {
5108					delete this.previousFilter;
5109				}, 1000 );
5110			} else {
5111				delete this.previousFilter;
5112			}
5113		}
5114
5115		if ( preventDefault ) {
5116			event.preventDefault();
5117		}
5118	},
5119
5120	_activate: function( event ) {
5121		if ( this.active && !this.active.is( ".ui-state-disabled" ) ) {
5122			if ( this.active.children( "[aria-haspopup='true']" ).length ) {
5123				this.expand( event );
5124			} else {
5125				this.select( event );
5126			}
5127		}
5128	},
5129
5130	refresh: function() {
5131		var menus, items, newSubmenus, newItems, newWrappers,
5132			that = this,
5133			icon = this.options.icons.submenu,
5134			submenus = this.element.find( this.options.menus );
5135
5136		this._toggleClass( "ui-menu-icons", null, !!this.element.find( ".ui-icon" ).length );
5137
5138		// Initialize nested menus
5139		newSubmenus = submenus.filter( ":not(.ui-menu)" )
5140			.hide()
5141			.attr( {
5142				role: this.options.role,
5143				"aria-hidden": "true",
5144				"aria-expanded": "false"
5145			} )
5146			.each( function() {
5147				var menu = $( this ),
5148					item = menu.prev(),
5149					submenuCaret = $( "<span>" ).data( "ui-menu-submenu-caret", true );
5150
5151				that._addClass( submenuCaret, "ui-menu-icon", "ui-icon " + icon );
5152				item
5153					.attr( "aria-haspopup", "true" )
5154					.prepend( submenuCaret );
5155				menu.attr( "aria-labelledby", item.attr( "id" ) );
5156			} );
5157
5158		this._addClass( newSubmenus, "ui-menu", "ui-widget ui-widget-content ui-front" );
5159
5160		menus = submenus.add( this.element );
5161		items = menus.find( this.options.items );
5162
vendor: 4,715 bytes, lines 5163-5325
5163		// Initialize menu-items containing spaces and/or dashes only as dividers
5164		items.not( ".ui-menu-item" ).each( function() {
5165			var item = $( this );
5166			if ( that._isDivider( item ) ) {
5167				that._addClass( item, "ui-menu-divider", "ui-widget-content" );
5168			}
5169		} );
5170
5171		// Don't refresh list items that are already adapted
5172		newItems = items.not( ".ui-menu-item, .ui-menu-divider" );
5173		newWrappers = newItems.children()
5174			.not( ".ui-menu" )
5175				.uniqueId()
5176				.attr( {
5177					tabIndex: -1,
5178					role: this._itemRole()
5179				} );
5180		this._addClass( newItems, "ui-menu-item" )
5181			._addClass( newWrappers, "ui-menu-item-wrapper" );
5182
5183		// Add aria-disabled attribute to any disabled menu item
5184		items.filter( ".ui-state-disabled" ).attr( "aria-disabled", "true" );
5185
5186		// If the active item has been removed, blur the menu
5187		if ( this.active && !$.contains( this.element[ 0 ], this.active[ 0 ] ) ) {
5188			this.blur();
5189		}
5190	},
5191
5192	_itemRole: function() {
5193		return {
5194			menu: "menuitem",
5195			listbox: "option"
5196		}[ this.options.role ];
5197	},
5198
5199	_setOption: function( key, value ) {
5200		if ( key === "icons" ) {
5201			var icons = this.element.find( ".ui-menu-icon" );
5202			this._removeClass( icons, null, this.options.icons.submenu )
5203				._addClass( icons, null, value.submenu );
5204		}
5205		this._super( key, value );
5206	},
5207
5208	_setOptionDisabled: function( value ) {
5209		this._super( value );
5210
5211		this.element.attr( "aria-disabled", String( value ) );
5212		this._toggleClass( null, "ui-state-disabled", !!value );
5213	},
5214
5215	focus: function( event, item ) {
5216		var nested, focused, activeParent;
5217		this.blur( event, event && event.type === "focus" );
5218
5219		this._scrollIntoView( item );
5220
5221		this.active = item.first();
5222
5223		focused = this.active.children( ".ui-menu-item-wrapper" );
5224		this._addClass( focused, null, "ui-state-active" );
5225
5226		// Only update aria-activedescendant if there's a role
5227		// otherwise we assume focus is managed elsewhere
5228		if ( this.options.role ) {
5229			this.element.attr( "aria-activedescendant", focused.attr( "id" ) );
5230		}
5231
5232		// Highlight active parent menu item, if any
5233		activeParent = this.active
5234			.parent()
5235				.closest( ".ui-menu-item" )
5236					.children( ".ui-menu-item-wrapper" );
5237		this._addClass( activeParent, null, "ui-state-active" );
5238
5239		if ( event && event.type === "keydown" ) {
5240			this._close();
5241		} else {
5242			this.timer = this._delay( function() {
5243				this._close();
5244			}, this.delay );
5245		}
5246
5247		nested = item.children( ".ui-menu" );
5248		if ( nested.length && event && ( /^mouse/.test( event.type ) ) ) {
5249			this._startOpening( nested );
5250		}
5251		this.activeMenu = item.parent();
5252
5253		this._trigger( "focus", event, { item: item } );
5254	},
5255
5256	_scrollIntoView: function( item ) {
5257		var borderTop, paddingTop, offset, scroll, elementHeight, itemHeight;
5258		if ( this._hasScroll() ) {
5259			borderTop = parseFloat( $.css( this.activeMenu[ 0 ], "borderTopWidth" ) ) || 0;
5260			paddingTop = parseFloat( $.css( this.activeMenu[ 0 ], "paddingTop" ) ) || 0;
5261			offset = item.offset().top - this.activeMenu.offset().top - borderTop - paddingTop;
5262			scroll = this.activeMenu.scrollTop();
5263			elementHeight = this.activeMenu.height();
5264			itemHeight = item.outerHeight();
5265
5266			if ( offset < 0 ) {
5267				this.activeMenu.scrollTop( scroll + offset );
5268			} else if ( offset + itemHeight > elementHeight ) {
5269				this.activeMenu.scrollTop( scroll + offset - elementHeight + itemHeight );
5270			}
5271		}
5272	},
5273
5274	blur: function( event, fromFocus ) {
5275		if ( !fromFocus ) {
5276			clearTimeout( this.timer );
5277		}
5278
5279		if ( !this.active ) {
5280			return;
5281		}
5282
5283		this._removeClass( this.active.children( ".ui-menu-item-wrapper" ),
5284			null, "ui-state-active" );
5285
5286		this._trigger( "blur", event, { item: this.active } );
5287		this.active = null;
5288	},
5289
5290	_startOpening: function( submenu ) {
5291		clearTimeout( this.timer );
5292
5293		// Don't open if already open fixes a Firefox bug that caused a .5 pixel
5294		// shift in the submenu position when mousing over the caret icon
5295		if ( submenu.attr( "aria-hidden" ) !== "true" ) {
5296			return;
5297		}
5298
5299		this.timer = this._delay( function() {
5300			this._close();
5301			this._open( submenu );
5302		}, this.delay );
5303	},
5304
5305	_open: function( submenu ) {
5306		var position = $.extend( {
5307			of: this.active
5308		}, this.options.position );
5309
5310		clearTimeout( this.timer );
5311		this.element.find( ".ui-menu" ).not( submenu.parents( ".ui-menu" ) )
5312			.hide()
5313			.attr( "aria-hidden", "true" );
5314
5315		submenu
5316			.show()
5317			.removeAttr( "aria-hidden" )
5318			.attr( "aria-expanded", "true" )
5319			.position( position );
5320	},
5321
5322	collapseAll: function( event, all ) {
5323		clearTimeout( this.timer );
5324		this.timer = this._delay( function() {
5325
vendor: 37,529 bytes, lines 5326-6679
5326			// If we were passed an event, look for the submenu that contains the event
5327			var currentMenu = all ? this.element :
5328				$( event && event.target ).closest( this.element.find( ".ui-menu" ) );
5329
5330			// If we found no valid submenu ancestor, use the main menu to close all
5331			// sub menus anyway
5332			if ( !currentMenu.length ) {
5333				currentMenu = this.element;
5334			}
5335
5336			this._close( currentMenu );
5337
5338			this.blur( event );
5339
5340			// Work around active item staying active after menu is blurred
5341			this._removeClass( currentMenu.find( ".ui-state-active" ), null, "ui-state-active" );
5342
5343			this.activeMenu = currentMenu;
5344		}, this.delay );
5345	},
5346
5347	// With no arguments, closes the currently active menu - if nothing is active
5348	// it closes all menus.  If passed an argument, it will search for menus BELOW
5349	_close: function( startMenu ) {
5350		if ( !startMenu ) {
5351			startMenu = this.active ? this.active.parent() : this.element;
5352		}
5353
5354		startMenu.find( ".ui-menu" )
5355			.hide()
5356			.attr( "aria-hidden", "true" )
5357			.attr( "aria-expanded", "false" );
5358	},
5359
5360	_closeOnDocumentClick: function( event ) {
5361		return !$( event.target ).closest( ".ui-menu" ).length;
5362	},
5363
5364	_isDivider: function( item ) {
5365
5366		// Match hyphen, em dash, en dash
5367		return !/[^\-\u2014\u2013\s]/.test( item.text() );
5368	},
5369
5370	collapse: function( event ) {
5371		var newItem = this.active &&
5372			this.active.parent().closest( ".ui-menu-item", this.element );
5373		if ( newItem && newItem.length ) {
5374			this._close();
5375			this.focus( event, newItem );
5376		}
5377	},
5378
5379	expand: function( event ) {
5380		var newItem = this.active &&
5381			this.active
5382				.children( ".ui-menu " )
5383					.find( this.options.items )
5384						.first();
5385
5386		if ( newItem && newItem.length ) {
5387			this._open( newItem.parent() );
5388
5389			// Delay so Firefox will not hide activedescendant change in expanding submenu from AT
5390			this._delay( function() {
5391				this.focus( event, newItem );
5392			} );
5393		}
5394	},
5395
5396	next: function( event ) {
5397		this._move( "next", "first", event );
5398	},
5399
5400	previous: function( event ) {
5401		this._move( "prev", "last", event );
5402	},
5403
5404	isFirstItem: function() {
5405		return this.active && !this.active.prevAll( ".ui-menu-item" ).length;
5406	},
5407
5408	isLastItem: function() {
5409		return this.active && !this.active.nextAll( ".ui-menu-item" ).length;
5410	},
5411
5412	_move: function( direction, filter, event ) {
5413		var next;
5414		if ( this.active ) {
5415			if ( direction === "first" || direction === "last" ) {
5416				next = this.active
5417					[ direction === "first" ? "prevAll" : "nextAll" ]( ".ui-menu-item" )
5418					.eq( -1 );
5419			} else {
5420				next = this.active
5421					[ direction + "All" ]( ".ui-menu-item" )
5422					.eq( 0 );
5423			}
5424		}
5425		if ( !next || !next.length || !this.active ) {
5426			next = this.activeMenu.find( this.options.items )[ filter ]();
5427		}
5428
5429		this.focus( event, next );
5430	},
5431
5432	nextPage: function( event ) {
5433		var item, base, height;
5434
5435		if ( !this.active ) {
5436			this.next( event );
5437			return;
5438		}
5439		if ( this.isLastItem() ) {
5440			return;
5441		}
5442		if ( this._hasScroll() ) {
5443			base = this.active.offset().top;
5444			height = this.element.height();
5445			this.active.nextAll( ".ui-menu-item" ).each( function() {
5446				item = $( this );
5447				return item.offset().top - base - height < 0;
5448			} );
5449
5450			this.focus( event, item );
5451		} else {
5452			this.focus( event, this.activeMenu.find( this.options.items )
5453				[ !this.active ? "first" : "last" ]() );
5454		}
5455	},
5456
5457	previousPage: function( event ) {
5458		var item, base, height;
5459		if ( !this.active ) {
5460			this.next( event );
5461			return;
5462		}
5463		if ( this.isFirstItem() ) {
5464			return;
5465		}
5466		if ( this._hasScroll() ) {
5467			base = this.active.offset().top;
5468			height = this.element.height();
5469			this.active.prevAll( ".ui-menu-item" ).each( function() {
5470				item = $( this );
5471				return item.offset().top - base + height > 0;
5472			} );
5473
5474			this.focus( event, item );
5475		} else {
5476			this.focus( event, this.activeMenu.find( this.options.items ).first() );
5477		}
5478	},
5479
5480	_hasScroll: function() {
5481		return this.element.outerHeight() < this.element.prop( "scrollHeight" );
5482	},
5483
5484	select: function( event ) {
5485
5486		// TODO: It should never be possible to not have an active item at this
5487		// point, but the tests don't trigger mouseenter before click.
5488		this.active = this.active || $( event.target ).closest( ".ui-menu-item" );
5489		var ui = { item: this.active };
5490		if ( !this.active.has( ".ui-menu" ).length ) {
5491			this.collapseAll( event, true );
5492		}
5493		this._trigger( "select", event, ui );
5494	},
5495
5496	_filterMenuItems: function( character ) {
5497		var escapedCharacter = character.replace( /[\-\[\]{}()*+?.,\\\^$|#\s]/g, "\\$&" ),
5498			regex = new RegExp( "^" + escapedCharacter, "i" );
5499
5500		return this.activeMenu
5501			.find( this.options.items )
5502
5503				// Only match on items, not dividers or other content (#10571)
5504				.filter( ".ui-menu-item" )
5505					.filter( function() {
5506						return regex.test(
5507							$.trim( $( this ).children( ".ui-menu-item-wrapper" ).text() ) );
5508					} );
5509	}
5510} );
5511
5512
5513/*!
5514 * jQuery UI Autocomplete 1.12.1
5515 * http://jqueryui.com
5516 *
5517 * Copyright jQuery Foundation and other contributors
5518 * Released under the MIT license.
5519 * http://jquery.org/license
5520 */
5521
5522//>>label: Autocomplete
5523//>>group: Widgets
5524//>>description: Lists suggested words as the user is typing.
5525//>>docs: http://api.jqueryui.com/autocomplete/
5526//>>demos: http://jqueryui.com/autocomplete/
5527//>>css.structure: ../../themes/base/core.css
5528//>>css.structure: ../../themes/base/autocomplete.css
5529//>>css.theme: ../../themes/base/theme.css
5530
5531
5532
5533$.widget( "ui.autocomplete", {
5534	version: "1.12.1",
5535	defaultElement: "<input>",
5536	options: {
5537		appendTo: null,
5538		autoFocus: false,
5539		delay: 300,
5540		minLength: 1,
5541		position: {
5542			my: "left top",
5543			at: "left bottom",
5544			collision: "none"
5545		},
5546		source: null,
5547
5548		// Callbacks
5549		change: null,
5550		close: null,
5551		focus: null,
5552		open: null,
5553		response: null,
5554		search: null,
5555		select: null
5556	},
5557	cache: [],
5558
5559	requestIndex: 0,
5560	pending: 0,
5561
5562	_create: function() {
5563
5564		// Some browsers only repeat keydown events, not keypress events,
5565		// so we use the suppressKeyPress flag to determine if we've already
5566		// handled the keydown event. #7269
5567		// Unfortunately the code for & in keypress is the same as the up arrow,
5568		// so we use the suppressKeyPressRepeat flag to avoid handling keypress
5569		// events when we know the keydown event was used to modify the
5570		// search term. #7799
5571		var suppressKeyPress, suppressKeyPressRepeat, suppressInput,
5572			nodeName = this.element[ 0 ].nodeName.toLowerCase(),
5573			isTextarea = nodeName === "textarea",
5574			isInput = nodeName === "input";
5575
5576		// Textareas are always multi-line
5577		// Inputs are always single-line, even if inside a contentEditable element
5578		// IE also treats inputs as contentEditable
5579		// All other element types are determined by whether or not they're contentEditable
5580		this.isMultiLine = isTextarea || !isInput && this._isContentEditable( this.element );
5581
5582		this.valueMethod = this.element[ isTextarea || isInput ? "val" : "text" ];
5583		this.isNewMenu = true;
5584
5585		this._addClass( "ui-autocomplete-input" );
5586		this.element.attr( "autocomplete", "off" );
5587
5588		this._on( this.element, {
5589			keydown: function( event ) {
5590				if ( this.element.prop( "readOnly" ) ) {
5591					suppressKeyPress = true;
5592					suppressInput = true;
5593					suppressKeyPressRepeat = true;
5594					return;
5595				}
5596
5597				suppressKeyPress = false;
5598				suppressInput = false;
5599				suppressKeyPressRepeat = false;
5600				var keyCode = $.ui.keyCode;
5601				switch ( event.keyCode ) {
5602				case keyCode.PAGE_UP:
5603					suppressKeyPress = true;
5604					this._move( "previousPage", event );
5605					break;
5606				case keyCode.PAGE_DOWN:
5607					suppressKeyPress = true;
5608					this._move( "nextPage", event );
5609					break;
5610				case keyCode.UP:
5611					suppressKeyPress = true;
5612					this._keyEvent( "previous", event );
5613					break;
5614				case keyCode.DOWN:
5615					suppressKeyPress = true;
5616					this._keyEvent( "next", event );
5617					break;
5618				case keyCode.ENTER:
5619
5620					// when menu is open and has focus
5621					if ( this.menu.active ) {
5622
5623						// #6055 - Opera still allows the keypress to occur
5624						// which causes forms to submit
5625						suppressKeyPress = true;
5626						event.preventDefault();
5627						this.menu.select( event );
5628					}
5629					break;
5630				case keyCode.TAB:
5631					if ( this.menu.active ) {
5632						this.menu.select( event );
5633					}
5634					break;
5635				case keyCode.ESCAPE:
5636					if ( this.menu.element.is( ":visible" ) ) {
5637						if ( !this.isMultiLine ) {
5638							this._value( this.term );
5639						}
5640						this.close( event );
5641
5642						// Different browsers have different default behavior for escape
5643						// Single press can mean undo or clear
5644						// Double press in IE means clear the whole form
5645						event.preventDefault();
5646					}
5647					break;
5648				default:
5649					suppressKeyPressRepeat = true;
5650
5651					// search timeout should be triggered before the input value is changed
5652					this._searchTimeout( event );
5653					break;
5654				}
5655			},
5656			keypress: function( event ) {
5657				if ( suppressKeyPress ) {
5658					suppressKeyPress = false;
5659					if ( !this.isMultiLine || this.menu.element.is( ":visible" ) ) {
5660						event.preventDefault();
5661					}
5662					return;
5663				}
5664				if ( suppressKeyPressRepeat ) {
5665					return;
5666				}
5667
5668				// Replicate some key handlers to allow them to repeat in Firefox and Opera
5669				var keyCode = $.ui.keyCode;
5670				switch ( event.keyCode ) {
5671				case keyCode.PAGE_UP:
5672					this._move( "previousPage", event );
5673					break;
5674				case keyCode.PAGE_DOWN:
5675					this._move( "nextPage", event );
5676					break;
5677				case keyCode.UP:
5678					this._keyEvent( "previous", event );
5679					break;
5680				case keyCode.DOWN:
5681					this._keyEvent( "next", event );
5682					break;
5683				}
5684			},
5685			input: function( event ) {
5686				if ( suppressInput ) {
5687					suppressInput = false;
5688					event.preventDefault();
5689					return;
5690				}
5691				this._searchTimeout( event );
5692			},
5693			focus: function() {
5694				this.selectedItem = null;
5695				this.previous = this._value();
5696			},
5697			blur: function( event ) {
5698				if ( this.cancelBlur ) {
5699					delete this.cancelBlur;
5700					return;
5701				}
5702
5703				clearTimeout( this.searching );
5704				this.close( event );
5705				this._change( event );
5706			}
5707		} );
5708
5709		this._initSource();
5710		this.menu = $( "<ul>" )
5711			.appendTo( this._appendTo() )
5712			.menu( {
5713
5714				// disable ARIA support, the live region takes care of that
5715				role: null
5716			} )
5717			.hide()
5718			.menu( "instance" );
5719
5720		this._addClass( this.menu.element, "ui-autocomplete", "ui-front" );
5721		this._on( this.menu.element, {
5722			mousedown: function( event ) {
5723
5724				// prevent moving focus out of the text field
5725				event.preventDefault();
5726
5727				// IE doesn't prevent moving focus even with event.preventDefault()
5728				// so we set a flag to know when we should ignore the blur event
5729				this.cancelBlur = true;
5730				this._delay( function() {
5731					delete this.cancelBlur;
5732
5733					// Support: IE 8 only
5734					// Right clicking a menu item or selecting text from the menu items will
5735					// result in focus moving out of the input. However, we've already received
5736					// and ignored the blur event because of the cancelBlur flag set above. So
5737					// we restore focus to ensure that the menu closes properly based on the user's
5738					// next actions.
5739					if ( this.element[ 0 ] !== $.ui.safeActiveElement( this.document[ 0 ] ) ) {
5740						this.element.trigger( "focus" );
5741					}
5742				} );
5743			},
5744			menufocus: function( event, ui ) {
5745				var label, item;
5746
5747				// support: Firefox
5748				// Prevent accidental activation of menu items in Firefox (#7024 #9118)
5749				if ( this.isNewMenu ) {
5750					this.isNewMenu = false;
5751					if ( event.originalEvent && /^mouse/.test( event.originalEvent.type ) ) {
5752						this.menu.blur();
5753
5754						this.document.one( "mousemove", function() {
5755							$( event.target ).trigger( event.originalEvent );
5756						} );
5757
5758						return;
5759					}
5760				}
5761
5762				item = ui.item.data( "ui-autocomplete-item" );
5763				if ( false !== this._trigger( "focus", event, { item: item } ) ) {
5764
5765					// use value to match what will end up in the input, if it was a key event
5766					if ( event.originalEvent && /^key/.test( event.originalEvent.type ) ) {
5767						this._value( item.value );
5768					}
5769				}
5770
5771				// Announce the value in the liveRegion
5772				label = ui.item.attr( "aria-label" ) || item.value;
5773				if ( label && $.trim( label ).length ) {
5774					this.liveRegion.children().hide();
5775					$( "<div>" ).text( label ).appendTo( this.liveRegion );
5776				}
5777			},
5778			menuselect: function( event, ui ) {
5779				var item = ui.item.data( "ui-autocomplete-item" ),
5780					previous = this.previous;
5781
5782				// Only trigger when focus was lost (click on menu)
5783				if ( this.element[ 0 ] !== $.ui.safeActiveElement( this.document[ 0 ] ) ) {
5784					this.element.trigger( "focus" );
5785					this.previous = previous;
5786
5787					// #6109 - IE triggers two focus events and the second
5788					// is asynchronous, so we need to reset the previous
5789					// term synchronously and asynchronously :-(
5790					this._delay( function() {
5791						this.previous = previous;
5792						this.selectedItem = item;
5793					} );
5794				}
5795
5796				if ( false !== this._trigger( "select", event, { item: item } ) ) {
5797					this._value( item.value );
5798				}
5799
5800				// reset the term after the select event
5801				// this allows custom select handling to work properly
5802				this.term = this._value();
5803
5804				this.close( event );
5805				this.selectedItem = item;
5806			}
5807		} );
5808
5809		this.liveRegion = $( "<div>", {
5810			role: "status",
5811			"aria-live": "assertive",
5812			"aria-relevant": "additions"
5813		} )
5814			.appendTo( this.document[ 0 ].body );
5815
5816		this._addClass( this.liveRegion, null, "ui-helper-hidden-accessible" );
5817
5818		// Turning off autocomplete prevents the browser from remembering the
5819		// value when navigating through history, so we re-enable autocomplete
5820		// if the page is unloaded before the widget is destroyed. #7790
5821		this._on( this.window, {
5822			beforeunload: function() {
5823				this.element.removeAttr( "autocomplete" );
5824			}
5825		} );
5826	},
5827
5828	_destroy: function() {
5829		clearTimeout( this.searching );
5830		this.element.removeAttr( "autocomplete" );
5831		this.menu.element.remove();
5832		this.liveRegion.remove();
5833	},
5834
5835	_setOption: function( key, value ) {
5836		this._super( key, value );
5837		if ( key === "source" ) {
5838			this._initSource();
5839		}
5840		if ( key === "appendTo" ) {
5841			this.menu.element.appendTo( this._appendTo() );
5842		}
5843		if ( key === "disabled" && value && this.xhr ) {
5844			this.xhr.abort();
5845		}
5846	},
5847
5848	_isEventTargetInWidget: function( event ) {
5849		var menuElement = this.menu.element[ 0 ];
5850
5851		return event.target === this.element[ 0 ] ||
5852			event.target === menuElement ||
5853			$.contains( menuElement, event.target );
5854	},
5855
5856	_closeOnClickOutside: function( event ) {
5857		if ( !this._isEventTargetInWidget( event ) ) {
5858			this.close();
5859		}
5860	},
5861
5862	_appendTo: function() {
5863		var element = this.options.appendTo;
5864
5865		if ( element ) {
5866			element = element.jquery || element.nodeType ?
5867				$( element ) :
5868				this.document.find( element ).eq( 0 );
5869		}
5870
5871		if ( !element || !element[ 0 ] ) {
5872			element = this.element.closest( ".ui-front, dialog" );
5873		}
5874
5875		if ( !element.length ) {
5876			element = this.document[ 0 ].body;
5877		}
5878
5879		return element;
5880	},
5881
5882	_initSource: function() {
5883		var array, url,
5884			that = this,
5885			selector = this.element[0].classList[0];
5886
5887		if ( $.isArray( this.options.source ) ) {
5888			array = this.options.source;
5889			this.source = function( request, response ) {
5890				response( $.ui.autocomplete.filter( array, request.term ) );
5891			};
5892		} else if ( typeof this.options.source === "string" ) {
5893			url = this.options.source;
5894
5895			this.source = function( request, response ) {
5896					
5897			var keyCache = selector+request.term;
5898
5899			if(that.cache[keyCache])
5900			{
5901				response( that.cache[keyCache] );
5902				return true;
5903			}
5904			
5905			if ( that.xhr ) {
5906				that.xhr.abort();
5907			}
5908			that.xhr = $.ajax( {
5909				url: url,
5910				data: request,
5911				dataType: "json",
5912				success: function( data ) {
5913					that.cache[keyCache]=data;
5914					response( data );
5915				},
5916				error: function() {
5917					response( [] );
5918				}
5919			} );
5920			};
5921
5922
5923		} else {
5924			this.source = this.options.source;
5925		}
5926	},
5927
5928	_searchTimeout: function( event ) {
5929		clearTimeout( this.searching );
5930		this.searching = this._delay( function() {
5931
5932			// Search if the value has changed, or if the user retypes the same value (see #7434)
5933			var equalValues = this.term === this._value(),
5934				menuVisible = this.menu.element.is( ":visible" ),
5935				modifierKey = event.altKey || event.ctrlKey || event.metaKey || event.shiftKey;
5936
5937			if ( !equalValues || ( equalValues && !menuVisible && !modifierKey ) ) {
5938				this.selectedItem = null;
5939				this.search( null, event );
5940			}
5941		}, this.options.delay );
5942	},
5943
5944	search: function( value, event ) {
5945		value = value != null ? value : this._value();
5946
5947		// Always save the actual value, not the one passed as an argument
5948		this.term = this._value();
5949
5950		if ( value.length < this.options.minLength ) {
5951			return this.close( event );
5952		}
5953
5954		if ( this._trigger( "search", event ) === false ) {
5955			return;
5956		}
5957
5958		return this._search( value );
5959	},
5960
5961	_search: function( value ) {
5962
5963		var that = this;
5964		clearTimeout($.data(this, 'timer-response'));
5965
5966		$.data(this, 'timer-response', setTimeout($.proxy(function() {
5967
5968			that.pending++;
5969			that._addClass( "ui-autocomplete-loading" );
5970			that.cancelSearch = false;
5971			that.source( { 
5972				term: value,
5973				site_id: $("input.site_id").val()
5974				 }, that._response() );
5975
5976		}, this), 1000));
5977
5978
5979	},
5980
5981	_response: function() {
5982		var index = ++this.requestIndex;
5983
5984		return $.proxy( function( content ) {
5985			var th = this;
5986			setTimeout(function() {
5987				if ( index === th.requestIndex ) {
5988					th.__response( content );
5989				}
5990				th.pending--;
5991
5992				
5993				if ( !th.pending ) {
5994					th._removeClass( "ui-autocomplete-loading" );
5995				}
5996
5997            }, 600);
5998            
5999		}, this );
6000	},
6001
6002	__response: function( content ) {
6003		if ( content ) {
6004			content = this._normalize( content );
6005		}
6006		this._trigger( "response", null, { content: content } );
6007		if ( !this.options.disabled && content && content.length && !this.cancelSearch ) {
6008			this._suggest( content );
6009			this._trigger( "open" );
6010		} else {
6011
6012			// use ._close() instead of .close() so we don't cancel future searches
6013			this._close();
6014		}
6015	},
6016
6017	close: function( event ) {
6018		this.cancelSearch = true;
6019		this._close( event );
6020	},
6021
6022	_close: function( event ) {
6023
6024		// Remove the handler that closes the menu on outside clicks
6025		this._off( this.document, "mousedown" );
6026
6027		if ( this.menu.element.is( ":visible" ) ) {
6028			this.menu.element.hide();
6029			this.menu.blur();
6030			this.isNewMenu = true;
6031			this._trigger( "close", event );
6032		}
6033	},
6034
6035	_change: function( event ) {
6036		if ( this.previous !== this._value() ) {
6037			this._trigger( "change", event, { item: this.selectedItem } );
6038		}
6039	},
6040
6041	_normalize: function( items ) {
6042
6043		// assume all items have the right format when the first item is complete
6044		if ( items.length && items[ 0 ].label && items[ 0 ].value ) {
6045			return items;
6046		}
6047		return $.map( items, function( item ) {
6048			if ( typeof item === "string" ) {
6049				return {
6050					label: item,
6051					value: item
6052				};
6053			}
6054			return $.extend( {}, item, {
6055				label: item.label || item.value,
6056				value: item.value || item.label
6057			} );
6058		} );
6059	},
6060
6061	_suggest: function( items ) {
6062		var ul = this.menu.element.empty();
6063		this._renderMenu( ul, items );
6064		this.isNewMenu = true;
6065		this.menu.refresh();
6066
6067		// Size and position menu
6068		ul.show();
6069		this._resizeMenu();
6070		ul.position( $.extend( {
6071			of: this.element
6072		}, this.options.position ) );
6073
6074		if ( this.options.autoFocus ) {
6075			this.menu.next();
6076		}
6077
6078		// Listen for interactions outside of the widget (#6642)
6079		this._on( this.document, {
6080			mousedown: "_closeOnClickOutside"
6081		} );
6082	},
6083
6084	_resizeMenu: function() {
6085		var ul = this.menu.element;
6086		ul.outerWidth( Math.max(
6087
6088			// Firefox wraps long text (possibly a rounding bug)
6089			// so we add 1px to avoid the wrapping (#7513)
6090			ul.width( "" ).outerWidth() + 1,
6091			this.element.outerWidth()
6092		) );
6093	},
6094
6095	_renderMenu: function( ul, items ) {
6096		var that = this;
6097		$.each( items, function( index, item ) {
6098			that._renderItemData( ul, item );
6099		} );
6100	},
6101
6102	_renderItemData: function( ul, item ) {
6103		return this._renderItem( ul, item ).data( "ui-autocomplete-item", item );
6104	},
6105
6106	_renderItem: function( ul, item ) {
6107		return $( "<li>" )
6108			.append( $( "<div>" ).text( item.label ) )
6109			.appendTo( ul );
6110	},
6111
6112	_move: function( direction, event ) {
6113		if ( !this.menu.element.is( ":visible" ) ) {
6114			this.search( null, event );
6115			return;
6116		}
6117		if ( this.menu.isFirstItem() && /^previous/.test( direction ) ||
6118				this.menu.isLastItem() && /^next/.test( direction ) ) {
6119
6120			if ( !this.isMultiLine ) {
6121				this._value( this.term );
6122			}
6123
6124			this.menu.blur();
6125			return;
6126		}
6127		this.menu[ direction ]( event );
6128	},
6129
6130	widget: function() {
6131		return this.menu.element;
6132	},
6133
6134	_value: function() {
6135		return this.valueMethod.apply( this.element, arguments );
6136	},
6137
6138	_keyEvent: function( keyEvent, event ) {
6139		if ( !this.isMultiLine || this.menu.element.is( ":visible" ) ) {
6140			this._move( keyEvent, event );
6141
6142			// Prevents moving cursor to beginning/end of the text field in some browsers
6143			event.preventDefault();
6144		}
6145	},
6146
6147	// Support: Chrome <=50
6148	// We should be able to just use this.element.prop( "isContentEditable" )
6149	// but hidden elements always report false in Chrome.
6150	// https://code.google.com/p/chromium/issues/detail?id=313082
6151	_isContentEditable: function( element ) {
6152		if ( !element.length ) {
6153			return false;
6154		}
6155
6156		var editable = element.prop( "contentEditable" );
6157
6158		if ( editable === "inherit" ) {
6159		  return this._isContentEditable( element.parent() );
6160		}
6161
6162		return editable === "true";
6163	}
6164} );
6165
6166$.extend( $.ui.autocomplete, {
6167	escapeRegex: function( value ) {
6168		return value.replace( /[\-\[\]{}()*+?.,\\\^$|#\s]/g, "\\$&" );
6169	},
6170	filter: function( array, term ) {
6171		var matcher = new RegExp( $.ui.autocomplete.escapeRegex( term ), "i" );
6172		return $.grep( array, function( value ) {
6173			return matcher.test( value.label || value.value || value );
6174		} );
6175	}
6176} );
6177
6178// Live region extension, adding a `messages` option
6179// NOTE: This is an experimental API. We are still investigating
6180// a full solution for string manipulation and internationalization.
6181$.widget( "ui.autocomplete", $.ui.autocomplete, {
6182	options: {
6183		messages: {
6184			noResults: "No search results.",
6185			results: function( amount ) {
6186				return amount + ( amount > 1 ? " results are" : " result is" ) +
6187					" available, use up and down arrow keys to navigate.";
6188			}
6189		}
6190	},
6191
6192	__response: function( content ) {
6193		var message;
6194		this._superApply( arguments );
6195		if ( this.options.disabled || this.cancelSearch ) {
6196			return;
6197		}
6198		if ( content && content.length ) {
6199			message = this.options.messages.results( content.length );
6200		} else {
6201			message = this.options.messages.noResults;
6202		}
6203		this.liveRegion.children().hide();
6204		$( "<div>" ).text( message ).appendTo( this.liveRegion );
6205	}
6206} );
6207
6208var widgetsAutocomplete = $.ui.autocomplete;
6209
6210
6211/*!
6212 * jQuery UI Controlgroup 1.12.1
6213 * http://jqueryui.com
6214 *
6215 * Copyright jQuery Foundation and other contributors
6216 * Released under the MIT license.
6217 * http://jquery.org/license
6218 */
6219
6220//>>label: Controlgroup
6221//>>group: Widgets
6222//>>description: Visually groups form control widgets
6223//>>docs: http://api.jqueryui.com/controlgroup/
6224//>>demos: http://jqueryui.com/controlgroup/
6225//>>css.structure: ../../themes/base/core.css
6226//>>css.structure: ../../themes/base/controlgroup.css
6227//>>css.theme: ../../themes/base/theme.css
6228
6229
6230var controlgroupCornerRegex = /ui-corner-([a-z]){2,6}/g;
6231
6232var widgetsControlgroup = $.widget( "ui.controlgroup", {
6233	version: "1.12.1",
6234	defaultElement: "<div>",
6235	options: {
6236		direction: "horizontal",
6237		disabled: null,
6238		onlyVisible: true,
6239		items: {
6240			"button": "input[type=button], input[type=submit], input[type=reset], button, a",
6241			"controlgroupLabel": ".ui-controlgroup-label",
6242			"checkboxradio": "input[type='checkbox'], input[type='radio']",
6243			"selectmenu": "select",
6244			"spinner": ".ui-spinner-input"
6245		}
6246	},
6247
6248	_create: function() {
6249		this._enhance();
6250	},
6251
6252	// To support the enhanced option in jQuery Mobile, we isolate DOM manipulation
6253	_enhance: function() {
6254		this.element.attr( "role", "toolbar" );
6255		this.refresh();
6256	},
6257
6258	_destroy: function() {
6259		this._callChildMethod( "destroy" );
6260		this.childWidgets.removeData( "ui-controlgroup-data" );
6261		this.element.removeAttr( "role" );
6262		if ( this.options.items.controlgroupLabel ) {
6263			this.element
6264				.find( this.options.items.controlgroupLabel )
6265				.find( ".ui-controlgroup-label-contents" )
6266				.contents().unwrap();
6267		}
6268	},
6269
6270	_initWidgets: function() {
6271		var that = this,
6272			childWidgets = [];
6273
6274		// First we iterate over each of the items options
6275		$.each( this.options.items, function( widget, selector ) {
6276			var labels;
6277			var options = {};
6278
6279			// Make sure the widget has a selector set
6280			if ( !selector ) {
6281				return;
6282			}
6283
6284			if ( widget === "controlgroupLabel" ) {
6285				labels = that.element.find( selector );
6286				labels.each( function() {
6287					var element = $( this );
6288
6289					if ( element.children( ".ui-controlgroup-label-contents" ).length ) {
6290						return;
6291					}
6292					element.contents()
6293						.wrapAll( "<span class='ui-controlgroup-label-contents'></span>" );
6294				} );
6295				that._addClass( labels, null, "ui-widget ui-widget-content ui-state-default" );
6296				childWidgets = childWidgets.concat( labels.get() );
6297				return;
6298			}
6299
6300			// Make sure the widget actually exists
6301			if ( !$.fn[ widget ] ) {
6302				return;
6303			}
6304
6305			// We assume everything is in the middle to start because we can't determine
6306			// first / last elements until all enhancments are done.
6307			if ( that[ "_" + widget + "Options" ] ) {
6308				options = that[ "_" + widget + "Options" ]( "middle" );
6309			} else {
6310				options = { classes: {} };
6311			}
6312
6313			// Find instances of this widget inside controlgroup and init them
6314			that.element
6315				.find( selector )
6316				.each( function() {
6317					var element = $( this );
6318					var instance = element[ widget ]( "instance" );
6319
6320					// We need to clone the default options for this type of widget to avoid
6321					// polluting the variable options which has a wider scope than a single widget.
6322					var instanceOptions = $.widget.extend( {}, options );
6323
6324					// If the button is the child of a spinner ignore it
6325					// TODO: Find a more generic solution
6326					if ( widget === "button" && element.parent( ".ui-spinner" ).length ) {
6327						return;
6328					}
6329
6330					// Create the widget if it doesn't exist
6331					if ( !instance ) {
6332						instance = element[ widget ]()[ widget ]( "instance" );
6333					}
6334					if ( instance ) {
6335						instanceOptions.classes =
6336							that._resolveClassesValues( instanceOptions.classes, instance );
6337					}
6338					element[ widget ]( instanceOptions );
6339
6340					// Store an instance of the controlgroup to be able to reference
6341					// from the outermost element for changing options and refresh
6342					var widgetElement = element[ widget ]( "widget" );
6343					$.data( widgetElement[ 0 ], "ui-controlgroup-data",
6344						instance ? instance : element[ widget ]( "instance" ) );
6345
6346					childWidgets.push( widgetElement[ 0 ] );
6347				} );
6348		} );
6349
6350		this.childWidgets = $( $.unique( childWidgets ) );
6351		this._addClass( this.childWidgets, "ui-controlgroup-item" );
6352	},
6353
6354	_callChildMethod: function( method ) {
6355		this.childWidgets.each( function() {
6356			var element = $( this ),
6357				data = element.data( "ui-controlgroup-data" );
6358			if ( data && data[ method ] ) {
6359				data[ method ]();
6360			}
6361		} );
6362	},
6363
6364	_updateCornerClass: function( element, position ) {
6365		var remove = "ui-corner-top ui-corner-bottom ui-corner-left ui-corner-right ui-corner-all";
6366		var add = this._buildSimpleOptions( position, "label" ).classes.label;
6367
6368		this._removeClass( element, null, remove );
6369		this._addClass( element, null, add );
6370	},
6371
6372	_buildSimpleOptions: function( position, key ) {
6373		var direction = this.options.direction === "vertical";
6374		var result = {
6375			classes: {}
6376		};
6377		result.classes[ key ] = {
6378			"middle": "",
6379			"first": "ui-corner-" + ( direction ? "top" : "left" ),
6380			"last": "ui-corner-" + ( direction ? "bottom" : "right" ),
6381			"only": "ui-corner-all"
6382		}[ position ];
6383
6384		return result;
6385	},
6386
6387	_spinnerOptions: function( position ) {
6388		var options = this._buildSimpleOptions( position, "ui-spinner" );
6389
6390		options.classes[ "ui-spinner-up" ] = "";
6391		options.classes[ "ui-spinner-down" ] = "";
6392
6393		return options;
6394	},
6395
6396	_buttonOptions: function( position ) {
6397		return this._buildSimpleOptions( position, "ui-button" );
6398	},
6399
6400	_checkboxradioOptions: function( position ) {
6401		return this._buildSimpleOptions( position, "ui-checkboxradio-label" );
6402	},
6403
6404	_selectmenuOptions: function( position ) {
6405		var direction = this.options.direction === "vertical";
6406		return {
6407			width: direction ? "auto" : false,
6408			classes: {
6409				middle: {
6410					"ui-selectmenu-button-open": "",
6411					"ui-selectmenu-button-closed": ""
6412				},
6413				first: {
6414					"ui-selectmenu-button-open": "ui-corner-" + ( direction ? "top" : "tl" ),
6415					"ui-selectmenu-button-closed": "ui-corner-" + ( direction ? "top" : "left" )
6416				},
6417				last: {
6418					"ui-selectmenu-button-open": direction ? "" : "ui-corner-tr",
6419					"ui-selectmenu-button-closed": "ui-corner-" + ( direction ? "bottom" : "right" )
6420				},
6421				only: {
6422					"ui-selectmenu-button-open": "ui-corner-top",
6423					"ui-selectmenu-button-closed": "ui-corner-all"
6424				}
6425
6426			}[ position ]
6427		};
6428	},
6429
6430	_resolveClassesValues: function( classes, instance ) {
6431		var result = {};
6432		$.each( classes, function( key ) {
6433			var current = instance.options.classes[ key ] || "";
6434			current = $.trim( current.replace( controlgroupCornerRegex, "" ) );
6435			result[ key ] = ( current + " " + classes[ key ] ).replace( /\s+/g, " " );
6436		} );
6437		return result;
6438	},
6439
6440	_setOption: function( key, value ) {
6441		if ( key === "direction" ) {
6442			this._removeClass( "ui-controlgroup-" + this.options.direction );
6443		}
6444
6445		this._super( key, value );
6446		if ( key === "disabled" ) {
6447			this._callChildMethod( value ? "disable" : "enable" );
6448			return;
6449		}
6450
6451		this.refresh();
6452	},
6453
6454	refresh: function() {
6455		var children,
6456			that = this;
6457
6458		this._addClass( "ui-controlgroup ui-controlgroup-" + this.options.direction );
6459
6460		if ( this.options.direction === "horizontal" ) {
6461			this._addClass( null, "ui-helper-clearfix" );
6462		}
6463		this._initWidgets();
6464
6465		children = this.childWidgets;
6466
6467		// We filter here because we need to track all childWidgets not just the visible ones
6468		if ( this.options.onlyVisible ) {
6469			children = children.filter( ":visible" );
6470		}
6471
6472		if ( children.length ) {
6473
6474			// We do this last because we need to make sure all enhancment is done
6475			// before determining first and last
6476			$.each( [ "first", "last" ], function( index, value ) {
6477				var instance = children[ value ]().data( "ui-controlgroup-data" );
6478
6479				if ( instance && that[ "_" + instance.widgetName + "Options" ] ) {
6480					var options = that[ "_" + instance.widgetName + "Options" ](
6481						children.length === 1 ? "only" : value
6482					);
6483					options.classes = that._resolveClassesValues( options.classes, instance );
6484					instance.element[ instance.widgetName ]( options );
6485				} else {
6486					that._updateCornerClass( children[ value ](), value );
6487				}
6488			} );
6489
6490			// Finally call the refresh method on each of the child widgets.
6491			this._callChildMethod( "refresh" );
6492		}
6493	}
6494} );
6495
6496/*!
6497 * jQuery UI Checkboxradio 1.12.1
6498 * http://jqueryui.com
6499 *
6500 * Copyright jQuery Foundation and other contributors
6501 * Released under the MIT license.
6502 * http://jquery.org/license
6503 */
6504
6505//>>label: Checkboxradio
6506//>>group: Widgets
6507//>>description: Enhances a form with multiple themeable checkboxes or radio buttons.
6508//>>docs: http://api.jqueryui.com/checkboxradio/
6509//>>demos: http://jqueryui.com/checkboxradio/
6510//>>css.structure: ../../themes/base/core.css
6511//>>css.structure: ../../themes/base/button.css
6512//>>css.structure: ../../themes/base/checkboxradio.css
6513//>>css.theme: ../../themes/base/theme.css
6514
6515
6516
6517$.widget( "ui.checkboxradio", [ $.ui.formResetMixin, {
6518	version: "1.12.1",
6519	options: {
6520		disabled: null,
6521		label: null,
6522		icon: true,
6523		classes: {
6524			"ui-checkboxradio-label": "ui-corner-all",
6525			"ui-checkboxradio-icon": "ui-corner-all"
6526		}
6527	},
6528
6529	_getCreateOptions: function() {
6530		var disabled, labels;
6531		var that = this;
6532		var options = this._super() || {};
6533
6534		// We read the type here, because it makes more sense to throw a element type error first,
6535		// rather then the error for lack of a label. Often if its the wrong type, it
6536		// won't have a label (e.g. calling on a div, btn, etc)
6537		this._readType();
6538
6539		labels = this.element.labels();
6540
6541		// If there are multiple labels, use the last one
6542		this.label = $( labels[ labels.length - 1 ] );
6543		if ( !this.label.length ) {
6544			$.error( "No label found for checkboxradio widget" );
6545		}
6546
6547		this.originalLabel = "";
6548
6549		// We need to get the label text but this may also need to make sure it does not contain the
6550		// input itself.
6551		this.label.contents().not( this.element[ 0 ] ).each( function() {
6552
6553			// The label contents could be text, html, or a mix. We concat each element to get a
6554			// string representation of the label, without the input as part of it.
6555			that.originalLabel += this.nodeType === 3 ? $( this ).text() : this.outerHTML;
6556		} );
6557
6558		// Set the label option if we found label text
6559		if ( this.originalLabel ) {
6560			options.label = this.originalLabel;
6561		}
6562
6563		disabled = this.element[ 0 ].disabled;
6564		if ( disabled != null ) {
6565			options.disabled = disabled;
6566		}
6567		return options;
6568	},
6569
6570	_create: function() {
6571		var checked = this.element[ 0 ].checked;
6572
6573		this._bindFormResetHandler();
6574
6575		if ( this.options.disabled == null ) {
6576			this.options.disabled = this.element[ 0 ].disabled;
6577		}
6578
6579		this._setOption( "disabled", this.options.disabled );
6580		this._addClass( "ui-checkboxradio", "ui-helper-hidden-accessible" );
6581		this._addClass( this.label, "ui-checkboxradio-label", "ui-button ui-widget" );
6582
6583		if ( this.type === "radio" ) {
6584			this._addClass( this.label, "ui-checkboxradio-radio-label" );
6585		}
6586
6587		if ( this.options.label && this.options.label !== this.originalLabel ) {
6588			this._updateLabel();
6589		} else if ( this.originalLabel ) {
6590			this.options.label = this.originalLabel;
6591		}
6592
6593		this._enhance();
6594
6595		if ( checked ) {
6596			this._addClass( this.label, "ui-checkboxradio-checked", "ui-state-active" );
6597			if ( this.icon ) {
6598				this._addClass( this.icon, null, "ui-state-hover" );
6599			}
6600		}
6601
6602		this._on( {
6603			change: "_toggleClasses",
6604			focus: function() {
6605				this._addClass( this.label, null, "ui-state-focus ui-visual-focus" );
6606			},
6607			blur: function() {
6608				this._removeClass( this.label, null, "ui-state-focus ui-visual-focus" );
6609			}
6610		} );
6611	},
6612
6613	_readType: function() {
6614		var nodeName = this.element[ 0 ].nodeName.toLowerCase();
6615		this.type = this.element[ 0 ].type;
6616		if ( nodeName !== "input" || !/radio|checkbox/.test( this.type ) ) {
6617			$.error( "Can't create checkboxradio on element.nodeName=" + nodeName +
6618				" and element.type=" + this.type );
6619		}
6620	},
6621
6622	// Support jQuery Mobile enhanced option
6623	_enhance: function() {
6624		this._updateIcon( this.element[ 0 ].checked );
6625	},
6626
6627	widget: function() {
6628		return this.label;
6629	},
6630
6631	_getRadioGroup: function() {
6632		var group;
6633		var name = this.element[ 0 ].name;
6634		var nameSelector = "input[name='" + $.ui.escapeSelector( name ) + "']";
6635
6636		if ( !name ) {
6637			return $( [] );
6638		}
6639
6640		if ( this.form.length ) {
6641			group = $( this.form[ 0 ].elements ).filter( nameSelector );
6642		} else {
6643
6644			// Not inside a form, check all inputs that also are not inside a form
6645			group = $( nameSelector ).filter( function() {
6646				return $( this ).form().length === 0;
6647			} );
6648		}
6649
6650		return group.not( this.element );
6651	},
6652
6653	_toggleClasses: function() {
6654		var checked = this.element[ 0 ].checked;
6655		this._toggleClass( this.label, "ui-checkboxradio-checked", "ui-state-active", checked );
6656
6657		if ( this.options.icon && this.type === "checkbox" ) {
6658			this._toggleClass( this.icon, null, "ui-icon-check ui-state-checked", checked )
6659				._toggleClass( this.icon, null, "ui-icon-blank", !checked );
6660		}
6661
6662		if ( this.type === "radio" ) {
6663			this._getRadioGroup()
6664				.each( function() {
6665					var instance = $( this ).checkboxradio( "instance" );
6666
6667					if ( instance ) {
6668						instance._removeClass( instance.label,
6669							"ui-checkboxradio-checked", "ui-state-active" );
6670					}
6671				} );
6672		}
6673	},
6674
6675	_destroy: function() {
6676		this._unbindFormResetHandler();
6677
6678		if ( this.icon ) {
6679			this.icon.remove();
vendor: 4,659 bytes, lines 6680-6853
6680			this.iconSpace.remove();
6681		}
6682	},
6683
6684	_setOption: function( key, value ) {
6685
6686		// We don't allow the value to be set to nothing
6687		if ( key === "label" && !value ) {
6688			return;
6689		}
6690
6691		this._super( key, value );
6692
6693		if ( key === "disabled" ) {
6694			this._toggleClass( this.label, null, "ui-state-disabled", value );
6695			this.element[ 0 ].disabled = value;
6696
6697			// Don't refresh when setting disabled
6698			return;
6699		}
6700		this.refresh();
6701	},
6702
6703	_updateIcon: function( checked ) {
6704		var toAdd = "ui-icon ui-icon-background ";
6705
6706		if ( this.options.icon ) {
6707			if ( !this.icon ) {
6708				this.icon = $( "<span>" );
6709				this.iconSpace = $( "<span> </span>" );
6710				this._addClass( this.iconSpace, "ui-checkboxradio-icon-space" );
6711			}
6712
6713			if ( this.type === "checkbox" ) {
6714				toAdd += checked ? "ui-icon-check ui-state-checked" : "ui-icon-blank";
6715				this._removeClass( this.icon, null, checked ? "ui-icon-blank" : "ui-icon-check" );
6716			} else {
6717				toAdd += "ui-icon-blank";
6718			}
6719			this._addClass( this.icon, "ui-checkboxradio-icon", toAdd );
6720			if ( !checked ) {
6721				this._removeClass( this.icon, null, "ui-icon-check ui-state-checked" );
6722			}
6723			this.icon.prependTo( this.label ).after( this.iconSpace );
6724		} else if ( this.icon !== undefined ) {
6725			this.icon.remove();
6726			this.iconSpace.remove();
6727			delete this.icon;
6728		}
6729	},
6730
6731	_updateLabel: function() {
6732
6733		// Remove the contents of the label ( minus the icon, icon space, and input )
6734		var contents = this.label.contents().not( this.element[ 0 ] );
6735		if ( this.icon ) {
6736			contents = contents.not( this.icon[ 0 ] );
6737		}
6738		if ( this.iconSpace ) {
6739			contents = contents.not( this.iconSpace[ 0 ] );
6740		}
6741		contents.remove();
6742
6743		this.label.append( this.options.label );
6744	},
6745
6746	refresh: function() {
6747		var checked = this.element[ 0 ].checked,
6748			isDisabled = this.element[ 0 ].disabled;
6749
6750		this._updateIcon( checked );
6751		this._toggleClass( this.label, "ui-checkboxradio-checked", "ui-state-active", checked );
6752		if ( this.options.label !== null ) {
6753			this._updateLabel();
6754		}
6755
6756		if ( isDisabled !== this.options.disabled ) {
6757			this._setOptions( { "disabled": isDisabled } );
6758		}
6759	}
6760
6761} ] );
6762
6763var widgetsCheckboxradio = $.ui.checkboxradio;
6764
6765
6766/*!
6767 * jQuery UI Button 1.12.1
6768 * http://jqueryui.com
6769 *
6770 * Copyright jQuery Foundation and other contributors
6771 * Released under the MIT license.
6772 * http://jquery.org/license
6773 */
6774
6775//>>label: Button
6776//>>group: Widgets
6777//>>description: Enhances a form with themeable buttons.
6778//>>docs: http://api.jqueryui.com/button/
6779//>>demos: http://jqueryui.com/button/
6780//>>css.structure: ../../themes/base/core.css
6781//>>css.structure: ../../themes/base/button.css
6782//>>css.theme: ../../themes/base/theme.css
6783
6784
6785
6786$.widget( "ui.button", {
6787	version: "1.12.1",
6788	defaultElement: "<button>",
6789	options: {
6790		classes: {
6791			"ui-button": "ui-corner-all"
6792		},
6793		disabled: null,
6794		icon: null,
6795		iconPosition: "beginning",
6796		label: null,
6797		showLabel: true
6798	},
6799
6800	_getCreateOptions: function() {
6801		var disabled,
6802
6803			// This is to support cases like in jQuery Mobile where the base widget does have
6804			// an implementation of _getCreateOptions
6805			options = this._super() || {};
6806
6807		this.isInput = this.element.is( "input" );
6808
6809		disabled = this.element[ 0 ].disabled;
6810		if ( disabled != null ) {
6811			options.disabled = disabled;
6812		}
6813
6814		this.originalLabel = this.isInput ? this.element.val() : this.element.html();
6815		if ( this.originalLabel ) {
6816			options.label = this.originalLabel;
6817		}
6818
6819		return options;
6820	},
6821
6822	_create: function() {
6823		if ( !this.option.showLabel & !this.options.icon ) {
6824			this.options.showLabel = true;
6825		}
6826
6827		// We have to check the option again here even though we did in _getCreateOptions,
6828		// because null may have been passed on init which would override what was set in
6829		// _getCreateOptions
6830		if ( this.options.disabled == null ) {
6831			this.options.disabled = this.element[ 0 ].disabled || false;
6832		}
6833
6834		this.hasTitle = !!this.element.attr( "title" );
6835
6836		// Check to see if the label needs to be set or if its already correct
6837		if ( this.options.label && this.options.label !== this.originalLabel ) {
6838			if ( this.isInput ) {
6839				this.element.val( this.options.label );
6840			} else {
6841				this.element.html( this.options.label );
6842			}
6843		}
6844		this._addClass( "ui-button", "ui-widget" );
6845		this._setOption( "disabled", this.options.disabled );
6846		this._enhance();
6847
6848		if ( this.element.is( "a" ) ) {
6849			this._on( {
6850				"keyup": function( event ) {
6851					if ( event.keyCode === $.ui.keyCode.SPACE ) {
6852						event.preventDefault();
6853
vendor: 7,743 bytes, lines 6854-7136
6854						// Support: PhantomJS <= 1.9, IE 8 Only
6855						// If a native click is available use it so we actually cause navigation
6856						// otherwise just trigger a click event
6857						if ( this.element[ 0 ].click ) {
6858							this.element[ 0 ].click();
6859						} else {
6860							this.element.trigger( "click" );
6861						}
6862					}
6863				}
6864			} );
6865		}
6866	},
6867
6868	_enhance: function() {
6869		if ( !this.element.is( "button" ) ) {
6870			this.element.attr( "role", "button" );
6871		}
6872
6873		if ( this.options.icon ) {
6874			this._updateIcon( "icon", this.options.icon );
6875			this._updateTooltip();
6876		}
6877	},
6878
6879	_updateTooltip: function() {
6880		this.title = this.element.attr( "title" );
6881
6882		if ( !this.options.showLabel && !this.title ) {
6883			this.element.attr( "title", this.options.label );
6884		}
6885	},
6886
6887	_updateIcon: function( option, value ) {
6888		var icon = option !== "iconPosition",
6889			position = icon ? this.options.iconPosition : value,
6890			displayBlock = position === "top" || position === "bottom";
6891
6892		// Create icon
6893		if ( !this.icon ) {
6894			this.icon = $( "<span>" );
6895
6896			this._addClass( this.icon, "ui-button-icon", "ui-icon" );
6897
6898			if ( !this.options.showLabel ) {
6899				this._addClass( "ui-button-icon-only" );
6900			}
6901		} else if ( icon ) {
6902
6903			// If we are updating the icon remove the old icon class
6904			this._removeClass( this.icon, null, this.options.icon );
6905		}
6906
6907		// If we are updating the icon add the new icon class
6908		if ( icon ) {
6909			this._addClass( this.icon, null, value );
6910		}
6911
6912		this._attachIcon( position );
6913
6914		// If the icon is on top or bottom we need to add the ui-widget-icon-block class and remove
6915		// the iconSpace if there is one.
6916		if ( displayBlock ) {
6917			this._addClass( this.icon, null, "ui-widget-icon-block" );
6918			if ( this.iconSpace ) {
6919				this.iconSpace.remove();
6920			}
6921		} else {
6922
6923			// Position is beginning or end so remove the ui-widget-icon-block class and add the
6924			// space if it does not exist
6925			if ( !this.iconSpace ) {
6926				this.iconSpace = $( "<span> </span>" );
6927				this._addClass( this.iconSpace, "ui-button-icon-space" );
6928			}
6929			this._removeClass( this.icon, null, "ui-wiget-icon-block" );
6930			this._attachIconSpace( position );
6931		}
6932	},
6933
6934	_destroy: function() {
6935		this.element.removeAttr( "role" );
6936
6937		if ( this.icon ) {
6938			this.icon.remove();
6939		}
6940		if ( this.iconSpace ) {
6941			this.iconSpace.remove();
6942		}
6943		if ( !this.hasTitle ) {
6944			this.element.removeAttr( "title" );
6945		}
6946	},
6947
6948	_attachIconSpace: function( iconPosition ) {
6949		this.icon[ /^(?:end|bottom)/.test( iconPosition ) ? "before" : "after" ]( this.iconSpace );
6950	},
6951
6952	_attachIcon: function( iconPosition ) {
6953		this.element[ /^(?:end|bottom)/.test( iconPosition ) ? "append" : "prepend" ]( this.icon );
6954	},
6955
6956	_setOptions: function( options ) {
6957		var newShowLabel = options.showLabel === undefined ?
6958				this.options.showLabel :
6959				options.showLabel,
6960			newIcon = options.icon === undefined ? this.options.icon : options.icon;
6961
6962		if ( !newShowLabel && !newIcon ) {
6963			options.showLabel = true;
6964		}
6965		this._super( options );
6966	},
6967
6968	_setOption: function( key, value ) {
6969		if ( key === "icon" ) {
6970			if ( value ) {
6971				this._updateIcon( key, value );
6972			} else if ( this.icon ) {
6973				this.icon.remove();
6974				if ( this.iconSpace ) {
6975					this.iconSpace.remove();
6976				}
6977			}
6978		}
6979
6980		if ( key === "iconPosition" ) {
6981			this._updateIcon( key, value );
6982		}
6983
6984		// Make sure we can't end up with a button that has neither text nor icon
6985		if ( key === "showLabel" ) {
6986				this._toggleClass( "ui-button-icon-only", null, !value );
6987				this._updateTooltip();
6988		}
6989
6990		if ( key === "label" ) {
6991			if ( this.isInput ) {
6992				this.element.val( value );
6993			} else {
6994
6995				// If there is an icon, append it, else nothing then append the value
6996				// this avoids removal of the icon when setting label text
6997				this.element.html( value );
6998				if ( this.icon ) {
6999					this._attachIcon( this.options.iconPosition );
7000					this._attachIconSpace( this.options.iconPosition );
7001				}
7002			}
7003		}
7004
7005		this._super( key, value );
7006
7007		if ( key === "disabled" ) {
7008			this._toggleClass( null, "ui-state-disabled", value );
7009			this.element[ 0 ].disabled = value;
7010			if ( value ) {
7011				this.element.blur();
7012			}
7013		}
7014	},
7015
7016	refresh: function() {
7017
7018		// Make sure to only check disabled if its an element that supports this otherwise
7019		// check for the disabled class to determine state
7020		var isDisabled = this.element.is( "input, button" ) ?
7021			this.element[ 0 ].disabled : this.element.hasClass( "ui-button-disabled" );
7022
7023		if ( isDisabled !== this.options.disabled ) {
7024			this._setOptions( { disabled: isDisabled } );
7025		}
7026
7027		this._updateTooltip();
7028	}
7029} );
7030
7031// DEPRECATED
7032if ( $.uiBackCompat !== false ) {
7033
7034	// Text and Icons options
7035	$.widget( "ui.button", $.ui.button, {
7036		options: {
7037			text: true,
7038			icons: {
7039				primary: null,
7040				secondary: null
7041			}
7042		},
7043
7044		_create: function() {
7045			if ( this.options.showLabel && !this.options.text ) {
7046				this.options.showLabel = this.options.text;
7047			}
7048			if ( !this.options.showLabel && this.options.text ) {
7049				this.options.text = this.options.showLabel;
7050			}
7051			if ( !this.options.icon && ( this.options.icons.primary ||
7052					this.options.icons.secondary ) ) {
7053				if ( this.options.icons.primary ) {
7054					this.options.icon = this.options.icons.primary;
7055				} else {
7056					this.options.icon = this.options.icons.secondary;
7057					this.options.iconPosition = "end";
7058				}
7059			} else if ( this.options.icon ) {
7060				this.options.icons.primary = this.options.icon;
7061			}
7062			this._super();
7063		},
7064
7065		_setOption: function( key, value ) {
7066			if ( key === "text" ) {
7067				this._super( "showLabel", value );
7068				return;
7069			}
7070			if ( key === "showLabel" ) {
7071				this.options.text = value;
7072			}
7073			if ( key === "icon" ) {
7074				this.options.icons.primary = value;
7075			}
7076			if ( key === "icons" ) {
7077				if ( value.primary ) {
7078					this._super( "icon", value.primary );
7079					this._super( "iconPosition", "beginning" );
7080				} else if ( value.secondary ) {
7081					this._super( "icon", value.secondary );
7082					this._super( "iconPosition", "end" );
7083				}
7084			}
7085			this._superApply( arguments );
7086		}
7087	} );
7088
7089	$.fn.button = ( function( orig ) {
7090		return function() {
7091			if ( !this.length || ( this.length && this[ 0 ].tagName !== "INPUT" ) ||
7092					( this.length && this[ 0 ].tagName === "INPUT" && (
7093						this.attr( "type" ) !== "checkbox" && this.attr( "type" ) !== "radio"
7094					) ) ) {
7095				return orig.apply( this, arguments );
7096			}
7097			if ( !$.ui.checkboxradio ) {
7098				$.error( "Checkboxradio widget missing" );
7099			}
7100			if ( arguments.length === 0 ) {
7101				return this.checkboxradio( {
7102					"icon": false
7103				} );
7104			}
7105			return this.checkboxradio.apply( this, arguments );
7106		};
7107	} )( $.fn.button );
7108
7109	$.fn.buttonset = function() {
7110		if ( !$.ui.controlgroup ) {
7111			$.error( "Controlgroup widget missing" );
7112		}
7113		if ( arguments[ 0 ] === "option" && arguments[ 1 ] === "items" && arguments[ 2 ] ) {
7114			return this.controlgroup.apply( this,
7115				[ arguments[ 0 ], "items.button", arguments[ 2 ] ] );
7116		}
7117		if ( arguments[ 0 ] === "option" && arguments[ 1 ] === "items" ) {
7118			return this.controlgroup.apply( this, [ arguments[ 0 ], "items.button" ] );
7119		}
7120		if ( typeof arguments[ 0 ] === "object" && arguments[ 0 ].items ) {
7121			arguments[ 0 ].items = {
7122				button: arguments[ 0 ].items
7123			};
7124		}
7125		return this.controlgroup.apply( this, arguments );
7126	};
7127}
7128
7129var widgetsButton = $.ui.button;
7130
7131
7132// jscs:disable maximumLineLength
7133/* jscs:disable requireCamelCaseOrUpperCaseIdentifiers */
7134/*!
7135 * jQuery UI Datepicker 1.12.1
7136 * http://jqueryui.com
vendor: 4,553 bytes, lines 7137-7223
7137 *
7138 * Copyright jQuery Foundation and other contributors
7139 * Released under the MIT license.
7140 * http://jquery.org/license
7141 */
7142
7143//>>label: Datepicker
7144//>>group: Widgets
7145//>>description: Displays a calendar from an input or inline for selecting dates.
7146//>>docs: http://api.jqueryui.com/datepicker/
7147//>>demos: http://jqueryui.com/datepicker/
7148//>>css.structure: ../../themes/base/core.css
7149//>>css.structure: ../../themes/base/datepicker.css
7150//>>css.theme: ../../themes/base/theme.css
7151
7152
7153
7154$.extend( $.ui, { datepicker: { version: "1.12.1" } } );
7155
7156var datepicker_instActive;
7157
7158function datepicker_getZindex( elem ) {
7159	var position, value;
7160	while ( elem.length && elem[ 0 ] !== document ) {
7161
7162		// Ignore z-index if position is set to a value where z-index is ignored by the browser
7163		// This makes behavior of this function consistent across browsers
7164		// WebKit always returns auto if the element is positioned
7165		position = elem.css( "position" );
7166		if ( position === "absolute" || position === "relative" || position === "fixed" ) {
7167
7168			// IE returns 0 when zIndex is not specified
7169			// other browsers return a string
7170			// we ignore the case of nested elements with an explicit value of 0
7171			// <div style="z-index: -10;"><div style="z-index: 0;"></div></div>
7172			value = parseInt( elem.css( "zIndex" ), 10 );
7173			if ( !isNaN( value ) && value !== 0 ) {
7174				return value;
7175			}
7176		}
7177		elem = elem.parent();
7178	}
7179
7180	return 0;
7181}
7182/* Date picker manager.
7183   Use the singleton instance of this class, $.datepicker, to interact with the date picker.
7184   Settings for (groups of) date pickers are maintained in an instance object,
7185   allowing multiple different settings on the same page. */
7186
7187function Datepicker() {
7188	this._curInst = null; // The current instance in use
7189	this._keyEvent = false; // If the last event was a key event
7190	this._disabledInputs = []; // List of date picker inputs that have been disabled
7191	this._datepickerShowing = false; // True if the popup picker is showing , false if not
7192	this._inDialog = false; // True if showing within a "dialog", false if not
7193	this._mainDivId = "ui-datepicker-div"; // The ID of the main datepicker division
7194	this._inlineClass = "ui-datepicker-inline"; // The name of the inline marker class
7195	this._appendClass = "ui-datepicker-append"; // The name of the append marker class
7196	this._triggerClass = "ui-datepicker-trigger"; // The name of the trigger marker class
7197	this._dialogClass = "ui-datepicker-dialog"; // The name of the dialog marker class
7198	this._disableClass = "ui-datepicker-disabled"; // The name of the disabled covering marker class
7199	this._unselectableClass = "ui-datepicker-unselectable"; // The name of the unselectable cell marker class
7200	this._currentClass = "ui-datepicker-current-day"; // The name of the current day marker class
7201	this._dayOverClass = "ui-datepicker-days-cell-over"; // The name of the day hover marker class
7202	this.regional = []; // Available regional settings, indexed by language code
7203	this.regional[ "" ] = { // Default regional settings
7204		closeText: "Done", // Display text for close link
7205		prevText: "Prev", // Display text for previous month link
7206		nextText: "Next", // Display text for next month link
7207		currentText: "Today", // Display text for current month link
7208		monthNames: [ "January","February","March","April","May","June",
7209			"July","August","September","October","November","December" ], // Names of months for drop-down and formatting
7210		monthNamesShort: [ "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" ], // For formatting
7211		dayNames: [ "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday" ], // For formatting
7212		dayNamesShort: [ "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" ], // For formatting
7213		dayNamesMin: [ "Su","Mo","Tu","We","Th","Fr","Sa" ], // Column headings for days starting at Sunday
7214		weekHeader: "Wk", // Column header for week of the year
7215		dateFormat: "mm/dd/yy", // See format options on parseDate
7216		firstDay: 0, // The first day of the week, Sun = 0, Mon = 1, ...
7217		isRTL: false, // True if right-to-left language, false if left-to-right
7218		showMonthAfterYear: false, // True if the year select precedes month, false for month then year
7219		yearSuffix: "" // Additional text to append to the year in the month headers
7220	};
7221	this._defaults = { // Global defaults for all the date picker instances
7222		showOn: "focus", // "focus" for popup on focus,
7223			// "button" for trigger button, or "both" for either
vendor: 6,761 bytes, lines 7224-7356
7224		showAnim: "fadeIn", // Name of jQuery animation for popup
7225		showOptions: {}, // Options for enhanced animations
7226		defaultDate: null, // Used when field is blank: actual date,
7227			// +/-number for offset from today, null for today
7228		appendText: "", // Display text following the input box, e.g. showing the format
7229		buttonText: "...", // Text for trigger button
7230		buttonImage: "", // URL for trigger button image
7231		buttonImageOnly: false, // True if the image appears alone, false if it appears on a button
7232		hideIfNoPrevNext: false, // True to hide next/previous month links
7233			// if not applicable, false to just disable them
7234		navigationAsDateFormat: false, // True if date formatting applied to prev/today/next links
7235		gotoCurrent: false, // True if today link goes back to current selection instead
7236		changeMonth: false, // True if month can be selected directly, false if only prev/next
7237		changeYear: false, // True if year can be selected directly, false if only prev/next
7238		yearRange: "c-10:c+10", // Range of years to display in drop-down,
7239			// either relative to today's year (-nn:+nn), relative to currently displayed year
7240			// (c-nn:c+nn), absolute (nnnn:nnnn), or a combination of the above (nnnn:-n)
7241		showOtherMonths: false, // True to show dates in other months, false to leave blank
7242		selectOtherMonths: false, // True to allow selection of dates in other months, false for unselectable
7243		showWeek: false, // True to show week of the year, false to not show it
7244		calculateWeek: this.iso8601Week, // How to calculate the week of the year,
7245			// takes a Date and returns the number of the week for it
7246		shortYearCutoff: "+10", // Short year values < this are in the current century,
7247			// > this are in the previous century,
7248			// string value starting with "+" for current year + value
7249		minDate: null, // The earliest selectable date, or null for no limit
7250		maxDate: null, // The latest selectable date, or null for no limit
7251		duration: "fast", // Duration of display/closure
7252		beforeShowDay: null, // Function that takes a date and returns an array with
7253			// [0] = true if selectable, false if not, [1] = custom CSS class name(s) or "",
7254			// [2] = cell title (optional), e.g. $.datepicker.noWeekends
7255		beforeShow: null, // Function that takes an input field and
7256			// returns a set of custom settings for the date picker
7257		onSelect: null, // Define a callback function when a date is selected
7258		onChangeMonthYear: null, // Define a callback function when the month or year is changed
7259		onClose: null, // Define a callback function when the datepicker is closed
7260		numberOfMonths: 1, // Number of months to show at a time
7261		showCurrentAtPos: 0, // The position in multipe months at which to show the current month (starting at 0)
7262		stepMonths: 1, // Number of months to step back/forward
7263		stepBigMonths: 12, // Number of months to step back/forward for the big links
7264		altField: "", // Selector for an alternate field to store selected dates into
7265		altFormat: "", // The date format to use for the alternate field
7266		constrainInput: true, // The input is constrained by the current date format
7267		showButtonPanel: false, // True to show button panel, false to not show it
7268		autoSize: false, // True to size the input for the date format, false to leave as is
7269		disabled: false // The initial disabled state
7270	};
7271	$.extend( this._defaults, this.regional[ "" ] );
7272	this.regional.en = $.extend( true, {}, this.regional[ "" ] );
7273	this.regional[ "en-US" ] = $.extend( true, {}, this.regional.en );
7274	this.dpDiv = datepicker_bindHover( $( "<div id='" + this._mainDivId + "' class='ui-datepicker ui-widget ui-widget-content ui-helper-clearfix ui-corner-all'></div>" ) );
7275}
7276
7277$.extend( Datepicker.prototype, {
7278	/* Class name added to elements to indicate already configured with a date picker. */
7279	markerClassName: "hasDatepicker",
7280
7281	//Keep track of the maximum number of rows displayed (see #7043)
7282	maxRows: 4,
7283
7284	// TODO rename to "widget" when switching to widget factory
7285	_widgetDatepicker: function() {
7286		return this.dpDiv;
7287	},
7288
7289	/* Override the default settings for all instances of the date picker.
7290	 * @param  settings  object - the new settings to use as defaults (anonymous object)
7291	 * @return the manager object
7292	 */
7293	setDefaults: function( settings ) {
7294		datepicker_extendRemove( this._defaults, settings || {} );
7295		return this;
7296	},
7297
7298	/* Attach the date picker to a jQuery selection.
7299	 * @param  target	element - the target input field or division or span
7300	 * @param  settings  object - the new settings to use for this date picker instance (anonymous)
7301	 */
7302	_attachDatepicker: function( target, settings ) {
7303		var nodeName, inline, inst;
7304		nodeName = target.nodeName.toLowerCase();
7305		inline = ( nodeName === "div" || nodeName === "span" );
7306		if ( !target.id ) {
7307			this.uuid += 1;
7308			target.id = "dp" + this.uuid;
7309		}
7310		inst = this._newInst( $( target ), inline );
7311		inst.settings = $.extend( {}, settings || {} );
7312		if ( nodeName === "input" ) {
7313			this._connectDatepicker( target, inst );
7314		} else if ( inline ) {
7315			this._inlineDatepicker( target, inst );
7316		}
7317	},
7318
7319	/* Create a new instance object. */
7320	_newInst: function( target, inline ) {
7321		var id = target[ 0 ].id.replace( /([^A-Za-z0-9_\-])/g, "\\\\$1" ); // escape jQuery meta chars
7322		return { id: id, input: target, // associated target
7323			selectedDay: 0, selectedMonth: 0, selectedYear: 0, // current selection
7324			drawMonth: 0, drawYear: 0, // month being drawn
7325			inline: inline, // is datepicker inline or not
7326			dpDiv: ( !inline ? this.dpDiv : // presentation div
7327			datepicker_bindHover( $( "<div class='" + this._inlineClass + " ui-datepicker ui-widget ui-widget-content ui-helper-clearfix ui-corner-all'></div>" ) ) ) };
7328	},
7329
7330	/* Attach the date picker to an input field. */
7331	_connectDatepicker: function( target, inst ) {
7332		var input = $( target );
7333		inst.append = $( [] );
7334		inst.trigger = $( [] );
7335		if ( input.hasClass( this.markerClassName ) ) {
7336			return;
7337		}
7338		this._attachments( input, inst );
7339		input.addClass( this.markerClassName ).on( "keydown", this._doKeyDown ).
7340			on( "keypress", this._doKeyPress ).on( "keyup", this._doKeyUp );
7341		this._autoSize( inst );
7342		$.data( target, "datepicker", inst );
7343
7344		//If disabled option is true, disable the datepicker once it has been attached to the input (see ticket #5665)
7345		if ( inst.settings.disabled ) {
7346			this._disableDatepicker( target );
7347		}
7348	},
7349
7350	/* Make attachments based on settings. */
7351	_attachments: function( input, inst ) {
7352		var showOn, buttonText, buttonImage,
7353			appendText = this._get( inst, "appendText" ),
7354			isRTL = this._get( inst, "isRTL" );
7355
7356		if ( inst.append ) {
vendor: 6,192 bytes, lines 7357-7514
7357			inst.append.remove();
7358		}
7359		if ( appendText ) {
7360			inst.append = $( "<span class='" + this._appendClass + "'>" + appendText + "</span>" );
7361			input[ isRTL ? "before" : "after" ]( inst.append );
7362		}
7363
7364		input.off( "focus", this._showDatepicker );
7365
7366		if ( inst.trigger ) {
7367			inst.trigger.remove();
7368		}
7369
7370		showOn = this._get( inst, "showOn" );
7371		if ( showOn === "focus" || showOn === "both" ) { // pop-up date picker when in the marked field
7372			input.on( "focus", this._showDatepicker );
7373		}
7374		if ( showOn === "button" || showOn === "both" ) { // pop-up date picker when button clicked
7375			buttonText = this._get( inst, "buttonText" );
7376			buttonImage = this._get( inst, "buttonImage" );
7377			inst.trigger = $( this._get( inst, "buttonImageOnly" ) ?
7378				$( "<img/>" ).addClass( this._triggerClass ).
7379					attr( { src: buttonImage, alt: buttonText, title: buttonText } ) :
7380				$( "<button type='button'></button>" ).addClass( this._triggerClass ).
7381					html( !buttonImage ? buttonText : $( "<img/>" ).attr(
7382					{ src:buttonImage, alt:buttonText, title:buttonText } ) ) );
7383			input[ isRTL ? "before" : "after" ]( inst.trigger );
7384			inst.trigger.on( "click", function() {
7385				if ( $.datepicker._datepickerShowing && $.datepicker._lastInput === input[ 0 ] ) {
7386					$.datepicker._hideDatepicker();
7387				} else if ( $.datepicker._datepickerShowing && $.datepicker._lastInput !== input[ 0 ] ) {
7388					$.datepicker._hideDatepicker();
7389					$.datepicker._showDatepicker( input[ 0 ] );
7390				} else {
7391					$.datepicker._showDatepicker( input[ 0 ] );
7392				}
7393				return false;
7394			} );
7395		}
7396	},
7397
7398	/* Apply the maximum length for the date format. */
7399	_autoSize: function( inst ) {
7400		if ( this._get( inst, "autoSize" ) && !inst.inline ) {
7401			var findMax, max, maxI, i,
7402				date = new Date( 2009, 12 - 1, 20 ), // Ensure double digits
7403				dateFormat = this._get( inst, "dateFormat" );
7404
7405			if ( dateFormat.match( /[DM]/ ) ) {
7406				findMax = function( names ) {
7407					max = 0;
7408					maxI = 0;
7409					for ( i = 0; i < names.length; i++ ) {
7410						if ( names[ i ].length > max ) {
7411							max = names[ i ].length;
7412							maxI = i;
7413						}
7414					}
7415					return maxI;
7416				};
7417				date.setMonth( findMax( this._get( inst, ( dateFormat.match( /MM/ ) ?
7418					"monthNames" : "monthNamesShort" ) ) ) );
7419				date.setDate( findMax( this._get( inst, ( dateFormat.match( /DD/ ) ?
7420					"dayNames" : "dayNamesShort" ) ) ) + 20 - date.getDay() );
7421			}
7422			inst.input.attr( "size", this._formatDate( inst, date ).length );
7423		}
7424	},
7425
7426	/* Attach an inline date picker to a div. */
7427	_inlineDatepicker: function( target, inst ) {
7428		var divSpan = $( target );
7429		if ( divSpan.hasClass( this.markerClassName ) ) {
7430			return;
7431		}
7432		divSpan.addClass( this.markerClassName ).append( inst.dpDiv );
7433		$.data( target, "datepicker", inst );
7434		this._setDate( inst, this._getDefaultDate( inst ), true );
7435		this._updateDatepicker( inst );
7436		this._updateAlternate( inst );
7437
7438		//If disabled option is true, disable the datepicker before showing it (see ticket #5665)
7439		if ( inst.settings.disabled ) {
7440			this._disableDatepicker( target );
7441		}
7442
7443		// Set display:block in place of inst.dpDiv.show() which won't work on disconnected elements
7444		// http://bugs.jqueryui.com/ticket/7552 - A Datepicker created on a detached div has zero height
7445		inst.dpDiv.css( "display", "block" );
7446	},
7447
7448	/* Pop-up the date picker in a "dialog" box.
7449	 * @param  input element - ignored
7450	 * @param  date	string or Date - the initial date to display
7451	 * @param  onSelect  function - the function to call when a date is selected
7452	 * @param  settings  object - update the dialog date picker instance's settings (anonymous object)
7453	 * @param  pos int[2] - coordinates for the dialog's position within the screen or
7454	 *					event - with x/y coordinates or
7455	 *					leave empty for default (screen centre)
7456	 * @return the manager object
7457	 */
7458	_dialogDatepicker: function( input, date, onSelect, settings, pos ) {
7459		var id, browserWidth, browserHeight, scrollX, scrollY,
7460			inst = this._dialogInst; // internal instance
7461
7462		if ( !inst ) {
7463			this.uuid += 1;
7464			id = "dp" + this.uuid;
7465			this._dialogInput = $( "<input type='text' id='" + id +
7466				"' style='position: absolute; top: -100px; width: 0px;'/>" );
7467			this._dialogInput.on( "keydown", this._doKeyDown );
7468			$( "body" ).append( this._dialogInput );
7469			inst = this._dialogInst = this._newInst( this._dialogInput, false );
7470			inst.settings = {};
7471			$.data( this._dialogInput[ 0 ], "datepicker", inst );
7472		}
7473		datepicker_extendRemove( inst.settings, settings || {} );
7474		date = ( date && date.constructor === Date ? this._formatDate( inst, date ) : date );
7475		this._dialogInput.val( date );
7476
7477		this._pos = ( pos ? ( pos.length ? pos : [ pos.pageX, pos.pageY ] ) : null );
7478		if ( !this._pos ) {
7479			browserWidth = document.documentElement.clientWidth;
7480			browserHeight = document.documentElement.clientHeight;
7481			scrollX = document.documentElement.scrollLeft || document.body.scrollLeft;
7482			scrollY = document.documentElement.scrollTop || document.body.scrollTop;
7483			this._pos = // should use actual width/height below
7484				[ ( browserWidth / 2 ) - 100 + scrollX, ( browserHeight / 2 ) - 150 + scrollY ];
7485		}
7486
7487		// Move input on screen for focus, but hidden behind dialog
7488		this._dialogInput.css( "left", ( this._pos[ 0 ] + 20 ) + "px" ).css( "top", this._pos[ 1 ] + "px" );
7489		inst.settings.onSelect = onSelect;
7490		this._inDialog = true;
7491		this.dpDiv.addClass( this._dialogClass );
7492		this._showDatepicker( this._dialogInput[ 0 ] );
7493		if ( $.blockUI ) {
7494			$.blockUI( this.dpDiv );
7495		}
7496		$.data( this._dialogInput[ 0 ], "datepicker", inst );
7497		return this;
7498	},
7499
7500	/* Detach a datepicker from its control.
7501	 * @param  target	element - the target input field or division or span
7502	 */
7503	_destroyDatepicker: function( target ) {
7504		var nodeName,
7505			$target = $( target ),
7506			inst = $.data( target, "datepicker" );
7507
7508		if ( !$target.hasClass( this.markerClassName ) ) {
7509			return;
7510		}
7511
7512		nodeName = target.nodeName.toLowerCase();
7513		$.removeData( target, "datepicker" );
7514		if ( nodeName === "input" ) {
vendor: 12,111 bytes, lines 7515-7855
7515			inst.append.remove();
7516			inst.trigger.remove();
7517			$target.removeClass( this.markerClassName ).
7518				off( "focus", this._showDatepicker ).
7519				off( "keydown", this._doKeyDown ).
7520				off( "keypress", this._doKeyPress ).
7521				off( "keyup", this._doKeyUp );
7522		} else if ( nodeName === "div" || nodeName === "span" ) {
7523			$target.removeClass( this.markerClassName ).empty();
7524		}
7525
7526		if ( datepicker_instActive === inst ) {
7527			datepicker_instActive = null;
7528		}
7529	},
7530
7531	/* Enable the date picker to a jQuery selection.
7532	 * @param  target	element - the target input field or division or span
7533	 */
7534	_enableDatepicker: function( target ) {
7535		var nodeName, inline,
7536			$target = $( target ),
7537			inst = $.data( target, "datepicker" );
7538
7539		if ( !$target.hasClass( this.markerClassName ) ) {
7540			return;
7541		}
7542
7543		nodeName = target.nodeName.toLowerCase();
7544		if ( nodeName === "input" ) {
7545			target.disabled = false;
7546			inst.trigger.filter( "button" ).
7547				each( function() { this.disabled = false; } ).end().
7548				filter( "img" ).css( { opacity: "1.0", cursor: "" } );
7549		} else if ( nodeName === "div" || nodeName === "span" ) {
7550			inline = $target.children( "." + this._inlineClass );
7551			inline.children().removeClass( "ui-state-disabled" );
7552			inline.find( "select.ui-datepicker-month, select.ui-datepicker-year" ).
7553				prop( "disabled", false );
7554		}
7555		this._disabledInputs = $.map( this._disabledInputs,
7556			function( value ) { return ( value === target ? null : value ); } ); // delete entry
7557	},
7558
7559	/* Disable the date picker to a jQuery selection.
7560	 * @param  target	element - the target input field or division or span
7561	 */
7562	_disableDatepicker: function( target ) {
7563		var nodeName, inline,
7564			$target = $( target ),
7565			inst = $.data( target, "datepicker" );
7566
7567		if ( !$target.hasClass( this.markerClassName ) ) {
7568			return;
7569		}
7570
7571		nodeName = target.nodeName.toLowerCase();
7572		if ( nodeName === "input" ) {
7573			target.disabled = true;
7574			inst.trigger.filter( "button" ).
7575				each( function() { this.disabled = true; } ).end().
7576				filter( "img" ).css( { opacity: "0.5", cursor: "default" } );
7577		} else if ( nodeName === "div" || nodeName === "span" ) {
7578			inline = $target.children( "." + this._inlineClass );
7579			inline.children().addClass( "ui-state-disabled" );
7580			inline.find( "select.ui-datepicker-month, select.ui-datepicker-year" ).
7581				prop( "disabled", true );
7582		}
7583		this._disabledInputs = $.map( this._disabledInputs,
7584			function( value ) { return ( value === target ? null : value ); } ); // delete entry
7585		this._disabledInputs[ this._disabledInputs.length ] = target;
7586	},
7587
7588	/* Is the first field in a jQuery collection disabled as a datepicker?
7589	 * @param  target	element - the target input field or division or span
7590	 * @return boolean - true if disabled, false if enabled
7591	 */
7592	_isDisabledDatepicker: function( target ) {
7593		if ( !target ) {
7594			return false;
7595		}
7596		for ( var i = 0; i < this._disabledInputs.length; i++ ) {
7597			if ( this._disabledInputs[ i ] === target ) {
7598				return true;
7599			}
7600		}
7601		return false;
7602	},
7603
7604	/* Retrieve the instance data for the target control.
7605	 * @param  target  element - the target input field or division or span
7606	 * @return  object - the associated instance data
7607	 * @throws  error if a jQuery problem getting data
7608	 */
7609	_getInst: function( target ) {
7610		try {
7611			return $.data( target, "datepicker" );
7612		}
7613		catch ( err ) {
7614			throw "Missing instance data for this datepicker";
7615		}
7616	},
7617
7618	/* Update or retrieve the settings for a date picker attached to an input field or division.
7619	 * @param  target  element - the target input field or division or span
7620	 * @param  name	object - the new settings to update or
7621	 *				string - the name of the setting to change or retrieve,
7622	 *				when retrieving also "all" for all instance settings or
7623	 *				"defaults" for all global defaults
7624	 * @param  value   any - the new value for the setting
7625	 *				(omit if above is an object or to retrieve a value)
7626	 */
7627	_optionDatepicker: function( target, name, value ) {
7628		var settings, date, minDate, maxDate,
7629			inst = this._getInst( target );
7630
7631		if ( arguments.length === 2 && typeof name === "string" ) {
7632			return ( name === "defaults" ? $.extend( {}, $.datepicker._defaults ) :
7633				( inst ? ( name === "all" ? $.extend( {}, inst.settings ) :
7634				this._get( inst, name ) ) : null ) );
7635		}
7636
7637		settings = name || {};
7638		if ( typeof name === "string" ) {
7639			settings = {};
7640			settings[ name ] = value;
7641		}
7642
7643		if ( inst ) {
7644			if ( this._curInst === inst ) {
7645				this._hideDatepicker();
7646			}
7647
7648			date = this._getDateDatepicker( target, true );
7649			minDate = this._getMinMaxDate( inst, "min" );
7650			maxDate = this._getMinMaxDate( inst, "max" );
7651			datepicker_extendRemove( inst.settings, settings );
7652
7653			// reformat the old minDate/maxDate values if dateFormat changes and a new minDate/maxDate isn't provided
7654			if ( minDate !== null && settings.dateFormat !== undefined && settings.minDate === undefined ) {
7655				inst.settings.minDate = this._formatDate( inst, minDate );
7656			}
7657			if ( maxDate !== null && settings.dateFormat !== undefined && settings.maxDate === undefined ) {
7658				inst.settings.maxDate = this._formatDate( inst, maxDate );
7659			}
7660			if ( "disabled" in settings ) {
7661				if ( settings.disabled ) {
7662					this._disableDatepicker( target );
7663				} else {
7664					this._enableDatepicker( target );
7665				}
7666			}
7667			this._attachments( $( target ), inst );
7668			this._autoSize( inst );
7669			this._setDate( inst, date );
7670			this._updateAlternate( inst );
7671			this._updateDatepicker( inst );
7672		}
7673	},
7674
7675	// Change method deprecated
7676	_changeDatepicker: function( target, name, value ) {
7677		this._optionDatepicker( target, name, value );
7678	},
7679
7680	/* Redraw the date picker attached to an input field or division.
7681	 * @param  target  element - the target input field or division or span
7682	 */
7683	_refreshDatepicker: function( target ) {
7684		var inst = this._getInst( target );
7685		if ( inst ) {
7686			this._updateDatepicker( inst );
7687		}
7688	},
7689
7690	/* Set the dates for a jQuery selection.
7691	 * @param  target element - the target input field or division or span
7692	 * @param  date	Date - the new date
7693	 */
7694	_setDateDatepicker: function( target, date ) {
7695		var inst = this._getInst( target );
7696		if ( inst ) {
7697			this._setDate( inst, date );
7698			this._updateDatepicker( inst );
7699			this._updateAlternate( inst );
7700		}
7701	},
7702
7703	/* Get the date(s) for the first entry in a jQuery selection.
7704	 * @param  target element - the target input field or division or span
7705	 * @param  noDefault boolean - true if no default date is to be used
7706	 * @return Date - the current date
7707	 */
7708	_getDateDatepicker: function( target, noDefault ) {
7709		var inst = this._getInst( target );
7710		if ( inst && !inst.inline ) {
7711			this._setDateFromField( inst, noDefault );
7712		}
7713		return ( inst ? this._getDate( inst ) : null );
7714	},
7715
7716	/* Handle keystrokes. */
7717	_doKeyDown: function( event ) {
7718		var onSelect, dateStr, sel,
7719			inst = $.datepicker._getInst( event.target ),
7720			handled = true,
7721			isRTL = inst.dpDiv.is( ".ui-datepicker-rtl" );
7722
7723		inst._keyEvent = true;
7724		if ( $.datepicker._datepickerShowing ) {
7725			switch ( event.keyCode ) {
7726				case 9: $.datepicker._hideDatepicker();
7727						handled = false;
7728						break; // hide on tab out
7729				case 13: sel = $( "td." + $.datepicker._dayOverClass + ":not(." +
7730									$.datepicker._currentClass + ")", inst.dpDiv );
7731						if ( sel[ 0 ] ) {
7732							$.datepicker._selectDay( event.target, inst.selectedMonth, inst.selectedYear, sel[ 0 ] );
7733						}
7734
7735						onSelect = $.datepicker._get( inst, "onSelect" );
7736						if ( onSelect ) {
7737							dateStr = $.datepicker._formatDate( inst );
7738
7739							// Trigger custom callback
7740							onSelect.apply( ( inst.input ? inst.input[ 0 ] : null ), [ dateStr, inst ] );
7741						} else {
7742							$.datepicker._hideDatepicker();
7743						}
7744
7745						return false; // don't submit the form
7746				case 27: $.datepicker._hideDatepicker();
7747						break; // hide on escape
7748				case 33: $.datepicker._adjustDate( event.target, ( event.ctrlKey ?
7749							-$.datepicker._get( inst, "stepBigMonths" ) :
7750							-$.datepicker._get( inst, "stepMonths" ) ), "M" );
7751						break; // previous month/year on page up/+ ctrl
7752				case 34: $.datepicker._adjustDate( event.target, ( event.ctrlKey ?
7753							+$.datepicker._get( inst, "stepBigMonths" ) :
7754							+$.datepicker._get( inst, "stepMonths" ) ), "M" );
7755						break; // next month/year on page down/+ ctrl
7756				case 35: if ( event.ctrlKey || event.metaKey ) {
7757							$.datepicker._clearDate( event.target );
7758						}
7759						handled = event.ctrlKey || event.metaKey;
7760						break; // clear on ctrl or command +end
7761				case 36: if ( event.ctrlKey || event.metaKey ) {
7762							$.datepicker._gotoToday( event.target );
7763						}
7764						handled = event.ctrlKey || event.metaKey;
7765						break; // current on ctrl or command +home
7766				case 37: if ( event.ctrlKey || event.metaKey ) {
7767							$.datepicker._adjustDate( event.target, ( isRTL ? +1 : -1 ), "D" );
7768						}
7769						handled = event.ctrlKey || event.metaKey;
7770
7771						// -1 day on ctrl or command +left
7772						if ( event.originalEvent.altKey ) {
7773							$.datepicker._adjustDate( event.target, ( event.ctrlKey ?
7774								-$.datepicker._get( inst, "stepBigMonths" ) :
7775								-$.datepicker._get( inst, "stepMonths" ) ), "M" );
7776						}
7777
7778						// next month/year on alt +left on Mac
7779						break;
7780				case 38: if ( event.ctrlKey || event.metaKey ) {
7781							$.datepicker._adjustDate( event.target, -7, "D" );
7782						}
7783						handled = event.ctrlKey || event.metaKey;
7784						break; // -1 week on ctrl or command +up
7785				case 39: if ( event.ctrlKey || event.metaKey ) {
7786							$.datepicker._adjustDate( event.target, ( isRTL ? -1 : +1 ), "D" );
7787						}
7788						handled = event.ctrlKey || event.metaKey;
7789
7790						// +1 day on ctrl or command +right
7791						if ( event.originalEvent.altKey ) {
7792							$.datepicker._adjustDate( event.target, ( event.ctrlKey ?
7793								+$.datepicker._get( inst, "stepBigMonths" ) :
7794								+$.datepicker._get( inst, "stepMonths" ) ), "M" );
7795						}
7796
7797						// next month/year on alt +right
7798						break;
7799				case 40: if ( event.ctrlKey || event.metaKey ) {
7800							$.datepicker._adjustDate( event.target, +7, "D" );
7801						}
7802						handled = event.ctrlKey || event.metaKey;
7803						break; // +1 week on ctrl or command +down
7804				default: handled = false;
7805			}
7806		} else if ( event.keyCode === 36 && event.ctrlKey ) { // display the date picker on ctrl+home
7807			$.datepicker._showDatepicker( this );
7808		} else {
7809			handled = false;
7810		}
7811
7812		if ( handled ) {
7813			event.preventDefault();
7814			event.stopPropagation();
7815		}
7816	},
7817
7818	/* Filter entered characters - based on date format. */
7819	_doKeyPress: function( event ) {
7820		var chars, chr,
7821			inst = $.datepicker._getInst( event.target );
7822
7823		if ( $.datepicker._get( inst, "constrainInput" ) ) {
7824			chars = $.datepicker._possibleChars( $.datepicker._get( inst, "dateFormat" ) );
7825			chr = String.fromCharCode( event.charCode == null ? event.keyCode : event.charCode );
7826			return event.ctrlKey || event.metaKey || ( chr < " " || !chars || chars.indexOf( chr ) > -1 );
7827		}
7828	},
7829
7830	/* Synchronise manual entry and field/alternate field. */
7831	_doKeyUp: function( event ) {
7832		var date,
7833			inst = $.datepicker._getInst( event.target );
7834
7835		if ( inst.input.val() !== inst.lastVal ) {
7836			try {
7837				date = $.datepicker.parseDate( $.datepicker._get( inst, "dateFormat" ),
7838					( inst.input ? inst.input.val() : null ),
7839					$.datepicker._getFormatConfig( inst ) );
7840
7841				if ( date ) { // only if valid
7842					$.datepicker._setDateFromField( inst );
7843					$.datepicker._updateAlternate( inst );
7844					$.datepicker._updateDatepicker( inst );
7845				}
7846			}
7847			catch ( err ) {
7848			}
7849		}
7850		return true;
7851	},
7852
7853	/* Pop-up the date picker for a given input field.
7854	 * If false returned from beforeShow event handler do not show.
7855	 * @param  input  element - the input field attached to the date picker or
vendor: 1,885 bytes, lines 7856-7913
7856	 *					event - if triggered by focus
7857	 */
7858	_showDatepicker: function( input ) {
7859		input = input.target || input;
7860		if ( input.nodeName.toLowerCase() !== "input" ) { // find from button/image trigger
7861			input = $( "input", input.parentNode )[ 0 ];
7862		}
7863
7864		if ( $.datepicker._isDisabledDatepicker( input ) || $.datepicker._lastInput === input ) { // already here
7865			return;
7866		}
7867
7868		var inst, beforeShow, beforeShowSettings, isFixed,
7869			offset, showAnim, duration;
7870
7871		inst = $.datepicker._getInst( input );
7872		if ( $.datepicker._curInst && $.datepicker._curInst !== inst ) {
7873			$.datepicker._curInst.dpDiv.stop( true, true );
7874			if ( inst && $.datepicker._datepickerShowing ) {
7875				$.datepicker._hideDatepicker( $.datepicker._curInst.input[ 0 ] );
7876			}
7877		}
7878
7879		beforeShow = $.datepicker._get( inst, "beforeShow" );
7880		beforeShowSettings = beforeShow ? beforeShow.apply( input, [ input, inst ] ) : {};
7881		if ( beforeShowSettings === false ) {
7882			return;
7883		}
7884		datepicker_extendRemove( inst.settings, beforeShowSettings );
7885
7886		inst.lastVal = null;
7887		$.datepicker._lastInput = input;
7888		$.datepicker._setDateFromField( inst );
7889
7890		if ( $.datepicker._inDialog ) { // hide cursor
7891			input.value = "";
7892		}
7893		if ( !$.datepicker._pos ) { // position below input
7894			$.datepicker._pos = $.datepicker._findPos( input );
7895			$.datepicker._pos[ 1 ] += input.offsetHeight; // add the height
7896		}
7897
7898		isFixed = false;
7899		$( input ).parents().each( function() {
7900			isFixed |= $( this ).css( "position" ) === "fixed";
7901			return !isFixed;
7902		} );
7903
7904		offset = { left: $.datepicker._pos[ 0 ], top: $.datepicker._pos[ 1 ] };
7905		$.datepicker._pos = null;
7906
7907		//to avoid flashes on Firefox
7908		inst.dpDiv.empty();
7909
7910		// determine sizing offscreen
7911		inst.dpDiv.css( { position: "absolute", display: "block", top: "-1000px" } );
7912		$.datepicker._updateDatepicker( inst );
7913
vendor: 12,837 bytes, lines 7914-8266
7914		// fix width for dynamic number of date pickers
7915		// and adjust position before showing
7916		offset = $.datepicker._checkOffset( inst, offset, isFixed );
7917		inst.dpDiv.css( { position: ( $.datepicker._inDialog && $.blockUI ?
7918			"static" : ( isFixed ? "fixed" : "absolute" ) ), display: "none",
7919			left: offset.left + "px", top: offset.top + "px" } );
7920
7921		if ( !inst.inline ) {
7922			showAnim = $.datepicker._get( inst, "showAnim" );
7923			duration = $.datepicker._get( inst, "duration" );
7924			inst.dpDiv.css( "z-index", datepicker_getZindex( $( input ) ) + 1 );
7925			$.datepicker._datepickerShowing = true;
7926
7927			if ( $.effects && $.effects.effect[ showAnim ] ) {
7928				inst.dpDiv.show( showAnim, $.datepicker._get( inst, "showOptions" ), duration );
7929			} else {
7930				inst.dpDiv[ showAnim || "show" ]( showAnim ? duration : null );
7931			}
7932
7933			if ( $.datepicker._shouldFocusInput( inst ) ) {
7934				inst.input.trigger( "focus" );
7935			}
7936
7937			$.datepicker._curInst = inst;
7938		}
7939	},
7940
7941	/* Generate the date picker content. */
7942	_updateDatepicker: function( inst ) {
7943		this.maxRows = 4; //Reset the max number of rows being displayed (see #7043)
7944		datepicker_instActive = inst; // for delegate hover events
7945		inst.dpDiv.empty().append( this._generateHTML( inst ) );
7946		this._attachHandlers( inst );
7947
7948		var origyearshtml,
7949			numMonths = this._getNumberOfMonths( inst ),
7950			cols = numMonths[ 1 ],
7951			width = 17,
7952			activeCell = inst.dpDiv.find( "." + this._dayOverClass + " a" );
7953
7954		if ( activeCell.length > 0 ) {
7955			datepicker_handleMouseover.apply( activeCell.get( 0 ) );
7956		}
7957
7958		inst.dpDiv.removeClass( "ui-datepicker-multi-2 ui-datepicker-multi-3 ui-datepicker-multi-4" ).width( "" );
7959		if ( cols > 1 ) {
7960			inst.dpDiv.addClass( "ui-datepicker-multi-" + cols ).css( "width", ( width * cols ) + "em" );
7961		}
7962		inst.dpDiv[ ( numMonths[ 0 ] !== 1 || numMonths[ 1 ] !== 1 ? "add" : "remove" ) +
7963			"Class" ]( "ui-datepicker-multi" );
7964		inst.dpDiv[ ( this._get( inst, "isRTL" ) ? "add" : "remove" ) +
7965			"Class" ]( "ui-datepicker-rtl" );
7966
7967		if ( inst === $.datepicker._curInst && $.datepicker._datepickerShowing && $.datepicker._shouldFocusInput( inst ) ) {
7968			inst.input.trigger( "focus" );
7969		}
7970
7971		// Deffered render of the years select (to avoid flashes on Firefox)
7972		if ( inst.yearshtml ) {
7973			origyearshtml = inst.yearshtml;
7974			setTimeout( function() {
7975
7976				//assure that inst.yearshtml didn't change.
7977				if ( origyearshtml === inst.yearshtml && inst.yearshtml ) {
7978					inst.dpDiv.find( "select.ui-datepicker-year:first" ).replaceWith( inst.yearshtml );
7979				}
7980				origyearshtml = inst.yearshtml = null;
7981			}, 0 );
7982		}
7983	},
7984
7985	// #6694 - don't focus the input if it's already focused
7986	// this breaks the change event in IE
7987	// Support: IE and jQuery <1.9
7988	_shouldFocusInput: function( inst ) {
7989		return inst.input && inst.input.is( ":visible" ) && !inst.input.is( ":disabled" ) && !inst.input.is( ":focus" );
7990	},
7991
7992	/* Check positioning to remain on screen. */
7993	_checkOffset: function( inst, offset, isFixed ) {
7994		var dpWidth = inst.dpDiv.outerWidth(),
7995			dpHeight = inst.dpDiv.outerHeight(),
7996			inputWidth = inst.input ? inst.input.outerWidth() : 0,
7997			inputHeight = inst.input ? inst.input.outerHeight() : 0,
7998			viewWidth = document.documentElement.clientWidth + ( isFixed ? 0 : $( document ).scrollLeft() ),
7999			viewHeight = document.documentElement.clientHeight + ( isFixed ? 0 : $( document ).scrollTop() );
8000
8001		offset.left -= ( this._get( inst, "isRTL" ) ? ( dpWidth - inputWidth ) : 0 );
8002		offset.left -= ( isFixed && offset.left === inst.input.offset().left ) ? $( document ).scrollLeft() : 0;
8003		offset.top -= ( isFixed && offset.top === ( inst.input.offset().top + inputHeight ) ) ? $( document ).scrollTop() : 0;
8004
8005		// Now check if datepicker is showing outside window viewport - move to a better place if so.
8006		offset.left -= Math.min( offset.left, ( offset.left + dpWidth > viewWidth && viewWidth > dpWidth ) ?
8007			Math.abs( offset.left + dpWidth - viewWidth ) : 0 );
8008		offset.top -= Math.min( offset.top, ( offset.top + dpHeight > viewHeight && viewHeight > dpHeight ) ?
8009			Math.abs( dpHeight + inputHeight ) : 0 );
8010
8011		return offset;
8012	},
8013
8014	/* Find an object's position on the screen. */
8015	_findPos: function( obj ) {
8016		var position,
8017			inst = this._getInst( obj ),
8018			isRTL = this._get( inst, "isRTL" );
8019
8020		while ( obj && ( obj.type === "hidden" || obj.nodeType !== 1 || $.expr.filters.hidden( obj ) ) ) {
8021			obj = obj[ isRTL ? "previousSibling" : "nextSibling" ];
8022		}
8023
8024		position = $( obj ).offset();
8025		return [ position.left, position.top ];
8026	},
8027
8028	/* Hide the date picker from view.
8029	 * @param  input  element - the input field attached to the date picker
8030	 */
8031	_hideDatepicker: function( input ) {
8032		var showAnim, duration, postProcess, onClose,
8033			inst = this._curInst;
8034
8035		if ( !inst || ( input && inst !== $.data( input, "datepicker" ) ) ) {
8036			return;
8037		}
8038
8039		if ( this._datepickerShowing ) {
8040			showAnim = this._get( inst, "showAnim" );
8041			duration = this._get( inst, "duration" );
8042			postProcess = function() {
8043				$.datepicker._tidyDialog( inst );
8044			};
8045
8046			// DEPRECATED: after BC for 1.8.x $.effects[ showAnim ] is not needed
8047			if ( $.effects && ( $.effects.effect[ showAnim ] || $.effects[ showAnim ] ) ) {
8048				inst.dpDiv.hide( showAnim, $.datepicker._get( inst, "showOptions" ), duration, postProcess );
8049			} else {
8050				inst.dpDiv[ ( showAnim === "slideDown" ? "slideUp" :
8051					( showAnim === "fadeIn" ? "fadeOut" : "hide" ) ) ]( ( showAnim ? duration : null ), postProcess );
8052			}
8053
8054			if ( !showAnim ) {
8055				postProcess();
8056			}
8057			this._datepickerShowing = false;
8058
8059			onClose = this._get( inst, "onClose" );
8060			if ( onClose ) {
8061				onClose.apply( ( inst.input ? inst.input[ 0 ] : null ), [ ( inst.input ? inst.input.val() : "" ), inst ] );
8062			}
8063
8064			this._lastInput = null;
8065			if ( this._inDialog ) {
8066				this._dialogInput.css( { position: "absolute", left: "0", top: "-100px" } );
8067				if ( $.blockUI ) {
8068					$.unblockUI();
8069					$( "body" ).append( this.dpDiv );
8070				}
8071			}
8072			this._inDialog = false;
8073		}
8074	},
8075
8076	/* Tidy up after a dialog display. */
8077	_tidyDialog: function( inst ) {
8078		inst.dpDiv.removeClass( this._dialogClass ).off( ".ui-datepicker-calendar" );
8079	},
8080
8081	/* Close date picker if clicked elsewhere. */
8082	_checkExternalClick: function( event ) {
8083		if ( !$.datepicker._curInst ) {
8084			return;
8085		}
8086
8087		var $target = $( event.target ),
8088			inst = $.datepicker._getInst( $target[ 0 ] );
8089
8090		if ( ( ( $target[ 0 ].id !== $.datepicker._mainDivId &&
8091				$target.parents( "#" + $.datepicker._mainDivId ).length === 0 &&
8092				!$target.hasClass( $.datepicker.markerClassName ) &&
8093				!$target.closest( "." + $.datepicker._triggerClass ).length &&
8094				$.datepicker._datepickerShowing && !( $.datepicker._inDialog && $.blockUI ) ) ) ||
8095			( $target.hasClass( $.datepicker.markerClassName ) && $.datepicker._curInst !== inst ) ) {
8096				$.datepicker._hideDatepicker();
8097		}
8098	},
8099
8100	/* Adjust one of the date sub-fields. */
8101	_adjustDate: function( id, offset, period ) {
8102		var target = $( id ),
8103			inst = this._getInst( target[ 0 ] );
8104
8105		if ( this._isDisabledDatepicker( target[ 0 ] ) ) {
8106			return;
8107		}
8108		this._adjustInstDate( inst, offset +
8109			( period === "M" ? this._get( inst, "showCurrentAtPos" ) : 0 ), // undo positioning
8110			period );
8111		this._updateDatepicker( inst );
8112	},
8113
8114	/* Action for current link. */
8115	_gotoToday: function( id ) {
8116		var date,
8117			target = $( id ),
8118			inst = this._getInst( target[ 0 ] );
8119
8120		if ( this._get( inst, "gotoCurrent" ) && inst.currentDay ) {
8121			inst.selectedDay = inst.currentDay;
8122			inst.drawMonth = inst.selectedMonth = inst.currentMonth;
8123			inst.drawYear = inst.selectedYear = inst.currentYear;
8124		} else {
8125			date = new Date();
8126			inst.selectedDay = date.getDate();
8127			inst.drawMonth = inst.selectedMonth = date.getMonth();
8128			inst.drawYear = inst.selectedYear = date.getFullYear();
8129		}
8130		this._notifyChange( inst );
8131		this._adjustDate( target );
8132	},
8133
8134	/* Action for selecting a new month/year. */
8135	_selectMonthYear: function( id, select, period ) {
8136		var target = $( id ),
8137			inst = this._getInst( target[ 0 ] );
8138
8139		inst[ "selected" + ( period === "M" ? "Month" : "Year" ) ] =
8140		inst[ "draw" + ( period === "M" ? "Month" : "Year" ) ] =
8141			parseInt( select.options[ select.selectedIndex ].value, 10 );
8142
8143		this._notifyChange( inst );
8144		this._adjustDate( target );
8145	},
8146
8147	/* Action for selecting a day. */
8148	_selectDay: function( id, month, year, td ) {
8149		var inst,
8150			target = $( id );
8151
8152		if ( $( td ).hasClass( this._unselectableClass ) || this._isDisabledDatepicker( target[ 0 ] ) ) {
8153			return;
8154		}
8155
8156		inst = this._getInst( target[ 0 ] );
8157		inst.selectedDay = inst.currentDay = $( "a", td ).html();
8158		inst.selectedMonth = inst.currentMonth = month;
8159		inst.selectedYear = inst.currentYear = year;
8160		this._selectDate( id, this._formatDate( inst,
8161			inst.currentDay, inst.currentMonth, inst.currentYear ) );
8162	},
8163
8164	/* Erase the input field and hide the date picker. */
8165	_clearDate: function( id ) {
8166		var target = $( id );
8167		this._selectDate( target, "" );
8168	},
8169
8170	/* Update the input field with the selected date. */
8171	_selectDate: function( id, dateStr ) {
8172		var onSelect,
8173			target = $( id ),
8174			inst = this._getInst( target[ 0 ] );
8175
8176		dateStr = ( dateStr != null ? dateStr : this._formatDate( inst ) );
8177		if ( inst.input ) {
8178			inst.input.val( dateStr );
8179		}
8180		this._updateAlternate( inst );
8181
8182		onSelect = this._get( inst, "onSelect" );
8183		if ( onSelect ) {
8184			onSelect.apply( ( inst.input ? inst.input[ 0 ] : null ), [ dateStr, inst ] );  // trigger custom callback
8185		} else if ( inst.input ) {
8186			inst.input.trigger( "change" ); // fire the change event
8187		}
8188
8189		if ( inst.inline ) {
8190			this._updateDatepicker( inst );
8191		} else {
8192			this._hideDatepicker();
8193			this._lastInput = inst.input[ 0 ];
8194			if ( typeof( inst.input[ 0 ] ) !== "object" ) {
8195				inst.input.trigger( "focus" ); // restore focus
8196			}
8197			this._lastInput = null;
8198		}
8199	},
8200
8201	/* Update any alternate field to synchronise with the main field. */
8202	_updateAlternate: function( inst ) {
8203		var altFormat, date, dateStr,
8204			altField = this._get( inst, "altField" );
8205
8206		if ( altField ) { // update alternate field too
8207			altFormat = this._get( inst, "altFormat" ) || this._get( inst, "dateFormat" );
8208			date = this._getDate( inst );
8209			dateStr = this.formatDate( altFormat, date, this._getFormatConfig( inst ) );
8210			$( altField ).val( dateStr );
8211		}
8212	},
8213
8214	/* Set as beforeShowDay function to prevent selection of weekends.
8215	 * @param  date  Date - the date to customise
8216	 * @return [boolean, string] - is this date selectable?, what is its CSS class?
8217	 */
8218	noWeekends: function( date ) {
8219		var day = date.getDay();
8220		return [ ( day > 0 && day < 6 ), "" ];
8221	},
8222
8223	/* Set as calculateWeek to determine the week of the year based on the ISO 8601 definition.
8224	 * @param  date  Date - the date to get the week for
8225	 * @return  number - the number of the week within the year that contains this date
8226	 */
8227	iso8601Week: function( date ) {
8228		var time,
8229			checkDate = new Date( date.getTime() );
8230
8231		// Find Thursday of this week starting on Monday
8232		checkDate.setDate( checkDate.getDate() + 4 - ( checkDate.getDay() || 7 ) );
8233
8234		time = checkDate.getTime();
8235		checkDate.setMonth( 0 ); // Compare with Jan 1
8236		checkDate.setDate( 1 );
8237		return Math.floor( Math.round( ( time - checkDate ) / 86400000 ) / 7 ) + 1;
8238	},
8239
8240	/* Parse a string value into a date object.
8241	 * See formatDate below for the possible formats.
8242	 *
8243	 * @param  format string - the expected format of the date
8244	 * @param  value string - the date in the above format
8245	 * @param  settings Object - attributes include:
8246	 *					shortYearCutoff  number - the cutoff year for determining the century (optional)
8247	 *					dayNamesShort	string[7] - abbreviated names of the days from Sunday (optional)
8248	 *					dayNames		string[7] - names of the days from Sunday (optional)
8249	 *					monthNamesShort string[12] - abbreviated names of the months (optional)
8250	 *					monthNames		string[12] - names of the months (optional)
8251	 * @return  Date - the extracted date value or null if value is blank
8252	 */
8253	parseDate: function( format, value, settings ) {
8254		if ( format == null || value == null ) {
8255			throw "Invalid arguments";
8256		}
8257
8258		value = ( typeof value === "object" ? value.toString() : value + "" );
8259		if ( value === "" ) {
8260			return null;
8261		}
8262
8263		var iFormat, dim, extra,
8264			iValue = 0,
8265			shortYearCutoffTemp = ( settings ? settings.shortYearCutoff : null ) || this._defaults.shortYearCutoff,
8266			shortYearCutoff = ( typeof shortYearCutoffTemp !== "string" ? shortYearCutoffTemp 
vendor: 15,177 bytes, lines 8266-8742
8266:
8267				new Date().getFullYear() % 100 + parseInt( shortYearCutoffTemp, 10 ) ),
8268			dayNamesShort = ( settings ? settings.dayNamesShort : null ) || this._defaults.dayNamesShort,
8269			dayNames = ( settings ? settings.dayNames : null ) || this._defaults.dayNames,
8270			monthNamesShort = ( settings ? settings.monthNamesShort : null ) || this._defaults.monthNamesShort,
8271			monthNames = ( settings ? settings.monthNames : null ) || this._defaults.monthNames,
8272			year = -1,
8273			month = -1,
8274			day = -1,
8275			doy = -1,
8276			literal = false,
8277			date,
8278
8279			// Check whether a format character is doubled
8280			lookAhead = function( match ) {
8281				var matches = ( iFormat + 1 < format.length && format.charAt( iFormat + 1 ) === match );
8282				if ( matches ) {
8283					iFormat++;
8284				}
8285				return matches;
8286			},
8287
8288			// Extract a number from the string value
8289			getNumber = function( match ) {
8290				var isDoubled = lookAhead( match ),
8291					size = ( match === "@" ? 14 : ( match === "!" ? 20 :
8292					( match === "y" && isDoubled ? 4 : ( match === "o" ? 3 : 2 ) ) ) ),
8293					minSize = ( match === "y" ? size : 1 ),
8294					digits = new RegExp( "^\\d{" + minSize + "," + size + "}" ),
8295					num = value.substring( iValue ).match( digits );
8296				if ( !num ) {
8297					throw "Missing number at position " + iValue;
8298				}
8299				iValue += num[ 0 ].length;
8300				return parseInt( num[ 0 ], 10 );
8301			},
8302
8303			// Extract a name from the string value and convert to an index
8304			getName = function( match, shortNames, longNames ) {
8305				var index = -1,
8306					names = $.map( lookAhead( match ) ? longNames : shortNames, function( v, k ) {
8307						return [ [ k, v ] ];
8308					} ).sort( function( a, b ) {
8309						return -( a[ 1 ].length - b[ 1 ].length );
8310					} );
8311
8312				$.each( names, function( i, pair ) {
8313					var name = pair[ 1 ];
8314					if ( value.substr( iValue, name.length ).toLowerCase() === name.toLowerCase() ) {
8315						index = pair[ 0 ];
8316						iValue += name.length;
8317						return false;
8318					}
8319				} );
8320				if ( index !== -1 ) {
8321					return index + 1;
8322				} else {
8323					throw "Unknown name at position " + iValue;
8324				}
8325			},
8326
8327			// Confirm that a literal character matches the string value
8328			checkLiteral = function() {
8329				if ( value.charAt( iValue ) !== format.charAt( iFormat ) ) {
8330					throw "Unexpected literal at position " + iValue;
8331				}
8332				iValue++;
8333			};
8334
8335		for ( iFormat = 0; iFormat < format.length; iFormat++ ) {
8336			if ( literal ) {
8337				if ( format.charAt( iFormat ) === "'" && !lookAhead( "'" ) ) {
8338					literal = false;
8339				} else {
8340					checkLiteral();
8341				}
8342			} else {
8343				switch ( format.charAt( iFormat ) ) {
8344					case "d":
8345						day = getNumber( "d" );
8346						break;
8347					case "D":
8348						getName( "D", dayNamesShort, dayNames );
8349						break;
8350					case "o":
8351						doy = getNumber( "o" );
8352						break;
8353					case "m":
8354						month = getNumber( "m" );
8355						break;
8356					case "M":
8357						month = getName( "M", monthNamesShort, monthNames );
8358						break;
8359					case "y":
8360						year = getNumber( "y" );
8361						break;
8362					case "@":
8363						date = new Date( getNumber( "@" ) );
8364						year = date.getFullYear();
8365						month = date.getMonth() + 1;
8366						day = date.getDate();
8367						break;
8368					case "!":
8369						date = new Date( ( getNumber( "!" ) - this._ticksTo1970 ) / 10000 );
8370						year = date.getFullYear();
8371						month = date.getMonth() + 1;
8372						day = date.getDate();
8373						break;
8374					case "'":
8375						if ( lookAhead( "'" ) ) {
8376							checkLiteral();
8377						} else {
8378							literal = true;
8379						}
8380						break;
8381					default:
8382						checkLiteral();
8383				}
8384			}
8385		}
8386
8387		if ( iValue < value.length ) {
8388			extra = value.substr( iValue );
8389			if ( !/^\s+/.test( extra ) ) {
8390				throw "Extra/unparsed characters found in date: " + extra;
8391			}
8392		}
8393
8394		if ( year === -1 ) {
8395			year = new Date().getFullYear();
8396		} else if ( year < 100 ) {
8397			year += new Date().getFullYear() - new Date().getFullYear() % 100 +
8398				( year <= shortYearCutoff ? 0 : -100 );
8399		}
8400
8401		if ( doy > -1 ) {
8402			month = 1;
8403			day = doy;
8404			do {
8405				dim = this._getDaysInMonth( year, month - 1 );
8406				if ( day <= dim ) {
8407					break;
8408				}
8409				month++;
8410				day -= dim;
8411			} while ( true );
8412		}
8413
8414		date = this._daylightSavingAdjust( new Date( year, month - 1, day ) );
8415		if ( date.getFullYear() !== year || date.getMonth() + 1 !== month || date.getDate() !== day ) {
8416			throw "Invalid date"; // E.g. 31/02/00
8417		}
8418		return date;
8419	},
8420
8421	/* Standard date formats. */
8422	ATOM: "yy-mm-dd", // RFC 3339 (ISO 8601)
8423	COOKIE: "D, dd M yy",
8424	ISO_8601: "yy-mm-dd",
8425	RFC_822: "D, d M y",
8426	RFC_850: "DD, dd-M-y",
8427	RFC_1036: "D, d M y",
8428	RFC_1123: "D, d M yy",
8429	RFC_2822: "D, d M yy",
8430	RSS: "D, d M y", // RFC 822
8431	TICKS: "!",
8432	TIMESTAMP: "@",
8433	W3C: "yy-mm-dd", // ISO 8601
8434
8435	_ticksTo1970: ( ( ( 1970 - 1 ) * 365 + Math.floor( 1970 / 4 ) - Math.floor( 1970 / 100 ) +
8436		Math.floor( 1970 / 400 ) ) * 24 * 60 * 60 * 10000000 ),
8437
8438	/* Format a date object into a string value.
8439	 * The format can be combinations of the following:
8440	 * d  - day of month (no leading zero)
8441	 * dd - day of month (two digit)
8442	 * o  - day of year (no leading zeros)
8443	 * oo - day of year (three digit)
8444	 * D  - day name short
8445	 * DD - day name long
8446	 * m  - month of year (no leading zero)
8447	 * mm - month of year (two digit)
8448	 * M  - month name short
8449	 * MM - month name long
8450	 * y  - year (two digit)
8451	 * yy - year (four digit)
8452	 * @ - Unix timestamp (ms since 01/01/1970)
8453	 * ! - Windows ticks (100ns since 01/01/0001)
8454	 * "..." - literal text
8455	 * '' - single quote
8456	 *
8457	 * @param  format string - the desired format of the date
8458	 * @param  date Date - the date value to format
8459	 * @param  settings Object - attributes include:
8460	 *					dayNamesShort	string[7] - abbreviated names of the days from Sunday (optional)
8461	 *					dayNames		string[7] - names of the days from Sunday (optional)
8462	 *					monthNamesShort string[12] - abbreviated names of the months (optional)
8463	 *					monthNames		string[12] - names of the months (optional)
8464	 * @return  string - the date in the above format
8465	 */
8466	formatDate: function( format, date, settings ) {
8467		if ( !date ) {
8468			return "";
8469		}
8470
8471		var iFormat,
8472			dayNamesShort = ( settings ? settings.dayNamesShort : null ) || this._defaults.dayNamesShort,
8473			dayNames = ( settings ? settings.dayNames : null ) || this._defaults.dayNames,
8474			monthNamesShort = ( settings ? settings.monthNamesShort : null ) || this._defaults.monthNamesShort,
8475			monthNames = ( settings ? settings.monthNames : null ) || this._defaults.monthNames,
8476
8477			// Check whether a format character is doubled
8478			lookAhead = function( match ) {
8479				var matches = ( iFormat + 1 < format.length && format.charAt( iFormat + 1 ) === match );
8480				if ( matches ) {
8481					iFormat++;
8482				}
8483				return matches;
8484			},
8485
8486			// Format a number, with leading zero if necessary
8487			formatNumber = function( match, value, len ) {
8488				var num = "" + value;
8489				if ( lookAhead( match ) ) {
8490					while ( num.length < len ) {
8491						num = "0" + num;
8492					}
8493				}
8494				return num;
8495			},
8496
8497			// Format a name, short or long as requested
8498			formatName = function( match, value, shortNames, longNames ) {
8499				return ( lookAhead( match ) ? longNames[ value ] : shortNames[ value ] );
8500			},
8501			output = "",
8502			literal = false;
8503
8504		if ( date ) {
8505			for ( iFormat = 0; iFormat < format.length; iFormat++ ) {
8506				if ( literal ) {
8507					if ( format.charAt( iFormat ) === "'" && !lookAhead( "'" ) ) {
8508						literal = false;
8509					} else {
8510						output += format.charAt( iFormat );
8511					}
8512				} else {
8513					switch ( format.charAt( iFormat ) ) {
8514						case "d":
8515							output += formatNumber( "d", date.getDate(), 2 );
8516							break;
8517						case "D":
8518							output += formatName( "D", date.getDay(), dayNamesShort, dayNames );
8519							break;
8520						case "o":
8521							output += formatNumber( "o",
8522								Math.round( ( new Date( date.getFullYear(), date.getMonth(), date.getDate() ).getTime() - new Date( date.getFullYear(), 0, 0 ).getTime() ) / 86400000 ), 3 );
8523							break;
8524						case "m":
8525							output += formatNumber( "m", date.getMonth() + 1, 2 );
8526							break;
8527						case "M":
8528							output += formatName( "M", date.getMonth(), monthNamesShort, monthNames );
8529							break;
8530						case "y":
8531							output += ( lookAhead( "y" ) ? date.getFullYear() :
8532								( date.getFullYear() % 100 < 10 ? "0" : "" ) + date.getFullYear() % 100 );
8533							break;
8534						case "@":
8535							output += date.getTime();
8536							break;
8537						case "!":
8538							output += date.getTime() * 10000 + this._ticksTo1970;
8539							break;
8540						case "'":
8541							if ( lookAhead( "'" ) ) {
8542								output += "'";
8543							} else {
8544								literal = true;
8545							}
8546							break;
8547						default:
8548							output += format.charAt( iFormat );
8549					}
8550				}
8551			}
8552		}
8553		return output;
8554	},
8555
8556	/* Extract all possible characters from the date format. */
8557	_possibleChars: function( format ) {
8558		var iFormat,
8559			chars = "",
8560			literal = false,
8561
8562			// Check whether a format character is doubled
8563			lookAhead = function( match ) {
8564				var matches = ( iFormat + 1 < format.length && format.charAt( iFormat + 1 ) === match );
8565				if ( matches ) {
8566					iFormat++;
8567				}
8568				return matches;
8569			};
8570
8571		for ( iFormat = 0; iFormat < format.length; iFormat++ ) {
8572			if ( literal ) {
8573				if ( format.charAt( iFormat ) === "'" && !lookAhead( "'" ) ) {
8574					literal = false;
8575				} else {
8576					chars += format.charAt( iFormat );
8577				}
8578			} else {
8579				switch ( format.charAt( iFormat ) ) {
8580					case "d": case "m": case "y": case "@":
8581						chars += "0123456789";
8582						break;
8583					case "D": case "M":
8584						return null; // Accept anything
8585					case "'":
8586						if ( lookAhead( "'" ) ) {
8587							chars += "'";
8588						} else {
8589							literal = true;
8590						}
8591						break;
8592					default:
8593						chars += format.charAt( iFormat );
8594				}
8595			}
8596		}
8597		return chars;
8598	},
8599
8600	/* Get a setting value, defaulting if necessary. */
8601	_get: function( inst, name ) {
8602		return inst.settings[ name ] !== undefined ?
8603			inst.settings[ name ] : this._defaults[ name ];
8604	},
8605
8606	/* Parse existing date and initialise date picker. */
8607	_setDateFromField: function( inst, noDefault ) {
8608		if ( inst.input.val() === inst.lastVal ) {
8609			return;
8610		}
8611
8612		var dateFormat = this._get( inst, "dateFormat" ),
8613			dates = inst.lastVal = inst.input ? inst.input.val() : null,
8614			defaultDate = this._getDefaultDate( inst ),
8615			date = defaultDate,
8616			settings = this._getFormatConfig( inst );
8617
8618		try {
8619			date = this.parseDate( dateFormat, dates, settings ) || defaultDate;
8620		} catch ( event ) {
8621			dates = ( noDefault ? "" : dates );
8622		}
8623		inst.selectedDay = date.getDate();
8624		inst.drawMonth = inst.selectedMonth = date.getMonth();
8625		inst.drawYear = inst.selectedYear = date.getFullYear();
8626		inst.currentDay = ( dates ? date.getDate() : 0 );
8627		inst.currentMonth = ( dates ? date.getMonth() : 0 );
8628		inst.currentYear = ( dates ? date.getFullYear() : 0 );
8629		this._adjustInstDate( inst );
8630	},
8631
8632	/* Retrieve the default date shown on opening. */
8633	_getDefaultDate: function( inst ) {
8634		return this._restrictMinMax( inst,
8635			this._determineDate( inst, this._get( inst, "defaultDate" ), new Date() ) );
8636	},
8637
8638	/* A date may be specified as an exact value or a relative one. */
8639	_determineDate: function( inst, date, defaultDate ) {
8640		var offsetNumeric = function( offset ) {
8641				var date = new Date();
8642				date.setDate( date.getDate() + offset );
8643				return date;
8644			},
8645			offsetString = function( offset ) {
8646				try {
8647					return $.datepicker.parseDate( $.datepicker._get( inst, "dateFormat" ),
8648						offset, $.datepicker._getFormatConfig( inst ) );
8649				}
8650				catch ( e ) {
8651
8652					// Ignore
8653				}
8654
8655				var date = ( offset.toLowerCase().match( /^c/ ) ?
8656					$.datepicker._getDate( inst ) : null ) || new Date(),
8657					year = date.getFullYear(),
8658					month = date.getMonth(),
8659					day = date.getDate(),
8660					pattern = /([+\-]?[0-9]+)\s*(d|D|w|W|m|M|y|Y)?/g,
8661					matches = pattern.exec( offset );
8662
8663				while ( matches ) {
8664					switch ( matches[ 2 ] || "d" ) {
8665						case "d" : case "D" :
8666							day += parseInt( matches[ 1 ], 10 ); break;
8667						case "w" : case "W" :
8668							day += parseInt( matches[ 1 ], 10 ) * 7; break;
8669						case "m" : case "M" :
8670							month += parseInt( matches[ 1 ], 10 );
8671							day = Math.min( day, $.datepicker._getDaysInMonth( year, month ) );
8672							break;
8673						case "y": case "Y" :
8674							year += parseInt( matches[ 1 ], 10 );
8675							day = Math.min( day, $.datepicker._getDaysInMonth( year, month ) );
8676							break;
8677					}
8678					matches = pattern.exec( offset );
8679				}
8680				return new Date( year, month, day );
8681			},
8682			newDate = ( date == null || date === "" ? defaultDate : ( typeof date === "string" ? offsetString( date ) :
8683				( typeof date === "number" ? ( isNaN( date ) ? defaultDate : offsetNumeric( date ) ) : new Date( date.getTime() ) ) ) );
8684
8685		newDate = ( newDate && newDate.toString() === "Invalid Date" ? defaultDate : newDate );
8686		if ( newDate ) {
8687			newDate.setHours( 0 );
8688			newDate.setMinutes( 0 );
8689			newDate.setSeconds( 0 );
8690			newDate.setMilliseconds( 0 );
8691		}
8692		return this._daylightSavingAdjust( newDate );
8693	},
8694
8695	/* Handle switch to/from daylight saving.
8696	 * Hours may be non-zero on daylight saving cut-over:
8697	 * > 12 when midnight changeover, but then cannot generate
8698	 * midnight datetime, so jump to 1AM, otherwise reset.
8699	 * @param  date  (Date) the date to check
8700	 * @return  (Date) the corrected date
8701	 */
8702	_daylightSavingAdjust: function( date ) {
8703		if ( !date ) {
8704			return null;
8705		}
8706		date.setHours( date.getHours() > 12 ? date.getHours() + 2 : 0 );
8707		return date;
8708	},
8709
8710	/* Set the date(s) directly. */
8711	_setDate: function( inst, date, noChange ) {
8712		var clear = !date,
8713			origMonth = inst.selectedMonth,
8714			origYear = inst.selectedYear,
8715			newDate = this._restrictMinMax( inst, this._determineDate( inst, date, new Date() ) );
8716
8717		inst.selectedDay = inst.currentDay = newDate.getDate();
8718		inst.drawMonth = inst.selectedMonth = inst.currentMonth = newDate.getMonth();
8719		inst.drawYear = inst.selectedYear = inst.currentYear = newDate.getFullYear();
8720		if ( ( origMonth !== inst.selectedMonth || origYear !== inst.selectedYear ) && !noChange ) {
8721			this._notifyChange( inst );
8722		}
8723		this._adjustInstDate( inst );
8724		if ( inst.input ) {
8725			inst.input.val( clear ? "" : this._formatDate( inst ) );
8726		}
8727	},
8728
8729	/* Retrieve the date(s) directly. */
8730	_getDate: function( inst ) {
8731		var startDate = ( !inst.currentYear || ( inst.input && inst.input.val() === "" ) ? null :
8732			this._daylightSavingAdjust( new Date(
8733			inst.currentYear, inst.currentMonth, inst.currentDay ) ) );
8734			return startDate;
8735	},
8736
8737	/* Attach the onxxx handlers.  These are declared statically so
8738	 * they work with static code transformers like Caja.
8739	 */
8740	_attachHandlers: function( inst ) {
8741		var stepMonths = this._get( inst, "stepMonths" ),
8742			id = "#" + inst.id.replace( /\\\\/g, "\\" );
vendor: 42,013 bytes, lines 8743-9927
8743		inst.dpDiv.find( "[data-handler]" ).map( function() {
8744			var handler = {
8745				prev: function() {
8746					$.datepicker._adjustDate( id, -stepMonths, "M" );
8747				},
8748				next: function() {
8749					$.datepicker._adjustDate( id, +stepMonths, "M" );
8750				},
8751				hide: function() {
8752					$.datepicker._hideDatepicker();
8753				},
8754				today: function() {
8755					$.datepicker._gotoToday( id );
8756				},
8757				selectDay: function() {
8758					$.datepicker._selectDay( id, +this.getAttribute( "data-month" ), +this.getAttribute( "data-year" ), this );
8759					return false;
8760				},
8761				selectMonth: function() {
8762					$.datepicker._selectMonthYear( id, this, "M" );
8763					return false;
8764				},
8765				selectYear: function() {
8766					$.datepicker._selectMonthYear( id, this, "Y" );
8767					return false;
8768				}
8769			};
8770			$( this ).on( this.getAttribute( "data-event" ), handler[ this.getAttribute( "data-handler" ) ] );
8771		} );
8772	},
8773
8774	/* Generate the HTML for the current state of the date picker. */
8775	_generateHTML: function( inst ) {
8776		var maxDraw, prevText, prev, nextText, next, currentText, gotoDate,
8777			controls, buttonPanel, firstDay, showWeek, dayNames, dayNamesMin,
8778			monthNames, monthNamesShort, beforeShowDay, showOtherMonths,
8779			selectOtherMonths, defaultDate, html, dow, row, group, col, selectedDate,
8780			cornerClass, calender, thead, day, daysInMonth, leadDays, curRows, numRows,
8781			printDate, dRow, tbody, daySettings, otherMonth, unselectable,
8782			tempDate = new Date(),
8783			today = this._daylightSavingAdjust(
8784				new Date( tempDate.getFullYear(), tempDate.getMonth(), tempDate.getDate() ) ), // clear time
8785			isRTL = this._get( inst, "isRTL" ),
8786			showButtonPanel = this._get( inst, "showButtonPanel" ),
8787			hideIfNoPrevNext = this._get( inst, "hideIfNoPrevNext" ),
8788			navigationAsDateFormat = this._get( inst, "navigationAsDateFormat" ),
8789			numMonths = this._getNumberOfMonths( inst ),
8790			showCurrentAtPos = this._get( inst, "showCurrentAtPos" ),
8791			stepMonths = this._get( inst, "stepMonths" ),
8792			isMultiMonth = ( numMonths[ 0 ] !== 1 || numMonths[ 1 ] !== 1 ),
8793			currentDate = this._daylightSavingAdjust( ( !inst.currentDay ? new Date( 9999, 9, 9 ) :
8794				new Date( inst.currentYear, inst.currentMonth, inst.currentDay ) ) ),
8795			minDate = this._getMinMaxDate( inst, "min" ),
8796			maxDate = this._getMinMaxDate( inst, "max" ),
8797			drawMonth = inst.drawMonth - showCurrentAtPos,
8798			drawYear = inst.drawYear;
8799
8800		if ( drawMonth < 0 ) {
8801			drawMonth += 12;
8802			drawYear--;
8803		}
8804		if ( maxDate ) {
8805			maxDraw = this._daylightSavingAdjust( new Date( maxDate.getFullYear(),
8806				maxDate.getMonth() - ( numMonths[ 0 ] * numMonths[ 1 ] ) + 1, maxDate.getDate() ) );
8807			maxDraw = ( minDate && maxDraw < minDate ? minDate : maxDraw );
8808			while ( this._daylightSavingAdjust( new Date( drawYear, drawMonth, 1 ) ) > maxDraw ) {
8809				drawMonth--;
8810				if ( drawMonth < 0 ) {
8811					drawMonth = 11;
8812					drawYear--;
8813				}
8814			}
8815		}
8816		inst.drawMonth = drawMonth;
8817		inst.drawYear = drawYear;
8818
8819		prevText = this._get( inst, "prevText" );
8820		prevText = ( !navigationAsDateFormat ? prevText : this.formatDate( prevText,
8821			this._daylightSavingAdjust( new Date( drawYear, drawMonth - stepMonths, 1 ) ),
8822			this._getFormatConfig( inst ) ) );
8823
8824		prev = ( this._canAdjustMonth( inst, -1, drawYear, drawMonth ) ?
8825			"<a class='ui-datepicker-prev ui-corner-all' data-handler='prev' data-event='click'" +
8826			" title='" + prevText + "'><span class='ui-icon ui-icon-circle-triangle-" + ( isRTL ? "e" : "w" ) + "'>" + prevText + "</span></a>" :
8827			( 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>" ) );
8828
8829		nextText = this._get( inst, "nextText" );
8830		nextText = ( !navigationAsDateFormat ? nextText : this.formatDate( nextText,
8831			this._daylightSavingAdjust( new Date( drawYear, drawMonth + stepMonths, 1 ) ),
8832			this._getFormatConfig( inst ) ) );
8833
8834		next = ( this._canAdjustMonth( inst, +1, drawYear, drawMonth ) ?
8835			"<a class='ui-datepicker-next ui-corner-all' data-handler='next' data-event='click'" +
8836			" title='" + nextText + "'><span class='ui-icon ui-icon-circle-triangle-" + ( isRTL ? "w" : "e" ) + "'>" + nextText + "</span></a>" :
8837			( 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>" ) );
8838
8839		currentText = this._get( inst, "currentText" );
8840		gotoDate = ( this._get( inst, "gotoCurrent" ) && inst.currentDay ? currentDate : today );
8841		currentText = ( !navigationAsDateFormat ? currentText :
8842			this.formatDate( currentText, gotoDate, this._getFormatConfig( inst ) ) );
8843
8844		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'>" +
8845			this._get( inst, "closeText" ) + "</button>" : "" );
8846
8847		buttonPanel = ( showButtonPanel ) ? "<div class='ui-datepicker-buttonpane ui-widget-content'>" + ( isRTL ? controls : "" ) +
8848			( 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'" +
8849			">" + currentText + "</button>" : "" ) + ( isRTL ? "" : controls ) + "</div>" : "";
8850
8851		firstDay = parseInt( this._get( inst, "firstDay" ), 10 );
8852		firstDay = ( isNaN( firstDay ) ? 0 : firstDay );
8853
8854		showWeek = this._get( inst, "showWeek" );
8855		dayNames = this._get( inst, "dayNames" );
8856		dayNamesMin = this._get( inst, "dayNamesMin" );
8857		monthNames = this._get( inst, "monthNames" );
8858		monthNamesShort = this._get( inst, "monthNamesShort" );
8859		beforeShowDay = this._get( inst, "beforeShowDay" );
8860		showOtherMonths = this._get( inst, "showOtherMonths" );
8861		selectOtherMonths = this._get( inst, "selectOtherMonths" );
8862		defaultDate = this._getDefaultDate( inst );
8863		html = "";
8864
8865		for ( row = 0; row < numMonths[ 0 ]; row++ ) {
8866			group = "";
8867			this.maxRows = 4;
8868			for ( col = 0; col < numMonths[ 1 ]; col++ ) {
8869				selectedDate = this._daylightSavingAdjust( new Date( drawYear, drawMonth, inst.selectedDay ) );
8870				cornerClass = " ui-corner-all";
8871				calender = "";
8872				if ( isMultiMonth ) {
8873					calender += "<div class='ui-datepicker-group";
8874					if ( numMonths[ 1 ] > 1 ) {
8875						switch ( col ) {
8876							case 0: calender += " ui-datepicker-group-first";
8877								cornerClass = " ui-corner-" + ( isRTL ? "right" : "left" ); break;
8878							case numMonths[ 1 ] - 1: calender += " ui-datepicker-group-last";
8879								cornerClass = " ui-corner-" + ( isRTL ? "left" : "right" ); break;
8880							default: calender += " ui-datepicker-group-middle"; cornerClass = ""; break;
8881						}
8882					}
8883					calender += "'>";
8884				}
8885				calender += "<div class='ui-datepicker-header ui-widget-header ui-helper-clearfix" + cornerClass + "'>" +
8886					( /all|left/.test( cornerClass ) && row === 0 ? ( isRTL ? next : prev ) : "" ) +
8887					( /all|right/.test( cornerClass ) && row === 0 ? ( isRTL ? prev : next ) : "" ) +
8888					this._generateMonthYearHeader( inst, drawMonth, drawYear, minDate, maxDate,
8889					row > 0 || col > 0, monthNames, monthNamesShort ) + // draw month headers
8890					"</div><table class='ui-datepicker-calendar'><thead>" +
8891					"<tr>";
8892				thead = ( showWeek ? "<th class='ui-datepicker-week-col'>" + this._get( inst, "weekHeader" ) + "</th>" : "" );
8893				for ( dow = 0; dow < 7; dow++ ) { // days of the week
8894					day = ( dow + firstDay ) % 7;
8895					thead += "<th scope='col'" + ( ( dow + firstDay + 6 ) % 7 >= 5 ? " class='ui-datepicker-week-end'" : "" ) + ">" +
8896						"<span title='" + dayNames[ day ] + "'>" + dayNamesMin[ day ] + "</span></th>";
8897				}
8898				calender += thead + "</tr></thead><tbody>";
8899				daysInMonth = this._getDaysInMonth( drawYear, drawMonth );
8900				if ( drawYear === inst.selectedYear && drawMonth === inst.selectedMonth ) {
8901					inst.selectedDay = Math.min( inst.selectedDay, daysInMonth );
8902				}
8903				leadDays = ( this._getFirstDayOfMonth( drawYear, drawMonth ) - firstDay + 7 ) % 7;
8904				curRows = Math.ceil( ( leadDays + daysInMonth ) / 7 ); // calculate the number of rows to generate
8905				numRows = ( isMultiMonth ? this.maxRows > curRows ? this.maxRows : curRows : curRows ); //If multiple months, use the higher number of rows (see #7043)
8906				this.maxRows = numRows;
8907				printDate = this._daylightSavingAdjust( new Date( drawYear, drawMonth, 1 - leadDays ) );
8908				for ( dRow = 0; dRow < numRows; dRow++ ) { // create date picker rows
8909					calender += "<tr>";
8910					tbody = ( !showWeek ? "" : "<td class='ui-datepicker-week-col'>" +
8911						this._get( inst, "calculateWeek" )( printDate ) + "</td>" );
8912					for ( dow = 0; dow < 7; dow++ ) { // create date picker days
8913						daySettings = ( beforeShowDay ?
8914							beforeShowDay.apply( ( inst.input ? inst.input[ 0 ] : null ), [ printDate ] ) : [ true, "" ] );
8915						otherMonth = ( printDate.getMonth() !== drawMonth );
8916						unselectable = ( otherMonth && !selectOtherMonths ) || !daySettings[ 0 ] ||
8917							( minDate && printDate < minDate ) || ( maxDate && printDate > maxDate );
8918						tbody += "<td class='" +
8919							( ( dow + firstDay + 6 ) % 7 >= 5 ? " ui-datepicker-week-end" : "" ) + // highlight weekends
8920							( otherMonth ? " ui-datepicker-other-month" : "" ) + // highlight days from other months
8921							( ( printDate.getTime() === selectedDate.getTime() && drawMonth === inst.selectedMonth && inst._keyEvent ) || // user pressed key
8922							( defaultDate.getTime() === printDate.getTime() && defaultDate.getTime() === selectedDate.getTime() ) ?
8923
8924							// or defaultDate is current printedDate and defaultDate is selectedDate
8925							" " + this._dayOverClass : "" ) + // highlight selected day
8926							( unselectable ? " " + this._unselectableClass + " ui-state-disabled" : "" ) +  // highlight unselectable days
8927							( otherMonth && !showOtherMonths ? "" : " " + daySettings[ 1 ] + // highlight custom dates
8928							( printDate.getTime() === currentDate.getTime() ? " " + this._currentClass : "" ) + // highlight selected day
8929							( printDate.getTime() === today.getTime() ? " ui-datepicker-today" : "" ) ) + "'" + // highlight today (if different)
8930							( ( !otherMonth || showOtherMonths ) && daySettings[ 2 ] ? " title='" + daySettings[ 2 ].replace( /'/g, "&#39;" ) + "'" : "" ) + // cell title
8931							( unselectable ? "" : " data-handler='selectDay' data-event='click' data-month='" + printDate.getMonth() + "' data-year='" + printDate.getFullYear() + "'" ) + ">" + // actions
8932							( otherMonth && !showOtherMonths ? "&#xa0;" : // display for other months
8933							( unselectable ? "<span class='ui-state-default'>" + printDate.getDate() + "</span>" : "<a class='ui-state-default" +
8934							( printDate.getTime() === today.getTime() ? " ui-state-highlight" : "" ) +
8935							( printDate.getTime() === currentDate.getTime() ? " ui-state-active" : "" ) + // highlight selected day
8936							( otherMonth ? " ui-priority-secondary" : "" ) + // distinguish dates from other months
8937							"' href='#'>" + printDate.getDate() + "</a>" ) ) + "</td>"; // display selectable date
8938						printDate.setDate( printDate.getDate() + 1 );
8939						printDate = this._daylightSavingAdjust( printDate );
8940					}
8941					calender += tbody + "</tr>";
8942				}
8943				drawMonth++;
8944				if ( drawMonth > 11 ) {
8945					drawMonth = 0;
8946					drawYear++;
8947				}
8948				calender += "</tbody></table>" + ( isMultiMonth ? "</div>" +
8949							( ( numMonths[ 0 ] > 0 && col === numMonths[ 1 ] - 1 ) ? "<div class='ui-datepicker-row-break'></div>" : "" ) : "" );
8950				group += calender;
8951			}
8952			html += group;
8953		}
8954		html += buttonPanel;
8955		inst._keyEvent = false;
8956		return html;
8957	},
8958
8959	/* Generate the month and year header. */
8960	_generateMonthYearHeader: function( inst, drawMonth, drawYear, minDate, maxDate,
8961			secondary, monthNames, monthNamesShort ) {
8962
8963		var inMinYear, inMaxYear, month, years, thisYear, determineYear, year, endYear,
8964			changeMonth = this._get( inst, "changeMonth" ),
8965			changeYear = this._get( inst, "changeYear" ),
8966			showMonthAfterYear = this._get( inst, "showMonthAfterYear" ),
8967			html = "<div class='ui-datepicker-title'>",
8968			monthHtml = "";
8969
8970		// Month selection
8971		if ( secondary || !changeMonth ) {
8972			monthHtml += "<span class='ui-datepicker-month'>" + monthNames[ drawMonth ] + "</span>";
8973		} else {
8974			inMinYear = ( minDate && minDate.getFullYear() === drawYear );
8975			inMaxYear = ( maxDate && maxDate.getFullYear() === drawYear );
8976			monthHtml += "<select class='ui-datepicker-month' data-handler='selectMonth' data-event='change'>";
8977			for ( month = 0; month < 12; month++ ) {
8978				if ( ( !inMinYear || month >= minDate.getMonth() ) && ( !inMaxYear || month <= maxDate.getMonth() ) ) {
8979					monthHtml += "<option value='" + month + "'" +
8980						( month === drawMonth ? " selected='selected'" : "" ) +
8981						">" + monthNamesShort[ month ] + "</option>";
8982				}
8983			}
8984			monthHtml += "</select>";
8985		}
8986
8987		if ( !showMonthAfterYear ) {
8988			html += monthHtml + ( secondary || !( changeMonth && changeYear ) ? "&#xa0;" : "" );
8989		}
8990
8991		// Year selection
8992		if ( !inst.yearshtml ) {
8993			inst.yearshtml = "";
8994			if ( secondary || !changeYear ) {
8995				html += "<span class='ui-datepicker-year'>" + drawYear + "</span>";
8996			} else {
8997
8998				// determine range of years to display
8999				years = this._get( inst, "yearRange" ).split( ":" );
9000				thisYear = new Date().getFullYear();
9001				determineYear = function( value ) {
9002					var year = ( value.match( /c[+\-].*/ ) ? drawYear + parseInt( value.substring( 1 ), 10 ) :
9003						( value.match( /[+\-].*/ ) ? thisYear + parseInt( value, 10 ) :
9004						parseInt( value, 10 ) ) );
9005					return ( isNaN( year ) ? thisYear : year );
9006				};
9007				year = determineYear( years[ 0 ] );
9008				endYear = Math.max( year, determineYear( years[ 1 ] || "" ) );
9009				year = ( minDate ? Math.max( year, minDate.getFullYear() ) : year );
9010				endYear = ( maxDate ? Math.min( endYear, maxDate.getFullYear() ) : endYear );
9011				inst.yearshtml += "<select class='ui-datepicker-year' data-handler='selectYear' data-event='change'>";
9012				for ( ; year <= endYear; year++ ) {
9013					inst.yearshtml += "<option value='" + year + "'" +
9014						( year === drawYear ? " selected='selected'" : "" ) +
9015						">" + year + "</option>";
9016				}
9017				inst.yearshtml += "</select>";
9018
9019				html += inst.yearshtml;
9020				inst.yearshtml = null;
9021			}
9022		}
9023
9024		html += this._get( inst, "yearSuffix" );
9025		if ( showMonthAfterYear ) {
9026			html += ( secondary || !( changeMonth && changeYear ) ? "&#xa0;" : "" ) + monthHtml;
9027		}
9028		html += "</div>"; // Close datepicker_header
9029		return html;
9030	},
9031
9032	/* Adjust one of the date sub-fields. */
9033	_adjustInstDate: function( inst, offset, period ) {
9034		var year = inst.selectedYear + ( period === "Y" ? offset : 0 ),
9035			month = inst.selectedMonth + ( period === "M" ? offset : 0 ),
9036			day = Math.min( inst.selectedDay, this._getDaysInMonth( year, month ) ) + ( period === "D" ? offset : 0 ),
9037			date = this._restrictMinMax( inst, this._daylightSavingAdjust( new Date( year, month, day ) ) );
9038
9039		inst.selectedDay = date.getDate();
9040		inst.drawMonth = inst.selectedMonth = date.getMonth();
9041		inst.drawYear = inst.selectedYear = date.getFullYear();
9042		if ( period === "M" || period === "Y" ) {
9043			this._notifyChange( inst );
9044		}
9045	},
9046
9047	/* Ensure a date is within any min/max bounds. */
9048	_restrictMinMax: function( inst, date ) {
9049		var minDate = this._getMinMaxDate( inst, "min" ),
9050			maxDate = this._getMinMaxDate( inst, "max" ),
9051			newDate = ( minDate && date < minDate ? minDate : date );
9052		return ( maxDate && newDate > maxDate ? maxDate : newDate );
9053	},
9054
9055	/* Notify change of month/year. */
9056	_notifyChange: function( inst ) {
9057		var onChange = this._get( inst, "onChangeMonthYear" );
9058		if ( onChange ) {
9059			onChange.apply( ( inst.input ? inst.input[ 0 ] : null ),
9060				[ inst.selectedYear, inst.selectedMonth + 1, inst ] );
9061		}
9062	},
9063
9064	/* Determine the number of months to show. */
9065	_getNumberOfMonths: function( inst ) {
9066		var numMonths = this._get( inst, "numberOfMonths" );
9067		return ( numMonths == null ? [ 1, 1 ] : ( typeof numMonths === "number" ? [ 1, numMonths ] : numMonths ) );
9068	},
9069
9070	/* Determine the current maximum date - ensure no time components are set. */
9071	_getMinMaxDate: function( inst, minMax ) {
9072		return this._determineDate( inst, this._get( inst, minMax + "Date" ), null );
9073	},
9074
9075	/* Find the number of days in a given month. */
9076	_getDaysInMonth: function( year, month ) {
9077		return 32 - this._daylightSavingAdjust( new Date( year, month, 32 ) ).getDate();
9078	},
9079
9080	/* Find the day of the week of the first of a month. */
9081	_getFirstDayOfMonth: function( year, month ) {
9082		return new Date( year, month, 1 ).getDay();
9083	},
9084
9085	/* Determines if we should allow a "next/prev" month display change. */
9086	_canAdjustMonth: function( inst, offset, curYear, curMonth ) {
9087		var numMonths = this._getNumberOfMonths( inst ),
9088			date = this._daylightSavingAdjust( new Date( curYear,
9089			curMonth + ( offset < 0 ? offset : numMonths[ 0 ] * numMonths[ 1 ] ), 1 ) );
9090
9091		if ( offset < 0 ) {
9092			date.setDate( this._getDaysInMonth( date.getFullYear(), date.getMonth() ) );
9093		}
9094		return this._isInRange( inst, date );
9095	},
9096
9097	/* Is the given date in the accepted range? */
9098	_isInRange: function( inst, date ) {
9099		var yearSplit, currentYear,
9100			minDate = this._getMinMaxDate( inst, "min" ),
9101			maxDate = this._getMinMaxDate( inst, "max" ),
9102			minYear = null,
9103			maxYear = null,
9104			years = this._get( inst, "yearRange" );
9105			if ( years ) {
9106				yearSplit = years.split( ":" );
9107				currentYear = new Date().getFullYear();
9108				minYear = parseInt( yearSplit[ 0 ], 10 );
9109				maxYear = parseInt( yearSplit[ 1 ], 10 );
9110				if ( yearSplit[ 0 ].match( /[+\-].*/ ) ) {
9111					minYear += currentYear;
9112				}
9113				if ( yearSplit[ 1 ].match( /[+\-].*/ ) ) {
9114					maxYear += currentYear;
9115				}
9116			}
9117
9118		return ( ( !minDate || date.getTime() >= minDate.getTime() ) &&
9119			( !maxDate || date.getTime() <= maxDate.getTime() ) &&
9120			( !minYear || date.getFullYear() >= minYear ) &&
9121			( !maxYear || date.getFullYear() <= maxYear ) );
9122	},
9123
9124	/* Provide the configuration settings for formatting/parsing. */
9125	_getFormatConfig: function( inst ) {
9126		var shortYearCutoff = this._get( inst, "shortYearCutoff" );
9127		shortYearCutoff = ( typeof shortYearCutoff !== "string" ? shortYearCutoff :
9128			new Date().getFullYear() % 100 + parseInt( shortYearCutoff, 10 ) );
9129		return { shortYearCutoff: shortYearCutoff,
9130			dayNamesShort: this._get( inst, "dayNamesShort" ), dayNames: this._get( inst, "dayNames" ),
9131			monthNamesShort: this._get( inst, "monthNamesShort" ), monthNames: this._get( inst, "monthNames" ) };
9132	},
9133
9134	/* Format the given date for display. */
9135	_formatDate: function( inst, day, month, year ) {
9136		if ( !day ) {
9137			inst.currentDay = inst.selectedDay;
9138			inst.currentMonth = inst.selectedMonth;
9139			inst.currentYear = inst.selectedYear;
9140		}
9141		var date = ( day ? ( typeof day === "object" ? day :
9142			this._daylightSavingAdjust( new Date( year, month, day ) ) ) :
9143			this._daylightSavingAdjust( new Date( inst.currentYear, inst.currentMonth, inst.currentDay ) ) );
9144		return this.formatDate( this._get( inst, "dateFormat" ), date, this._getFormatConfig( inst ) );
9145	}
9146} );
9147
9148/*
9149 * Bind hover events for datepicker elements.
9150 * Done via delegate so the binding only occurs once in the lifetime of the parent div.
9151 * Global datepicker_instActive, set by _updateDatepicker allows the handlers to find their way back to the active picker.
9152 */
9153function datepicker_bindHover( dpDiv ) {
9154	var selector = "button, .ui-datepicker-prev, .ui-datepicker-next, .ui-datepicker-calendar td a";
9155	return dpDiv.on( "mouseout", selector, function() {
9156			$( this ).removeClass( "ui-state-hover" );
9157			if ( this.className.indexOf( "ui-datepicker-prev" ) !== -1 ) {
9158				$( this ).removeClass( "ui-datepicker-prev-hover" );
9159			}
9160			if ( this.className.indexOf( "ui-datepicker-next" ) !== -1 ) {
9161				$( this ).removeClass( "ui-datepicker-next-hover" );
9162			}
9163		} )
9164		.on( "mouseover", selector, datepicker_handleMouseover );
9165}
9166
9167function datepicker_handleMouseover() {
9168	if ( !$.datepicker._isDisabledDatepicker( datepicker_instActive.inline ? datepicker_instActive.dpDiv.parent()[ 0 ] : datepicker_instActive.input[ 0 ] ) ) {
9169		$( this ).parents( ".ui-datepicker-calendar" ).find( "a" ).removeClass( "ui-state-hover" );
9170		$( this ).addClass( "ui-state-hover" );
9171		if ( this.className.indexOf( "ui-datepicker-prev" ) !== -1 ) {
9172			$( this ).addClass( "ui-datepicker-prev-hover" );
9173		}
9174		if ( this.className.indexOf( "ui-datepicker-next" ) !== -1 ) {
9175			$( this ).addClass( "ui-datepicker-next-hover" );
9176		}
9177	}
9178}
9179
9180/* jQuery extend now ignores nulls! */
9181function datepicker_extendRemove( target, props ) {
9182	$.extend( target, props );
9183	for ( var name in props ) {
9184		if ( props[ name ] == null ) {
9185			target[ name ] = props[ name ];
9186		}
9187	}
9188	return target;
9189}
9190
9191/* Invoke the datepicker functionality.
9192   @param  options  string - a command, optionally followed by additional parameters or
9193					Object - settings for attaching new datepicker functionality
9194   @return  jQuery object */
9195$.fn.datepicker = function( options ) {
9196
9197	/* Verify an empty collection wasn't passed - Fixes #6976 */
9198	if ( !this.length ) {
9199		return this;
9200	}
9201
9202	/* Initialise the date picker. */
9203	if ( !$.datepicker.initialized ) {
9204		$( document ).on( "mousedown", $.datepicker._checkExternalClick );
9205		$.datepicker.initialized = true;
9206	}
9207
9208	/* Append datepicker main container to body if not exist. */
9209	if ( $( "#" + $.datepicker._mainDivId ).length === 0 ) {
9210		$( "body" ).append( $.datepicker.dpDiv );
9211	}
9212
9213	var otherArgs = Array.prototype.slice.call( arguments, 1 );
9214	if ( typeof options === "string" && ( options === "isDisabled" || options === "getDate" || options === "widget" ) ) {
9215		return $.datepicker[ "_" + options + "Datepicker" ].
9216			apply( $.datepicker, [ this[ 0 ] ].concat( otherArgs ) );
9217	}
9218	if ( options === "option" && arguments.length === 2 && typeof arguments[ 1 ] === "string" ) {
9219		return $.datepicker[ "_" + options + "Datepicker" ].
9220			apply( $.datepicker, [ this[ 0 ] ].concat( otherArgs ) );
9221	}
9222	return this.each( function() {
9223		typeof options === "string" ?
9224			$.datepicker[ "_" + options + "Datepicker" ].
9225				apply( $.datepicker, [ this ].concat( otherArgs ) ) :
9226			$.datepicker._attachDatepicker( this, options );
9227	} );
9228};
9229
9230$.datepicker = new Datepicker(); // singleton instance
9231$.datepicker.initialized = false;
9232$.datepicker.uuid = new Date().getTime();
9233$.datepicker.version = "1.12.1";
9234
9235var widgetsDatepicker = $.datepicker;
9236
9237
9238
9239
9240// This file is deprecated
9241var ie = $.ui.ie = !!/msie [\w.]+/.exec( navigator.userAgent.toLowerCase() );
9242
9243/*!
9244 * jQuery UI Mouse 1.12.1
9245 * http://jqueryui.com
9246 *
9247 * Copyright jQuery Foundation and other contributors
9248 * Released under the MIT license.
9249 * http://jquery.org/license
9250 */
9251
9252//>>label: Mouse
9253//>>group: Widgets
9254//>>description: Abstracts mouse-based interactions to assist in creating certain widgets.
9255//>>docs: http://api.jqueryui.com/mouse/
9256
9257
9258
9259var mouseHandled = false;
9260$( document ).on( "mouseup", function() {
9261	mouseHandled = false;
9262} );
9263
9264var widgetsMouse = $.widget( "ui.mouse", {
9265	version: "1.12.1",
9266	options: {
9267		cancel: "input, textarea, button, select, option",
9268		distance: 1,
9269		delay: 0
9270	},
9271	_mouseInit: function() {
9272		var that = this;
9273
9274		this.element
9275			.on( "mousedown." + this.widgetName, function( event ) {
9276				return that._mouseDown( event );
9277			} )
9278			.on( "click." + this.widgetName, function( event ) {
9279				if ( true === $.data( event.target, that.widgetName + ".preventClickEvent" ) ) {
9280					$.removeData( event.target, that.widgetName + ".preventClickEvent" );
9281					event.stopImmediatePropagation();
9282					return false;
9283				}
9284			} );
9285
9286		this.started = false;
9287	},
9288
9289	// TODO: make sure destroying one instance of mouse doesn't mess with
9290	// other instances of mouse
9291	_mouseDestroy: function() {
9292		this.element.off( "." + this.widgetName );
9293		if ( this._mouseMoveDelegate ) {
9294			this.document
9295				.off( "mousemove." + this.widgetName, this._mouseMoveDelegate )
9296				.off( "mouseup." + this.widgetName, this._mouseUpDelegate );
9297		}
9298	},
9299
9300	_mouseDown: function( event ) {
9301
9302		// don't let more than one widget handle mouseStart
9303		if ( mouseHandled ) {
9304			return;
9305		}
9306
9307		this._mouseMoved = false;
9308
9309		// We may have missed mouseup (out of window)
9310		( this._mouseStarted && this._mouseUp( event ) );
9311
9312		this._mouseDownEvent = event;
9313
9314		var that = this,
9315			btnIsLeft = ( event.which === 1 ),
9316
9317			// event.target.nodeName works around a bug in IE 8 with
9318			// disabled inputs (#7620)
9319			elIsCancel = ( typeof this.options.cancel === "string" && event.target.nodeName ?
9320				$( event.target ).closest( this.options.cancel ).length : false );
9321		if ( !btnIsLeft || elIsCancel || !this._mouseCapture( event ) ) {
9322			return true;
9323		}
9324
9325		this.mouseDelayMet = !this.options.delay;
9326		if ( !this.mouseDelayMet ) {
9327			this._mouseDelayTimer = setTimeout( function() {
9328				that.mouseDelayMet = true;
9329			}, this.options.delay );
9330		}
9331
9332		if ( this._mouseDistanceMet( event ) && this._mouseDelayMet( event ) ) {
9333			this._mouseStarted = ( this._mouseStart( event ) !== false );
9334			if ( !this._mouseStarted ) {
9335				event.preventDefault();
9336				return true;
9337			}
9338		}
9339
9340		// Click event may never have fired (Gecko & Opera)
9341		if ( true === $.data( event.target, this.widgetName + ".preventClickEvent" ) ) {
9342			$.removeData( event.target, this.widgetName + ".preventClickEvent" );
9343		}
9344
9345		// These delegates are required to keep context
9346		this._mouseMoveDelegate = function( event ) {
9347			return that._mouseMove( event );
9348		};
9349		this._mouseUpDelegate = function( event ) {
9350			return that._mouseUp( event );
9351		};
9352
9353		this.document
9354			.on( "mousemove." + this.widgetName, this._mouseMoveDelegate )
9355			.on( "mouseup." + this.widgetName, this._mouseUpDelegate );
9356
9357		event.preventDefault();
9358
9359		mouseHandled = true;
9360		return true;
9361	},
9362
9363	_mouseMove: function( event ) {
9364
9365		// Only check for mouseups outside the document if you've moved inside the document
9366		// at least once. This prevents the firing of mouseup in the case of IE<9, which will
9367		// fire a mousemove event if content is placed under the cursor. See #7778
9368		// Support: IE <9
9369		if ( this._mouseMoved ) {
9370
9371			// IE mouseup check - mouseup happened when mouse was out of window
9372			if ( $.ui.ie && ( !document.documentMode || document.documentMode < 9 ) &&
9373					!event.button ) {
9374				return this._mouseUp( event );
9375
9376			// Iframe mouseup check - mouseup occurred in another document
9377			} else if ( !event.which ) {
9378
9379				// Support: Safari <=8 - 9
9380				// Safari sets which to 0 if you press any of the following keys
9381				// during a drag (#14461)
9382				if ( event.originalEvent.altKey || event.originalEvent.ctrlKey ||
9383						event.originalEvent.metaKey || event.originalEvent.shiftKey ) {
9384					this.ignoreMissingWhich = true;
9385				} else if ( !this.ignoreMissingWhich ) {
9386					return this._mouseUp( event );
9387				}
9388			}
9389		}
9390
9391		if ( event.which || event.button ) {
9392			this._mouseMoved = true;
9393		}
9394
9395		if ( this._mouseStarted ) {
9396			this._mouseDrag( event );
9397			return event.preventDefault();
9398		}
9399
9400		if ( this._mouseDistanceMet( event ) && this._mouseDelayMet( event ) ) {
9401			this._mouseStarted =
9402				( this._mouseStart( this._mouseDownEvent, event ) !== false );
9403			( this._mouseStarted ? this._mouseDrag( event ) : this._mouseUp( event ) );
9404		}
9405
9406		return !this._mouseStarted;
9407	},
9408
9409	_mouseUp: function( event ) {
9410		this.document
9411			.off( "mousemove." + this.widgetName, this._mouseMoveDelegate )
9412			.off( "mouseup." + this.widgetName, this._mouseUpDelegate );
9413
9414		if ( this._mouseStarted ) {
9415			this._mouseStarted = false;
9416
9417			if ( event.target === this._mouseDownEvent.target ) {
9418				$.data( event.target, this.widgetName + ".preventClickEvent", true );
9419			}
9420
9421			this._mouseStop( event );
9422		}
9423
9424		if ( this._mouseDelayTimer ) {
9425			clearTimeout( this._mouseDelayTimer );
9426			delete this._mouseDelayTimer;
9427		}
9428
9429		this.ignoreMissingWhich = false;
9430		mouseHandled = false;
9431		event.preventDefault();
9432	},
9433
9434	_mouseDistanceMet: function( event ) {
9435		return ( Math.max(
9436				Math.abs( this._mouseDownEvent.pageX - event.pageX ),
9437				Math.abs( this._mouseDownEvent.pageY - event.pageY )
9438			) >= this.options.distance
9439		);
9440	},
9441
9442	_mouseDelayMet: function( /* event */ ) {
9443		return this.mouseDelayMet;
9444	},
9445
9446	// These are placeholder methods, to be overriden by extending plugin
9447	_mouseStart: function( /* event */ ) {},
9448	_mouseDrag: function( /* event */ ) {},
9449	_mouseStop: function( /* event */ ) {},
9450	_mouseCapture: function( /* event */ ) { return true; }
9451} );
9452
9453
9454
9455
9456// $.ui.plugin is deprecated. Use $.widget() extensions instead.
9457var plugin = $.ui.plugin = {
9458	add: function( module, option, set ) {
9459		var i,
9460			proto = $.ui[ module ].prototype;
9461		for ( i in set ) {
9462			proto.plugins[ i ] = proto.plugins[ i ] || [];
9463			proto.plugins[ i ].push( [ option, set[ i ] ] );
9464		}
9465	},
9466	call: function( instance, name, args, allowDisconnected ) {
9467		var i,
9468			set = instance.plugins[ name ];
9469
9470		if ( !set ) {
9471			return;
9472		}
9473
9474		if ( !allowDisconnected && ( !instance.element[ 0 ].parentNode ||
9475				instance.element[ 0 ].parentNode.nodeType === 11 ) ) {
9476			return;
9477		}
9478
9479		for ( i = 0; i < set.length; i++ ) {
9480			if ( instance.options[ set[ i ][ 0 ] ] ) {
9481				set[ i ][ 1 ].apply( instance.element, args );
9482			}
9483		}
9484	}
9485};
9486
9487
9488
9489var safeBlur = $.ui.safeBlur = function( element ) {
9490
9491	// Support: IE9 - 10 only
9492	// If the <body> is blurred, IE will switch windows, see #9420
9493	if ( element && element.nodeName.toLowerCase() !== "body" ) {
9494		$( element ).trigger( "blur" );
9495	}
9496};
9497
9498
9499/*!
9500 * jQuery UI Draggable 1.12.1
9501 * http://jqueryui.com
9502 *
9503 * Copyright jQuery Foundation and other contributors
9504 * Released under the MIT license.
9505 * http://jquery.org/license
9506 */
9507
9508//>>label: Draggable
9509//>>group: Interactions
9510//>>description: Enables dragging functionality for any element.
9511//>>docs: http://api.jqueryui.com/draggable/
9512//>>demos: http://jqueryui.com/draggable/
9513//>>css.structure: ../../themes/base/draggable.css
9514
9515
9516
9517$.widget( "ui.draggable", $.ui.mouse, {
9518	version: "1.12.1",
9519	widgetEventPrefix: "drag",
9520	options: {
9521		addClasses: true,
9522		appendTo: "parent",
9523		axis: false,
9524		connectToSortable: false,
9525		containment: false,
9526		cursor: "auto",
9527		cursorAt: false,
9528		grid: false,
9529		handle: false,
9530		helper: "original",
9531		iframeFix: false,
9532		opacity: false,
9533		refreshPositions: false,
9534		revert: false,
9535		revertDuration: 500,
9536		scope: "default",
9537		scroll: true,
9538		scrollSensitivity: 20,
9539		scrollSpeed: 20,
9540		snap: false,
9541		snapMode: "both",
9542		snapTolerance: 20,
9543		stack: false,
9544		zIndex: false,
9545
9546		// Callbacks
9547		drag: null,
9548		start: null,
9549		stop: null
9550	},
9551	_create: function() {
9552
9553		if ( this.options.helper === "original" ) {
9554			this._setPositionRelative();
9555		}
9556		if ( this.options.addClasses ) {
9557			this._addClass( "ui-draggable" );
9558		}
9559		this._setHandleClassName();
9560
9561		this._mouseInit();
9562	},
9563
9564	_setOption: function( key, value ) {
9565		this._super( key, value );
9566		if ( key === "handle" ) {
9567			this._removeHandleClassName();
9568			this._setHandleClassName();
9569		}
9570	},
9571
9572	_destroy: function() {
9573		if ( ( this.helper || this.element ).is( ".ui-draggable-dragging" ) ) {
9574			this.destroyOnClear = true;
9575			return;
9576		}
9577		this._removeHandleClassName();
9578		this._mouseDestroy();
9579	},
9580
9581	_mouseCapture: function( event ) {
9582		var o = this.options;
9583
9584		// Among others, prevent a drag on a resizable-handle
9585		if ( this.helper || o.disabled ||
9586				$( event.target ).closest( ".ui-resizable-handle" ).length > 0 ) {
9587			return false;
9588		}
9589
9590		//Quit if we're not on a valid handle
9591		this.handle = this._getHandle( event );
9592		if ( !this.handle ) {
9593			return false;
9594		}
9595
9596		this._blurActiveElement( event );
9597
9598		this._blockFrames( o.iframeFix === true ? "iframe" : o.iframeFix );
9599
9600		return true;
9601
9602	},
9603
9604	_blockFrames: function( selector ) {
9605		this.iframeBlocks = this.document.find( selector ).map( function() {
9606			var iframe = $( this );
9607
9608			return $( "<div>" )
9609				.css( "position", "absolute" )
9610				.appendTo( iframe.parent() )
9611				.outerWidth( iframe.outerWidth() )
9612				.outerHeight( iframe.outerHeight() )
9613				.offset( iframe.offset() )[ 0 ];
9614		} );
9615	},
9616
9617	_unblockFrames: function() {
9618		if ( this.iframeBlocks ) {
9619			this.iframeBlocks.remove();
9620			delete this.iframeBlocks;
9621		}
9622	},
9623
9624	_blurActiveElement: function( event ) {
9625		var activeElement = $.ui.safeActiveElement( this.document[ 0 ] ),
9626			target = $( event.target );
9627
9628		// Don't blur if the event occurred on an element that is within
9629		// the currently focused element
9630		// See #10527, #12472
9631		if ( target.closest( activeElement ).length ) {
9632			return;
9633		}
9634
9635		// Blur any element that currently has focus, see #4261
9636		$.ui.safeBlur( activeElement );
9637	},
9638
9639	_mouseStart: function( event ) {
9640
9641		var o = this.options;
9642
9643		//Create and append the visible helper
9644		this.helper = this._createHelper( event );
9645
9646		this._addClass( this.helper, "ui-draggable-dragging" );
9647
9648		//Cache the helper size
9649		this._cacheHelperProportions();
9650
9651		//If ddmanager is used for droppables, set the global draggable
9652		if ( $.ui.ddmanager ) {
9653			$.ui.ddmanager.current = this;
9654		}
9655
9656		/*
9657		 * - Position generation -
9658		 * This block generates everything position related - it's the core of draggables.
9659		 */
9660
9661		//Cache the margins of the original element
9662		this._cacheMargins();
9663
9664		//Store the helper's css position
9665		this.cssPosition = this.helper.css( "position" );
9666		this.scrollParent = this.helper.scrollParent( true );
9667		this.offsetParent = this.helper.offsetParent();
9668		this.hasFixedAncestor = this.helper.parents().filter( function() {
9669				return $( this ).css( "position" ) === "fixed";
9670			} ).length > 0;
9671
9672		//The element's absolute position on the page minus margins
9673		this.positionAbs = this.element.offset();
9674		this._refreshOffsets( event );
9675
9676		//Generate the original position
9677		this.originalPosition = this.position = this._generatePosition( event, false );
9678		this.originalPageX = event.pageX;
9679		this.originalPageY = event.pageY;
9680
9681		//Adjust the mouse offset relative to the helper if "cursorAt" is supplied
9682		( o.cursorAt && this._adjustOffsetFromHelper( o.cursorAt ) );
9683
9684		//Set a containment if given in the options
9685		this._setContainment();
9686
9687		//Trigger event + callbacks
9688		if ( this._trigger( "start", event ) === false ) {
9689			this._clear();
9690			return false;
9691		}
9692
9693		//Recache the helper size
9694		this._cacheHelperProportions();
9695
9696		//Prepare the droppable offsets
9697		if ( $.ui.ddmanager && !o.dropBehaviour ) {
9698			$.ui.ddmanager.prepareOffsets( this, event );
9699		}
9700
9701		// Execute the drag once - this causes the helper not to be visible before getting its
9702		// correct position
9703		this._mouseDrag( event, true );
9704
9705		// If the ddmanager is used for droppables, inform the manager that dragging has started
9706		// (see #5003)
9707		if ( $.ui.ddmanager ) {
9708			$.ui.ddmanager.dragStart( this, event );
9709		}
9710
9711		return true;
9712	},
9713
9714	_refreshOffsets: function( event ) {
9715		this.offset = {
9716			top: this.positionAbs.top - this.margins.top,
9717			left: this.positionAbs.left - this.margins.left,
9718			scroll: false,
9719			parent: this._getParentOffset(),
9720			relative: this._getRelativeOffset()
9721		};
9722
9723		this.offset.click = {
9724			left: event.pageX - this.offset.left,
9725			top: event.pageY - this.offset.top
9726		};
9727	},
9728
9729	_mouseDrag: function( event, noPropagation ) {
9730
9731		// reset any necessary cached properties (see #5009)
9732		if ( this.hasFixedAncestor ) {
9733			this.offset.parent = this._getParentOffset();
9734		}
9735
9736		//Compute the helpers position
9737		this.position = this._generatePosition( event, true );
9738		this.positionAbs = this._convertPositionTo( "absolute" );
9739
9740		//Call plugins and callbacks and use the resulting position if something is returned
9741		if ( !noPropagation ) {
9742			var ui = this._uiHash();
9743			if ( this._trigger( "drag", event, ui ) === false ) {
9744				this._mouseUp( new $.Event( "mouseup", event ) );
9745				return false;
9746			}
9747			this.position = ui.position;
9748		}
9749
9750		this.helper[ 0 ].style.left = this.position.left + "px";
9751		this.helper[ 0 ].style.top = this.position.top + "px";
9752
9753		if ( $.ui.ddmanager ) {
9754			$.ui.ddmanager.drag( this, event );
9755		}
9756
9757		return false;
9758	},
9759
9760	_mouseStop: function( event ) {
9761
9762		//If we are using droppables, inform the manager about the drop
9763		var that = this,
9764			dropped = false;
9765		if ( $.ui.ddmanager && !this.options.dropBehaviour ) {
9766			dropped = $.ui.ddmanager.drop( this, event );
9767		}
9768
9769		//if a drop comes from outside (a sortable)
9770		if ( this.dropped ) {
9771			dropped = this.dropped;
9772			this.dropped = false;
9773		}
9774
9775		if ( ( this.options.revert === "invalid" && !dropped ) ||
9776				( this.options.revert === "valid" && dropped ) ||
9777				this.options.revert === true || ( $.isFunction( this.options.revert ) &&
9778				this.options.revert.call( this.element, dropped ) )
9779		) {
9780			$( this.helper ).animate(
9781				this.originalPosition,
9782				parseInt( this.options.revertDuration, 10 ),
9783				function() {
9784					if ( that._trigger( "stop", event ) !== false ) {
9785						that._clear();
9786					}
9787				}
9788			);
9789		} else {
9790			if ( this._trigger( "stop", event ) !== false ) {
9791				this._clear();
9792			}
9793		}
9794
9795		return false;
9796	},
9797
9798	_mouseUp: function( event ) {
9799		this._unblockFrames();
9800
9801		// If the ddmanager is used for droppables, inform the manager that dragging has stopped
9802		// (see #5003)
9803		if ( $.ui.ddmanager ) {
9804			$.ui.ddmanager.dragStop( this, event );
9805		}
9806
9807		// Only need to focus if the event occurred on the draggable itself, see #10527
9808		if ( this.handleElement.is( event.target ) ) {
9809
9810			// The interaction is over; whether or not the click resulted in a drag,
9811			// focus the element
9812			this.element.trigger( "focus" );
9813		}
9814
9815		return $.ui.mouse.prototype._mouseUp.call( this, event );
9816	},
9817
9818	cancel: function() {
9819
9820		if ( this.helper.is( ".ui-draggable-dragging" ) ) {
9821			this._mouseUp( new $.Event( "mouseup", { target: this.element[ 0 ] } ) );
9822		} else {
9823			this._clear();
9824		}
9825
9826		return this;
9827
9828	},
9829
9830	_getHandle: function( event ) {
9831		return this.options.handle ?
9832			!!$( event.target ).closest( this.element.find( this.options.handle ) ).length :
9833			true;
9834	},
9835
9836	_setHandleClassName: function() {
9837		this.handleElement = this.options.handle ?
9838			this.element.find( this.options.handle ) : this.element;
9839		this._addClass( this.handleElement, "ui-draggable-handle" );
9840	},
9841
9842	_removeHandleClassName: function() {
9843		this._removeClass( this.handleElement, "ui-draggable-handle" );
9844	},
9845
9846	_createHelper: function( event ) {
9847
9848		var o = this.options,
9849			helperIsFunction = $.isFunction( o.helper ),
9850			helper = helperIsFunction ?
9851				$( o.helper.apply( this.element[ 0 ], [ event ] ) ) :
9852				( o.helper === "clone" ?
9853					this.element.clone().removeAttr( "id" ) :
9854					this.element );
9855
9856		if ( !helper.parents( "body" ).length ) {
9857			helper.appendTo( ( o.appendTo === "parent" ?
9858				this.element[ 0 ].parentNode :
9859				o.appendTo ) );
9860		}
9861
9862		// Http://bugs.jqueryui.com/ticket/9446
9863		// a helper function can return the original element
9864		// which wouldn't have been set to relative in _create
9865		if ( helperIsFunction && helper[ 0 ] === this.element[ 0 ] ) {
9866			this._setPositionRelative();
9867		}
9868
9869		if ( helper[ 0 ] !== this.element[ 0 ] &&
9870				!( /(fixed|absolute)/ ).test( helper.css( "position" ) ) ) {
9871			helper.css( "position", "absolute" );
9872		}
9873
9874		return helper;
9875
9876	},
9877
9878	_setPositionRelative: function() {
9879		if ( !( /^(?:r|a|f)/ ).test( this.element.css( "position" ) ) ) {
9880			this.element[ 0 ].style.position = "relative";
9881		}
9882	},
9883
9884	_adjustOffsetFromHelper: function( obj ) {
9885		if ( typeof obj === "string" ) {
9886			obj = obj.split( " " );
9887		}
9888		if ( $.isArray( obj ) ) {
9889			obj = { left: +obj[ 0 ], top: +obj[ 1 ] || 0 };
9890		}
9891		if ( "left" in obj ) {
9892			this.offset.click.left = obj.left + this.margins.left;
9893		}
9894		if ( "right" in obj ) {
9895			this.offset.click.left = this.helperProportions.width - obj.right + this.margins.left;
9896		}
9897		if ( "top" in obj ) {
9898			this.offset.click.top = obj.top + this.margins.top;
9899		}
9900		if ( "bottom" in obj ) {
9901			this.offset.click.top = this.helperProportions.height - obj.bottom + this.margins.top;
9902		}
9903	},
9904
9905	_isRootNode: function( element ) {
9906		return ( /(html|body)/i ).test( element.tagName ) || element === this.document[ 0 ];
9907	},
9908
9909	_getParentOffset: function() {
9910
9911		//Get the offsetParent and cache its position
9912		var po = this.offsetParent.offset(),
9913			document = this.document[ 0 ];
9914
9915		// This is a special case where we need to modify a offset calculated on start, since the
9916		// following happened:
9917		// 1. The position of the helper is absolute, so it's position is calculated based on the
9918		// next positioned parent
9919		// 2. The actual offset parent is a child of the scroll parent, and the scroll parent isn't
9920		// the document, which means that the scroll is included in the initial calculation of the
9921		// offset of the parent, and never recalculated upon drag
9922		if ( this.cssPosition === "absolute" && this.scrollParent[ 0 ] !== document &&
9923				$.contains( this.scrollParent[ 0 ], this.offsetParent[ 0 ] ) ) {
9924			po.left += this.scrollParent.scrollLeft();
9925			po.top += this.scrollParent.scrollTop();
9926		}
9927
vendor: 13,156 bytes, lines 9928-10356
9928		if ( this._isRootNode( this.offsetParent[ 0 ] ) ) {
9929			po = { top: 0, left: 0 };
9930		}
9931
9932		return {
9933			top: po.top + ( parseInt( this.offsetParent.css( "borderTopWidth" ), 10 ) || 0 ),
9934			left: po.left + ( parseInt( this.offsetParent.css( "borderLeftWidth" ), 10 ) || 0 )
9935		};
9936
9937	},
9938
9939	_getRelativeOffset: function() {
9940		if ( this.cssPosition !== "relative" ) {
9941			return { top: 0, left: 0 };
9942		}
9943
9944		var p = this.element.position(),
9945			scrollIsRootNode = this._isRootNode( this.scrollParent[ 0 ] );
9946
9947		return {
9948			top: p.top - ( parseInt( this.helper.css( "top" ), 10 ) || 0 ) +
9949				( !scrollIsRootNode ? this.scrollParent.scrollTop() : 0 ),
9950			left: p.left - ( parseInt( this.helper.css( "left" ), 10 ) || 0 ) +
9951				( !scrollIsRootNode ? this.scrollParent.scrollLeft() : 0 )
9952		};
9953
9954	},
9955
9956	_cacheMargins: function() {
9957		this.margins = {
9958			left: ( parseInt( this.element.css( "marginLeft" ), 10 ) || 0 ),
9959			top: ( parseInt( this.element.css( "marginTop" ), 10 ) || 0 ),
9960			right: ( parseInt( this.element.css( "marginRight" ), 10 ) || 0 ),
9961			bottom: ( parseInt( this.element.css( "marginBottom" ), 10 ) || 0 )
9962		};
9963	},
9964
9965	_cacheHelperProportions: function() {
9966		this.helperProportions = {
9967			width: this.helper.outerWidth(),
9968			height: this.helper.outerHeight()
9969		};
9970	},
9971
9972	_setContainment: function() {
9973
9974		var isUserScrollable, c, ce,
9975			o = this.options,
9976			document = this.document[ 0 ];
9977
9978		this.relativeContainer = null;
9979
9980		if ( !o.containment ) {
9981			this.containment = null;
9982			return;
9983		}
9984
9985		if ( o.containment === "window" ) {
9986			this.containment = [
9987				$( window ).scrollLeft() - this.offset.relative.left - this.offset.parent.left,
9988				$( window ).scrollTop() - this.offset.relative.top - this.offset.parent.top,
9989				$( window ).scrollLeft() + $( window ).width() -
9990					this.helperProportions.width - this.margins.left,
9991				$( window ).scrollTop() +
9992					( $( window ).height() || document.body.parentNode.scrollHeight ) -
9993					this.helperProportions.height - this.margins.top
9994			];
9995			return;
9996		}
9997
9998		if ( o.containment === "document" ) {
9999			this.containment = [
10000				0,
10001				0,
10002				$( document ).width() - this.helperProportions.width - this.margins.left,
10003				( $( document ).height() || document.body.parentNode.scrollHeight ) -
10004					this.helperProportions.height - this.margins.top
10005			];
10006			return;
10007		}
10008
10009		if ( o.containment.constructor === Array ) {
10010			this.containment = o.containment;
10011			return;
10012		}
10013
10014		if ( o.containment === "parent" ) {
10015			o.containment = this.helper[ 0 ].parentNode;
10016		}
10017
10018		c = $( o.containment );
10019		ce = c[ 0 ];
10020
10021		if ( !ce ) {
10022			return;
10023		}
10024
10025		isUserScrollable = /(scroll|auto)/.test( c.css( "overflow" ) );
10026
10027		this.containment = [
10028			( parseInt( c.css( "borderLeftWidth" ), 10 ) || 0 ) +
10029				( parseInt( c.css( "paddingLeft" ), 10 ) || 0 ),
10030			( parseInt( c.css( "borderTopWidth" ), 10 ) || 0 ) +
10031				( parseInt( c.css( "paddingTop" ), 10 ) || 0 ),
10032			( isUserScrollable ? Math.max( ce.scrollWidth, ce.offsetWidth ) : ce.offsetWidth ) -
10033				( parseInt( c.css( "borderRightWidth" ), 10 ) || 0 ) -
10034				( parseInt( c.css( "paddingRight" ), 10 ) || 0 ) -
10035				this.helperProportions.width -
10036				this.margins.left -
10037				this.margins.right,
10038			( isUserScrollable ? Math.max( ce.scrollHeight, ce.offsetHeight ) : ce.offsetHeight ) -
10039				( parseInt( c.css( "borderBottomWidth" ), 10 ) || 0 ) -
10040				( parseInt( c.css( "paddingBottom" ), 10 ) || 0 ) -
10041				this.helperProportions.height -
10042				this.margins.top -
10043				this.margins.bottom
10044		];
10045		this.relativeContainer = c;
10046	},
10047
10048	_convertPositionTo: function( d, pos ) {
10049
10050		if ( !pos ) {
10051			pos = this.position;
10052		}
10053
10054		var mod = d === "absolute" ? 1 : -1,
10055			scrollIsRootNode = this._isRootNode( this.scrollParent[ 0 ] );
10056
10057		return {
10058			top: (
10059
10060				// The absolute mouse position
10061				pos.top	+
10062
10063				// Only for relative positioned nodes: Relative offset from element to offset parent
10064				this.offset.relative.top * mod +
10065
10066				// The offsetParent's offset without borders (offset + border)
10067				this.offset.parent.top * mod -
10068				( ( this.cssPosition === "fixed" ?
10069					-this.offset.scroll.top :
10070					( scrollIsRootNode ? 0 : this.offset.scroll.top ) ) * mod )
10071			),
10072			left: (
10073
10074				// The absolute mouse position
10075				pos.left +
10076
10077				// Only for relative positioned nodes: Relative offset from element to offset parent
10078				this.offset.relative.left * mod +
10079
10080				// The offsetParent's offset without borders (offset + border)
10081				this.offset.parent.left * mod	-
10082				( ( this.cssPosition === "fixed" ?
10083					-this.offset.scroll.left :
10084					( scrollIsRootNode ? 0 : this.offset.scroll.left ) ) * mod )
10085			)
10086		};
10087
10088	},
10089
10090	_generatePosition: function( event, constrainPosition ) {
10091
10092		var containment, co, top, left,
10093			o = this.options,
10094			scrollIsRootNode = this._isRootNode( this.scrollParent[ 0 ] ),
10095			pageX = event.pageX,
10096			pageY = event.pageY;
10097
10098		// Cache the scroll
10099		if ( !scrollIsRootNode || !this.offset.scroll ) {
10100			this.offset.scroll = {
10101				top: this.scrollParent.scrollTop(),
10102				left: this.scrollParent.scrollLeft()
10103			};
10104		}
10105
10106		/*
10107		 * - Position constraining -
10108		 * Constrain the position to a mix of grid, containment.
10109		 */
10110
10111		// If we are not dragging yet, we won't check for options
10112		if ( constrainPosition ) {
10113			if ( this.containment ) {
10114				if ( this.relativeContainer ) {
10115					co = this.relativeContainer.offset();
10116					containment = [
10117						this.containment[ 0 ] + co.left,
10118						this.containment[ 1 ] + co.top,
10119						this.containment[ 2 ] + co.left,
10120						this.containment[ 3 ] + co.top
10121					];
10122				} else {
10123					containment = this.containment;
10124				}
10125
10126				if ( event.pageX - this.offset.click.left < containment[ 0 ] ) {
10127					pageX = containment[ 0 ] + this.offset.click.left;
10128				}
10129				if ( event.pageY - this.offset.click.top < containment[ 1 ] ) {
10130					pageY = containment[ 1 ] + this.offset.click.top;
10131				}
10132				if ( event.pageX - this.offset.click.left > containment[ 2 ] ) {
10133					pageX = containment[ 2 ] + this.offset.click.left;
10134				}
10135				if ( event.pageY - this.offset.click.top > containment[ 3 ] ) {
10136					pageY = containment[ 3 ] + this.offset.click.top;
10137				}
10138			}
10139
10140			if ( o.grid ) {
10141
10142				//Check for grid elements set to 0 to prevent divide by 0 error causing invalid
10143				// argument errors in IE (see ticket #6950)
10144				top = o.grid[ 1 ] ? this.originalPageY + Math.round( ( pageY -
10145					this.originalPageY ) / o.grid[ 1 ] ) * o.grid[ 1 ] : this.originalPageY;
10146				pageY = containment ? ( ( top - this.offset.click.top >= containment[ 1 ] ||
10147					top - this.offset.click.top > containment[ 3 ] ) ?
10148						top :
10149						( ( top - this.offset.click.top >= containment[ 1 ] ) ?
10150							top - o.grid[ 1 ] : top + o.grid[ 1 ] ) ) : top;
10151
10152				left = o.grid[ 0 ] ? this.originalPageX +
10153					Math.round( ( pageX - this.originalPageX ) / o.grid[ 0 ] ) * o.grid[ 0 ] :
10154					this.originalPageX;
10155				pageX = containment ? ( ( left - this.offset.click.left >= containment[ 0 ] ||
10156					left - this.offset.click.left > containment[ 2 ] ) ?
10157						left :
10158						( ( left - this.offset.click.left >= containment[ 0 ] ) ?
10159							left - o.grid[ 0 ] : left + o.grid[ 0 ] ) ) : left;
10160			}
10161
10162			if ( o.axis === "y" ) {
10163				pageX = this.originalPageX;
10164			}
10165
10166			if ( o.axis === "x" ) {
10167				pageY = this.originalPageY;
10168			}
10169		}
10170
10171		return {
10172			top: (
10173
10174				// The absolute mouse position
10175				pageY -
10176
10177				// Click offset (relative to the element)
10178				this.offset.click.top -
10179
10180				// Only for relative positioned nodes: Relative offset from element to offset parent
10181				this.offset.relative.top -
10182
10183				// The offsetParent's offset without borders (offset + border)
10184				this.offset.parent.top +
10185				( this.cssPosition === "fixed" ?
10186					-this.offset.scroll.top :
10187					( scrollIsRootNode ? 0 : this.offset.scroll.top ) )
10188			),
10189			left: (
10190
10191				// The absolute mouse position
10192				pageX -
10193
10194				// Click offset (relative to the element)
10195				this.offset.click.left -
10196
10197				// Only for relative positioned nodes: Relative offset from element to offset parent
10198				this.offset.relative.left -
10199
10200				// The offsetParent's offset without borders (offset + border)
10201				this.offset.parent.left +
10202				( this.cssPosition === "fixed" ?
10203					-this.offset.scroll.left :
10204					( scrollIsRootNode ? 0 : this.offset.scroll.left ) )
10205			)
10206		};
10207
10208	},
10209
10210	_clear: function() {
10211		this._removeClass( this.helper, "ui-draggable-dragging" );
10212		if ( this.helper[ 0 ] !== this.element[ 0 ] && !this.cancelHelperRemoval ) {
10213			this.helper.remove();
10214		}
10215		this.helper = null;
10216		this.cancelHelperRemoval = false;
10217		if ( this.destroyOnClear ) {
10218			this.destroy();
10219		}
10220	},
10221
10222	// From now on bulk stuff - mainly helpers
10223
10224	_trigger: function( type, event, ui ) {
10225		ui = ui || this._uiHash();
10226		$.ui.plugin.call( this, type, [ event, ui, this ], true );
10227
10228		// Absolute position and offset (see #6884 ) have to be recalculated after plugins
10229		if ( /^(drag|start|stop)/.test( type ) ) {
10230			this.positionAbs = this._convertPositionTo( "absolute" );
10231			ui.offset = this.positionAbs;
10232		}
10233		return $.Widget.prototype._trigger.call( this, type, event, ui );
10234	},
10235
10236	plugins: {},
10237
10238	_uiHash: function() {
10239		return {
10240			helper: this.helper,
10241			position: this.position,
10242			originalPosition: this.originalPosition,
10243			offset: this.positionAbs
10244		};
10245	}
10246
10247} );
10248
10249$.ui.plugin.add( "draggable", "connectToSortable", {
10250	start: function( event, ui, draggable ) {
10251		var uiSortable = $.extend( {}, ui, {
10252			item: draggable.element
10253		} );
10254
10255		draggable.sortables = [];
10256		$( draggable.options.connectToSortable ).each( function() {
10257			var sortable = $( this ).sortable( "instance" );
10258
10259			if ( sortable && !sortable.options.disabled ) {
10260				draggable.sortables.push( sortable );
10261
10262				// RefreshPositions is called at drag start to refresh the containerCache
10263				// which is used in drag. This ensures it's initialized and synchronized
10264				// with any changes that might have happened on the page since initialization.
10265				sortable.refreshPositions();
10266				sortable._trigger( "activate", event, uiSortable );
10267			}
10268		} );
10269	},
10270	stop: function( event, ui, draggable ) {
10271		var uiSortable = $.extend( {}, ui, {
10272			item: draggable.element
10273		} );
10274
10275		draggable.cancelHelperRemoval = false;
10276
10277		$.each( draggable.sortables, function() {
10278			var sortable = this;
10279
10280			if ( sortable.isOver ) {
10281				sortable.isOver = 0;
10282
10283				// Allow this sortable to handle removing the helper
10284				draggable.cancelHelperRemoval = true;
10285				sortable.cancelHelperRemoval = false;
10286
10287				// Use _storedCSS To restore properties in the sortable,
10288				// as this also handles revert (#9675) since the draggable
10289				// may have modified them in unexpected ways (#8809)
10290				sortable._storedCSS = {
10291					position: sortable.placeholder.css( "position" ),
10292					top: sortable.placeholder.css( "top" ),
10293					left: sortable.placeholder.css( "left" )
10294				};
10295
10296				sortable._mouseStop( event );
10297
10298				// Once drag has ended, the sortable should return to using
10299				// its original helper, not the shared helper from draggable
10300				sortable.options.helper = sortable.options._helper;
10301			} else {
10302
10303				// Prevent this Sortable from removing the helper.
10304				// However, don't set the draggable to remove the helper
10305				// either as another connected Sortable may yet handle the removal.
10306				sortable.cancelHelperRemoval = true;
10307
10308				sortable._trigger( "deactivate", event, uiSortable );
10309			}
10310		} );
10311	},
10312	drag: function( event, ui, draggable ) {
10313		$.each( draggable.sortables, function() {
10314			var innermostIntersecting = false,
10315				sortable = this;
10316
10317			// Copy over variables that sortable's _intersectsWith uses
10318			sortable.positionAbs = draggable.positionAbs;
10319			sortable.helperProportions = draggable.helperProportions;
10320			sortable.offset.click = draggable.offset.click;
10321
10322			if ( sortable._intersectsWith( sortable.containerCache ) ) {
10323				innermostIntersecting = true;
10324
10325				$.each( draggable.sortables, function() {
10326
10327					// Copy over variables that sortable's _intersectsWith uses
10328					this.positionAbs = draggable.positionAbs;
10329					this.helperProportions = draggable.helperProportions;
10330					this.offset.click = draggable.offset.click;
10331
10332					if ( this !== sortable &&
10333							this._intersectsWith( this.containerCache ) &&
10334							$.contains( sortable.element[ 0 ], this.element[ 0 ] ) ) {
10335						innermostIntersecting = false;
10336					}
10337
10338					return innermostIntersecting;
10339				} );
10340			}
10341
10342			if ( innermostIntersecting ) {
10343
10344				// If it intersects, we use a little isOver variable and set it once,
10345				// so that the move-in stuff gets fired only once.
10346				if ( !sortable.isOver ) {
10347					sortable.isOver = 1;
10348
10349					// Store draggable's parent in case we need to reappend to it later.
10350					draggable._parent = ui.helper.parent();
10351
10352					sortable.currentItem = ui.helper
10353						.appendTo( sortable.element )
10354						.data( "ui-sortable-item", true );
10355
10356					// Store helper option to later restore it
vendor: 11,429 bytes, lines 10357-10731
10357					sortable.options._helper = sortable.options.helper;
10358
10359					sortable.options.helper = function() {
10360						return ui.helper[ 0 ];
10361					};
10362
10363					// Fire the start events of the sortable with our passed browser event,
10364					// and our own helper (so it doesn't create a new one)
10365					event.target = sortable.currentItem[ 0 ];
10366					sortable._mouseCapture( event, true );
10367					sortable._mouseStart( event, true, true );
10368
10369					// Because the browser event is way off the new appended portlet,
10370					// modify necessary variables to reflect the changes
10371					sortable.offset.click.top = draggable.offset.click.top;
10372					sortable.offset.click.left = draggable.offset.click.left;
10373					sortable.offset.parent.left -= draggable.offset.parent.left -
10374						sortable.offset.parent.left;
10375					sortable.offset.parent.top -= draggable.offset.parent.top -
10376						sortable.offset.parent.top;
10377
10378					draggable._trigger( "toSortable", event );
10379
10380					// Inform draggable that the helper is in a valid drop zone,
10381					// used solely in the revert option to handle "valid/invalid".
10382					draggable.dropped = sortable.element;
10383
10384					// Need to refreshPositions of all sortables in the case that
10385					// adding to one sortable changes the location of the other sortables (#9675)
10386					$.each( draggable.sortables, function() {
10387						this.refreshPositions();
10388					} );
10389
10390					// Hack so receive/update callbacks work (mostly)
10391					draggable.currentItem = draggable.element;
10392					sortable.fromOutside = draggable;
10393				}
10394
10395				if ( sortable.currentItem ) {
10396					sortable._mouseDrag( event );
10397
10398					// Copy the sortable's position because the draggable's can potentially reflect
10399					// a relative position, while sortable is always absolute, which the dragged
10400					// element has now become. (#8809)
10401					ui.position = sortable.position;
10402				}
10403			} else {
10404
10405				// If it doesn't intersect with the sortable, and it intersected before,
10406				// we fake the drag stop of the sortable, but make sure it doesn't remove
10407				// the helper by using cancelHelperRemoval.
10408				if ( sortable.isOver ) {
10409
10410					sortable.isOver = 0;
10411					sortable.cancelHelperRemoval = true;
10412
10413					// Calling sortable's mouseStop would trigger a revert,
10414					// so revert must be temporarily false until after mouseStop is called.
10415					sortable.options._revert = sortable.options.revert;
10416					sortable.options.revert = false;
10417
10418					sortable._trigger( "out", event, sortable._uiHash( sortable ) );
10419					sortable._mouseStop( event, true );
10420
10421					// Restore sortable behaviors that were modfied
10422					// when the draggable entered the sortable area (#9481)
10423					sortable.options.revert = sortable.options._revert;
10424					sortable.options.helper = sortable.options._helper;
10425
10426					if ( sortable.placeholder ) {
10427						sortable.placeholder.remove();
10428					}
10429
10430					// Restore and recalculate the draggable's offset considering the sortable
10431					// may have modified them in unexpected ways. (#8809, #10669)
10432					ui.helper.appendTo( draggable._parent );
10433					draggable._refreshOffsets( event );
10434					ui.position = draggable._generatePosition( event, true );
10435
10436					draggable._trigger( "fromSortable", event );
10437
10438					// Inform draggable that the helper is no longer in a valid drop zone
10439					draggable.dropped = false;
10440
10441					// Need to refreshPositions of all sortables just in case removing
10442					// from one sortable changes the location of other sortables (#9675)
10443					$.each( draggable.sortables, function() {
10444						this.refreshPositions();
10445					} );
10446				}
10447			}
10448		} );
10449	}
10450} );
10451
10452$.ui.plugin.add( "draggable", "cursor", {
10453	start: function( event, ui, instance ) {
10454		var t = $( "body" ),
10455			o = instance.options;
10456
10457		if ( t.css( "cursor" ) ) {
10458			o._cursor = t.css( "cursor" );
10459		}
10460		t.css( "cursor", o.cursor );
10461	},
10462	stop: function( event, ui, instance ) {
10463		var o = instance.options;
10464		if ( o._cursor ) {
10465			$( "body" ).css( "cursor", o._cursor );
10466		}
10467	}
10468} );
10469
10470$.ui.plugin.add( "draggable", "opacity", {
10471	start: function( event, ui, instance ) {
10472		var t = $( ui.helper ),
10473			o = instance.options;
10474		if ( t.css( "opacity" ) ) {
10475			o._opacity = t.css( "opacity" );
10476		}
10477		t.css( "opacity", o.opacity );
10478	},
10479	stop: function( event, ui, instance ) {
10480		var o = instance.options;
10481		if ( o._opacity ) {
10482			$( ui.helper ).css( "opacity", o._opacity );
10483		}
10484	}
10485} );
10486
10487$.ui.plugin.add( "draggable", "scroll", {
10488	start: function( event, ui, i ) {
10489		if ( !i.scrollParentNotHidden ) {
10490			i.scrollParentNotHidden = i.helper.scrollParent( false );
10491		}
10492
10493		if ( i.scrollParentNotHidden[ 0 ] !== i.document[ 0 ] &&
10494				i.scrollParentNotHidden[ 0 ].tagName !== "HTML" ) {
10495			i.overflowOffset = i.scrollParentNotHidden.offset();
10496		}
10497	},
10498	drag: function( event, ui, i  ) {
10499
10500		var o = i.options,
10501			scrolled = false,
10502			scrollParent = i.scrollParentNotHidden[ 0 ],
10503			document = i.document[ 0 ];
10504
10505		if ( scrollParent !== document && scrollParent.tagName !== "HTML" ) {
10506			if ( !o.axis || o.axis !== "x" ) {
10507				if ( ( i.overflowOffset.top + scrollParent.offsetHeight ) - event.pageY <
10508						o.scrollSensitivity ) {
10509					scrollParent.scrollTop = scrolled = scrollParent.scrollTop + o.scrollSpeed;
10510				} else if ( event.pageY - i.overflowOffset.top < o.scrollSensitivity ) {
10511					scrollParent.scrollTop = scrolled = scrollParent.scrollTop - o.scrollSpeed;
10512				}
10513			}
10514
10515			if ( !o.axis || o.axis !== "y" ) {
10516				if ( ( i.overflowOffset.left + scrollParent.offsetWidth ) - event.pageX <
10517						o.scrollSensitivity ) {
10518					scrollParent.scrollLeft = scrolled = scrollParent.scrollLeft + o.scrollSpeed;
10519				} else if ( event.pageX - i.overflowOffset.left < o.scrollSensitivity ) {
10520					scrollParent.scrollLeft = scrolled = scrollParent.scrollLeft - o.scrollSpeed;
10521				}
10522			}
10523
10524		} else {
10525
10526			if ( !o.axis || o.axis !== "x" ) {
10527				if ( event.pageY - $( document ).scrollTop() < o.scrollSensitivity ) {
10528					scrolled = $( document ).scrollTop( $( document ).scrollTop() - o.scrollSpeed );
10529				} else if ( $( window ).height() - ( event.pageY - $( document ).scrollTop() ) <
10530						o.scrollSensitivity ) {
10531					scrolled = $( document ).scrollTop( $( document ).scrollTop() + o.scrollSpeed );
10532				}
10533			}
10534
10535			if ( !o.axis || o.axis !== "y" ) {
10536				if ( event.pageX - $( document ).scrollLeft() < o.scrollSensitivity ) {
10537					scrolled = $( document ).scrollLeft(
10538						$( document ).scrollLeft() - o.scrollSpeed
10539					);
10540				} else if ( $( window ).width() - ( event.pageX - $( document ).scrollLeft() ) <
10541						o.scrollSensitivity ) {
10542					scrolled = $( document ).scrollLeft(
10543						$( document ).scrollLeft() + o.scrollSpeed
10544					);
10545				}
10546			}
10547
10548		}
10549
10550		if ( scrolled !== false && $.ui.ddmanager && !o.dropBehaviour ) {
10551			$.ui.ddmanager.prepareOffsets( i, event );
10552		}
10553
10554	}
10555} );
10556
10557$.ui.plugin.add( "draggable", "snap", {
10558	start: function( event, ui, i ) {
10559
10560		var o = i.options;
10561
10562		i.snapElements = [];
10563
10564		$( o.snap.constructor !== String ? ( o.snap.items || ":data(ui-draggable)" ) : o.snap )
10565			.each( function() {
10566				var $t = $( this ),
10567					$o = $t.offset();
10568				if ( this !== i.element[ 0 ] ) {
10569					i.snapElements.push( {
10570						item: this,
10571						width: $t.outerWidth(), height: $t.outerHeight(),
10572						top: $o.top, left: $o.left
10573					} );
10574				}
10575			} );
10576
10577	},
10578	drag: function( event, ui, inst ) {
10579
10580		var ts, bs, ls, rs, l, r, t, b, i, first,
10581			o = inst.options,
10582			d = o.snapTolerance,
10583			x1 = ui.offset.left, x2 = x1 + inst.helperProportions.width,
10584			y1 = ui.offset.top, y2 = y1 + inst.helperProportions.height;
10585
10586		for ( i = inst.snapElements.length - 1; i >= 0; i-- ) {
10587
10588			l = inst.snapElements[ i ].left - inst.margins.left;
10589			r = l + inst.snapElements[ i ].width;
10590			t = inst.snapElements[ i ].top - inst.margins.top;
10591			b = t + inst.snapElements[ i ].height;
10592
10593			if ( x2 < l - d || x1 > r + d || y2 < t - d || y1 > b + d ||
10594					!$.contains( inst.snapElements[ i ].item.ownerDocument,
10595					inst.snapElements[ i ].item ) ) {
10596				if ( inst.snapElements[ i ].snapping ) {
10597					( inst.options.snap.release &&
10598						inst.options.snap.release.call(
10599							inst.element,
10600							event,
10601							$.extend( inst._uiHash(), { snapItem: inst.snapElements[ i ].item } )
10602						) );
10603				}
10604				inst.snapElements[ i ].snapping = false;
10605				continue;
10606			}
10607
10608			if ( o.snapMode !== "inner" ) {
10609				ts = Math.abs( t - y2 ) <= d;
10610				bs = Math.abs( b - y1 ) <= d;
10611				ls = Math.abs( l - x2 ) <= d;
10612				rs = Math.abs( r - x1 ) <= d;
10613				if ( ts ) {
10614					ui.position.top = inst._convertPositionTo( "relative", {
10615						top: t - inst.helperProportions.height,
10616						left: 0
10617					} ).top;
10618				}
10619				if ( bs ) {
10620					ui.position.top = inst._convertPositionTo( "relative", {
10621						top: b,
10622						left: 0
10623					} ).top;
10624				}
10625				if ( ls ) {
10626					ui.position.left = inst._convertPositionTo( "relative", {
10627						top: 0,
10628						left: l - inst.helperProportions.width
10629					} ).left;
10630				}
10631				if ( rs ) {
10632					ui.position.left = inst._convertPositionTo( "relative", {
10633						top: 0,
10634						left: r
10635					} ).left;
10636				}
10637			}
10638
10639			first = ( ts || bs || ls || rs );
10640
10641			if ( o.snapMode !== "outer" ) {
10642				ts = Math.abs( t - y1 ) <= d;
10643				bs = Math.abs( b - y2 ) <= d;
10644				ls = Math.abs( l - x1 ) <= d;
10645				rs = Math.abs( r - x2 ) <= d;
10646				if ( ts ) {
10647					ui.position.top = inst._convertPositionTo( "relative", {
10648						top: t,
10649						left: 0
10650					} ).top;
10651				}
10652				if ( bs ) {
10653					ui.position.top = inst._convertPositionTo( "relative", {
10654						top: b - inst.helperProportions.height,
10655						left: 0
10656					} ).top;
10657				}
10658				if ( ls ) {
10659					ui.position.left = inst._convertPositionTo( "relative", {
10660						top: 0,
10661						left: l
10662					} ).left;
10663				}
10664				if ( rs ) {
10665					ui.position.left = inst._convertPositionTo( "relative", {
10666						top: 0,
10667						left: r - inst.helperProportions.width
10668					} ).left;
10669				}
10670			}
10671
10672			if ( !inst.snapElements[ i ].snapping && ( ts || bs || ls || rs || first ) ) {
10673				( inst.options.snap.snap &&
10674					inst.options.snap.snap.call(
10675						inst.element,
10676						event,
10677						$.extend( inst._uiHash(), {
10678							snapItem: inst.snapElements[ i ].item
10679						} ) ) );
10680			}
10681			inst.snapElements[ i ].snapping = ( ts || bs || ls || rs || first );
10682
10683		}
10684
10685	}
10686} );
10687
10688$.ui.plugin.add( "draggable", "stack", {
10689	start: function( event, ui, instance ) {
10690		var min,
10691			o = instance.options,
10692			group = $.makeArray( $( o.stack ) ).sort( function( a, b ) {
10693				return ( parseInt( $( a ).css( "zIndex" ), 10 ) || 0 ) -
10694					( parseInt( $( b ).css( "zIndex" ), 10 ) || 0 );
10695			} );
10696
10697		if ( !group.length ) { return; }
10698
10699		min = parseInt( $( group[ 0 ] ).css( "zIndex" ), 10 ) || 0;
10700		$( group ).each( function( i ) {
10701			$( this ).css( "zIndex", min + i );
10702		} );
10703		this.css( "zIndex", ( min + group.length ) );
10704	}
10705} );
10706
10707$.ui.plugin.add( "draggable", "zIndex", {
10708	start: function( event, ui, instance ) {
10709		var t = $( ui.helper ),
10710			o = instance.options;
10711
10712		if ( t.css( "zIndex" ) ) {
10713			o._zIndex = t.css( "zIndex" );
10714		}
10715		t.css( "zIndex", o.zIndex );
10716	},
10717	stop: function( event, ui, instance ) {
10718		var o = instance.options;
10719
10720		if ( o._zIndex ) {
10721			$( ui.helper ).css( "zIndex", o._zIndex );
10722		}
10723	}
10724} );
10725
10726var widgetsDraggable = $.ui.draggable;
10727
10728
10729/*!
10730 * jQuery UI Resizable 1.12.1
10731 * http://jqueryui.com
vendor: 6,932 bytes, lines 10732-11010
10732 *
10733 * Copyright jQuery Foundation and other contributors
10734 * Released under the MIT license.
10735 * http://jquery.org/license
10736 */
10737
10738//>>label: Resizable
10739//>>group: Interactions
10740//>>description: Enables resize functionality for any element.
10741//>>docs: http://api.jqueryui.com/resizable/
10742//>>demos: http://jqueryui.com/resizable/
10743//>>css.structure: ../../themes/base/core.css
10744//>>css.structure: ../../themes/base/resizable.css
10745//>>css.theme: ../../themes/base/theme.css
10746
10747
10748
10749$.widget( "ui.resizable", $.ui.mouse, {
10750	version: "1.12.1",
10751	widgetEventPrefix: "resize",
10752	options: {
10753		alsoResize: false,
10754		animate: false,
10755		animateDuration: "slow",
10756		animateEasing: "swing",
10757		aspectRatio: false,
10758		autoHide: false,
10759		classes: {
10760			"ui-resizable-se": "ui-icon ui-icon-gripsmall-diagonal-se"
10761		},
10762		containment: false,
10763		ghost: false,
10764		grid: false,
10765		handles: "e,s,se",
10766		helper: false,
10767		maxHeight: null,
10768		maxWidth: null,
10769		minHeight: 10,
10770		minWidth: 10,
10771
10772		// See #7960
10773		zIndex: 90,
10774
10775		// Callbacks
10776		resize: null,
10777		start: null,
10778		stop: null
10779	},
10780
10781	_num: function( value ) {
10782		return parseFloat( value ) || 0;
10783	},
10784
10785	_isNumber: function( value ) {
10786		return !isNaN( parseFloat( value ) );
10787	},
10788
10789	_hasScroll: function( el, a ) {
10790
10791		if ( $( el ).css( "overflow" ) === "hidden" ) {
10792			return false;
10793		}
10794
10795		var scroll = ( a && a === "left" ) ? "scrollLeft" : "scrollTop",
10796			has = false;
10797
10798		if ( el[ scroll ] > 0 ) {
10799			return true;
10800		}
10801
10802		// TODO: determine which cases actually cause this to happen
10803		// if the element doesn't have the scroll set, see if it's possible to
10804		// set the scroll
10805		el[ scroll ] = 1;
10806		has = ( el[ scroll ] > 0 );
10807		el[ scroll ] = 0;
10808		return has;
10809	},
10810
10811	_create: function() {
10812
10813		var margins,
10814			o = this.options,
10815			that = this;
10816		this._addClass( "ui-resizable" );
10817
10818		$.extend( this, {
10819			_aspectRatio: !!( o.aspectRatio ),
10820			aspectRatio: o.aspectRatio,
10821			originalElement: this.element,
10822			_proportionallyResizeElements: [],
10823			_helper: o.helper || o.ghost || o.animate ? o.helper || "ui-resizable-helper" : null
10824		} );
10825
10826		// Wrap the element if it cannot hold child nodes
10827		if ( this.element[ 0 ].nodeName.match( /^(canvas|textarea|input|select|button|img)$/i ) ) {
10828
10829			this.element.wrap(
10830				$( "<div class='ui-wrapper' style='overflow: hidden;'></div>" ).css( {
10831					position: this.element.css( "position" ),
10832					width: this.element.outerWidth(),
10833					height: this.element.outerHeight(),
10834					top: this.element.css( "top" ),
10835					left: this.element.css( "left" )
10836				} )
10837			);
10838
10839			this.element = this.element.parent().data(
10840				"ui-resizable", this.element.resizable( "instance" )
10841			);
10842
10843			this.elementIsWrapper = true;
10844
10845			margins = {
10846				marginTop: this.originalElement.css( "marginTop" ),
10847				marginRight: this.originalElement.css( "marginRight" ),
10848				marginBottom: this.originalElement.css( "marginBottom" ),
10849				marginLeft: this.originalElement.css( "marginLeft" )
10850			};
10851
10852			this.element.css( margins );
10853			this.originalElement.css( "margin", 0 );
10854
10855			// support: Safari
10856			// Prevent Safari textarea resize
10857			this.originalResizeStyle = this.originalElement.css( "resize" );
10858			this.originalElement.css( "resize", "none" );
10859
10860			this._proportionallyResizeElements.push( this.originalElement.css( {
10861				position: "static",
10862				zoom: 1,
10863				display: "block"
10864			} ) );
10865
10866			// Support: IE9
10867			// avoid IE jump (hard set the margin)
10868			this.originalElement.css( margins );
10869
10870			this._proportionallyResize();
10871		}
10872
10873		this._setupHandles();
10874
10875		if ( o.autoHide ) {
10876			$( this.element )
10877				.on( "mouseenter", function() {
10878					if ( o.disabled ) {
10879						return;
10880					}
10881					that._removeClass( "ui-resizable-autohide" );
10882					that._handles.show();
10883				} )
10884				.on( "mouseleave", function() {
10885					if ( o.disabled ) {
10886						return;
10887					}
10888					if ( !that.resizing ) {
10889						that._addClass( "ui-resizable-autohide" );
10890						that._handles.hide();
10891					}
10892				} );
10893		}
10894
10895		this._mouseInit();
10896	},
10897
10898	_destroy: function() {
10899
10900		this._mouseDestroy();
10901
10902		var wrapper,
10903			_destroy = function( exp ) {
10904				$( exp )
10905					.removeData( "resizable" )
10906					.removeData( "ui-resizable" )
10907					.off( ".resizable" )
10908					.find( ".ui-resizable-handle" )
10909						.remove();
10910			};
10911
10912		// TODO: Unwrap at same DOM position
10913		if ( this.elementIsWrapper ) {
10914			_destroy( this.element );
10915			wrapper = this.element;
10916			this.originalElement.css( {
10917				position: wrapper.css( "position" ),
10918				width: wrapper.outerWidth(),
10919				height: wrapper.outerHeight(),
10920				top: wrapper.css( "top" ),
10921				left: wrapper.css( "left" )
10922			} ).insertAfter( wrapper );
10923			wrapper.remove();
10924		}
10925
10926		this.originalElement.css( "resize", this.originalResizeStyle );
10927		_destroy( this.originalElement );
10928
10929		return this;
10930	},
10931
10932	_setOption: function( key, value ) {
10933		this._super( key, value );
10934
10935		switch ( key ) {
10936		case "handles":
10937			this._removeHandles();
10938			this._setupHandles();
10939			break;
10940		default:
10941			break;
10942		}
10943	},
10944
10945	_setupHandles: function() {
10946		var o = this.options, handle, i, n, hname, axis, that = this;
10947		this.handles = o.handles ||
10948			( !$( ".ui-resizable-handle", this.element ).length ?
10949				"e,s,se" : {
10950					n: ".ui-resizable-n",
10951					e: ".ui-resizable-e",
10952					s: ".ui-resizable-s",
10953					w: ".ui-resizable-w",
10954					se: ".ui-resizable-se",
10955					sw: ".ui-resizable-sw",
10956					ne: ".ui-resizable-ne",
10957					nw: ".ui-resizable-nw"
10958				} );
10959
10960		this._handles = $();
10961		if ( this.handles.constructor === String ) {
10962
10963			if ( this.handles === "all" ) {
10964				this.handles = "n,e,s,w,se,sw,ne,nw";
10965			}
10966
10967			n = this.handles.split( "," );
10968			this.handles = {};
10969
10970			for ( i = 0; i < n.length; i++ ) {
10971
10972				handle = $.trim( n[ i ] );
10973				hname = "ui-resizable-" + handle;
10974				axis = $( "<div>" );
10975				this._addClass( axis, "ui-resizable-handle " + hname );
10976
10977				axis.css( { zIndex: o.zIndex } );
10978
10979				this.handles[ handle ] = ".ui-resizable-" + handle;
10980				this.element.append( axis );
10981			}
10982
10983		}
10984
10985		this._renderAxis = function( target ) {
10986
10987			var i, axis, padPos, padWrapper;
10988
10989			target = target || this.element;
10990
10991			for ( i in this.handles ) {
10992
10993				if ( this.handles[ i ].constructor === String ) {
10994					this.handles[ i ] = this.element.children( this.handles[ i ] ).first().show();
10995				} else if ( this.handles[ i ].jquery || this.handles[ i ].nodeType ) {
10996					this.handles[ i ] = $( this.handles[ i ] );
10997					this._on( this.handles[ i ], { "mousedown": that._mouseDown } );
10998				}
10999
11000				if ( this.elementIsWrapper &&
11001						this.originalElement[ 0 ]
11002							.nodeName
11003							.match( /^(textarea|input|select|button)$/i ) ) {
11004					axis = $( this.handles[ i ], this.element );
11005
11006					padWrapper = /sw|ne|nw|se|n|s/.test( i ) ?
11007						axis.outerHeight() :
11008						axis.outerWidth();
11009
11010					padPos = [ "padding",
vendor: 4,678 bytes, lines 11011-11191
11011						/ne|nw|n/.test( i ) ? "Top" :
11012						/se|sw|s/.test( i ) ? "Bottom" :
11013						/^e$/.test( i ) ? "Right" : "Left" ].join( "" );
11014
11015					target.css( padPos, padWrapper );
11016
11017					this._proportionallyResize();
11018				}
11019
11020				this._handles = this._handles.add( this.handles[ i ] );
11021			}
11022		};
11023
11024		// TODO: make renderAxis a prototype function
11025		this._renderAxis( this.element );
11026
11027		this._handles = this._handles.add( this.element.find( ".ui-resizable-handle" ) );
11028		this._handles.disableSelection();
11029
11030		this._handles.on( "mouseover", function() {
11031			if ( !that.resizing ) {
11032				if ( this.className ) {
11033					axis = this.className.match( /ui-resizable-(se|sw|ne|nw|n|e|s|w)/i );
11034				}
11035				that.axis = axis && axis[ 1 ] ? axis[ 1 ] : "se";
11036			}
11037		} );
11038
11039		if ( o.autoHide ) {
11040			this._handles.hide();
11041			this._addClass( "ui-resizable-autohide" );
11042		}
11043	},
11044
11045	_removeHandles: function() {
11046		this._handles.remove();
11047	},
11048
11049	_mouseCapture: function( event ) {
11050		var i, handle,
11051			capture = false;
11052
11053		for ( i in this.handles ) {
11054			handle = $( this.handles[ i ] )[ 0 ];
11055			if ( handle === event.target || $.contains( handle, event.target ) ) {
11056				capture = true;
11057			}
11058		}
11059
11060		return !this.options.disabled && capture;
11061	},
11062
11063	_mouseStart: function( event ) {
11064
11065		var curleft, curtop, cursor,
11066			o = this.options,
11067			el = this.element;
11068
11069		this.resizing = true;
11070
11071		this._renderProxy();
11072
11073		curleft = this._num( this.helper.css( "left" ) );
11074		curtop = this._num( this.helper.css( "top" ) );
11075
11076		if ( o.containment ) {
11077			curleft += $( o.containment ).scrollLeft() || 0;
11078			curtop += $( o.containment ).scrollTop() || 0;
11079		}
11080
11081		this.offset = this.helper.offset();
11082		this.position = { left: curleft, top: curtop };
11083
11084		this.size = this._helper ? {
11085				width: this.helper.width(),
11086				height: this.helper.height()
11087			} : {
11088				width: el.width(),
11089				height: el.height()
11090			};
11091
11092		this.originalSize = this._helper ? {
11093				width: el.outerWidth(),
11094				height: el.outerHeight()
11095			} : {
11096				width: el.width(),
11097				height: el.height()
11098			};
11099
11100		this.sizeDiff = {
11101			width: el.outerWidth() - el.width(),
11102			height: el.outerHeight() - el.height()
11103		};
11104
11105		this.originalPosition = { left: curleft, top: curtop };
11106		this.originalMousePosition = { left: event.pageX, top: event.pageY };
11107
11108		this.aspectRatio = ( typeof o.aspectRatio === "number" ) ?
11109			o.aspectRatio :
11110			( ( this.originalSize.width / this.originalSize.height ) || 1 );
11111
11112		cursor = $( ".ui-resizable-" + this.axis ).css( "cursor" );
11113		$( "body" ).css( "cursor", cursor === "auto" ? this.axis + "-resize" : cursor );
11114
11115		this._addClass( "ui-resizable-resizing" );
11116		this._propagate( "start", event );
11117		return true;
11118	},
11119
11120	_mouseDrag: function( event ) {
11121
11122		var data, props,
11123			smp = this.originalMousePosition,
11124			a = this.axis,
11125			dx = ( event.pageX - smp.left ) || 0,
11126			dy = ( event.pageY - smp.top ) || 0,
11127			trigger = this._change[ a ];
11128
11129		this._updatePrevProperties();
11130
11131		if ( !trigger ) {
11132			return false;
11133		}
11134
11135		data = trigger.apply( this, [ event, dx, dy ] );
11136
11137		this._updateVirtualBoundaries( event.shiftKey );
11138		if ( this._aspectRatio || event.shiftKey ) {
11139			data = this._updateRatio( data, event );
11140		}
11141
11142		data = this._respectSize( data, event );
11143
11144		this._updateCache( data );
11145
11146		this._propagate( "resize", event );
11147
11148		props = this._applyChanges();
11149
11150		if ( !this._helper && this._proportionallyResizeElements.length ) {
11151			this._proportionallyResize();
11152		}
11153
11154		if ( !$.isEmptyObject( props ) ) {
11155			this._updatePrevProperties();
11156			this._trigger( "resize", event, this.ui() );
11157			this._applyChanges();
11158		}
11159
11160		return false;
11161	},
11162
11163	_mouseStop: function( event ) {
11164
11165		this.resizing = false;
11166		var pr, ista, soffseth, soffsetw, s, left, top,
11167			o = this.options, that = this;
11168
11169		if ( this._helper ) {
11170
11171			pr = this._proportionallyResizeElements;
11172			ista = pr.length && ( /textarea/i ).test( pr[ 0 ].nodeName );
11173			soffseth = ista && this._hasScroll( pr[ 0 ], "left" ) ? 0 : that.sizeDiff.height;
11174			soffsetw = ista ? 0 : that.sizeDiff.width;
11175
11176			s = {
11177				width: ( that.helper.width()  - soffsetw ),
11178				height: ( that.helper.height() - soffseth )
11179			};
11180			left = ( parseFloat( that.element.css( "left" ) ) +
11181				( that.position.left - that.originalPosition.left ) ) || null;
11182			top = ( parseFloat( that.element.css( "top" ) ) +
11183				( that.position.top - that.originalPosition.top ) ) || null;
11184
11185			if ( !o.animate ) {
11186				this.element.css( $.extend( s, { top: top, left: left } ) );
11187			}
11188
11189			that.helper.height( that.size.height );
11190			that.helper.width( that.size.width );
11191
vendor: 6,168 bytes, lines 11192-11432
11192			if ( this._helper && !o.animate ) {
11193				this._proportionallyResize();
11194			}
11195		}
11196
11197		$( "body" ).css( "cursor", "auto" );
11198
11199		this._removeClass( "ui-resizable-resizing" );
11200
11201		this._propagate( "stop", event );
11202
11203		if ( this._helper ) {
11204			this.helper.remove();
11205		}
11206
11207		return false;
11208
11209	},
11210
11211	_updatePrevProperties: function() {
11212		this.prevPosition = {
11213			top: this.position.top,
11214			left: this.position.left
11215		};
11216		this.prevSize = {
11217			width: this.size.width,
11218			height: this.size.height
11219		};
11220	},
11221
11222	_applyChanges: function() {
11223		var props = {};
11224
11225		if ( this.position.top !== this.prevPosition.top ) {
11226			props.top = this.position.top + "px";
11227		}
11228		if ( this.position.left !== this.prevPosition.left ) {
11229			props.left = this.position.left + "px";
11230		}
11231		if ( this.size.width !== this.prevSize.width ) {
11232			props.width = this.size.width + "px";
11233		}
11234		if ( this.size.height !== this.prevSize.height ) {
11235			props.height = this.size.height + "px";
11236		}
11237
11238		this.helper.css( props );
11239
11240		return props;
11241	},
11242
11243	_updateVirtualBoundaries: function( forceAspectRatio ) {
11244		var pMinWidth, pMaxWidth, pMinHeight, pMaxHeight, b,
11245			o = this.options;
11246
11247		b = {
11248			minWidth: this._isNumber( o.minWidth ) ? o.minWidth : 0,
11249			maxWidth: this._isNumber( o.maxWidth ) ? o.maxWidth : Infinity,
11250			minHeight: this._isNumber( o.minHeight ) ? o.minHeight : 0,
11251			maxHeight: this._isNumber( o.maxHeight ) ? o.maxHeight : Infinity
11252		};
11253
11254		if ( this._aspectRatio || forceAspectRatio ) {
11255			pMinWidth = b.minHeight * this.aspectRatio;
11256			pMinHeight = b.minWidth / this.aspectRatio;
11257			pMaxWidth = b.maxHeight * this.aspectRatio;
11258			pMaxHeight = b.maxWidth / this.aspectRatio;
11259
11260			if ( pMinWidth > b.minWidth ) {
11261				b.minWidth = pMinWidth;
11262			}
11263			if ( pMinHeight > b.minHeight ) {
11264				b.minHeight = pMinHeight;
11265			}
11266			if ( pMaxWidth < b.maxWidth ) {
11267				b.maxWidth = pMaxWidth;
11268			}
11269			if ( pMaxHeight < b.maxHeight ) {
11270				b.maxHeight = pMaxHeight;
11271			}
11272		}
11273		this._vBoundaries = b;
11274	},
11275
11276	_updateCache: function( data ) {
11277		this.offset = this.helper.offset();
11278		if ( this._isNumber( data.left ) ) {
11279			this.position.left = data.left;
11280		}
11281		if ( this._isNumber( data.top ) ) {
11282			this.position.top = data.top;
11283		}
11284		if ( this._isNumber( data.height ) ) {
11285			this.size.height = data.height;
11286		}
11287		if ( this._isNumber( data.width ) ) {
11288			this.size.width = data.width;
11289		}
11290	},
11291
11292	_updateRatio: function( data ) {
11293
11294		var cpos = this.position,
11295			csize = this.size,
11296			a = this.axis;
11297
11298		if ( this._isNumber( data.height ) ) {
11299			data.width = ( data.height * this.aspectRatio );
11300		} else if ( this._isNumber( data.width ) ) {
11301			data.height = ( data.width / this.aspectRatio );
11302		}
11303
11304		if ( a === "sw" ) {
11305			data.left = cpos.left + ( csize.width - data.width );
11306			data.top = null;
11307		}
11308		if ( a === "nw" ) {
11309			data.top = cpos.top + ( csize.height - data.height );
11310			data.left = cpos.left + ( csize.width - data.width );
11311		}
11312
11313		return data;
11314	},
11315
11316	_respectSize: function( data ) {
11317
11318		var o = this._vBoundaries,
11319			a = this.axis,
11320			ismaxw = this._isNumber( data.width ) && o.maxWidth && ( o.maxWidth < data.width ),
11321			ismaxh = this._isNumber( data.height ) && o.maxHeight && ( o.maxHeight < data.height ),
11322			isminw = this._isNumber( data.width ) && o.minWidth && ( o.minWidth > data.width ),
11323			isminh = this._isNumber( data.height ) && o.minHeight && ( o.minHeight > data.height ),
11324			dw = this.originalPosition.left + this.originalSize.width,
11325			dh = this.originalPosition.top + this.originalSize.height,
11326			cw = /sw|nw|w/.test( a ), ch = /nw|ne|n/.test( a );
11327		if ( isminw ) {
11328			data.width = o.minWidth;
11329		}
11330		if ( isminh ) {
11331			data.height = o.minHeight;
11332		}
11333		if ( ismaxw ) {
11334			data.width = o.maxWidth;
11335		}
11336		if ( ismaxh ) {
11337			data.height = o.maxHeight;
11338		}
11339
11340		if ( isminw && cw ) {
11341			data.left = dw - o.minWidth;
11342		}
11343		if ( ismaxw && cw ) {
11344			data.left = dw - o.maxWidth;
11345		}
11346		if ( isminh && ch ) {
11347			data.top = dh - o.minHeight;
11348		}
11349		if ( ismaxh && ch ) {
11350			data.top = dh - o.maxHeight;
11351		}
11352
11353		// Fixing jump error on top/left - bug #2330
11354		if ( !data.width && !data.height && !data.left && data.top ) {
11355			data.top = null;
11356		} else if ( !data.width && !data.height && !data.top && data.left ) {
11357			data.left = null;
11358		}
11359
11360		return data;
11361	},
11362
11363	_getPaddingPlusBorderDimensions: function( element ) {
11364		var i = 0,
11365			widths = [],
11366			borders = [
11367				element.css( "borderTopWidth" ),
11368				element.css( "borderRightWidth" ),
11369				element.css( "borderBottomWidth" ),
11370				element.css( "borderLeftWidth" )
11371			],
11372			paddings = [
11373				element.css( "paddingTop" ),
11374				element.css( "paddingRight" ),
11375				element.css( "paddingBottom" ),
11376				element.css( "paddingLeft" )
11377			];
11378
11379		for ( ; i < 4; i++ ) {
11380			widths[ i ] = ( parseFloat( borders[ i ] ) || 0 );
11381			widths[ i ] += ( parseFloat( paddings[ i ] ) || 0 );
11382		}
11383
11384		return {
11385			height: widths[ 0 ] + widths[ 2 ],
11386			width: widths[ 1 ] + widths[ 3 ]
11387		};
11388	},
11389
11390	_proportionallyResize: function() {
11391
11392		if ( !this._proportionallyResizeElements.length ) {
11393			return;
11394		}
11395
11396		var prel,
11397			i = 0,
11398			element = this.helper || this.element;
11399
11400		for ( ; i < this._proportionallyResizeElements.length; i++ ) {
11401
11402			prel = this._proportionallyResizeElements[ i ];
11403
11404			// TODO: Seems like a bug to cache this.outerDimensions
11405			// considering that we are in a loop.
11406			if ( !this.outerDimensions ) {
11407				this.outerDimensions = this._getPaddingPlusBorderDimensions( prel );
11408			}
11409
11410			prel.css( {
11411				height: ( element.height() - this.outerDimensions.height ) || 0,
11412				width: ( element.width() - this.outerDimensions.width ) || 0
11413			} );
11414
11415		}
11416
11417	},
11418
11419	_renderProxy: function() {
11420
11421		var el = this.element, o = this.options;
11422		this.elementOffset = el.offset();
11423
11424		if ( this._helper ) {
11425
11426			this.helper = this.helper || $( "<div style='overflow:hidden;'></div>" );
11427
11428			this._addClass( this.helper, this._helper );
11429			this.helper.css( {
11430				width: this.element.outerWidth(),
11431				height: this.element.outerHeight(),
11432				position: "absolute",
vendor: 1,421 bytes, lines 11433-11480
11433				left: this.elementOffset.left + "px",
11434				top: this.elementOffset.top + "px",
11435				zIndex: ++o.zIndex //TODO: Don't modify option
11436			} );
11437
11438			this.helper
11439				.appendTo( "body" )
11440				.disableSelection();
11441
11442		} else {
11443			this.helper = this.element;
11444		}
11445
11446	},
11447
11448	_change: {
11449		e: function( event, dx ) {
11450			return { width: this.originalSize.width + dx };
11451		},
11452		w: function( event, dx ) {
11453			var cs = this.originalSize, sp = this.originalPosition;
11454			return { left: sp.left + dx, width: cs.width - dx };
11455		},
11456		n: function( event, dx, dy ) {
11457			var cs = this.originalSize, sp = this.originalPosition;
11458			return { top: sp.top + dy, height: cs.height - dy };
11459		},
11460		s: function( event, dx, dy ) {
11461			return { height: this.originalSize.height + dy };
11462		},
11463		se: function( event, dx, dy ) {
11464			return $.extend( this._change.s.apply( this, arguments ),
11465				this._change.e.apply( this, [ event, dx, dy ] ) );
11466		},
11467		sw: function( event, dx, dy ) {
11468			return $.extend( this._change.s.apply( this, arguments ),
11469				this._change.w.apply( this, [ event, dx, dy ] ) );
11470		},
11471		ne: function( event, dx, dy ) {
11472			return $.extend( this._change.n.apply( this, arguments ),
11473				this._change.e.apply( this, [ event, dx, dy ] ) );
11474		},
11475		nw: function( event, dx, dy ) {
11476			return $.extend( this._change.n.apply( this, arguments ),
11477				this._change.w.apply( this, [ event, dx, dy ] ) );
11478		}
11479	},
11480
vendor: 9,740 bytes, lines 11481-11846
11481	_propagate: function( n, event ) {
11482		$.ui.plugin.call( this, n, [ event, this.ui() ] );
11483		( n !== "resize" && this._trigger( n, event, this.ui() ) );
11484	},
11485
11486	plugins: {},
11487
11488	ui: function() {
11489		return {
11490			originalElement: this.originalElement,
11491			element: this.element,
11492			helper: this.helper,
11493			position: this.position,
11494			size: this.size,
11495			originalSize: this.originalSize,
11496			originalPosition: this.originalPosition
11497		};
11498	}
11499
11500} );
11501
11502/*
11503 * Resizable Extensions
11504 */
11505
11506$.ui.plugin.add( "resizable", "animate", {
11507
11508	stop: function( event ) {
11509		var that = $( this ).resizable( "instance" ),
11510			o = that.options,
11511			pr = that._proportionallyResizeElements,
11512			ista = pr.length && ( /textarea/i ).test( pr[ 0 ].nodeName ),
11513			soffseth = ista && that._hasScroll( pr[ 0 ], "left" ) ? 0 : that.sizeDiff.height,
11514			soffsetw = ista ? 0 : that.sizeDiff.width,
11515			style = {
11516				width: ( that.size.width - soffsetw ),
11517				height: ( that.size.height - soffseth )
11518			},
11519			left = ( parseFloat( that.element.css( "left" ) ) +
11520				( that.position.left - that.originalPosition.left ) ) || null,
11521			top = ( parseFloat( that.element.css( "top" ) ) +
11522				( that.position.top - that.originalPosition.top ) ) || null;
11523
11524		that.element.animate(
11525			$.extend( style, top && left ? { top: top, left: left } : {} ), {
11526				duration: o.animateDuration,
11527				easing: o.animateEasing,
11528				step: function() {
11529
11530					var data = {
11531						width: parseFloat( that.element.css( "width" ) ),
11532						height: parseFloat( that.element.css( "height" ) ),
11533						top: parseFloat( that.element.css( "top" ) ),
11534						left: parseFloat( that.element.css( "left" ) )
11535					};
11536
11537					if ( pr && pr.length ) {
11538						$( pr[ 0 ] ).css( { width: data.width, height: data.height } );
11539					}
11540
11541					// Propagating resize, and updating values for each animation step
11542					that._updateCache( data );
11543					that._propagate( "resize", event );
11544
11545				}
11546			}
11547		);
11548	}
11549
11550} );
11551
11552$.ui.plugin.add( "resizable", "containment", {
11553
11554	start: function() {
11555		var element, p, co, ch, cw, width, height,
11556			that = $( this ).resizable( "instance" ),
11557			o = that.options,
11558			el = that.element,
11559			oc = o.containment,
11560			ce = ( oc instanceof $ ) ?
11561				oc.get( 0 ) :
11562				( /parent/.test( oc ) ) ? el.parent().get( 0 ) : oc;
11563
11564		if ( !ce ) {
11565			return;
11566		}
11567
11568		that.containerElement = $( ce );
11569
11570		if ( /document/.test( oc ) || oc === document ) {
11571			that.containerOffset = {
11572				left: 0,
11573				top: 0
11574			};
11575			that.containerPosition = {
11576				left: 0,
11577				top: 0
11578			};
11579
11580			that.parentData = {
11581				element: $( document ),
11582				left: 0,
11583				top: 0,
11584				width: $( document ).width(),
11585				height: $( document ).height() || document.body.parentNode.scrollHeight
11586			};
11587		} else {
11588			element = $( ce );
11589			p = [];
11590			$( [ "Top", "Right", "Left", "Bottom" ] ).each( function( i, name ) {
11591				p[ i ] = that._num( element.css( "padding" + name ) );
11592			} );
11593
11594			that.containerOffset = element.offset();
11595			that.containerPosition = element.position();
11596			that.containerSize = {
11597				height: ( element.innerHeight() - p[ 3 ] ),
11598				width: ( element.innerWidth() - p[ 1 ] )
11599			};
11600
11601			co = that.containerOffset;
11602			ch = that.containerSize.height;
11603			cw = that.containerSize.width;
11604			width = ( that._hasScroll ( ce, "left" ) ? ce.scrollWidth : cw );
11605			height = ( that._hasScroll ( ce ) ? ce.scrollHeight : ch ) ;
11606
11607			that.parentData = {
11608				element: ce,
11609				left: co.left,
11610				top: co.top,
11611				width: width,
11612				height: height
11613			};
11614		}
11615	},
11616
11617	resize: function( event ) {
11618		var woset, hoset, isParent, isOffsetRelative,
11619			that = $( this ).resizable( "instance" ),
11620			o = that.options,
11621			co = that.containerOffset,
11622			cp = that.position,
11623			pRatio = that._aspectRatio || event.shiftKey,
11624			cop = {
11625				top: 0,
11626				left: 0
11627			},
11628			ce = that.containerElement,
11629			continueResize = true;
11630
11631		if ( ce[ 0 ] !== document && ( /static/ ).test( ce.css( "position" ) ) ) {
11632			cop = co;
11633		}
11634
11635		if ( cp.left < ( that._helper ? co.left : 0 ) ) {
11636			that.size.width = that.size.width +
11637				( that._helper ?
11638					( that.position.left - co.left ) :
11639					( that.position.left - cop.left ) );
11640
11641			if ( pRatio ) {
11642				that.size.height = that.size.width / that.aspectRatio;
11643				continueResize = false;
11644			}
11645			that.position.left = o.helper ? co.left : 0;
11646		}
11647
11648		if ( cp.top < ( that._helper ? co.top : 0 ) ) {
11649			that.size.height = that.size.height +
11650				( that._helper ?
11651					( that.position.top - co.top ) :
11652					that.position.top );
11653
11654			if ( pRatio ) {
11655				that.size.width = that.size.height * that.aspectRatio;
11656				continueResize = false;
11657			}
11658			that.position.top = that._helper ? co.top : 0;
11659		}
11660
11661		isParent = that.containerElement.get( 0 ) === that.element.parent().get( 0 );
11662		isOffsetRelative = /relative|absolute/.test( that.containerElement.css( "position" ) );
11663
11664		if ( isParent && isOffsetRelative ) {
11665			that.offset.left = that.parentData.left + that.position.left;
11666			that.offset.top = that.parentData.top + that.position.top;
11667		} else {
11668			that.offset.left = that.element.offset().left;
11669			that.offset.top = that.element.offset().top;
11670		}
11671
11672		woset = Math.abs( that.sizeDiff.width +
11673			( that._helper ?
11674				that.offset.left - cop.left :
11675				( that.offset.left - co.left ) ) );
11676
11677		hoset = Math.abs( that.sizeDiff.height +
11678			( that._helper ?
11679				that.offset.top - cop.top :
11680				( that.offset.top - co.top ) ) );
11681
11682		if ( woset + that.size.width >= that.parentData.width ) {
11683			that.size.width = that.parentData.width - woset;
11684			if ( pRatio ) {
11685				that.size.height = that.size.width / that.aspectRatio;
11686				continueResize = false;
11687			}
11688		}
11689
11690		if ( hoset + that.size.height >= that.parentData.height ) {
11691			that.size.height = that.parentData.height - hoset;
11692			if ( pRatio ) {
11693				that.size.width = that.size.height * that.aspectRatio;
11694				continueResize = false;
11695			}
11696		}
11697
11698		if ( !continueResize ) {
11699			that.position.left = that.prevPosition.left;
11700			that.position.top = that.prevPosition.top;
11701			that.size.width = that.prevSize.width;
11702			that.size.height = that.prevSize.height;
11703		}
11704	},
11705
11706	stop: function() {
11707		var that = $( this ).resizable( "instance" ),
11708			o = that.options,
11709			co = that.containerOffset,
11710			cop = that.containerPosition,
11711			ce = that.containerElement,
11712			helper = $( that.helper ),
11713			ho = helper.offset(),
11714			w = helper.outerWidth() - that.sizeDiff.width,
11715			h = helper.outerHeight() - that.sizeDiff.height;
11716
11717		if ( that._helper && !o.animate && ( /relative/ ).test( ce.css( "position" ) ) ) {
11718			$( this ).css( {
11719				left: ho.left - cop.left - co.left,
11720				width: w,
11721				height: h
11722			} );
11723		}
11724
11725		if ( that._helper && !o.animate && ( /static/ ).test( ce.css( "position" ) ) ) {
11726			$( this ).css( {
11727				left: ho.left - cop.left - co.left,
11728				width: w,
11729				height: h
11730			} );
11731		}
11732	}
11733} );
11734
11735$.ui.plugin.add( "resizable", "alsoResize", {
11736
11737	start: function() {
11738		var that = $( this ).resizable( "instance" ),
11739			o = that.options;
11740
11741		$( o.alsoResize ).each( function() {
11742			var el = $( this );
11743			el.data( "ui-resizable-alsoresize", {
11744				width: parseFloat( el.width() ), height: parseFloat( el.height() ),
11745				left: parseFloat( el.css( "left" ) ), top: parseFloat( el.css( "top" ) )
11746			} );
11747		} );
11748	},
11749
11750	resize: function( event, ui ) {
11751		var that = $( this ).resizable( "instance" ),
11752			o = that.options,
11753			os = that.originalSize,
11754			op = that.originalPosition,
11755			delta = {
11756				height: ( that.size.height - os.height ) || 0,
11757				width: ( that.size.width - os.width ) || 0,
11758				top: ( that.position.top - op.top ) || 0,
11759				left: ( that.position.left - op.left ) || 0
11760			};
11761
11762			$( o.alsoResize ).each( function() {
11763				var el = $( this ), start = $( this ).data( "ui-resizable-alsoresize" ), style = {},
11764					css = el.parents( ui.originalElement[ 0 ] ).length ?
11765							[ "width", "height" ] :
11766							[ "width", "height", "top", "left" ];
11767
11768				$.each( css, function( i, prop ) {
11769					var sum = ( start[ prop ] || 0 ) + ( delta[ prop ] || 0 );
11770					if ( sum && sum >= 0 ) {
11771						style[ prop ] = sum || null;
11772					}
11773				} );
11774
11775				el.css( style );
11776			} );
11777	},
11778
11779	stop: function() {
11780		$( this ).removeData( "ui-resizable-alsoresize" );
11781	}
11782} );
11783
11784$.ui.plugin.add( "resizable", "ghost", {
11785
11786	start: function() {
11787
11788		var that = $( this ).resizable( "instance" ), cs = that.size;
11789
11790		that.ghost = that.originalElement.clone();
11791		that.ghost.css( {
11792			opacity: 0.25,
11793			display: "block",
11794			position: "relative",
11795			height: cs.height,
11796			width: cs.width,
11797			margin: 0,
11798			left: 0,
11799			top: 0
11800		} );
11801
11802		that._addClass( that.ghost, "ui-resizable-ghost" );
11803
11804		// DEPRECATED
11805		// TODO: remove after 1.12
11806		if ( $.uiBackCompat !== false && typeof that.options.ghost === "string" ) {
11807
11808			// Ghost option
11809			that.ghost.addClass( this.options.ghost );
11810		}
11811
11812		that.ghost.appendTo( that.helper );
11813
11814	},
11815
11816	resize: function() {
11817		var that = $( this ).resizable( "instance" );
11818		if ( that.ghost ) {
11819			that.ghost.css( {
11820				position: "relative",
11821				height: that.size.height,
11822				width: that.size.width
11823			} );
11824		}
11825	},
11826
11827	stop: function() {
11828		var that = $( this ).resizable( "instance" );
11829		if ( that.ghost && that.helper ) {
11830			that.helper.get( 0 ).removeChild( that.ghost.get( 0 ) );
11831		}
11832	}
11833
11834} );
11835
11836$.ui.plugin.add( "resizable", "grid", {
11837
11838	resize: function() {
11839		var outerDimensions,
11840			that = $( this ).resizable( "instance" ),
11841			o = that.options,
11842			cs = that.size,
11843			os = that.originalSize,
11844			op = that.originalPosition,
11845			a = that.axis,
11846			grid = typeof o.grid === "number" ? [ o.grid, o.grid ] : o.grid,
vendor: 4,400 bytes, lines 11847-12027
11847			gridX = ( grid[ 0 ] || 1 ),
11848			gridY = ( grid[ 1 ] || 1 ),
11849			ox = Math.round( ( cs.width - os.width ) / gridX ) * gridX,
11850			oy = Math.round( ( cs.height - os.height ) / gridY ) * gridY,
11851			newWidth = os.width + ox,
11852			newHeight = os.height + oy,
11853			isMaxWidth = o.maxWidth && ( o.maxWidth < newWidth ),
11854			isMaxHeight = o.maxHeight && ( o.maxHeight < newHeight ),
11855			isMinWidth = o.minWidth && ( o.minWidth > newWidth ),
11856			isMinHeight = o.minHeight && ( o.minHeight > newHeight );
11857
11858		o.grid = grid;
11859
11860		if ( isMinWidth ) {
11861			newWidth += gridX;
11862		}
11863		if ( isMinHeight ) {
11864			newHeight += gridY;
11865		}
11866		if ( isMaxWidth ) {
11867			newWidth -= gridX;
11868		}
11869		if ( isMaxHeight ) {
11870			newHeight -= gridY;
11871		}
11872
11873		if ( /^(se|s|e)$/.test( a ) ) {
11874			that.size.width = newWidth;
11875			that.size.height = newHeight;
11876		} else if ( /^(ne)$/.test( a ) ) {
11877			that.size.width = newWidth;
11878			that.size.height = newHeight;
11879			that.position.top = op.top - oy;
11880		} else if ( /^(sw)$/.test( a ) ) {
11881			that.size.width = newWidth;
11882			that.size.height = newHeight;
11883			that.position.left = op.left - ox;
11884		} else {
11885			if ( newHeight - gridY <= 0 || newWidth - gridX <= 0 ) {
11886				outerDimensions = that._getPaddingPlusBorderDimensions( this );
11887			}
11888
11889			if ( newHeight - gridY > 0 ) {
11890				that.size.height = newHeight;
11891				that.position.top = op.top - oy;
11892			} else {
11893				newHeight = gridY - outerDimensions.height;
11894				that.size.height = newHeight;
11895				that.position.top = op.top + os.height - newHeight;
11896			}
11897			if ( newWidth - gridX > 0 ) {
11898				that.size.width = newWidth;
11899				that.position.left = op.left - ox;
11900			} else {
11901				newWidth = gridX - outerDimensions.width;
11902				that.size.width = newWidth;
11903				that.position.left = op.left + os.width - newWidth;
11904			}
11905		}
11906	}
11907
11908} );
11909
11910var widgetsResizable = $.ui.resizable;
11911
11912
11913/*!
11914 * jQuery UI Dialog 1.12.1
11915 * http://jqueryui.com
11916 *
11917 * Copyright jQuery Foundation and other contributors
11918 * Released under the MIT license.
11919 * http://jquery.org/license
11920 */
11921
11922//>>label: Dialog
11923//>>group: Widgets
11924//>>description: Displays customizable dialog windows.
11925//>>docs: http://api.jqueryui.com/dialog/
11926//>>demos: http://jqueryui.com/dialog/
11927//>>css.structure: ../../themes/base/core.css
11928//>>css.structure: ../../themes/base/dialog.css
11929//>>css.theme: ../../themes/base/theme.css
11930
11931
11932
11933$.widget( "ui.dialog", {
11934	version: "1.12.1",
11935	options: {
11936		appendTo: "body",
11937		autoOpen: true,
11938		buttons: [],
11939		classes: {
11940			"ui-dialog": "ui-corner-all",
11941			"ui-dialog-titlebar": "ui-corner-all"
11942		},
11943		closeOnEscape: true,
11944		closeText: "Close",
11945		draggable: true,
11946		hide: null,
11947		height: "auto",
11948		maxHeight: null,
11949		maxWidth: null,
11950		minHeight: 150,
11951		minWidth: 150,
11952		modal: false,
11953		position: {
11954			my: "center",
11955			at: "center",
11956			of: window,
11957			collision: "fit",
11958
11959			// Ensure the titlebar is always visible
11960			using: function( pos ) {
11961				var topOffset = $( this ).css( pos ).offset().top;
11962				if ( topOffset < 0 ) {
11963					$( this ).css( "top", pos.top - topOffset );
11964				}
11965			}
11966		},
11967		resizable: true,
11968		show: null,
11969		title: null,
11970		width: 300,
11971
11972		// Callbacks
11973		beforeClose: null,
11974		close: null,
11975		drag: null,
11976		dragStart: null,
11977		dragStop: null,
11978		focus: null,
11979		open: null,
11980		resize: null,
11981		resizeStart: null,
11982		resizeStop: null
11983	},
11984
11985	sizeRelatedOptions: {
11986		buttons: true,
11987		height: true,
11988		maxHeight: true,
11989		maxWidth: true,
11990		minHeight: true,
11991		minWidth: true,
11992		width: true
11993	},
11994
11995	resizableRelatedOptions: {
11996		maxHeight: true,
11997		maxWidth: true,
11998		minHeight: true,
11999		minWidth: true
12000	},
12001
12002	_create: function() {
12003		this.originalCss = {
12004			display: this.element[ 0 ].style.display,
12005			width: this.element[ 0 ].style.width,
12006			minHeight: this.element[ 0 ].style.minHeight,
12007			maxHeight: this.element[ 0 ].style.maxHeight,
12008			height: this.element[ 0 ].style.height
12009		};
12010		this.originalPosition = {
12011			parent: this.element.parent(),
12012			index: this.element.parent().children().index( this.element )
12013		};
12014		this.originalTitle = this.element.attr( "title" );
12015		if ( this.options.title == null && this.originalTitle != null ) {
12016			this.options.title = this.originalTitle;
12017		}
12018
12019		// Dialogs can't be disabled
12020		if ( this.options.disabled ) {
12021			this.options.disabled = false;
12022		}
12023
12024		this._createWrapper();
12025
12026		this.element
12027			.show()
vendor: 34,211 bytes, lines 12028-13311
12028			.removeAttr( "title" )
12029			.appendTo( this.uiDialog );
12030
12031		this._addClass( "ui-dialog-content", "ui-widget-content" );
12032
12033		this._createTitlebar();
12034		this._createButtonPane();
12035
12036		if ( this.options.draggable && $.fn.draggable ) {
12037			this._makeDraggable();
12038		}
12039		if ( this.options.resizable && $.fn.resizable ) {
12040			this._makeResizable();
12041		}
12042
12043		this._isOpen = false;
12044
12045		this._trackFocus();
12046	},
12047
12048	_init: function() {
12049		if ( this.options.autoOpen ) {
12050			this.open();
12051		}
12052	},
12053
12054	_appendTo: function() {
12055		var element = this.options.appendTo;
12056		if ( element && ( element.jquery || element.nodeType ) ) {
12057			return $( element );
12058		}
12059		return this.document.find( element || "body" ).eq( 0 );
12060	},
12061
12062	_destroy: function() {
12063		var next,
12064			originalPosition = this.originalPosition;
12065
12066		this._untrackInstance();
12067		this._destroyOverlay();
12068
12069		this.element
12070			.removeUniqueId()
12071			.css( this.originalCss )
12072
12073			// Without detaching first, the following becomes really slow
12074			.detach();
12075
12076		this.uiDialog.remove();
12077
12078		if ( this.originalTitle ) {
12079			this.element.attr( "title", this.originalTitle );
12080		}
12081
12082		next = originalPosition.parent.children().eq( originalPosition.index );
12083
12084		// Don't try to place the dialog next to itself (#8613)
12085		if ( next.length && next[ 0 ] !== this.element[ 0 ] ) {
12086			next.before( this.element );
12087		} else {
12088			originalPosition.parent.append( this.element );
12089		}
12090	},
12091
12092	widget: function() {
12093		return this.uiDialog;
12094	},
12095
12096	disable: $.noop,
12097	enable: $.noop,
12098
12099	close: function( event ) {
12100		var that = this;
12101
12102		if ( !this._isOpen || this._trigger( "beforeClose", event ) === false ) {
12103			return;
12104		}
12105
12106		this._isOpen = false;
12107		this._focusedElement = null;
12108		this._destroyOverlay();
12109		this._untrackInstance();
12110
12111		if ( !this.opener.filter( ":focusable" ).trigger( "focus" ).length ) {
12112
12113			// Hiding a focused element doesn't trigger blur in WebKit
12114			// so in case we have nothing to focus on, explicitly blur the active element
12115			// https://bugs.webkit.org/show_bug.cgi?id=47182
12116			$.ui.safeBlur( $.ui.safeActiveElement( this.document[ 0 ] ) );
12117		}
12118
12119		this._hide( this.uiDialog, this.options.hide, function() {
12120			that._trigger( "close", event );
12121		} );
12122	},
12123
12124	isOpen: function() {
12125		return this._isOpen;
12126	},
12127
12128	moveToTop: function() {
12129		this._moveToTop();
12130	},
12131
12132	_moveToTop: function( event, silent ) {
12133		var moved = false,
12134			zIndices = this.uiDialog.siblings( ".ui-front:visible" ).map( function() {
12135				return +$( this ).css( "z-index" );
12136			} ).get(),
12137			zIndexMax = Math.max.apply( null, zIndices );
12138
12139		if ( zIndexMax >= +this.uiDialog.css( "z-index" ) ) {
12140			this.uiDialog.css( "z-index", zIndexMax + 1 );
12141			moved = true;
12142		}
12143
12144		if ( moved && !silent ) {
12145			this._trigger( "focus", event );
12146		}
12147		return moved;
12148	},
12149
12150	open: function() {
12151		var that = this;
12152		if ( this._isOpen ) {
12153			if ( this._moveToTop() ) {
12154				this._focusTabbable();
12155			}
12156			return;
12157		}
12158
12159		this._isOpen = true;
12160		this.opener = $( $.ui.safeActiveElement( this.document[ 0 ] ) );
12161
12162		this._size();
12163		this._position();
12164		this._createOverlay();
12165		this._moveToTop( null, true );
12166
12167		// Ensure the overlay is moved to the top with the dialog, but only when
12168		// opening. The overlay shouldn't move after the dialog is open so that
12169		// modeless dialogs opened after the modal dialog stack properly.
12170		if ( this.overlay ) {
12171			this.overlay.css( "z-index", this.uiDialog.css( "z-index" ) - 1 );
12172		}
12173
12174		this._show( this.uiDialog, this.options.show, function() {
12175			that._focusTabbable();
12176			that._trigger( "focus" );
12177		} );
12178
12179		// Track the dialog immediately upon openening in case a focus event
12180		// somehow occurs outside of the dialog before an element inside the
12181		// dialog is focused (#10152)
12182		this._makeFocusTarget();
12183
12184		this._trigger( "open" );
12185	},
12186
12187	_focusTabbable: function() {
12188
12189		// Set focus to the first match:
12190		// 1. An element that was focused previously
12191		// 2. First element inside the dialog matching [autofocus]
12192		// 3. Tabbable element inside the content element
12193		// 4. Tabbable element inside the buttonpane
12194		// 5. The close button
12195		// 6. The dialog itself
12196		var hasFocus = this._focusedElement;
12197		if ( !hasFocus ) {
12198			hasFocus = this.element.find( "[autofocus]" );
12199		}
12200		if ( !hasFocus.length ) {
12201			hasFocus = this.element.find( ":tabbable" );
12202		}
12203		if ( !hasFocus.length ) {
12204			hasFocus = this.uiDialogButtonPane.find( ":tabbable" );
12205		}
12206		if ( !hasFocus.length ) {
12207			hasFocus = this.uiDialogTitlebarClose.filter( ":tabbable" );
12208		}
12209		if ( !hasFocus.length ) {
12210			hasFocus = this.uiDialog;
12211		}
12212		hasFocus.eq( 0 ).trigger( "focus" );
12213	},
12214
12215	_keepFocus: function( event ) {
12216		function checkFocus() {
12217			var activeElement = $.ui.safeActiveElement( this.document[ 0 ] ),
12218				isActive = this.uiDialog[ 0 ] === activeElement ||
12219					$.contains( this.uiDialog[ 0 ], activeElement );
12220			if ( !isActive ) {
12221				this._focusTabbable();
12222			}
12223		}
12224		event.preventDefault();
12225		checkFocus.call( this );
12226
12227		// support: IE
12228		// IE <= 8 doesn't prevent moving focus even with event.preventDefault()
12229		// so we check again later
12230		this._delay( checkFocus );
12231	},
12232
12233	_createWrapper: function() {
12234		this.uiDialog = $( "<div>" )
12235			.hide()
12236			.attr( {
12237
12238				// Setting tabIndex makes the div focusable
12239				tabIndex: -1,
12240				role: "dialog"
12241			} )
12242			.appendTo( this._appendTo() );
12243
12244		this._addClass( this.uiDialog, "ui-dialog", "ui-widget ui-widget-content ui-front" );
12245		this._on( this.uiDialog, {
12246			keydown: function( event ) {
12247				if ( this.options.closeOnEscape && !event.isDefaultPrevented() && event.keyCode &&
12248						event.keyCode === $.ui.keyCode.ESCAPE ) {
12249					event.preventDefault();
12250					this.close( event );
12251					return;
12252				}
12253
12254				// Prevent tabbing out of dialogs
12255				if ( event.keyCode !== $.ui.keyCode.TAB || event.isDefaultPrevented() ) {
12256					return;
12257				}
12258				var tabbables = this.uiDialog.find( ":tabbable" ),
12259					first = tabbables.filter( ":first" ),
12260					last = tabbables.filter( ":last" );
12261
12262				if ( ( event.target === last[ 0 ] || event.target === this.uiDialog[ 0 ] ) &&
12263						!event.shiftKey ) {
12264					this._delay( function() {
12265						first.trigger( "focus" );
12266					} );
12267					event.preventDefault();
12268				} else if ( ( event.target === first[ 0 ] ||
12269						event.target === this.uiDialog[ 0 ] ) && event.shiftKey ) {
12270					this._delay( function() {
12271						last.trigger( "focus" );
12272					} );
12273					event.preventDefault();
12274				}
12275			},
12276			mousedown: function( event ) {
12277				if ( this._moveToTop( event ) ) {
12278					this._focusTabbable();
12279				}
12280			}
12281		} );
12282
12283		// We assume that any existing aria-describedby attribute means
12284		// that the dialog content is marked up properly
12285		// otherwise we brute force the content as the description
12286		if ( !this.element.find( "[aria-describedby]" ).length ) {
12287			this.uiDialog.attr( {
12288				"aria-describedby": this.element.uniqueId().attr( "id" )
12289			} );
12290		}
12291	},
12292
12293	_createTitlebar: function() {
12294		var uiDialogTitle;
12295
12296		this.uiDialogTitlebar = $( "<div>" );
12297		this._addClass( this.uiDialogTitlebar,
12298			"ui-dialog-titlebar", "ui-widget-header ui-helper-clearfix" );
12299		this._on( this.uiDialogTitlebar, {
12300			mousedown: function( event ) {
12301
12302				// Don't prevent click on close button (#8838)
12303				// Focusing a dialog that is partially scrolled out of view
12304				// causes the browser to scroll it into view, preventing the click event
12305				if ( !$( event.target ).closest( ".ui-dialog-titlebar-close" ) ) {
12306
12307					// Dialog isn't getting focus when dragging (#8063)
12308					this.uiDialog.trigger( "focus" );
12309				}
12310			}
12311		} );
12312
12313		// Support: IE
12314		// Use type="button" to prevent enter keypresses in textboxes from closing the
12315		// dialog in IE (#9312)
12316		this.uiDialogTitlebarClose = $( "<button type='button'></button>" )
12317			.button( {
12318				label: $( "<a>" ).text( this.options.closeText ).html(),
12319				icon: "ui-icon-closethick",
12320				showLabel: false
12321			} )
12322			.appendTo( this.uiDialogTitlebar );
12323
12324		this._addClass( this.uiDialogTitlebarClose, "ui-dialog-titlebar-close" );
12325		this._on( this.uiDialogTitlebarClose, {
12326			click: function( event ) {
12327				event.preventDefault();
12328				this.close( event );
12329			}
12330		} );
12331
12332		uiDialogTitle = $( "<span>" ).uniqueId().prependTo( this.uiDialogTitlebar );
12333		this._addClass( uiDialogTitle, "ui-dialog-title" );
12334		this._title( uiDialogTitle );
12335
12336		this.uiDialogTitlebar.prependTo( this.uiDialog );
12337
12338		this.uiDialog.attr( {
12339			"aria-labelledby": uiDialogTitle.attr( "id" )
12340		} );
12341	},
12342
12343	_title: function( title ) {
12344		if ( this.options.title ) {
12345			title.text( this.options.title );
12346		} else {
12347			title.html( "&#160;" );
12348		}
12349	},
12350
12351	_createButtonPane: function() {
12352		this.uiDialogButtonPane = $( "<div>" );
12353		this._addClass( this.uiDialogButtonPane, "ui-dialog-buttonpane",
12354			"ui-widget-content ui-helper-clearfix" );
12355
12356		this.uiButtonSet = $( "<div>" )
12357			.appendTo( this.uiDialogButtonPane );
12358		this._addClass( this.uiButtonSet, "ui-dialog-buttonset" );
12359
12360		this._createButtons();
12361	},
12362
12363	_createButtons: function() {
12364		var that = this,
12365			buttons = this.options.buttons;
12366
12367		// If we already have a button pane, remove it
12368		this.uiDialogButtonPane.remove();
12369		this.uiButtonSet.empty();
12370
12371		if ( $.isEmptyObject( buttons ) || ( $.isArray( buttons ) && !buttons.length ) ) {
12372			this._removeClass( this.uiDialog, "ui-dialog-buttons" );
12373			return;
12374		}
12375
12376		$.each( buttons, function( name, props ) {
12377			var click, buttonOptions;
12378			props = $.isFunction( props ) ?
12379				{ click: props, text: name } :
12380				props;
12381
12382			// Default to a non-submitting button
12383			props = $.extend( { type: "button" }, props );
12384
12385			// Change the context for the click callback to be the main element
12386			click = props.click;
12387			buttonOptions = {
12388				icon: props.icon,
12389				iconPosition: props.iconPosition,
12390				showLabel: props.showLabel,
12391
12392				// Deprecated options
12393				icons: props.icons,
12394				text: props.text
12395			};
12396
12397			delete props.click;
12398			delete props.icon;
12399			delete props.iconPosition;
12400			delete props.showLabel;
12401
12402			// Deprecated options
12403			delete props.icons;
12404			if ( typeof props.text === "boolean" ) {
12405				delete props.text;
12406			}
12407
12408			$( "<button></button>", props )
12409				.button( buttonOptions )
12410				.appendTo( that.uiButtonSet )
12411				.on( "click", function() {
12412					click.apply( that.element[ 0 ], arguments );
12413				} );
12414		} );
12415		this._addClass( this.uiDialog, "ui-dialog-buttons" );
12416		this.uiDialogButtonPane.appendTo( this.uiDialog );
12417	},
12418
12419	_makeDraggable: function() {
12420		var that = this,
12421			options = this.options;
12422
12423		function filteredUi( ui ) {
12424			return {
12425				position: ui.position,
12426				offset: ui.offset
12427			};
12428		}
12429
12430		this.uiDialog.draggable( {
12431			cancel: ".ui-dialog-content, .ui-dialog-titlebar-close",
12432			handle: ".ui-dialog-titlebar",
12433			containment: "document",
12434			start: function( event, ui ) {
12435				that._addClass( $( this ), "ui-dialog-dragging" );
12436				that._blockFrames();
12437				that._trigger( "dragStart", event, filteredUi( ui ) );
12438			},
12439			drag: function( event, ui ) {
12440				that._trigger( "drag", event, filteredUi( ui ) );
12441			},
12442			stop: function( event, ui ) {
12443				var left = ui.offset.left - that.document.scrollLeft(),
12444					top = ui.offset.top - that.document.scrollTop();
12445
12446				options.position = {
12447					my: "left top",
12448					at: "left" + ( left >= 0 ? "+" : "" ) + left + " " +
12449						"top" + ( top >= 0 ? "+" : "" ) + top,
12450					of: that.window
12451				};
12452				that._removeClass( $( this ), "ui-dialog-dragging" );
12453				that._unblockFrames();
12454				that._trigger( "dragStop", event, filteredUi( ui ) );
12455			}
12456		} );
12457	},
12458
12459	_makeResizable: function() {
12460		var that = this,
12461			options = this.options,
12462			handles = options.resizable,
12463
12464			// .ui-resizable has position: relative defined in the stylesheet
12465			// but dialogs have to use absolute or fixed positioning
12466			position = this.uiDialog.css( "position" ),
12467			resizeHandles = typeof handles === "string" ?
12468				handles :
12469				"n,e,s,w,se,sw,ne,nw";
12470
12471		function filteredUi( ui ) {
12472			return {
12473				originalPosition: ui.originalPosition,
12474				originalSize: ui.originalSize,
12475				position: ui.position,
12476				size: ui.size
12477			};
12478		}
12479
12480		this.uiDialog.resizable( {
12481			cancel: ".ui-dialog-content",
12482			containment: "document",
12483			alsoResize: this.element,
12484			maxWidth: options.maxWidth,
12485			maxHeight: options.maxHeight,
12486			minWidth: options.minWidth,
12487			minHeight: this._minHeight(),
12488			handles: resizeHandles,
12489			start: function( event, ui ) {
12490				that._addClass( $( this ), "ui-dialog-resizing" );
12491				that._blockFrames();
12492				that._trigger( "resizeStart", event, filteredUi( ui ) );
12493			},
12494			resize: function( event, ui ) {
12495				that._trigger( "resize", event, filteredUi( ui ) );
12496			},
12497			stop: function( event, ui ) {
12498				var offset = that.uiDialog.offset(),
12499					left = offset.left - that.document.scrollLeft(),
12500					top = offset.top - that.document.scrollTop();
12501
12502				options.height = that.uiDialog.height();
12503				options.width = that.uiDialog.width();
12504				options.position = {
12505					my: "left top",
12506					at: "left" + ( left >= 0 ? "+" : "" ) + left + " " +
12507						"top" + ( top >= 0 ? "+" : "" ) + top,
12508					of: that.window
12509				};
12510				that._removeClass( $( this ), "ui-dialog-resizing" );
12511				that._unblockFrames();
12512				that._trigger( "resizeStop", event, filteredUi( ui ) );
12513			}
12514		} )
12515			.css( "position", position );
12516	},
12517
12518	_trackFocus: function() {
12519		this._on( this.widget(), {
12520			focusin: function( event ) {
12521				this._makeFocusTarget();
12522				this._focusedElement = $( event.target );
12523			}
12524		} );
12525	},
12526
12527	_makeFocusTarget: function() {
12528		this._untrackInstance();
12529		this._trackingInstances().unshift( this );
12530	},
12531
12532	_untrackInstance: function() {
12533		var instances = this._trackingInstances(),
12534			exists = $.inArray( this, instances );
12535		if ( exists !== -1 ) {
12536			instances.splice( exists, 1 );
12537		}
12538	},
12539
12540	_trackingInstances: function() {
12541		var instances = this.document.data( "ui-dialog-instances" );
12542		if ( !instances ) {
12543			instances = [];
12544			this.document.data( "ui-dialog-instances", instances );
12545		}
12546		return instances;
12547	},
12548
12549	_minHeight: function() {
12550		var options = this.options;
12551
12552		return options.height === "auto" ?
12553			options.minHeight :
12554			Math.min( options.minHeight, options.height );
12555	},
12556
12557	_position: function() {
12558
12559		// Need to show the dialog to get the actual offset in the position plugin
12560		var isVisible = this.uiDialog.is( ":visible" );
12561		if ( !isVisible ) {
12562			this.uiDialog.show();
12563		}
12564		this.uiDialog.position( this.options.position );
12565		if ( !isVisible ) {
12566			this.uiDialog.hide();
12567		}
12568	},
12569
12570	_setOptions: function( options ) {
12571		var that = this,
12572			resize = false,
12573			resizableOptions = {};
12574
12575		$.each( options, function( key, value ) {
12576			that._setOption( key, value );
12577
12578			if ( key in that.sizeRelatedOptions ) {
12579				resize = true;
12580			}
12581			if ( key in that.resizableRelatedOptions ) {
12582				resizableOptions[ key ] = value;
12583			}
12584		} );
12585
12586		if ( resize ) {
12587			this._size();
12588			this._position();
12589		}
12590		if ( this.uiDialog.is( ":data(ui-resizable)" ) ) {
12591			this.uiDialog.resizable( "option", resizableOptions );
12592		}
12593	},
12594
12595	_setOption: function( key, value ) {
12596		var isDraggable, isResizable,
12597			uiDialog = this.uiDialog;
12598
12599		if ( key === "disabled" ) {
12600			return;
12601		}
12602
12603		this._super( key, value );
12604
12605		if ( key === "appendTo" ) {
12606			this.uiDialog.appendTo( this._appendTo() );
12607		}
12608
12609		if ( key === "buttons" ) {
12610			this._createButtons();
12611		}
12612
12613		if ( key === "closeText" ) {
12614			this.uiDialogTitlebarClose.button( {
12615
12616				// Ensure that we always pass a string
12617				label: $( "<a>" ).text( "" + this.options.closeText ).html()
12618			} );
12619		}
12620
12621		if ( key === "draggable" ) {
12622			isDraggable = uiDialog.is( ":data(ui-draggable)" );
12623			if ( isDraggable && !value ) {
12624				uiDialog.draggable( "destroy" );
12625			}
12626
12627			if ( !isDraggable && value ) {
12628				this._makeDraggable();
12629			}
12630		}
12631
12632		if ( key === "position" ) {
12633			this._position();
12634		}
12635
12636		if ( key === "resizable" ) {
12637
12638			// currently resizable, becoming non-resizable
12639			isResizable = uiDialog.is( ":data(ui-resizable)" );
12640			if ( isResizable && !value ) {
12641				uiDialog.resizable( "destroy" );
12642			}
12643
12644			// Currently resizable, changing handles
12645			if ( isResizable && typeof value === "string" ) {
12646				uiDialog.resizable( "option", "handles", value );
12647			}
12648
12649			// Currently non-resizable, becoming resizable
12650			if ( !isResizable && value !== false ) {
12651				this._makeResizable();
12652			}
12653		}
12654
12655		if ( key === "title" ) {
12656			this._title( this.uiDialogTitlebar.find( ".ui-dialog-title" ) );
12657		}
12658	},
12659
12660	_size: function() {
12661
12662		// If the user has resized the dialog, the .ui-dialog and .ui-dialog-content
12663		// divs will both have width and height set, so we need to reset them
12664		var nonContentHeight, minContentHeight, maxContentHeight,
12665			options = this.options;
12666
12667		// Reset content sizing
12668		this.element.show().css( {
12669			width: "auto",
12670			minHeight: 0,
12671			maxHeight: "none",
12672			height: 0
12673		} );
12674
12675		if ( options.minWidth > options.width ) {
12676			options.width = options.minWidth;
12677		}
12678
12679		// Reset wrapper sizing
12680		// determine the height of all the non-content elements
12681		nonContentHeight = this.uiDialog.css( {
12682			height: "auto",
12683			width: options.width
12684		} )
12685			.outerHeight();
12686		minContentHeight = Math.max( 0, options.minHeight - nonContentHeight );
12687		maxContentHeight = typeof options.maxHeight === "number" ?
12688			Math.max( 0, options.maxHeight - nonContentHeight ) :
12689			"none";
12690
12691		if ( options.height === "auto" ) {
12692			this.element.css( {
12693				minHeight: minContentHeight,
12694				maxHeight: maxContentHeight,
12695				height: "auto"
12696			} );
12697		} else {
12698			this.element.height( Math.max( 0, options.height - nonContentHeight ) );
12699		}
12700
12701		if ( this.uiDialog.is( ":data(ui-resizable)" ) ) {
12702			this.uiDialog.resizable( "option", "minHeight", this._minHeight() );
12703		}
12704	},
12705
12706	_blockFrames: function() {
12707		this.iframeBlocks = this.document.find( "iframe" ).map( function() {
12708			var iframe = $( this );
12709
12710			return $( "<div>" )
12711				.css( {
12712					position: "absolute",
12713					width: iframe.outerWidth(),
12714					height: iframe.outerHeight()
12715				} )
12716				.appendTo( iframe.parent() )
12717				.offset( iframe.offset() )[ 0 ];
12718		} );
12719	},
12720
12721	_unblockFrames: function() {
12722		if ( this.iframeBlocks ) {
12723			this.iframeBlocks.remove();
12724			delete this.iframeBlocks;
12725		}
12726	},
12727
12728	_allowInteraction: function( event ) {
12729		if ( $( event.target ).closest( ".ui-dialog" ).length ) {
12730			return true;
12731		}
12732
12733		// TODO: Remove hack when datepicker implements
12734		// the .ui-front logic (#8989)
12735		return !!$( event.target ).closest( ".ui-datepicker" ).length;
12736	},
12737
12738	_createOverlay: function() {
12739		if ( !this.options.modal ) {
12740			return;
12741		}
12742
12743		// We use a delay in case the overlay is created from an
12744		// event that we're going to be cancelling (#2804)
12745		var isOpening = true;
12746		this._delay( function() {
12747			isOpening = false;
12748		} );
12749
12750		if ( !this.document.data( "ui-dialog-overlays" ) ) {
12751
12752			// Prevent use of anchors and inputs
12753			// Using _on() for an event handler shared across many instances is
12754			// safe because the dialogs stack and must be closed in reverse order
12755			this._on( this.document, {
12756				focusin: function( event ) {
12757					if ( isOpening ) {
12758						return;
12759					}
12760
12761					if ( !this._allowInteraction( event ) ) {
12762						event.preventDefault();
12763						this._trackingInstances()[ 0 ]._focusTabbable();
12764					}
12765				}
12766			} );
12767		}
12768
12769		this.overlay = $( "<div>" )
12770			.appendTo( this._appendTo() );
12771
12772		this._addClass( this.overlay, null, "ui-widget-overlay ui-front" );
12773		this._on( this.overlay, {
12774			mousedown: "_keepFocus"
12775		} );
12776		this.document.data( "ui-dialog-overlays",
12777			( this.document.data( "ui-dialog-overlays" ) || 0 ) + 1 );
12778	},
12779
12780	_destroyOverlay: function() {
12781		if ( !this.options.modal ) {
12782			return;
12783		}
12784
12785		if ( this.overlay ) {
12786			var overlays = this.document.data( "ui-dialog-overlays" ) - 1;
12787
12788			if ( !overlays ) {
12789				this._off( this.document, "focusin" );
12790				this.document.removeData( "ui-dialog-overlays" );
12791			} else {
12792				this.document.data( "ui-dialog-overlays", overlays );
12793			}
12794
12795			this.overlay.remove();
12796			this.overlay = null;
12797		}
12798	}
12799} );
12800
12801// DEPRECATED
12802// TODO: switch return back to widget declaration at top of file when this is removed
12803if ( $.uiBackCompat !== false ) {
12804
12805	// Backcompat for dialogClass option
12806	$.widget( "ui.dialog", $.ui.dialog, {
12807		options: {
12808			dialogClass: ""
12809		},
12810		_createWrapper: function() {
12811			this._super();
12812			this.uiDialog.addClass( this.options.dialogClass );
12813		},
12814		_setOption: function( key, value ) {
12815			if ( key === "dialogClass" ) {
12816				this.uiDialog
12817					.removeClass( this.options.dialogClass )
12818					.addClass( value );
12819			}
12820			this._superApply( arguments );
12821		}
12822	} );
12823}
12824
12825var widgetsDialog = $.ui.dialog;
12826
12827
12828/*!
12829 * jQuery UI Droppable 1.12.1
12830 * http://jqueryui.com
12831 *
12832 * Copyright jQuery Foundation and other contributors
12833 * Released under the MIT license.
12834 * http://jquery.org/license
12835 */
12836
12837//>>label: Droppable
12838//>>group: Interactions
12839//>>description: Enables drop targets for draggable elements.
12840//>>docs: http://api.jqueryui.com/droppable/
12841//>>demos: http://jqueryui.com/droppable/
12842
12843
12844
12845$.widget( "ui.droppable", {
12846	version: "1.12.1",
12847	widgetEventPrefix: "drop",
12848	options: {
12849		accept: "*",
12850		addClasses: true,
12851		greedy: false,
12852		scope: "default",
12853		tolerance: "intersect",
12854
12855		// Callbacks
12856		activate: null,
12857		deactivate: null,
12858		drop: null,
12859		out: null,
12860		over: null
12861	},
12862	_create: function() {
12863
12864		var proportions,
12865			o = this.options,
12866			accept = o.accept;
12867
12868		this.isover = false;
12869		this.isout = true;
12870
12871		this.accept = $.isFunction( accept ) ? accept : function( d ) {
12872			return d.is( accept );
12873		};
12874
12875		this.proportions = function( /* valueToWrite */ ) {
12876			if ( arguments.length ) {
12877
12878				// Store the droppable's proportions
12879				proportions = arguments[ 0 ];
12880			} else {
12881
12882				// Retrieve or derive the droppable's proportions
12883				return proportions ?
12884					proportions :
12885					proportions = {
12886						width: this.element[ 0 ].offsetWidth,
12887						height: this.element[ 0 ].offsetHeight
12888					};
12889			}
12890		};
12891
12892		this._addToManager( o.scope );
12893
12894		o.addClasses && this._addClass( "ui-droppable" );
12895
12896	},
12897
12898	_addToManager: function( scope ) {
12899
12900		// Add the reference and positions to the manager
12901		$.ui.ddmanager.droppables[ scope ] = $.ui.ddmanager.droppables[ scope ] || [];
12902		$.ui.ddmanager.droppables[ scope ].push( this );
12903	},
12904
12905	_splice: function( drop ) {
12906		var i = 0;
12907		for ( ; i < drop.length; i++ ) {
12908			if ( drop[ i ] === this ) {
12909				drop.splice( i, 1 );
12910			}
12911		}
12912	},
12913
12914	_destroy: function() {
12915		var drop = $.ui.ddmanager.droppables[ this.options.scope ];
12916
12917		this._splice( drop );
12918	},
12919
12920	_setOption: function( key, value ) {
12921
12922		if ( key === "accept" ) {
12923			this.accept = $.isFunction( value ) ? value : function( d ) {
12924				return d.is( value );
12925			};
12926		} else if ( key === "scope" ) {
12927			var drop = $.ui.ddmanager.droppables[ this.options.scope ];
12928
12929			this._splice( drop );
12930			this._addToManager( value );
12931		}
12932
12933		this._super( key, value );
12934	},
12935
12936	_activate: function( event ) {
12937		var draggable = $.ui.ddmanager.current;
12938
12939		this._addActiveClass();
12940		if ( draggable ) {
12941			this._trigger( "activate", event, this.ui( draggable ) );
12942		}
12943	},
12944
12945	_deactivate: function( event ) {
12946		var draggable = $.ui.ddmanager.current;
12947
12948		this._removeActiveClass();
12949		if ( draggable ) {
12950			this._trigger( "deactivate", event, this.ui( draggable ) );
12951		}
12952	},
12953
12954	_over: function( event ) {
12955
12956		var draggable = $.ui.ddmanager.current;
12957
12958		// Bail if draggable and droppable are same element
12959		if ( !draggable || ( draggable.currentItem ||
12960				draggable.element )[ 0 ] === this.element[ 0 ] ) {
12961			return;
12962		}
12963
12964		if ( this.accept.call( this.element[ 0 ], ( draggable.currentItem ||
12965				draggable.element ) ) ) {
12966			this._addHoverClass();
12967			this._trigger( "over", event, this.ui( draggable ) );
12968		}
12969
12970	},
12971
12972	_out: function( event ) {
12973
12974		var draggable = $.ui.ddmanager.current;
12975
12976		// Bail if draggable and droppable are same element
12977		if ( !draggable || ( draggable.currentItem ||
12978				draggable.element )[ 0 ] === this.element[ 0 ] ) {
12979			return;
12980		}
12981
12982		if ( this.accept.call( this.element[ 0 ], ( draggable.currentItem ||
12983				draggable.element ) ) ) {
12984			this._removeHoverClass();
12985			this._trigger( "out", event, this.ui( draggable ) );
12986		}
12987
12988	},
12989
12990	_drop: function( event, custom ) {
12991
12992		var draggable = custom || $.ui.ddmanager.current,
12993			childrenIntersection = false;
12994
12995		// Bail if draggable and droppable are same element
12996		if ( !draggable || ( draggable.currentItem ||
12997				draggable.element )[ 0 ] === this.element[ 0 ] ) {
12998			return false;
12999		}
13000
13001		this.element
13002			.find( ":data(ui-droppable)" )
13003			.not( ".ui-draggable-dragging" )
13004			.each( function() {
13005				var inst = $( this ).droppable( "instance" );
13006				if (
13007					inst.options.greedy &&
13008					!inst.options.disabled &&
13009					inst.options.scope === draggable.options.scope &&
13010					inst.accept.call(
13011						inst.element[ 0 ], ( draggable.currentItem || draggable.element )
13012					) &&
13013					intersect(
13014						draggable,
13015						$.extend( inst, { offset: inst.element.offset() } ),
13016						inst.options.tolerance, event
13017					)
13018				) {
13019					childrenIntersection = true;
13020					return false; }
13021			} );
13022		if ( childrenIntersection ) {
13023			return false;
13024		}
13025
13026		if ( this.accept.call( this.element[ 0 ],
13027				( draggable.currentItem || draggable.element ) ) ) {
13028			this._removeActiveClass();
13029			this._removeHoverClass();
13030
13031			this._trigger( "drop", event, this.ui( draggable ) );
13032			return this.element;
13033		}
13034
13035		return false;
13036
13037	},
13038
13039	ui: function( c ) {
13040		return {
13041			draggable: ( c.currentItem || c.element ),
13042			helper: c.helper,
13043			position: c.position,
13044			offset: c.positionAbs
13045		};
13046	},
13047
13048	// Extension points just to make backcompat sane and avoid duplicating logic
13049	// TODO: Remove in 1.13 along with call to it below
13050	_addHoverClass: function() {
13051		this._addClass( "ui-droppable-hover" );
13052	},
13053
13054	_removeHoverClass: function() {
13055		this._removeClass( "ui-droppable-hover" );
13056	},
13057
13058	_addActiveClass: function() {
13059		this._addClass( "ui-droppable-active" );
13060	},
13061
13062	_removeActiveClass: function() {
13063		this._removeClass( "ui-droppable-active" );
13064	}
13065} );
13066
13067var intersect = $.ui.intersect = ( function() {
13068	function isOverAxis( x, reference, size ) {
13069		return ( x >= reference ) && ( x < ( reference + size ) );
13070	}
13071
13072	return function( draggable, droppable, toleranceMode, event ) {
13073
13074		if ( !droppable.offset ) {
13075			return false;
13076		}
13077
13078		var x1 = ( draggable.positionAbs ||
13079				draggable.position.absolute ).left + draggable.margins.left,
13080			y1 = ( draggable.positionAbs ||
13081				draggable.position.absolute ).top + draggable.margins.top,
13082			x2 = x1 + draggable.helperProportions.width,
13083			y2 = y1 + draggable.helperProportions.height,
13084			l = droppable.offset.left,
13085			t = droppable.offset.top,
13086			r = l + droppable.proportions().width,
13087			b = t + droppable.proportions().height;
13088
13089		switch ( toleranceMode ) {
13090		case "fit":
13091			return ( l <= x1 && x2 <= r && t <= y1 && y2 <= b );
13092		case "intersect":
13093			return ( l < x1 + ( draggable.helperProportions.width / 2 ) && // Right Half
13094				x2 - ( draggable.helperProportions.width / 2 ) < r && // Left Half
13095				t < y1 + ( draggable.helperProportions.height / 2 ) && // Bottom Half
13096				y2 - ( draggable.helperProportions.height / 2 ) < b ); // Top Half
13097		case "pointer":
13098			return isOverAxis( event.pageY, t, droppable.proportions().height ) &&
13099				isOverAxis( event.pageX, l, droppable.proportions().width );
13100		case "touch":
13101			return (
13102				( y1 >= t && y1 <= b ) || // Top edge touching
13103				( y2 >= t && y2 <= b ) || // Bottom edge touching
13104				( y1 < t && y2 > b ) // Surrounded vertically
13105			) && (
13106				( x1 >= l && x1 <= r ) || // Left edge touching
13107				( x2 >= l && x2 <= r ) || // Right edge touching
13108				( x1 < l && x2 > r ) // Surrounded horizontally
13109			);
13110		default:
13111			return false;
13112		}
13113	};
13114} )();
13115
13116/*
13117	This manager tracks offsets of draggables and droppables
13118*/
13119$.ui.ddmanager = {
13120	current: null,
13121	droppables: { "default": [] },
13122	prepareOffsets: function( t, event ) {
13123
13124		var i, j,
13125			m = $.ui.ddmanager.droppables[ t.options.scope ] || [],
13126			type = event ? event.type : null, // workaround for #2317
13127			list = ( t.currentItem || t.element ).find( ":data(ui-droppable)" ).addBack();
13128
13129		droppablesLoop: for ( i = 0; i < m.length; i++ ) {
13130
13131			// No disabled and non-accepted
13132			if ( m[ i ].options.disabled || ( t && !m[ i ].accept.call( m[ i ].element[ 0 ],
13133					( t.currentItem || t.element ) ) ) ) {
13134				continue;
13135			}
13136
13137			// Filter out elements in the current dragged item
13138			for ( j = 0; j < list.length; j++ ) {
13139				if ( list[ j ] === m[ i ].element[ 0 ] ) {
13140					m[ i ].proportions().height = 0;
13141					continue droppablesLoop;
13142				}
13143			}
13144
13145			m[ i ].visible = m[ i ].element.css( "display" ) !== "none";
13146			if ( !m[ i ].visible ) {
13147				continue;
13148			}
13149
13150			// Activate the droppable if used directly from draggables
13151			if ( type === "mousedown" ) {
13152				m[ i ]._activate.call( m[ i ], event );
13153			}
13154
13155			m[ i ].offset = m[ i ].element.offset();
13156			m[ i ].proportions( {
13157				width: m[ i ].element[ 0 ].offsetWidth,
13158				height: m[ i ].element[ 0 ].offsetHeight
13159			} );
13160
13161		}
13162
13163	},
13164	drop: function( draggable, event ) {
13165
13166		var dropped = false;
13167
13168		// Create a copy of the droppables in case the list changes during the drop (#9116)
13169		$.each( ( $.ui.ddmanager.droppables[ draggable.options.scope ] || [] ).slice(), function() {
13170
13171			if ( !this.options ) {
13172				return;
13173			}
13174			if ( !this.options.disabled && this.visible &&
13175					intersect( draggable, this, this.options.tolerance, event ) ) {
13176				dropped = this._drop.call( this, event ) || dropped;
13177			}
13178
13179			if ( !this.options.disabled && this.visible && this.accept.call( this.element[ 0 ],
13180					( draggable.currentItem || draggable.element ) ) ) {
13181				this.isout = true;
13182				this.isover = false;
13183				this._deactivate.call( this, event );
13184			}
13185
13186		} );
13187		return dropped;
13188
13189	},
13190	dragStart: function( draggable, event ) {
13191
13192		// Listen for scrolling so that if the dragging causes scrolling the position of the
13193		// droppables can be recalculated (see #5003)
13194		draggable.element.parentsUntil( "body" ).on( "scroll.droppable", function() {
13195			if ( !draggable.options.refreshPositions ) {
13196				$.ui.ddmanager.prepareOffsets( draggable, event );
13197			}
13198		} );
13199	},
13200	drag: function( draggable, event ) {
13201
13202		// If you have a highly dynamic page, you might try this option. It renders positions
13203		// every time you move the mouse.
13204		if ( draggable.options.refreshPositions ) {
13205			$.ui.ddmanager.prepareOffsets( draggable, event );
13206		}
13207
13208		// Run through all droppables and check their positions based on specific tolerance options
13209		$.each( $.ui.ddmanager.droppables[ draggable.options.scope ] || [], function() {
13210
13211			if ( this.options.disabled || this.greedyChild || !this.visible ) {
13212				return;
13213			}
13214
13215			var parentInstance, scope, parent,
13216				intersects = intersect( draggable, this, this.options.tolerance, event ),
13217				c = !intersects && this.isover ?
13218					"isout" :
13219					( intersects && !this.isover ? "isover" : null );
13220			if ( !c ) {
13221				return;
13222			}
13223
13224			if ( this.options.greedy ) {
13225
13226				// find droppable parents with same scope
13227				scope = this.options.scope;
13228				parent = this.element.parents( ":data(ui-droppable)" ).filter( function() {
13229					return $( this ).droppable( "instance" ).options.scope === scope;
13230				} );
13231
13232				if ( parent.length ) {
13233					parentInstance = $( parent[ 0 ] ).droppable( "instance" );
13234					parentInstance.greedyChild = ( c === "isover" );
13235				}
13236			}
13237
13238			// We just moved into a greedy child
13239			if ( parentInstance && c === "isover" ) {
13240				parentInstance.isover = false;
13241				parentInstance.isout = true;
13242				parentInstance._out.call( parentInstance, event );
13243			}
13244
13245			this[ c ] = true;
13246			this[ c === "isout" ? "isover" : "isout" ] = false;
13247			this[ c === "isover" ? "_over" : "_out" ].call( this, event );
13248
13249			// We just moved out of a greedy child
13250			if ( parentInstance && c === "isout" ) {
13251				parentInstance.isout = false;
13252				parentInstance.isover = true;
13253				parentInstance._over.call( parentInstance, event );
13254			}
13255		} );
13256
13257	},
13258	dragStop: function( draggable, event ) {
13259		draggable.element.parentsUntil( "body" ).off( "scroll.droppable" );
13260
13261		// Call prepareOffsets one final time since IE does not fire return scroll events when
13262		// overflow was caused by drag (see #5003)
13263		if ( !draggable.options.refreshPositions ) {
13264			$.ui.ddmanager.prepareOffsets( draggable, event );
13265		}
13266	}
13267};
13268
13269// DEPRECATED
13270// TODO: switch return back to widget declaration at top of file when this is removed
13271if ( $.uiBackCompat !== false ) {
13272
13273	// Backcompat for activeClass and hoverClass options
13274	$.widget( "ui.droppable", $.ui.droppable, {
13275		options: {
13276			hoverClass: false,
13277			activeClass: false
13278		},
13279		_addActiveClass: function() {
13280			this._super();
13281			if ( this.options.activeClass ) {
13282				this.element.addClass( this.options.activeClass );
13283			}
13284		},
13285		_removeActiveClass: function() {
13286			this._super();
13287			if ( this.options.activeClass ) {
13288				this.element.removeClass( this.options.activeClass );
13289			}
13290		},
13291		_addHoverClass: function() {
13292			this._super();
13293			if ( this.options.hoverClass ) {
13294				this.element.addClass( this.options.hoverClass );
13295			}
13296		},
13297		_removeHoverClass: function() {
13298			this._super();
13299			if ( this.options.hoverClass ) {
13300				this.element.removeClass( this.options.hoverClass );
13301			}
13302		}
13303	} );
13304}
13305
13306var widgetsDroppable = $.ui.droppable;
13307
13308
13309/*!
13310 * jQuery UI Progressbar 1.12.1
13311 * http://jqueryui.com
vendor: 12,231 bytes, lines 13312-13770
13312 *
13313 * Copyright jQuery Foundation and other contributors
13314 * Released under the MIT license.
13315 * http://jquery.org/license
13316 */
13317
13318//>>label: Progressbar
13319//>>group: Widgets
13320// jscs:disable maximumLineLength
13321//>>description: Displays a status indicator for loading state, standard percentage, and other progress indicators.
13322// jscs:enable maximumLineLength
13323//>>docs: http://api.jqueryui.com/progressbar/
13324//>>demos: http://jqueryui.com/progressbar/
13325//>>css.structure: ../../themes/base/core.css
13326//>>css.structure: ../../themes/base/progressbar.css
13327//>>css.theme: ../../themes/base/theme.css
13328
13329
13330
13331var widgetsProgressbar = $.widget( "ui.progressbar", {
13332	version: "1.12.1",
13333	options: {
13334		classes: {
13335			"ui-progressbar": "ui-corner-all",
13336			"ui-progressbar-value": "ui-corner-left",
13337			"ui-progressbar-complete": "ui-corner-right"
13338		},
13339		max: 100,
13340		value: 0,
13341
13342		change: null,
13343		complete: null
13344	},
13345
13346	min: 0,
13347
13348	_create: function() {
13349
13350		// Constrain initial value
13351		this.oldValue = this.options.value = this._constrainedValue();
13352
13353		this.element.attr( {
13354
13355			// Only set static values; aria-valuenow and aria-valuemax are
13356			// set inside _refreshValue()
13357			role: "progressbar",
13358			"aria-valuemin": this.min
13359		} );
13360		this._addClass( "ui-progressbar", "ui-widget ui-widget-content" );
13361
13362		this.valueDiv = $( "<div>" ).appendTo( this.element );
13363		this._addClass( this.valueDiv, "ui-progressbar-value", "ui-widget-header" );
13364		this._refreshValue();
13365	},
13366
13367	_destroy: function() {
13368		this.element.removeAttr( "role aria-valuemin aria-valuemax aria-valuenow" );
13369
13370		this.valueDiv.remove();
13371	},
13372
13373	value: function( newValue ) {
13374		if ( newValue === undefined ) {
13375			return this.options.value;
13376		}
13377
13378		this.options.value = this._constrainedValue( newValue );
13379		this._refreshValue();
13380	},
13381
13382	_constrainedValue: function( newValue ) {
13383		if ( newValue === undefined ) {
13384			newValue = this.options.value;
13385		}
13386
13387		this.indeterminate = newValue === false;
13388
13389		// Sanitize value
13390		if ( typeof newValue !== "number" ) {
13391			newValue = 0;
13392		}
13393
13394		return this.indeterminate ? false :
13395			Math.min( this.options.max, Math.max( this.min, newValue ) );
13396	},
13397
13398	_setOptions: function( options ) {
13399
13400		// Ensure "value" option is set after other values (like max)
13401		var value = options.value;
13402		delete options.value;
13403
13404		this._super( options );
13405
13406		this.options.value = this._constrainedValue( value );
13407		this._refreshValue();
13408	},
13409
13410	_setOption: function( key, value ) {
13411		if ( key === "max" ) {
13412
13413			// Don't allow a max less than min
13414			value = Math.max( this.min, value );
13415		}
13416		this._super( key, value );
13417	},
13418
13419	_setOptionDisabled: function( value ) {
13420		this._super( value );
13421
13422		this.element.attr( "aria-disabled", value );
13423		this._toggleClass( null, "ui-state-disabled", !!value );
13424	},
13425
13426	_percentage: function() {
13427		return this.indeterminate ?
13428			100 :
13429			100 * ( this.options.value - this.min ) / ( this.options.max - this.min );
13430	},
13431
13432	_refreshValue: function() {
13433		var value = this.options.value,
13434			percentage = this._percentage();
13435
13436		this.valueDiv
13437			.toggle( this.indeterminate || value > this.min )
13438			.width( percentage.toFixed( 0 ) + "%" );
13439
13440		this
13441			._toggleClass( this.valueDiv, "ui-progressbar-complete", null,
13442				value === this.options.max )
13443			._toggleClass( "ui-progressbar-indeterminate", null, this.indeterminate );
13444
13445		if ( this.indeterminate ) {
13446			this.element.removeAttr( "aria-valuenow" );
13447			if ( !this.overlayDiv ) {
13448				this.overlayDiv = $( "<div>" ).appendTo( this.valueDiv );
13449				this._addClass( this.overlayDiv, "ui-progressbar-overlay" );
13450			}
13451		} else {
13452			this.element.attr( {
13453				"aria-valuemax": this.options.max,
13454				"aria-valuenow": value
13455			} );
13456			if ( this.overlayDiv ) {
13457				this.overlayDiv.remove();
13458				this.overlayDiv = null;
13459			}
13460		}
13461
13462		if ( this.oldValue !== value ) {
13463			this.oldValue = value;
13464			this._trigger( "change" );
13465		}
13466		if ( value === this.options.max ) {
13467			this._trigger( "complete" );
13468		}
13469	}
13470} );
13471
13472
13473/*!
13474 * jQuery UI Selectable 1.12.1
13475 * http://jqueryui.com
13476 *
13477 * Copyright jQuery Foundation and other contributors
13478 * Released under the MIT license.
13479 * http://jquery.org/license
13480 */
13481
13482//>>label: Selectable
13483//>>group: Interactions
13484//>>description: Allows groups of elements to be selected with the mouse.
13485//>>docs: http://api.jqueryui.com/selectable/
13486//>>demos: http://jqueryui.com/selectable/
13487//>>css.structure: ../../themes/base/selectable.css
13488
13489
13490
13491var widgetsSelectable = $.widget( "ui.selectable", $.ui.mouse, {
13492	version: "1.12.1",
13493	options: {
13494		appendTo: "body",
13495		autoRefresh: true,
13496		distance: 0,
13497		filter: "*",
13498		tolerance: "touch",
13499
13500		// Callbacks
13501		selected: null,
13502		selecting: null,
13503		start: null,
13504		stop: null,
13505		unselected: null,
13506		unselecting: null
13507	},
13508	_create: function() {
13509		var that = this;
13510
13511		this._addClass( "ui-selectable" );
13512
13513		this.dragged = false;
13514
13515		// Cache selectee children based on filter
13516		this.refresh = function() {
13517			that.elementPos = $( that.element[ 0 ] ).offset();
13518			that.selectees = $( that.options.filter, that.element[ 0 ] );
13519			that._addClass( that.selectees, "ui-selectee" );
13520			that.selectees.each( function() {
13521				var $this = $( this ),
13522					selecteeOffset = $this.offset(),
13523					pos = {
13524						left: selecteeOffset.left - that.elementPos.left,
13525						top: selecteeOffset.top - that.elementPos.top
13526					};
13527				$.data( this, "selectable-item", {
13528					element: this,
13529					$element: $this,
13530					left: pos.left,
13531					top: pos.top,
13532					right: pos.left + $this.outerWidth(),
13533					bottom: pos.top + $this.outerHeight(),
13534					startselected: false,
13535					selected: $this.hasClass( "ui-selected" ),
13536					selecting: $this.hasClass( "ui-selecting" ),
13537					unselecting: $this.hasClass( "ui-unselecting" )
13538				} );
13539			} );
13540		};
13541		this.refresh();
13542
13543		this._mouseInit();
13544
13545		this.helper = $( "<div>" );
13546		this._addClass( this.helper, "ui-selectable-helper" );
13547	},
13548
13549	_destroy: function() {
13550		this.selectees.removeData( "selectable-item" );
13551		this._mouseDestroy();
13552	},
13553
13554	_mouseStart: function( event ) {
13555		var that = this,
13556			options = this.options;
13557
13558		this.opos = [ event.pageX, event.pageY ];
13559		this.elementPos = $( this.element[ 0 ] ).offset();
13560
13561		if ( this.options.disabled ) {
13562			return;
13563		}
13564
13565		this.selectees = $( options.filter, this.element[ 0 ] );
13566
13567		this._trigger( "start", event );
13568
13569		$( options.appendTo ).append( this.helper );
13570
13571		// position helper (lasso)
13572		this.helper.css( {
13573			"left": event.pageX,
13574			"top": event.pageY,
13575			"width": 0,
13576			"height": 0
13577		} );
13578
13579		if ( options.autoRefresh ) {
13580			this.refresh();
13581		}
13582
13583		this.selectees.filter( ".ui-selected" ).each( function() {
13584			var selectee = $.data( this, "selectable-item" );
13585			selectee.startselected = true;
13586			if ( !event.metaKey && !event.ctrlKey ) {
13587				that._removeClass( selectee.$element, "ui-selected" );
13588				selectee.selected = false;
13589				that._addClass( selectee.$element, "ui-unselecting" );
13590				selectee.unselecting = true;
13591
13592				// selectable UNSELECTING callback
13593				that._trigger( "unselecting", event, {
13594					unselecting: selectee.element
13595				} );
13596			}
13597		} );
13598
13599		$( event.target ).parents().addBack().each( function() {
13600			var doSelect,
13601				selectee = $.data( this, "selectable-item" );
13602			if ( selectee ) {
13603				doSelect = ( !event.metaKey && !event.ctrlKey ) ||
13604					!selectee.$element.hasClass( "ui-selected" );
13605				that._removeClass( selectee.$element, doSelect ? "ui-unselecting" : "ui-selected" )
13606					._addClass( selectee.$element, doSelect ? "ui-selecting" : "ui-unselecting" );
13607				selectee.unselecting = !doSelect;
13608				selectee.selecting = doSelect;
13609				selectee.selected = doSelect;
13610
13611				// selectable (UN)SELECTING callback
13612				if ( doSelect ) {
13613					that._trigger( "selecting", event, {
13614						selecting: selectee.element
13615					} );
13616				} else {
13617					that._trigger( "unselecting", event, {
13618						unselecting: selectee.element
13619					} );
13620				}
13621				return false;
13622			}
13623		} );
13624
13625	},
13626
13627	_mouseDrag: function( event ) {
13628
13629		this.dragged = true;
13630
13631		if ( this.options.disabled ) {
13632			return;
13633		}
13634
13635		var tmp,
13636			that = this,
13637			options = this.options,
13638			x1 = this.opos[ 0 ],
13639			y1 = this.opos[ 1 ],
13640			x2 = event.pageX,
13641			y2 = event.pageY;
13642
13643		if ( x1 > x2 ) { tmp = x2; x2 = x1; x1 = tmp; }
13644		if ( y1 > y2 ) { tmp = y2; y2 = y1; y1 = tmp; }
13645		this.helper.css( { left: x1, top: y1, width: x2 - x1, height: y2 - y1 } );
13646
13647		this.selectees.each( function() {
13648			var selectee = $.data( this, "selectable-item" ),
13649				hit = false,
13650				offset = {};
13651
13652			//prevent helper from being selected if appendTo: selectable
13653			if ( !selectee || selectee.element === that.element[ 0 ] ) {
13654				return;
13655			}
13656
13657			offset.left   = selectee.left   + that.elementPos.left;
13658			offset.right  = selectee.right  + that.elementPos.left;
13659			offset.top    = selectee.top    + that.elementPos.top;
13660			offset.bottom = selectee.bottom + that.elementPos.top;
13661
13662			if ( options.tolerance === "touch" ) {
13663				hit = ( !( offset.left > x2 || offset.right < x1 || offset.top > y2 ||
13664                    offset.bottom < y1 ) );
13665			} else if ( options.tolerance === "fit" ) {
13666				hit = ( offset.left > x1 && offset.right < x2 && offset.top > y1 &&
13667                    offset.bottom < y2 );
13668			}
13669
13670			if ( hit ) {
13671
13672				// SELECT
13673				if ( selectee.selected ) {
13674					that._removeClass( selectee.$element, "ui-selected" );
13675					selectee.selected = false;
13676				}
13677				if ( selectee.unselecting ) {
13678					that._removeClass( selectee.$element, "ui-unselecting" );
13679					selectee.unselecting = false;
13680				}
13681				if ( !selectee.selecting ) {
13682					that._addClass( selectee.$element, "ui-selecting" );
13683					selectee.selecting = true;
13684
13685					// selectable SELECTING callback
13686					that._trigger( "selecting", event, {
13687						selecting: selectee.element
13688					} );
13689				}
13690			} else {
13691
13692				// UNSELECT
13693				if ( selectee.selecting ) {
13694					if ( ( event.metaKey || event.ctrlKey ) && selectee.startselected ) {
13695						that._removeClass( selectee.$element, "ui-selecting" );
13696						selectee.selecting = false;
13697						that._addClass( selectee.$element, "ui-selected" );
13698						selectee.selected = true;
13699					} else {
13700						that._removeClass( selectee.$element, "ui-selecting" );
13701						selectee.selecting = false;
13702						if ( selectee.startselected ) {
13703							that._addClass( selectee.$element, "ui-unselecting" );
13704							selectee.unselecting = true;
13705						}
13706
13707						// selectable UNSELECTING callback
13708						that._trigger( "unselecting", event, {
13709							unselecting: selectee.element
13710						} );
13711					}
13712				}
13713				if ( selectee.selected ) {
13714					if ( !event.metaKey && !event.ctrlKey && !selectee.startselected ) {
13715						that._removeClass( selectee.$element, "ui-selected" );
13716						selectee.selected = false;
13717
13718						that._addClass( selectee.$element, "ui-unselecting" );
13719						selectee.unselecting = true;
13720
13721						// selectable UNSELECTING callback
13722						that._trigger( "unselecting", event, {
13723							unselecting: selectee.element
13724						} );
13725					}
13726				}
13727			}
13728		} );
13729
13730		return false;
13731	},
13732
13733	_mouseStop: function( event ) {
13734		var that = this;
13735
13736		this.dragged = false;
13737
13738		$( ".ui-unselecting", this.element[ 0 ] ).each( function() {
13739			var selectee = $.data( this, "selectable-item" );
13740			that._removeClass( selectee.$element, "ui-unselecting" );
13741			selectee.unselecting = false;
13742			selectee.startselected = false;
13743			that._trigger( "unselected", event, {
13744				unselected: selectee.element
13745			} );
13746		} );
13747		$( ".ui-selecting", this.element[ 0 ] ).each( function() {
13748			var selectee = $.data( this, "selectable-item" );
13749			that._removeClass( selectee.$element, "ui-selecting" )
13750				._addClass( selectee.$element, "ui-selected" );
13751			selectee.selecting = false;
13752			selectee.selected = true;
13753			selectee.startselected = true;
13754			that._trigger( "selected", event, {
13755				selected: selectee.element
13756			} );
13757		} );
13758		this._trigger( "stop", event );
13759
13760		this.helper.remove();
13761
13762		return false;
13763	}
13764
13765} );
13766
13767
13768/*!
13769 * jQuery UI Selectmenu 1.12.1
13770 * http://jqueryui.com
vendor: 5,543 bytes, lines 13771-13977
13771 *
13772 * Copyright jQuery Foundation and other contributors
13773 * Released under the MIT license.
13774 * http://jquery.org/license
13775 */
13776
13777//>>label: Selectmenu
13778//>>group: Widgets
13779// jscs:disable maximumLineLength
13780//>>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.
13781// jscs:enable maximumLineLength
13782//>>docs: http://api.jqueryui.com/selectmenu/
13783//>>demos: http://jqueryui.com/selectmenu/
13784//>>css.structure: ../../themes/base/core.css
13785//>>css.structure: ../../themes/base/selectmenu.css, ../../themes/base/button.css
13786//>>css.theme: ../../themes/base/theme.css
13787
13788
13789
13790var widgetsSelectmenu = $.widget( "ui.selectmenu", [ $.ui.formResetMixin, {
13791	version: "1.12.1",
13792	defaultElement: "<select>",
13793	options: {
13794		appendTo: null,
13795		classes: {
13796			"ui-selectmenu-button-open": "ui-corner-top",
13797			"ui-selectmenu-button-closed": "ui-corner-all"
13798		},
13799		disabled: null,
13800		icons: {
13801			button: "ui-icon-triangle-1-s"
13802		},
13803		position: {
13804			my: "left top",
13805			at: "left bottom",
13806			collision: "none"
13807		},
13808		width: false,
13809
13810		// Callbacks
13811		change: null,
13812		close: null,
13813		focus: null,
13814		open: null,
13815		select: null
13816	},
13817
13818	_create: function() {
13819		var selectmenuId = this.element.uniqueId().attr( "id" );
13820		this.ids = {
13821			element: selectmenuId,
13822			button: selectmenuId + "-button",
13823			menu: selectmenuId + "-menu"
13824		};
13825
13826		this._drawButton();
13827		this._drawMenu();
13828		this._bindFormResetHandler();
13829
13830		this._rendered = false;
13831		this.menuItems = $();
13832	},
13833
13834	_drawButton: function() {
13835		var icon,
13836			that = this,
13837			item = this._parseOption(
13838				this.element.find( "option:selected" ),
13839				this.element[ 0 ].selectedIndex
13840			);
13841
13842		// Associate existing label with the new button
13843		this.labels = this.element.labels().attr( "for", this.ids.button );
13844		this._on( this.labels, {
13845			click: function( event ) {
13846				this.button.focus();
13847				event.preventDefault();
13848			}
13849		} );
13850
13851		// Hide original select element
13852		this.element.hide();
13853
13854		// Create button
13855		this.button = $( "<span>", {
13856			tabindex: this.options.disabled ? -1 : 0,
13857			id: this.ids.button,
13858			role: "combobox",
13859			"aria-expanded": "false",
13860			"aria-autocomplete": "list",
13861			"aria-owns": this.ids.menu,
13862			"aria-haspopup": "true",
13863			title: this.element.attr( "title" )
13864		} )
13865			.insertAfter( this.element );
13866
13867		this._addClass( this.button, "ui-selectmenu-button ui-selectmenu-button-closed",
13868			"ui-button ui-widget" );
13869
13870		icon = $( "<span>" ).appendTo( this.button );
13871		this._addClass( icon, "ui-selectmenu-icon", "ui-icon " + this.options.icons.button );
13872		this.buttonItem = this._renderButtonItem( item )
13873			.appendTo( this.button );
13874
13875		if ( this.options.width !== false ) {
13876			this._resizeButton();
13877		}
13878
13879		this._on( this.button, this._buttonEvents );
13880		this.button.one( "focusin", function() {
13881
13882			// Delay rendering the menu items until the button receives focus.
13883			// The menu may have already been rendered via a programmatic open.
13884			if ( !that._rendered ) {
13885				that._refreshMenu();
13886			}
13887		} );
13888	},
13889
13890	_drawMenu: function() {
13891		var that = this;
13892
13893		// Create menu
13894		this.menu = $( "<ul>", {
13895			"aria-hidden": "true",
13896			"aria-labelledby": this.ids.button,
13897			id: this.ids.menu
13898		} );
13899
13900		// Wrap menu
13901		this.menuWrap = $( "<div>" ).append( this.menu );
13902		this._addClass( this.menuWrap, "ui-selectmenu-menu", "ui-front" );
13903		this.menuWrap.appendTo( this._appendTo() );
13904
13905		// Initialize menu widget
13906		this.menuInstance = this.menu
13907			.menu( {
13908				classes: {
13909					"ui-menu": "ui-corner-bottom"
13910				},
13911				role: "listbox",
13912				select: function( event, ui ) {
13913					event.preventDefault();
13914
13915					// Support: IE8
13916					// If the item was selected via a click, the text selection
13917					// will be destroyed in IE
13918					that._setSelection();
13919
13920					that._select( ui.item.data( "ui-selectmenu-item" ), event );
13921				},
13922				focus: function( event, ui ) {
13923					var item = ui.item.data( "ui-selectmenu-item" );
13924
13925					// Prevent inital focus from firing and check if its a newly focused item
13926					if ( that.focusIndex != null && item.index !== that.focusIndex ) {
13927						that._trigger( "focus", event, { item: item } );
13928						if ( !that.isOpen ) {
13929							that._select( item, event );
13930						}
13931					}
13932					that.focusIndex = item.index;
13933
13934					that.button.attr( "aria-activedescendant",
13935						that.menuItems.eq( item.index ).attr( "id" ) );
13936				}
13937			} )
13938			.menu( "instance" );
13939
13940		// Don't close the menu on mouseleave
13941		this.menuInstance._off( this.menu, "mouseleave" );
13942
13943		// Cancel the menu's collapseAll on document click
13944		this.menuInstance._closeOnDocumentClick = function() {
13945			return false;
13946		};
13947
13948		// Selects often contain empty items, but never contain dividers
13949		this.menuInstance._isDivider = function() {
13950			return false;
13951		};
13952	},
13953
13954	refresh: function() {
13955		this._refreshMenu();
13956		this.buttonItem.replaceWith(
13957			this.buttonItem = this._renderButtonItem(
13958
13959				// Fall back to an empty object in case there are no options
13960				this._getSelectedItem().data( "ui-selectmenu-item" ) || {}
13961			)
13962		);
13963		if ( this.options.width === null ) {
13964			this._resizeButton();
13965		}
13966	},
13967
13968	_refreshMenu: function() {
13969		var item,
13970			options = this.element.find( "option" );
13971
13972		this.menu.empty();
13973
13974		this._parseOptions( options );
13975		this._renderMenu( this.menu, this.items );
13976
13977		this.menuInstance.refresh();
vendor: 9,769 bytes, lines 13978-14385
13978		this.menuItems = this.menu.find( "li" )
13979			.not( ".ui-selectmenu-optgroup" )
13980				.find( ".ui-menu-item-wrapper" );
13981
13982		this._rendered = true;
13983
13984		if ( !options.length ) {
13985			return;
13986		}
13987
13988		item = this._getSelectedItem();
13989
13990		// Update the menu to have the correct item focused
13991		this.menuInstance.focus( null, item );
13992		this._setAria( item.data( "ui-selectmenu-item" ) );
13993
13994		// Set disabled state
13995		this._setOption( "disabled", this.element.prop( "disabled" ) );
13996	},
13997
13998	open: function( event ) {
13999		if ( this.options.disabled ) {
14000			return;
14001		}
14002
14003		// If this is the first time the menu is being opened, render the items
14004		if ( !this._rendered ) {
14005			this._refreshMenu();
14006		} else {
14007
14008			// Menu clears focus on close, reset focus to selected item
14009			this._removeClass( this.menu.find( ".ui-state-active" ), null, "ui-state-active" );
14010			this.menuInstance.focus( null, this._getSelectedItem() );
14011		}
14012
14013		// If there are no options, don't open the menu
14014		if ( !this.menuItems.length ) {
14015			return;
14016		}
14017
14018		this.isOpen = true;
14019		this._toggleAttr();
14020		this._resizeMenu();
14021		this._position();
14022
14023		this._on( this.document, this._documentClick );
14024
14025		this._trigger( "open", event );
14026	},
14027
14028	_position: function() {
14029		this.menuWrap.position( $.extend( { of: this.button }, this.options.position ) );
14030	},
14031
14032	close: function( event ) {
14033		if ( !this.isOpen ) {
14034			return;
14035		}
14036
14037		this.isOpen = false;
14038		this._toggleAttr();
14039
14040		this.range = null;
14041		this._off( this.document );
14042
14043		this._trigger( "close", event );
14044	},
14045
14046	widget: function() {
14047		return this.button;
14048	},
14049
14050	menuWidget: function() {
14051		return this.menu;
14052	},
14053
14054	_renderButtonItem: function( item ) {
14055		var buttonItem = $( "<span>" );
14056
14057		this._setText( buttonItem, item.label );
14058		this._addClass( buttonItem, "ui-selectmenu-text" );
14059
14060		return buttonItem;
14061	},
14062
14063	_renderMenu: function( ul, items ) {
14064		var that = this,
14065			currentOptgroup = "";
14066
14067		$.each( items, function( index, item ) {
14068			var li;
14069
14070			if ( item.optgroup !== currentOptgroup ) {
14071				li = $( "<li>", {
14072					text: item.optgroup
14073				} );
14074				that._addClass( li, "ui-selectmenu-optgroup", "ui-menu-divider" +
14075					( item.element.parent( "optgroup" ).prop( "disabled" ) ?
14076						" ui-state-disabled" :
14077						"" ) );
14078
14079				li.appendTo( ul );
14080
14081				currentOptgroup = item.optgroup;
14082			}
14083
14084			that._renderItemData( ul, item );
14085		} );
14086	},
14087
14088	_renderItemData: function( ul, item ) {
14089		return this._renderItem( ul, item ).data( "ui-selectmenu-item", item );
14090	},
14091
14092	_renderItem: function( ul, item ) {
14093		var li = $( "<li>" ),
14094			wrapper = $( "<div>", {
14095				title: item.element.attr( "title" )
14096			} );
14097
14098		if ( item.disabled ) {
14099			this._addClass( li, null, "ui-state-disabled" );
14100		}
14101		this._setText( wrapper, item.label );
14102
14103		return li.append( wrapper ).appendTo( ul );
14104	},
14105
14106	_setText: function( element, value ) {
14107		if ( value ) {
14108			element.text( value );
14109		} else {
14110			element.html( "&#160;" );
14111		}
14112	},
14113
14114	_move: function( direction, event ) {
14115		var item, next,
14116			filter = ".ui-menu-item";
14117
14118		if ( this.isOpen ) {
14119			item = this.menuItems.eq( this.focusIndex ).parent( "li" );
14120		} else {
14121			item = this.menuItems.eq( this.element[ 0 ].selectedIndex ).parent( "li" );
14122			filter += ":not(.ui-state-disabled)";
14123		}
14124
14125		if ( direction === "first" || direction === "last" ) {
14126			next = item[ direction === "first" ? "prevAll" : "nextAll" ]( filter ).eq( -1 );
14127		} else {
14128			next = item[ direction + "All" ]( filter ).eq( 0 );
14129		}
14130
14131		if ( next.length ) {
14132			this.menuInstance.focus( event, next );
14133		}
14134	},
14135
14136	_getSelectedItem: function() {
14137		return this.menuItems.eq( this.element[ 0 ].selectedIndex ).parent( "li" );
14138	},
14139
14140	_toggle: function( event ) {
14141		this[ this.isOpen ? "close" : "open" ]( event );
14142	},
14143
14144	_setSelection: function() {
14145		var selection;
14146
14147		if ( !this.range ) {
14148			return;
14149		}
14150
14151		if ( window.getSelection ) {
14152			selection = window.getSelection();
14153			selection.removeAllRanges();
14154			selection.addRange( this.range );
14155
14156		// Support: IE8
14157		} else {
14158			this.range.select();
14159		}
14160
14161		// Support: IE
14162		// Setting the text selection kills the button focus in IE, but
14163		// restoring the focus doesn't kill the selection.
14164		this.button.focus();
14165	},
14166
14167	_documentClick: {
14168		mousedown: function( event ) {
14169			if ( !this.isOpen ) {
14170				return;
14171			}
14172
14173			if ( !$( event.target ).closest( ".ui-selectmenu-menu, #" +
14174					$.ui.escapeSelector( this.ids.button ) ).length ) {
14175				this.close( event );
14176			}
14177		}
14178	},
14179
14180	_buttonEvents: {
14181
14182		// Prevent text selection from being reset when interacting with the selectmenu (#10144)
14183		mousedown: function() {
14184			var selection;
14185
14186			if ( window.getSelection ) {
14187				selection = window.getSelection();
14188				if ( selection.rangeCount ) {
14189					this.range = selection.getRangeAt( 0 );
14190				}
14191
14192			// Support: IE8
14193			} else {
14194				this.range = document.selection.createRange();
14195			}
14196		},
14197
14198		click: function( event ) {
14199			this._setSelection();
14200			this._toggle( event );
14201		},
14202
14203		keydown: function( event ) {
14204			var preventDefault = true;
14205			switch ( event.keyCode ) {
14206			case $.ui.keyCode.TAB:
14207			case $.ui.keyCode.ESCAPE:
14208				this.close( event );
14209				preventDefault = false;
14210				break;
14211			case $.ui.keyCode.ENTER:
14212				if ( this.isOpen ) {
14213					this._selectFocusedItem( event );
14214				}
14215				break;
14216			case $.ui.keyCode.UP:
14217				if ( event.altKey ) {
14218					this._toggle( event );
14219				} else {
14220					this._move( "prev", event );
14221				}
14222				break;
14223			case $.ui.keyCode.DOWN:
14224				if ( event.altKey ) {
14225					this._toggle( event );
14226				} else {
14227					this._move( "next", event );
14228				}
14229				break;
14230			case $.ui.keyCode.SPACE:
14231				if ( this.isOpen ) {
14232					this._selectFocusedItem( event );
14233				} else {
14234					this._toggle( event );
14235				}
14236				break;
14237			case $.ui.keyCode.LEFT:
14238				this._move( "prev", event );
14239				break;
14240			case $.ui.keyCode.RIGHT:
14241				this._move( "next", event );
14242				break;
14243			case $.ui.keyCode.HOME:
14244			case $.ui.keyCode.PAGE_UP:
14245				this._move( "first", event );
14246				break;
14247			case $.ui.keyCode.END:
14248			case $.ui.keyCode.PAGE_DOWN:
14249				this._move( "last", event );
14250				break;
14251			default:
14252				this.menu.trigger( event );
14253				preventDefault = false;
14254			}
14255
14256			if ( preventDefault ) {
14257				event.preventDefault();
14258			}
14259		}
14260	},
14261
14262	_selectFocusedItem: function( event ) {
14263		var item = this.menuItems.eq( this.focusIndex ).parent( "li" );
14264		if ( !item.hasClass( "ui-state-disabled" ) ) {
14265			this._select( item.data( "ui-selectmenu-item" ), event );
14266		}
14267	},
14268
14269	_select: function( item, event ) {
14270		var oldIndex = this.element[ 0 ].selectedIndex;
14271
14272		// Change native select element
14273		this.element[ 0 ].selectedIndex = item.index;
14274		this.buttonItem.replaceWith( this.buttonItem = this._renderButtonItem( item ) );
14275		this._setAria( item );
14276		this._trigger( "select", event, { item: item } );
14277
14278		if ( item.index !== oldIndex ) {
14279			this._trigger( "change", event, { item: item } );
14280		}
14281
14282		this.close( event );
14283	},
14284
14285	_setAria: function( item ) {
14286		var id = this.menuItems.eq( item.index ).attr( "id" );
14287
14288		this.button.attr( {
14289			"aria-labelledby": id,
14290			"aria-activedescendant": id
14291		} );
14292		this.menu.attr( "aria-activedescendant", id );
14293	},
14294
14295	_setOption: function( key, value ) {
14296		if ( key === "icons" ) {
14297			var icon = this.button.find( "span.ui-icon" );
14298			this._removeClass( icon, null, this.options.icons.button )
14299				._addClass( icon, null, value.button );
14300		}
14301
14302		this._super( key, value );
14303
14304		if ( key === "appendTo" ) {
14305			this.menuWrap.appendTo( this._appendTo() );
14306		}
14307
14308		if ( key === "width" ) {
14309			this._resizeButton();
14310		}
14311	},
14312
14313	_setOptionDisabled: function( value ) {
14314		this._super( value );
14315
14316		this.menuInstance.option( "disabled", value );
14317		this.button.attr( "aria-disabled", value );
14318		this._toggleClass( this.button, null, "ui-state-disabled", value );
14319
14320		this.element.prop( "disabled", value );
14321		if ( value ) {
14322			this.button.attr( "tabindex", -1 );
14323			this.close();
14324		} else {
14325			this.button.attr( "tabindex", 0 );
14326		}
14327	},
14328
14329	_appendTo: function() {
14330		var element = this.options.appendTo;
14331
14332		if ( element ) {
14333			element = element.jquery || element.nodeType ?
14334				$( element ) :
14335				this.document.find( element ).eq( 0 );
14336		}
14337
14338		if ( !element || !element[ 0 ] ) {
14339			element = this.element.closest( ".ui-front, dialog" );
14340		}
14341
14342		if ( !element.length ) {
14343			element = this.document[ 0 ].body;
14344		}
14345
14346		return element;
14347	},
14348
14349	_toggleAttr: function() {
14350		this.button.attr( "aria-expanded", this.isOpen );
14351
14352		// We can't use two _toggleClass() calls here, because we need to make sure
14353		// we always remove classes first and add them second, otherwise if both classes have the
14354		// same theme class, it will be removed after we add it.
14355		this._removeClass( this.button, "ui-selectmenu-button-" +
14356			( this.isOpen ? "closed" : "open" ) )
14357			._addClass( this.button, "ui-selectmenu-button-" +
14358				( this.isOpen ? "open" : "closed" ) )
14359			._toggleClass( this.menuWrap, "ui-selectmenu-open", null, this.isOpen );
14360
14361		this.menu.attr( "aria-hidden", !this.isOpen );
14362	},
14363
14364	_resizeButton: function() {
14365		var width = this.options.width;
14366
14367		// For `width: false`, just remove inline style and stop
14368		if ( width === false ) {
14369			this.button.css( "width", "" );
14370			return;
14371		}
14372
14373		// For `width: null`, match the width of the original element
14374		if ( width === null ) {
14375			width = this.element.show().outerWidth();
14376			this.element.hide();
14377		}
14378
14379		this.button.outerWidth( width );
14380	},
14381
14382	_resizeMenu: function() {
14383		this.menu.outerWidth( Math.max(
14384			this.button.outerWidth(),
14385
vendor: 5,390 bytes, lines 14386-14599
14386			// Support: IE10
14387			// IE10 wraps long text (possibly a rounding bug)
14388			// so we add 1px to avoid the wrapping
14389			this.menu.width( "" ).outerWidth() + 1
14390		) );
14391	},
14392
14393	_getCreateOptions: function() {
14394		var options = this._super();
14395
14396		options.disabled = this.element.prop( "disabled" );
14397
14398		return options;
14399	},
14400
14401	_parseOptions: function( options ) {
14402		var that = this,
14403			data = [];
14404		options.each( function( index, item ) {
14405			data.push( that._parseOption( $( item ), index ) );
14406		} );
14407		this.items = data;
14408	},
14409
14410	_parseOption: function( option, index ) {
14411		var optgroup = option.parent( "optgroup" );
14412
14413		return {
14414			element: option,
14415			index: index,
14416			value: option.val(),
14417			label: option.text(),
14418			optgroup: optgroup.attr( "label" ) || "",
14419			disabled: optgroup.prop( "disabled" ) || option.prop( "disabled" )
14420		};
14421	},
14422
14423	_destroy: function() {
14424		this._unbindFormResetHandler();
14425		this.menuWrap.remove();
14426		this.button.remove();
14427		this.element.show();
14428		this.element.removeUniqueId();
14429		this.labels.attr( "for", this.ids.element );
14430	}
14431} ] );
14432
14433
14434/*!
14435 * jQuery UI Slider 1.12.1
14436 * http://jqueryui.com
14437 *
14438 * Copyright jQuery Foundation and other contributors
14439 * Released under the MIT license.
14440 * http://jquery.org/license
14441 */
14442
14443//>>label: Slider
14444//>>group: Widgets
14445//>>description: Displays a flexible slider with ranges and accessibility via keyboard.
14446//>>docs: http://api.jqueryui.com/slider/
14447//>>demos: http://jqueryui.com/slider/
14448//>>css.structure: ../../themes/base/core.css
14449//>>css.structure: ../../themes/base/slider.css
14450//>>css.theme: ../../themes/base/theme.css
14451
14452
14453
14454var widgetsSlider = $.widget( "ui.slider", $.ui.mouse, {
14455	version: "1.12.1",
14456	widgetEventPrefix: "slide",
14457
14458	options: {
14459		animate: false,
14460		classes: {
14461			"ui-slider": "ui-corner-all",
14462			"ui-slider-handle": "ui-corner-all",
14463
14464			// Note: ui-widget-header isn't the most fittingly semantic framework class for this
14465			// element, but worked best visually with a variety of themes
14466			"ui-slider-range": "ui-corner-all ui-widget-header"
14467		},
14468		distance: 0,
14469		max: 100,
14470		min: 0,
14471		orientation: "horizontal",
14472		range: false,
14473		step: 1,
14474		value: 0,
14475		values: null,
14476
14477		// Callbacks
14478		change: null,
14479		slide: null,
14480		start: null,
14481		stop: null
14482	},
14483
14484	// Number of pages in a slider
14485	// (how many times can you page up/down to go through the whole range)
14486	numPages: 5,
14487
14488	_create: function() {
14489		this._keySliding = false;
14490		this._mouseSliding = false;
14491		this._animateOff = true;
14492		this._handleIndex = null;
14493		this._detectOrientation();
14494		this._mouseInit();
14495		this._calculateNewMax();
14496
14497		this._addClass( "ui-slider ui-slider-" + this.orientation,
14498			"ui-widget ui-widget-content" );
14499
14500		this._refresh();
14501
14502		this._animateOff = false;
14503	},
14504
14505	_refresh: function() {
14506		this._createRange();
14507		this._createHandles();
14508		this._setupEvents();
14509		this._refreshValue();
14510	},
14511
14512	_createHandles: function() {
14513		var i, handleCount,
14514			options = this.options,
14515			existingHandles = this.element.find( ".ui-slider-handle" ),
14516			handle = "<span tabindex='0'></span>",
14517			handles = [];
14518
14519		handleCount = ( options.values && options.values.length ) || 1;
14520
14521		if ( existingHandles.length > handleCount ) {
14522			existingHandles.slice( handleCount ).remove();
14523			existingHandles = existingHandles.slice( 0, handleCount );
14524		}
14525
14526		for ( i = existingHandles.length; i < handleCount; i++ ) {
14527			handles.push( handle );
14528		}
14529
14530		this.handles = existingHandles.add( $( handles.join( "" ) ).appendTo( this.element ) );
14531
14532		this._addClass( this.handles, "ui-slider-handle", "ui-state-default" );
14533
14534		this.handle = this.handles.eq( 0 );
14535
14536		this.handles.each( function( i ) {
14537			$( this )
14538				.data( "ui-slider-handle-index", i )
14539				.attr( "tabIndex", 0 );
14540		} );
14541	},
14542
14543	_createRange: function() {
14544		var options = this.options;
14545
14546		if ( options.range ) {
14547			if ( options.range === true ) {
14548				if ( !options.values ) {
14549					options.values = [ this._valueMin(), this._valueMin() ];
14550				} else if ( options.values.length && options.values.length !== 2 ) {
14551					options.values = [ options.values[ 0 ], options.values[ 0 ] ];
14552				} else if ( $.isArray( options.values ) ) {
14553					options.values = options.values.slice( 0 );
14554				}
14555			}
14556
14557			if ( !this.range || !this.range.length ) {
14558				this.range = $( "<div>" )
14559					.appendTo( this.element );
14560
14561				this._addClass( this.range, "ui-slider-range" );
14562			} else {
14563				this._removeClass( this.range, "ui-slider-range-min ui-slider-range-max" );
14564
14565				// Handle range switching from true to min/max
14566				this.range.css( {
14567					"left": "",
14568					"bottom": ""
14569				} );
14570			}
14571			if ( options.range === "min" || options.range === "max" ) {
14572				this._addClass( this.range, "ui-slider-range-" + options.range );
14573			}
14574		} else {
14575			if ( this.range ) {
14576				this.range.remove();
14577			}
14578			this.range = null;
14579		}
14580	},
14581
14582	_setupEvents: function() {
14583		this._off( this.handles );
14584		this._on( this.handles, this._handleEvents );
14585		this._hoverable( this.handles );
14586		this._focusable( this.handles );
14587	},
14588
14589	_destroy: function() {
14590		this.handles.remove();
14591		if ( this.range ) {
14592			this.range.remove();
14593		}
14594
14595		this._mouseDestroy();
14596	},
14597
14598	_mouseCapture: function( event ) {
14599		var position, normValue, distance, closestHandle, index, allowed, offset, mou
vendor: 15,762 bytes, lines 14599-15172
14599seOverHandle,
14600			that = this,
14601			o = this.options;
14602
14603		if ( o.disabled ) {
14604			return false;
14605		}
14606
14607		this.elementSize = {
14608			width: this.element.outerWidth(),
14609			height: this.element.outerHeight()
14610		};
14611		this.elementOffset = this.element.offset();
14612
14613		position = { x: event.pageX, y: event.pageY };
14614		normValue = this._normValueFromMouse( position );
14615		distance = this._valueMax() - this._valueMin() + 1;
14616		this.handles.each( function( i ) {
14617			var thisDistance = Math.abs( normValue - that.values( i ) );
14618			if ( ( distance > thisDistance ) ||
14619				( distance === thisDistance &&
14620					( i === that._lastChangedValue || that.values( i ) === o.min ) ) ) {
14621				distance = thisDistance;
14622				closestHandle = $( this );
14623				index = i;
14624			}
14625		} );
14626
14627		allowed = this._start( event, index );
14628		if ( allowed === false ) {
14629			return false;
14630		}
14631		this._mouseSliding = true;
14632
14633		this._handleIndex = index;
14634
14635		this._addClass( closestHandle, null, "ui-state-active" );
14636		closestHandle.trigger( "focus" );
14637
14638		offset = closestHandle.offset();
14639		mouseOverHandle = !$( event.target ).parents().addBack().is( ".ui-slider-handle" );
14640		this._clickOffset = mouseOverHandle ? { left: 0, top: 0 } : {
14641			left: event.pageX - offset.left - ( closestHandle.width() / 2 ),
14642			top: event.pageY - offset.top -
14643				( closestHandle.height() / 2 ) -
14644				( parseInt( closestHandle.css( "borderTopWidth" ), 10 ) || 0 ) -
14645				( parseInt( closestHandle.css( "borderBottomWidth" ), 10 ) || 0 ) +
14646				( parseInt( closestHandle.css( "marginTop" ), 10 ) || 0 )
14647		};
14648
14649		if ( !this.handles.hasClass( "ui-state-hover" ) ) {
14650			this._slide( event, index, normValue );
14651		}
14652		this._animateOff = true;
14653		return true;
14654	},
14655
14656	_mouseStart: function() {
14657		return true;
14658	},
14659
14660	_mouseDrag: function( event ) {
14661		var position = { x: event.pageX, y: event.pageY },
14662			normValue = this._normValueFromMouse( position );
14663
14664		this._slide( event, this._handleIndex, normValue );
14665
14666		return false;
14667	},
14668
14669	_mouseStop: function( event ) {
14670		this._removeClass( this.handles, null, "ui-state-active" );
14671		this._mouseSliding = false;
14672
14673		this._stop( event, this._handleIndex );
14674		this._change( event, this._handleIndex );
14675
14676		this._handleIndex = null;
14677		this._clickOffset = null;
14678		this._animateOff = false;
14679
14680		return false;
14681	},
14682
14683	_detectOrientation: function() {
14684		this.orientation = ( this.options.orientation === "vertical" ) ? "vertical" : "horizontal";
14685	},
14686
14687	_normValueFromMouse: function( position ) {
14688		var pixelTotal,
14689			pixelMouse,
14690			percentMouse,
14691			valueTotal,
14692			valueMouse;
14693
14694		if ( this.orientation === "horizontal" ) {
14695			pixelTotal = this.elementSize.width;
14696			pixelMouse = position.x - this.elementOffset.left -
14697				( this._clickOffset ? this._clickOffset.left : 0 );
14698		} else {
14699			pixelTotal = this.elementSize.height;
14700			pixelMouse = position.y - this.elementOffset.top -
14701				( this._clickOffset ? this._clickOffset.top : 0 );
14702		}
14703
14704		percentMouse = ( pixelMouse / pixelTotal );
14705		if ( percentMouse > 1 ) {
14706			percentMouse = 1;
14707		}
14708		if ( percentMouse < 0 ) {
14709			percentMouse = 0;
14710		}
14711		if ( this.orientation === "vertical" ) {
14712			percentMouse = 1 - percentMouse;
14713		}
14714
14715		valueTotal = this._valueMax() - this._valueMin();
14716		valueMouse = this._valueMin() + percentMouse * valueTotal;
14717
14718		return this._trimAlignValue( valueMouse );
14719	},
14720
14721	_uiHash: function( index, value, values ) {
14722		var uiHash = {
14723			handle: this.handles[ index ],
14724			handleIndex: index,
14725			value: value !== undefined ? value : this.value()
14726		};
14727
14728		if ( this._hasMultipleValues() ) {
14729			uiHash.value = value !== undefined ? value : this.values( index );
14730			uiHash.values = values || this.values();
14731		}
14732
14733		return uiHash;
14734	},
14735
14736	_hasMultipleValues: function() {
14737		return this.options.values && this.options.values.length;
14738	},
14739
14740	_start: function( event, index ) {
14741		return this._trigger( "start", event, this._uiHash( index ) );
14742	},
14743
14744	_slide: function( event, index, newVal ) {
14745		var allowed, otherVal,
14746			currentValue = this.value(),
14747			newValues = this.values();
14748
14749		if ( this._hasMultipleValues() ) {
14750			otherVal = this.values( index ? 0 : 1 );
14751			currentValue = this.values( index );
14752
14753			if ( this.options.values.length === 2 && this.options.range === true ) {
14754				newVal =  index === 0 ? Math.min( otherVal, newVal ) : Math.max( otherVal, newVal );
14755			}
14756
14757			newValues[ index ] = newVal;
14758		}
14759
14760		if ( newVal === currentValue ) {
14761			return;
14762		}
14763
14764		allowed = this._trigger( "slide", event, this._uiHash( index, newVal, newValues ) );
14765
14766		// A slide can be canceled by returning false from the slide callback
14767		if ( allowed === false ) {
14768			return;
14769		}
14770
14771		if ( this._hasMultipleValues() ) {
14772			this.values( index, newVal );
14773		} else {
14774			this.value( newVal );
14775		}
14776	},
14777
14778	_stop: function( event, index ) {
14779		this._trigger( "stop", event, this._uiHash( index ) );
14780	},
14781
14782	_change: function( event, index ) {
14783		if ( !this._keySliding && !this._mouseSliding ) {
14784
14785			//store the last changed value index for reference when handles overlap
14786			this._lastChangedValue = index;
14787			this._trigger( "change", event, this._uiHash( index ) );
14788		}
14789	},
14790
14791	value: function( newValue ) {
14792		if ( arguments.length ) {
14793			this.options.value = this._trimAlignValue( newValue );
14794			this._refreshValue();
14795			this._change( null, 0 );
14796			return;
14797		}
14798
14799		return this._value();
14800	},
14801
14802	values: function( index, newValue ) {
14803		var vals,
14804			newValues,
14805			i;
14806
14807		if ( arguments.length > 1 ) {
14808			this.options.values[ index ] = this._trimAlignValue( newValue );
14809			this._refreshValue();
14810			this._change( null, index );
14811			return;
14812		}
14813
14814		if ( arguments.length ) {
14815			if ( $.isArray( arguments[ 0 ] ) ) {
14816				vals = this.options.values;
14817				newValues = arguments[ 0 ];
14818				for ( i = 0; i < vals.length; i += 1 ) {
14819					vals[ i ] = this._trimAlignValue( newValues[ i ] );
14820					this._change( null, i );
14821				}
14822				this._refreshValue();
14823			} else {
14824				if ( this._hasMultipleValues() ) {
14825					return this._values( index );
14826				} else {
14827					return this.value();
14828				}
14829			}
14830		} else {
14831			return this._values();
14832		}
14833	},
14834
14835	_setOption: function( key, value ) {
14836		var i,
14837			valsLength = 0;
14838
14839		if ( key === "range" && this.options.range === true ) {
14840			if ( value === "min" ) {
14841				this.options.value = this._values( 0 );
14842				this.options.values = null;
14843			} else if ( value === "max" ) {
14844				this.options.value = this._values( this.options.values.length - 1 );
14845				this.options.values = null;
14846			}
14847		}
14848
14849		if ( $.isArray( this.options.values ) ) {
14850			valsLength = this.options.values.length;
14851		}
14852
14853		this._super( key, value );
14854
14855		switch ( key ) {
14856			case "orientation":
14857				this._detectOrientation();
14858				this._removeClass( "ui-slider-horizontal ui-slider-vertical" )
14859					._addClass( "ui-slider-" + this.orientation );
14860				this._refreshValue();
14861				if ( this.options.range ) {
14862					this._refreshRange( value );
14863				}
14864
14865				// Reset positioning from previous orientation
14866				this.handles.css( value === "horizontal" ? "bottom" : "left", "" );
14867				break;
14868			case "value":
14869				this._animateOff = true;
14870				this._refreshValue();
14871				this._change( null, 0 );
14872				this._animateOff = false;
14873				break;
14874			case "values":
14875				this._animateOff = true;
14876				this._refreshValue();
14877
14878				// Start from the last handle to prevent unreachable handles (#9046)
14879				for ( i = valsLength - 1; i >= 0; i-- ) {
14880					this._change( null, i );
14881				}
14882				this._animateOff = false;
14883				break;
14884			case "step":
14885			case "min":
14886			case "max":
14887				this._animateOff = true;
14888				this._calculateNewMax();
14889				this._refreshValue();
14890				this._animateOff = false;
14891				break;
14892			case "range":
14893				this._animateOff = true;
14894				this._refresh();
14895				this._animateOff = false;
14896				break;
14897		}
14898	},
14899
14900	_setOptionDisabled: function( value ) {
14901		this._super( value );
14902
14903		this._toggleClass( null, "ui-state-disabled", !!value );
14904	},
14905
14906	//internal value getter
14907	// _value() returns value trimmed by min and max, aligned by step
14908	_value: function() {
14909		var val = this.options.value;
14910		val = this._trimAlignValue( val );
14911
14912		return val;
14913	},
14914
14915	//internal values getter
14916	// _values() returns array of values trimmed by min and max, aligned by step
14917	// _values( index ) returns single value trimmed by min and max, aligned by step
14918	_values: function( index ) {
14919		var val,
14920			vals,
14921			i;
14922
14923		if ( arguments.length ) {
14924			val = this.options.values[ index ];
14925			val = this._trimAlignValue( val );
14926
14927			return val;
14928		} else if ( this._hasMultipleValues() ) {
14929
14930			// .slice() creates a copy of the array
14931			// this copy gets trimmed by min and max and then returned
14932			vals = this.options.values.slice();
14933			for ( i = 0; i < vals.length; i += 1 ) {
14934				vals[ i ] = this._trimAlignValue( vals[ i ] );
14935			}
14936
14937			return vals;
14938		} else {
14939			return [];
14940		}
14941	},
14942
14943	// Returns the step-aligned value that val is closest to, between (inclusive) min and max
14944	_trimAlignValue: function( val ) {
14945		if ( val <= this._valueMin() ) {
14946			return this._valueMin();
14947		}
14948		if ( val >= this._valueMax() ) {
14949			return this._valueMax();
14950		}
14951		var step = ( this.options.step > 0 ) ? this.options.step : 1,
14952			valModStep = ( val - this._valueMin() ) % step,
14953			alignValue = val - valModStep;
14954
14955		if ( Math.abs( valModStep ) * 2 >= step ) {
14956			alignValue += ( valModStep > 0 ) ? step : ( -step );
14957		}
14958
14959		// Since JavaScript has problems with large floats, round
14960		// the final value to 5 digits after the decimal point (see #4124)
14961		return parseFloat( alignValue.toFixed( 5 ) );
14962	},
14963
14964	_calculateNewMax: function() {
14965		var max = this.options.max,
14966			min = this._valueMin(),
14967			step = this.options.step,
14968			aboveMin = Math.round( ( max - min ) / step ) * step;
14969		max = aboveMin + min;
14970		if ( max > this.options.max ) {
14971
14972			//If max is not divisible by step, rounding off may increase its value
14973			max -= step;
14974		}
14975		this.max = parseFloat( max.toFixed( this._precision() ) );
14976	},
14977
14978	_precision: function() {
14979		var precision = this._precisionOf( this.options.step );
14980		if ( this.options.min !== null ) {
14981			precision = Math.max( precision, this._precisionOf( this.options.min ) );
14982		}
14983		return precision;
14984	},
14985
14986	_precisionOf: function( num ) {
14987		var str = num.toString(),
14988			decimal = str.indexOf( "." );
14989		return decimal === -1 ? 0 : str.length - decimal - 1;
14990	},
14991
14992	_valueMin: function() {
14993		return this.options.min;
14994	},
14995
14996	_valueMax: function() {
14997		return this.max;
14998	},
14999
15000	_refreshRange: function( orientation ) {
15001		if ( orientation === "vertical" ) {
15002			this.range.css( { "width": "", "left": "" } );
15003		}
15004		if ( orientation === "horizontal" ) {
15005			this.range.css( { "height": "", "bottom": "" } );
15006		}
15007	},
15008
15009	_refreshValue: function() {
15010		var lastValPercent, valPercent, value, valueMin, valueMax,
15011			oRange = this.options.range,
15012			o = this.options,
15013			that = this,
15014			animate = ( !this._animateOff ) ? o.animate : false,
15015			_set = {};
15016
15017		if ( this._hasMultipleValues() ) {
15018			this.handles.each( function( i ) {
15019				valPercent = ( that.values( i ) - that._valueMin() ) / ( that._valueMax() -
15020					that._valueMin() ) * 100;
15021				_set[ that.orientation === "horizontal" ? "left" : "bottom" ] = valPercent + "%";
15022				$( this ).stop( 1, 1 )[ animate ? "animate" : "css" ]( _set, o.animate );
15023				if ( that.options.range === true ) {
15024					if ( that.orientation === "horizontal" ) {
15025						if ( i === 0 ) {
15026							that.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( {
15027								left: valPercent + "%"
15028							}, o.animate );
15029						}
15030						if ( i === 1 ) {
15031							that.range[ animate ? "animate" : "css" ]( {
15032								width: ( valPercent - lastValPercent ) + "%"
15033							}, {
15034								queue: false,
15035								duration: o.animate
15036							} );
15037						}
15038					} else {
15039						if ( i === 0 ) {
15040							that.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( {
15041								bottom: ( valPercent ) + "%"
15042							}, o.animate );
15043						}
15044						if ( i === 1 ) {
15045							that.range[ animate ? "animate" : "css" ]( {
15046								height: ( valPercent - lastValPercent ) + "%"
15047							}, {
15048								queue: false,
15049								duration: o.animate
15050							} );
15051						}
15052					}
15053				}
15054				lastValPercent = valPercent;
15055			} );
15056		} else {
15057			value = this.value();
15058			valueMin = this._valueMin();
15059			valueMax = this._valueMax();
15060			valPercent = ( valueMax !== valueMin ) ?
15061					( value - valueMin ) / ( valueMax - valueMin ) * 100 :
15062					0;
15063			_set[ this.orientation === "horizontal" ? "left" : "bottom" ] = valPercent + "%";
15064			this.handle.stop( 1, 1 )[ animate ? "animate" : "css" ]( _set, o.animate );
15065
15066			if ( oRange === "min" && this.orientation === "horizontal" ) {
15067				this.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( {
15068					width: valPercent + "%"
15069				}, o.animate );
15070			}
15071			if ( oRange === "max" && this.orientation === "horizontal" ) {
15072				this.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( {
15073					width: ( 100 - valPercent ) + "%"
15074				}, o.animate );
15075			}
15076			if ( oRange === "min" && this.orientation === "vertical" ) {
15077				this.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( {
15078					height: valPercent + "%"
15079				}, o.animate );
15080			}
15081			if ( oRange === "max" && this.orientation === "vertical" ) {
15082				this.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( {
15083					height: ( 100 - valPercent ) + "%"
15084				}, o.animate );
15085			}
15086		}
15087	},
15088
15089	_handleEvents: {
15090		keydown: function( event ) {
15091			var allowed, curVal, newVal, step,
15092				index = $( event.target ).data( "ui-slider-handle-index" );
15093
15094			switch ( event.keyCode ) {
15095				case $.ui.keyCode.HOME:
15096				case $.ui.keyCode.END:
15097				case $.ui.keyCode.PAGE_UP:
15098				case $.ui.keyCode.PAGE_DOWN:
15099				case $.ui.keyCode.UP:
15100				case $.ui.keyCode.RIGHT:
15101				case $.ui.keyCode.DOWN:
15102				case $.ui.keyCode.LEFT:
15103					event.preventDefault();
15104					if ( !this._keySliding ) {
15105						this._keySliding = true;
15106						this._addClass( $( event.target ), null, "ui-state-active" );
15107						allowed = this._start( event, index );
15108						if ( allowed === false ) {
15109							return;
15110						}
15111					}
15112					break;
15113			}
15114
15115			step = this.options.step;
15116			if ( this._hasMultipleValues() ) {
15117				curVal = newVal = this.values( index );
15118			} else {
15119				curVal = newVal = this.value();
15120			}
15121
15122			switch ( event.keyCode ) {
15123				case $.ui.keyCode.HOME:
15124					newVal = this._valueMin();
15125					break;
15126				case $.ui.keyCode.END:
15127					newVal = this._valueMax();
15128					break;
15129				case $.ui.keyCode.PAGE_UP:
15130					newVal = this._trimAlignValue(
15131						curVal + ( ( this._valueMax() - this._valueMin() ) / this.numPages )
15132					);
15133					break;
15134				case $.ui.keyCode.PAGE_DOWN:
15135					newVal = this._trimAlignValue(
15136						curVal - ( ( this._valueMax() - this._valueMin() ) / this.numPages ) );
15137					break;
15138				case $.ui.keyCode.UP:
15139				case $.ui.keyCode.RIGHT:
15140					if ( curVal === this._valueMax() ) {
15141						return;
15142					}
15143					newVal = this._trimAlignValue( curVal + step );
15144					break;
15145				case $.ui.keyCode.DOWN:
15146				case $.ui.keyCode.LEFT:
15147					if ( curVal === this._valueMin() ) {
15148						return;
15149					}
15150					newVal = this._trimAlignValue( curVal - step );
15151					break;
15152			}
15153
15154			this._slide( event, index, newVal );
15155		},
15156		keyup: function( event ) {
15157			var index = $( event.target ).data( "ui-slider-handle-index" );
15158
15159			if ( this._keySliding ) {
15160				this._keySliding = false;
15161				this._stop( event, index );
15162				this._change( event, index );
15163				this._removeClass( $( event.target ), null, "ui-state-active" );
15164			}
15165		}
15166	}
15167} );
15168
15169
15170/*!
15171 * jQuery UI Sortable 1.12.1
15172 * http://jqueryui.com
vendor: 35,818 bytes, lines 15173-16360
15173 *
15174 * Copyright jQuery Foundation and other contributors
15175 * Released under the MIT license.
15176 * http://jquery.org/license
15177 */
15178
15179//>>label: Sortable
15180//>>group: Interactions
15181//>>description: Enables items in a list to be sorted using the mouse.
15182//>>docs: http://api.jqueryui.com/sortable/
15183//>>demos: http://jqueryui.com/sortable/
15184//>>css.structure: ../../themes/base/sortable.css
15185
15186
15187
15188var widgetsSortable = $.widget( "ui.sortable", $.ui.mouse, {
15189	version: "1.12.1",
15190	widgetEventPrefix: "sort",
15191	ready: false,
15192	options: {
15193		appendTo: "parent",
15194		axis: false,
15195		connectWith: false,
15196		containment: false,
15197		cursor: "auto",
15198		cursorAt: false,
15199		dropOnEmpty: true,
15200		forcePlaceholderSize: false,
15201		forceHelperSize: false,
15202		grid: false,
15203		handle: false,
15204		helper: "original",
15205		items: "> *",
15206		opacity: false,
15207		placeholder: false,
15208		revert: false,
15209		scroll: true,
15210		scrollSensitivity: 20,
15211		scrollSpeed: 20,
15212		scope: "default",
15213		tolerance: "intersect",
15214		zIndex: 1000,
15215
15216		// Callbacks
15217		activate: null,
15218		beforeStop: null,
15219		change: null,
15220		deactivate: null,
15221		out: null,
15222		over: null,
15223		receive: null,
15224		remove: null,
15225		sort: null,
15226		start: null,
15227		stop: null,
15228		update: null
15229	},
15230
15231	_isOverAxis: function( x, reference, size ) {
15232		return ( x >= reference ) && ( x < ( reference + size ) );
15233	},
15234
15235	_isFloating: function( item ) {
15236		return ( /left|right/ ).test( item.css( "float" ) ) ||
15237			( /inline|table-cell/ ).test( item.css( "display" ) );
15238	},
15239
15240	_create: function() {
15241		this.containerCache = {};
15242		this._addClass( "ui-sortable" );
15243
15244		//Get the items
15245		this.refresh();
15246
15247		//Let's determine the parent's offset
15248		this.offset = this.element.offset();
15249
15250		//Initialize mouse events for interaction
15251		this._mouseInit();
15252
15253		this._setHandleClassName();
15254
15255		//We're ready to go
15256		this.ready = true;
15257
15258	},
15259
15260	_setOption: function( key, value ) {
15261		this._super( key, value );
15262
15263		if ( key === "handle" ) {
15264			this._setHandleClassName();
15265		}
15266	},
15267
15268	_setHandleClassName: function() {
15269		var that = this;
15270		this._removeClass( this.element.find( ".ui-sortable-handle" ), "ui-sortable-handle" );
15271		$.each( this.items, function() {
15272			that._addClass(
15273				this.instance.options.handle ?
15274					this.item.find( this.instance.options.handle ) :
15275					this.item,
15276				"ui-sortable-handle"
15277			);
15278		} );
15279	},
15280
15281	_destroy: function() {
15282		this._mouseDestroy();
15283
15284		for ( var i = this.items.length - 1; i >= 0; i-- ) {
15285			this.items[ i ].item.removeData( this.widgetName + "-item" );
15286		}
15287
15288		return this;
15289	},
15290
15291	_mouseCapture: function( event, overrideHandle ) {
15292		var currentItem = null,
15293			validHandle = false,
15294			that = this;
15295
15296		if ( this.reverting ) {
15297			return false;
15298		}
15299
15300		if ( this.options.disabled || this.options.type === "static" ) {
15301			return false;
15302		}
15303
15304		//We have to refresh the items data once first
15305		this._refreshItems( event );
15306
15307		//Find out if the clicked node (or one of its parents) is a actual item in this.items
15308		$( event.target ).parents().each( function() {
15309			if ( $.data( this, that.widgetName + "-item" ) === that ) {
15310				currentItem = $( this );
15311				return false;
15312			}
15313		} );
15314		if ( $.data( event.target, that.widgetName + "-item" ) === that ) {
15315			currentItem = $( event.target );
15316		}
15317
15318		if ( !currentItem ) {
15319			return false;
15320		}
15321		if ( this.options.handle && !overrideHandle ) {
15322			$( this.options.handle, currentItem ).find( "*" ).addBack().each( function() {
15323				if ( this === event.target ) {
15324					validHandle = true;
15325				}
15326			} );
15327			if ( !validHandle ) {
15328				return false;
15329			}
15330		}
15331
15332		this.currentItem = currentItem;
15333		this._removeCurrentsFromItems();
15334		return true;
15335
15336	},
15337
15338	_mouseStart: function( event, overrideHandle, noActivation ) {
15339
15340		var i, body,
15341			o = this.options;
15342
15343		this.currentContainer = this;
15344
15345		//We only need to call refreshPositions, because the refreshItems call has been moved to
15346		// mouseCapture
15347		this.refreshPositions();
15348
15349		//Create and append the visible helper
15350		this.helper = this._createHelper( event );
15351
15352		//Cache the helper size
15353		this._cacheHelperProportions();
15354
15355		/*
15356		 * - Position generation -
15357		 * This block generates everything position related - it's the core of draggables.
15358		 */
15359
15360		//Cache the margins of the original element
15361		this._cacheMargins();
15362
15363		//Get the next scrolling parent
15364		this.scrollParent = this.helper.scrollParent();
15365
15366		//The element's absolute position on the page minus margins
15367		this.offset = this.currentItem.offset();
15368		this.offset = {
15369			top: this.offset.top - this.margins.top,
15370			left: this.offset.left - this.margins.left
15371		};
15372
15373		$.extend( this.offset, {
15374			click: { //Where the click happened, relative to the element
15375				left: event.pageX - this.offset.left,
15376				top: event.pageY - this.offset.top
15377			},
15378			parent: this._getParentOffset(),
15379
15380			// This is a relative to absolute position minus the actual position calculation -
15381			// only used for relative positioned helper
15382			relative: this._getRelativeOffset()
15383		} );
15384
15385		// Only after we got the offset, we can change the helper's position to absolute
15386		// TODO: Still need to figure out a way to make relative sorting possible
15387		this.helper.css( "position", "absolute" );
15388		this.cssPosition = this.helper.css( "position" );
15389
15390		//Generate the original position
15391		this.originalPosition = this._generatePosition( event );
15392		this.originalPageX = event.pageX;
15393		this.originalPageY = event.pageY;
15394
15395		//Adjust the mouse offset relative to the helper if "cursorAt" is supplied
15396		( o.cursorAt && this._adjustOffsetFromHelper( o.cursorAt ) );
15397
15398		//Cache the former DOM position
15399		this.domPosition = {
15400			prev: this.currentItem.prev()[ 0 ],
15401			parent: this.currentItem.parent()[ 0 ]
15402		};
15403
15404		// If the helper is not the original, hide the original so it's not playing any role during
15405		// the drag, won't cause anything bad this way
15406		if ( this.helper[ 0 ] !== this.currentItem[ 0 ] ) {
15407			this.currentItem.hide();
15408		}
15409
15410		//Create the placeholder
15411		this._createPlaceholder();
15412
15413		//Set a containment if given in the options
15414		if ( o.containment ) {
15415			this._setContainment();
15416		}
15417
15418		if ( o.cursor && o.cursor !== "auto" ) { // cursor option
15419			body = this.document.find( "body" );
15420
15421			// Support: IE
15422			this.storedCursor = body.css( "cursor" );
15423			body.css( "cursor", o.cursor );
15424
15425			this.storedStylesheet =
15426				$( "<style>*{ cursor: " + o.cursor + " !important; }</style>" ).appendTo( body );
15427		}
15428
15429		if ( o.opacity ) { // opacity option
15430			if ( this.helper.css( "opacity" ) ) {
15431				this._storedOpacity = this.helper.css( "opacity" );
15432			}
15433			this.helper.css( "opacity", o.opacity );
15434		}
15435
15436		if ( o.zIndex ) { // zIndex option
15437			if ( this.helper.css( "zIndex" ) ) {
15438				this._storedZIndex = this.helper.css( "zIndex" );
15439			}
15440			this.helper.css( "zIndex", o.zIndex );
15441		}
15442
15443		//Prepare scrolling
15444		if ( this.scrollParent[ 0 ] !== this.document[ 0 ] &&
15445				this.scrollParent[ 0 ].tagName !== "HTML" ) {
15446			this.overflowOffset = this.scrollParent.offset();
15447		}
15448
15449		//Call callbacks
15450		this._trigger( "start", event, this._uiHash() );
15451
15452		//Recache the helper size
15453		if ( !this._preserveHelperProportions ) {
15454			this._cacheHelperProportions();
15455		}
15456
15457		//Post "activate" events to possible containers
15458		if ( !noActivation ) {
15459			for ( i = this.containers.length - 1; i >= 0; i-- ) {
15460				this.containers[ i ]._trigger( "activate", event, this._uiHash( this ) );
15461			}
15462		}
15463
15464		//Prepare possible droppables
15465		if ( $.ui.ddmanager ) {
15466			$.ui.ddmanager.current = this;
15467		}
15468
15469		if ( $.ui.ddmanager && !o.dropBehaviour ) {
15470			$.ui.ddmanager.prepareOffsets( this, event );
15471		}
15472
15473		this.dragging = true;
15474
15475		this._addClass( this.helper, "ui-sortable-helper" );
15476
15477		// Execute the drag once - this causes the helper not to be visiblebefore getting its
15478		// correct position
15479		this._mouseDrag( event );
15480		return true;
15481
15482	},
15483
15484	_mouseDrag: function( event ) {
15485		var i, item, itemElement, intersection,
15486			o = this.options,
15487			scrolled = false;
15488
15489		//Compute the helpers position
15490		this.position = this._generatePosition( event );
15491		this.positionAbs = this._convertPositionTo( "absolute" );
15492
15493		if ( !this.lastPositionAbs ) {
15494			this.lastPositionAbs = this.positionAbs;
15495		}
15496
15497		//Do scrolling
15498		if ( this.options.scroll ) {
15499			if ( this.scrollParent[ 0 ] !== this.document[ 0 ] &&
15500					this.scrollParent[ 0 ].tagName !== "HTML" ) {
15501
15502				if ( ( this.overflowOffset.top + this.scrollParent[ 0 ].offsetHeight ) -
15503						event.pageY < o.scrollSensitivity ) {
15504					this.scrollParent[ 0 ].scrollTop =
15505						scrolled = this.scrollParent[ 0 ].scrollTop + o.scrollSpeed;
15506				} else if ( event.pageY - this.overflowOffset.top < o.scrollSensitivity ) {
15507					this.scrollParent[ 0 ].scrollTop =
15508						scrolled = this.scrollParent[ 0 ].scrollTop - o.scrollSpeed;
15509				}
15510
15511				if ( ( this.overflowOffset.left + this.scrollParent[ 0 ].offsetWidth ) -
15512						event.pageX < o.scrollSensitivity ) {
15513					this.scrollParent[ 0 ].scrollLeft = scrolled =
15514						this.scrollParent[ 0 ].scrollLeft + o.scrollSpeed;
15515				} else if ( event.pageX - this.overflowOffset.left < o.scrollSensitivity ) {
15516					this.scrollParent[ 0 ].scrollLeft = scrolled =
15517						this.scrollParent[ 0 ].scrollLeft - o.scrollSpeed;
15518				}
15519
15520			} else {
15521
15522				if ( event.pageY - this.document.scrollTop() < o.scrollSensitivity ) {
15523					scrolled = this.document.scrollTop( this.document.scrollTop() - o.scrollSpeed );
15524				} else if ( this.window.height() - ( event.pageY - this.document.scrollTop() ) <
15525						o.scrollSensitivity ) {
15526					scrolled = this.document.scrollTop( this.document.scrollTop() + o.scrollSpeed );
15527				}
15528
15529				if ( event.pageX - this.document.scrollLeft() < o.scrollSensitivity ) {
15530					scrolled = this.document.scrollLeft(
15531						this.document.scrollLeft() - o.scrollSpeed
15532					);
15533				} else if ( this.window.width() - ( event.pageX - this.document.scrollLeft() ) <
15534						o.scrollSensitivity ) {
15535					scrolled = this.document.scrollLeft(
15536						this.document.scrollLeft() + o.scrollSpeed
15537					);
15538				}
15539
15540			}
15541
15542			if ( scrolled !== false && $.ui.ddmanager && !o.dropBehaviour ) {
15543				$.ui.ddmanager.prepareOffsets( this, event );
15544			}
15545		}
15546
15547		//Regenerate the absolute position used for position checks
15548		this.positionAbs = this._convertPositionTo( "absolute" );
15549
15550		//Set the helper position
15551		if ( !this.options.axis || this.options.axis !== "y" ) {
15552			this.helper[ 0 ].style.left = this.position.left + "px";
15553		}
15554		if ( !this.options.axis || this.options.axis !== "x" ) {
15555			this.helper[ 0 ].style.top = this.position.top + "px";
15556		}
15557
15558		//Rearrange
15559		for ( i = this.items.length - 1; i >= 0; i-- ) {
15560
15561			//Cache variables and intersection, continue if no intersection
15562			item = this.items[ i ];
15563			itemElement = item.item[ 0 ];
15564			intersection = this._intersectsWithPointer( item );
15565			if ( !intersection ) {
15566				continue;
15567			}
15568
15569			// Only put the placeholder inside the current Container, skip all
15570			// items from other containers. This works because when moving
15571			// an item from one container to another the
15572			// currentContainer is switched before the placeholder is moved.
15573			//
15574			// Without this, moving items in "sub-sortables" can cause
15575			// the placeholder to jitter between the outer and inner container.
15576			if ( item.instance !== this.currentContainer ) {
15577				continue;
15578			}
15579
15580			// Cannot intersect with itself
15581			// no useless actions that have been done before
15582			// no action if the item moved is the parent of the item checked
15583			if ( itemElement !== this.currentItem[ 0 ] &&
15584				this.placeholder[ intersection === 1 ? "next" : "prev" ]()[ 0 ] !== itemElement &&
15585				!$.contains( this.placeholder[ 0 ], itemElement ) &&
15586				( this.options.type === "semi-dynamic" ?
15587					!$.contains( this.element[ 0 ], itemElement ) :
15588					true
15589				)
15590			) {
15591
15592				this.direction = intersection === 1 ? "down" : "up";
15593
15594				if ( this.options.tolerance === "pointer" || this._intersectsWithSides( item ) ) {
15595					this._rearrange( event, item );
15596				} else {
15597					break;
15598				}
15599
15600				this._trigger( "change", event, this._uiHash() );
15601				break;
15602			}
15603		}
15604
15605		//Post events to containers
15606		this._contactContainers( event );
15607
15608		//Interconnect with droppables
15609		if ( $.ui.ddmanager ) {
15610			$.ui.ddmanager.drag( this, event );
15611		}
15612
15613		//Call callbacks
15614		this._trigger( "sort", event, this._uiHash() );
15615
15616		this.lastPositionAbs = this.positionAbs;
15617		return false;
15618
15619	},
15620
15621	_mouseStop: function( event, noPropagation ) {
15622
15623		if ( !event ) {
15624			return;
15625		}
15626
15627		//If we are using droppables, inform the manager about the drop
15628		if ( $.ui.ddmanager && !this.options.dropBehaviour ) {
15629			$.ui.ddmanager.drop( this, event );
15630		}
15631
15632		if ( this.options.revert ) {
15633			var that = this,
15634				cur = this.placeholder.offset(),
15635				axis = this.options.axis,
15636				animation = {};
15637
15638			if ( !axis || axis === "x" ) {
15639				animation.left = cur.left - this.offset.parent.left - this.margins.left +
15640					( this.offsetParent[ 0 ] === this.document[ 0 ].body ?
15641						0 :
15642						this.offsetParent[ 0 ].scrollLeft
15643					);
15644			}
15645			if ( !axis || axis === "y" ) {
15646				animation.top = cur.top - this.offset.parent.top - this.margins.top +
15647					( this.offsetParent[ 0 ] === this.document[ 0 ].body ?
15648						0 :
15649						this.offsetParent[ 0 ].scrollTop
15650					);
15651			}
15652			this.reverting = true;
15653			$( this.helper ).animate(
15654				animation,
15655				parseInt( this.options.revert, 10 ) || 500,
15656				function() {
15657					that._clear( event );
15658				}
15659			);
15660		} else {
15661			this._clear( event, noPropagation );
15662		}
15663
15664		return false;
15665
15666	},
15667
15668	cancel: function() {
15669
15670		if ( this.dragging ) {
15671
15672			this._mouseUp( new $.Event( "mouseup", { target: null } ) );
15673
15674			if ( this.options.helper === "original" ) {
15675				this.currentItem.css( this._storedCSS );
15676				this._removeClass( this.currentItem, "ui-sortable-helper" );
15677			} else {
15678				this.currentItem.show();
15679			}
15680
15681			//Post deactivating events to containers
15682			for ( var i = this.containers.length - 1; i >= 0; i-- ) {
15683				this.containers[ i ]._trigger( "deactivate", null, this._uiHash( this ) );
15684				if ( this.containers[ i ].containerCache.over ) {
15685					this.containers[ i ]._trigger( "out", null, this._uiHash( this ) );
15686					this.containers[ i ].containerCache.over = 0;
15687				}
15688			}
15689
15690		}
15691
15692		if ( this.placeholder ) {
15693
15694			//$(this.placeholder[0]).remove(); would have been the jQuery way - unfortunately,
15695			// it unbinds ALL events from the original node!
15696			if ( this.placeholder[ 0 ].parentNode ) {
15697				this.placeholder[ 0 ].parentNode.removeChild( this.placeholder[ 0 ] );
15698			}
15699			if ( this.options.helper !== "original" && this.helper &&
15700					this.helper[ 0 ].parentNode ) {
15701				this.helper.remove();
15702			}
15703
15704			$.extend( this, {
15705				helper: null,
15706				dragging: false,
15707				reverting: false,
15708				_noFinalSort: null
15709			} );
15710
15711			if ( this.domPosition.prev ) {
15712				$( this.domPosition.prev ).after( this.currentItem );
15713			} else {
15714				$( this.domPosition.parent ).prepend( this.currentItem );
15715			}
15716		}
15717
15718		return this;
15719
15720	},
15721
15722	serialize: function( o ) {
15723
15724		var items = this._getItemsAsjQuery( o && o.connected ),
15725			str = [];
15726		o = o || {};
15727
15728		$( items ).each( function() {
15729			var res = ( $( o.item || this ).attr( o.attribute || "id" ) || "" )
15730				.match( o.expression || ( /(.+)[\-=_](.+)/ ) );
15731			if ( res ) {
15732				str.push(
15733					( o.key || res[ 1 ] + "[]" ) +
15734					"=" + ( o.key && o.expression ? res[ 1 ] : res[ 2 ] ) );
15735			}
15736		} );
15737
15738		if ( !str.length && o.key ) {
15739			str.push( o.key + "=" );
15740		}
15741
15742		return str.join( "&" );
15743
15744	},
15745
15746	toArray: function( o ) {
15747
15748		var items = this._getItemsAsjQuery( o && o.connected ),
15749			ret = [];
15750
15751		o = o || {};
15752
15753		items.each( function() {
15754			ret.push( $( o.item || this ).attr( o.attribute || "id" ) || "" );
15755		} );
15756		return ret;
15757
15758	},
15759
15760	/* Be careful with the following core functions */
15761	_intersectsWith: function( item ) {
15762
15763		var x1 = this.positionAbs.left,
15764			x2 = x1 + this.helperProportions.width,
15765			y1 = this.positionAbs.top,
15766			y2 = y1 + this.helperProportions.height,
15767			l = item.left,
15768			r = l + item.width,
15769			t = item.top,
15770			b = t + item.height,
15771			dyClick = this.offset.click.top,
15772			dxClick = this.offset.click.left,
15773			isOverElementHeight = ( this.options.axis === "x" ) || ( ( y1 + dyClick ) > t &&
15774				( y1 + dyClick ) < b ),
15775			isOverElementWidth = ( this.options.axis === "y" ) || ( ( x1 + dxClick ) > l &&
15776				( x1 + dxClick ) < r ),
15777			isOverElement = isOverElementHeight && isOverElementWidth;
15778
15779		if ( this.options.tolerance === "pointer" ||
15780			this.options.forcePointerForContainers ||
15781			( this.options.tolerance !== "pointer" &&
15782				this.helperProportions[ this.floating ? "width" : "height" ] >
15783				item[ this.floating ? "width" : "height" ] )
15784		) {
15785			return isOverElement;
15786		} else {
15787
15788			return ( l < x1 + ( this.helperProportions.width / 2 ) && // Right Half
15789				x2 - ( this.helperProportions.width / 2 ) < r && // Left Half
15790				t < y1 + ( this.helperProportions.height / 2 ) && // Bottom Half
15791				y2 - ( this.helperProportions.height / 2 ) < b ); // Top Half
15792
15793		}
15794	},
15795
15796	_intersectsWithPointer: function( item ) {
15797		var verticalDirection, horizontalDirection,
15798			isOverElementHeight = ( this.options.axis === "x" ) ||
15799				this._isOverAxis(
15800					this.positionAbs.top + this.offset.click.top, item.top, item.height ),
15801			isOverElementWidth = ( this.options.axis === "y" ) ||
15802				this._isOverAxis(
15803					this.positionAbs.left + this.offset.click.left, item.left, item.width ),
15804			isOverElement = isOverElementHeight && isOverElementWidth;
15805
15806		if ( !isOverElement ) {
15807			return false;
15808		}
15809
15810		verticalDirection = this._getDragVerticalDirection();
15811		horizontalDirection = this._getDragHorizontalDirection();
15812
15813		return this.floating ?
15814			( ( horizontalDirection === "right" || verticalDirection === "down" ) ? 2 : 1 )
15815			: ( verticalDirection && ( verticalDirection === "down" ? 2 : 1 ) );
15816
15817	},
15818
15819	_intersectsWithSides: function( item ) {
15820
15821		var isOverBottomHalf = this._isOverAxis( this.positionAbs.top +
15822				this.offset.click.top, item.top + ( item.height / 2 ), item.height ),
15823			isOverRightHalf = this._isOverAxis( this.positionAbs.left +
15824				this.offset.click.left, item.left + ( item.width / 2 ), item.width ),
15825			verticalDirection = this._getDragVerticalDirection(),
15826			horizontalDirection = this._getDragHorizontalDirection();
15827
15828		if ( this.floating && horizontalDirection ) {
15829			return ( ( horizontalDirection === "right" && isOverRightHalf ) ||
15830				( horizontalDirection === "left" && !isOverRightHalf ) );
15831		} else {
15832			return verticalDirection && ( ( verticalDirection === "down" && isOverBottomHalf ) ||
15833				( verticalDirection === "up" && !isOverBottomHalf ) );
15834		}
15835
15836	},
15837
15838	_getDragVerticalDirection: function() {
15839		var delta = this.positionAbs.top - this.lastPositionAbs.top;
15840		return delta !== 0 && ( delta > 0 ? "down" : "up" );
15841	},
15842
15843	_getDragHorizontalDirection: function() {
15844		var delta = this.positionAbs.left - this.lastPositionAbs.left;
15845		return delta !== 0 && ( delta > 0 ? "right" : "left" );
15846	},
15847
15848	refresh: function( event ) {
15849		this._refreshItems( event );
15850		this._setHandleClassName();
15851		this.refreshPositions();
15852		return this;
15853	},
15854
15855	_connectWith: function() {
15856		var options = this.options;
15857		return options.connectWith.constructor === String ?
15858			[ options.connectWith ] :
15859			options.connectWith;
15860	},
15861
15862	_getItemsAsjQuery: function( connected ) {
15863
15864		var i, j, cur, inst,
15865			items = [],
15866			queries = [],
15867			connectWith = this._connectWith();
15868
15869		if ( connectWith && connected ) {
15870			for ( i = connectWith.length - 1; i >= 0; i-- ) {
15871				cur = $( connectWith[ i ], this.document[ 0 ] );
15872				for ( j = cur.length - 1; j >= 0; j-- ) {
15873					inst = $.data( cur[ j ], this.widgetFullName );
15874					if ( inst && inst !== this && !inst.options.disabled ) {
15875						queries.push( [ $.isFunction( inst.options.items ) ?
15876							inst.options.items.call( inst.element ) :
15877							$( inst.options.items, inst.element )
15878								.not( ".ui-sortable-helper" )
15879								.not( ".ui-sortable-placeholder" ), inst ] );
15880					}
15881				}
15882			}
15883		}
15884
15885		queries.push( [ $.isFunction( this.options.items ) ?
15886			this.options.items
15887				.call( this.element, null, { options: this.options, item: this.currentItem } ) :
15888			$( this.options.items, this.element )
15889				.not( ".ui-sortable-helper" )
15890				.not( ".ui-sortable-placeholder" ), this ] );
15891
15892		function addItems() {
15893			items.push( this );
15894		}
15895		for ( i = queries.length - 1; i >= 0; i-- ) {
15896			queries[ i ][ 0 ].each( addItems );
15897		}
15898
15899		return $( items );
15900
15901	},
15902
15903	_removeCurrentsFromItems: function() {
15904
15905		var list = this.currentItem.find( ":data(" + this.widgetName + "-item)" );
15906
15907		this.items = $.grep( this.items, function( item ) {
15908			for ( var j = 0; j < list.length; j++ ) {
15909				if ( list[ j ] === item.item[ 0 ] ) {
15910					return false;
15911				}
15912			}
15913			return true;
15914		} );
15915
15916	},
15917
15918	_refreshItems: function( event ) {
15919
15920		this.items = [];
15921		this.containers = [ this ];
15922
15923		var i, j, cur, inst, targetData, _queries, item, queriesLength,
15924			items = this.items,
15925			queries = [ [ $.isFunction( this.options.items ) ?
15926				this.options.items.call( this.element[ 0 ], event, { item: this.currentItem } ) :
15927				$( this.options.items, this.element ), this ] ],
15928			connectWith = this._connectWith();
15929
15930		//Shouldn't be run the first time through due to massive slow-down
15931		if ( connectWith && this.ready ) {
15932			for ( i = connectWith.length - 1; i >= 0; i-- ) {
15933				cur = $( connectWith[ i ], this.document[ 0 ] );
15934				for ( j = cur.length - 1; j >= 0; j-- ) {
15935					inst = $.data( cur[ j ], this.widgetFullName );
15936					if ( inst && inst !== this && !inst.options.disabled ) {
15937						queries.push( [ $.isFunction( inst.options.items ) ?
15938							inst.options.items
15939								.call( inst.element[ 0 ], event, { item: this.currentItem } ) :
15940							$( inst.options.items, inst.element ), inst ] );
15941						this.containers.push( inst );
15942					}
15943				}
15944			}
15945		}
15946
15947		for ( i = queries.length - 1; i >= 0; i-- ) {
15948			targetData = queries[ i ][ 1 ];
15949			_queries = queries[ i ][ 0 ];
15950
15951			for ( j = 0, queriesLength = _queries.length; j < queriesLength; j++ ) {
15952				item = $( _queries[ j ] );
15953
15954				// Data for target checking (mouse manager)
15955				item.data( this.widgetName + "-item", targetData );
15956
15957				items.push( {
15958					item: item,
15959					instance: targetData,
15960					width: 0, height: 0,
15961					left: 0, top: 0
15962				} );
15963			}
15964		}
15965
15966	},
15967
15968	refreshPositions: function( fast ) {
15969
15970		// Determine whether items are being displayed horizontally
15971		this.floating = this.items.length ?
15972			this.options.axis === "x" || this._isFloating( this.items[ 0 ].item ) :
15973			false;
15974
15975		//This has to be redone because due to the item being moved out/into the offsetParent,
15976		// the offsetParent's position will change
15977		if ( this.offsetParent && this.helper ) {
15978			this.offset.parent = this._getParentOffset();
15979		}
15980
15981		var i, item, t, p;
15982
15983		for ( i = this.items.length - 1; i >= 0; i-- ) {
15984			item = this.items[ i ];
15985
15986			//We ignore calculating positions of all connected containers when we're not over them
15987			if ( item.instance !== this.currentContainer && this.currentContainer &&
15988					item.item[ 0 ] !== this.currentItem[ 0 ] ) {
15989				continue;
15990			}
15991
15992			t = this.options.toleranceElement ?
15993				$( this.options.toleranceElement, item.item ) :
15994				item.item;
15995
15996			if ( !fast ) {
15997				item.width = t.outerWidth();
15998				item.height = t.outerHeight();
15999			}
16000
16001			p = t.offset();
16002			item.left = p.left;
16003			item.top = p.top;
16004		}
16005
16006		if ( this.options.custom && this.options.custom.refreshContainers ) {
16007			this.options.custom.refreshContainers.call( this );
16008		} else {
16009			for ( i = this.containers.length - 1; i >= 0; i-- ) {
16010				p = this.containers[ i ].element.offset();
16011				this.containers[ i ].containerCache.left = p.left;
16012				this.containers[ i ].containerCache.top = p.top;
16013				this.containers[ i ].containerCache.width =
16014					this.containers[ i ].element.outerWidth();
16015				this.containers[ i ].containerCache.height =
16016					this.containers[ i ].element.outerHeight();
16017			}
16018		}
16019
16020		return this;
16021	},
16022
16023	_createPlaceholder: function( that ) {
16024		that = that || this;
16025		var className,
16026			o = that.options;
16027
16028		if ( !o.placeholder || o.placeholder.constructor === String ) {
16029			className = o.placeholder;
16030			o.placeholder = {
16031				element: function() {
16032
16033					var nodeName = that.currentItem[ 0 ].nodeName.toLowerCase(),
16034						element = $( "<" + nodeName + ">", that.document[ 0 ] );
16035
16036						that._addClass( element, "ui-sortable-placeholder",
16037								className || that.currentItem[ 0 ].className )
16038							._removeClass( element, "ui-sortable-helper" );
16039
16040					if ( nodeName === "tbody" ) {
16041						that._createTrPlaceholder(
16042							that.currentItem.find( "tr" ).eq( 0 ),
16043							$( "<tr>", that.document[ 0 ] ).appendTo( element )
16044						);
16045					} else if ( nodeName === "tr" ) {
16046						that._createTrPlaceholder( that.currentItem, element );
16047					} else if ( nodeName === "img" ) {
16048						element.attr( "src", that.currentItem.attr( "src" ) );
16049					}
16050
16051					if ( !className ) {
16052						element.css( "visibility", "hidden" );
16053					}
16054
16055					return element;
16056				},
16057				update: function( container, p ) {
16058
16059					// 1. If a className is set as 'placeholder option, we don't force sizes -
16060					// the class is responsible for that
16061					// 2. The option 'forcePlaceholderSize can be enabled to force it even if a
16062					// class name is specified
16063					if ( className && !o.forcePlaceholderSize ) {
16064						return;
16065					}
16066
16067					//If the element doesn't have a actual height by itself (without styles coming
16068					// from a stylesheet), it receives the inline height from the dragged item
16069					if ( !p.height() ) {
16070						p.height(
16071							that.currentItem.innerHeight() -
16072							parseInt( that.currentItem.css( "paddingTop" ) || 0, 10 ) -
16073							parseInt( that.currentItem.css( "paddingBottom" ) || 0, 10 ) );
16074					}
16075					if ( !p.width() ) {
16076						p.width(
16077							that.currentItem.innerWidth() -
16078							parseInt( that.currentItem.css( "paddingLeft" ) || 0, 10 ) -
16079							parseInt( that.currentItem.css( "paddingRight" ) || 0, 10 ) );
16080					}
16081				}
16082			};
16083		}
16084
16085		//Create the placeholder
16086		that.placeholder = $( o.placeholder.element.call( that.element, that.currentItem ) );
16087
16088		//Append it after the actual current item
16089		that.currentItem.after( that.placeholder );
16090
16091		//Update the size of the placeholder (TODO: Logic to fuzzy, see line 316/317)
16092		o.placeholder.update( that, that.placeholder );
16093
16094	},
16095
16096	_createTrPlaceholder: function( sourceTr, targetTr ) {
16097		var that = this;
16098
16099		sourceTr.children().each( function() {
16100			$( "<td>&#160;</td>", that.document[ 0 ] )
16101				.attr( "colspan", $( this ).attr( "colspan" ) || 1 )
16102				.appendTo( targetTr );
16103		} );
16104	},
16105
16106	_contactContainers: function( event ) {
16107		var i, j, dist, itemWithLeastDistance, posProperty, sizeProperty, cur, nearBottom,
16108			floating, axis,
16109			innermostContainer = null,
16110			innermostIndex = null;
16111
16112		// Get innermost container that intersects with item
16113		for ( i = this.containers.length - 1; i >= 0; i-- ) {
16114
16115			// Never consider a container that's located within the item itself
16116			if ( $.contains( this.currentItem[ 0 ], this.containers[ i ].element[ 0 ] ) ) {
16117				continue;
16118			}
16119
16120			if ( this._intersectsWith( this.containers[ i ].containerCache ) ) {
16121
16122				// If we've already found a container and it's more "inner" than this, then continue
16123				if ( innermostContainer &&
16124						$.contains(
16125							this.containers[ i ].element[ 0 ],
16126							innermostContainer.element[ 0 ] ) ) {
16127					continue;
16128				}
16129
16130				innermostContainer = this.containers[ i ];
16131				innermostIndex = i;
16132
16133			} else {
16134
16135				// container doesn't intersect. trigger "out" event if necessary
16136				if ( this.containers[ i ].containerCache.over ) {
16137					this.containers[ i ]._trigger( "out", event, this._uiHash( this ) );
16138					this.containers[ i ].containerCache.over = 0;
16139				}
16140			}
16141
16142		}
16143
16144		// If no intersecting containers found, return
16145		if ( !innermostContainer ) {
16146			return;
16147		}
16148
16149		// Move the item into the container if it's not there already
16150		if ( this.containers.length === 1 ) {
16151			if ( !this.containers[ innermostIndex ].containerCache.over ) {
16152				this.containers[ innermostIndex ]._trigger( "over", event, this._uiHash( this ) );
16153				this.containers[ innermostIndex ].containerCache.over = 1;
16154			}
16155		} else {
16156
16157			// When entering a new container, we will find the item with the least distance and
16158			// append our item near it
16159			dist = 10000;
16160			itemWithLeastDistance = null;
16161			floating = innermostContainer.floating || this._isFloating( this.currentItem );
16162			posProperty = floating ? "left" : "top";
16163			sizeProperty = floating ? "width" : "height";
16164			axis = floating ? "pageX" : "pageY";
16165
16166			for ( j = this.items.length - 1; j >= 0; j-- ) {
16167				if ( !$.contains(
16168						this.containers[ innermostIndex ].element[ 0 ], this.items[ j ].item[ 0 ] )
16169				) {
16170					continue;
16171				}
16172				if ( this.items[ j ].item[ 0 ] === this.currentItem[ 0 ] ) {
16173					continue;
16174				}
16175
16176				cur = this.items[ j ].item.offset()[ posProperty ];
16177				nearBottom = false;
16178				if ( event[ axis ] - cur > this.items[ j ][ sizeProperty ] / 2 ) {
16179					nearBottom = true;
16180				}
16181
16182				if ( Math.abs( event[ axis ] - cur ) < dist ) {
16183					dist = Math.abs( event[ axis ] - cur );
16184					itemWithLeastDistance = this.items[ j ];
16185					this.direction = nearBottom ? "up" : "down";
16186				}
16187			}
16188
16189			//Check if dropOnEmpty is enabled
16190			if ( !itemWithLeastDistance && !this.options.dropOnEmpty ) {
16191				return;
16192			}
16193
16194			if ( this.currentContainer === this.containers[ innermostIndex ] ) {
16195				if ( !this.currentContainer.containerCache.over ) {
16196					this.containers[ innermostIndex ]._trigger( "over", event, this._uiHash() );
16197					this.currentContainer.containerCache.over = 1;
16198				}
16199				return;
16200			}
16201
16202			itemWithLeastDistance ?
16203				this._rearrange( event, itemWithLeastDistance, null, true ) :
16204				this._rearrange( event, null, this.containers[ innermostIndex ].element, true );
16205			this._trigger( "change", event, this._uiHash() );
16206			this.containers[ innermostIndex ]._trigger( "change", event, this._uiHash( this ) );
16207			this.currentContainer = this.containers[ innermostIndex ];
16208
16209			//Update the placeholder
16210			this.options.placeholder.update( this.currentContainer, this.placeholder );
16211
16212			this.containers[ innermostIndex ]._trigger( "over", event, this._uiHash( this ) );
16213			this.containers[ innermostIndex ].containerCache.over = 1;
16214		}
16215
16216	},
16217
16218	_createHelper: function( event ) {
16219
16220		var o = this.options,
16221			helper = $.isFunction( o.helper ) ?
16222				$( o.helper.apply( this.element[ 0 ], [ event, this.currentItem ] ) ) :
16223				( o.helper === "clone" ? this.currentItem.clone() : this.currentItem );
16224
16225		//Add the helper to the DOM if that didn't happen already
16226		if ( !helper.parents( "body" ).length ) {
16227			$( o.appendTo !== "parent" ?
16228				o.appendTo :
16229				this.currentItem[ 0 ].parentNode )[ 0 ].appendChild( helper[ 0 ] );
16230		}
16231
16232		if ( helper[ 0 ] === this.currentItem[ 0 ] ) {
16233			this._storedCSS = {
16234				width: this.currentItem[ 0 ].style.width,
16235				height: this.currentItem[ 0 ].style.height,
16236				position: this.currentItem.css( "position" ),
16237				top: this.currentItem.css( "top" ),
16238				left: this.currentItem.css( "left" )
16239			};
16240		}
16241
16242		if ( !helper[ 0 ].style.width || o.forceHelperSize ) {
16243			helper.width( this.currentItem.width() );
16244		}
16245		if ( !helper[ 0 ].style.height || o.forceHelperSize ) {
16246			helper.height( this.currentItem.height() );
16247		}
16248
16249		return helper;
16250
16251	},
16252
16253	_adjustOffsetFromHelper: function( obj ) {
16254		if ( typeof obj === "string" ) {
16255			obj = obj.split( " " );
16256		}
16257		if ( $.isArray( obj ) ) {
16258			obj = { left: +obj[ 0 ], top: +obj[ 1 ] || 0 };
16259		}
16260		if ( "left" in obj ) {
16261			this.offset.click.left = obj.left + this.margins.left;
16262		}
16263		if ( "right" in obj ) {
16264			this.offset.click.left = this.helperProportions.width - obj.right + this.margins.left;
16265		}
16266		if ( "top" in obj ) {
16267			this.offset.click.top = obj.top + this.margins.top;
16268		}
16269		if ( "bottom" in obj ) {
16270			this.offset.click.top = this.helperProportions.height - obj.bottom + this.margins.top;
16271		}
16272	},
16273
16274	_getParentOffset: function() {
16275
16276		//Get the offsetParent and cache its position
16277		this.offsetParent = this.helper.offsetParent();
16278		var po = this.offsetParent.offset();
16279
16280		// This is a special case where we need to modify a offset calculated on start, since the
16281		// following happened:
16282		// 1. The position of the helper is absolute, so it's position is calculated based on the
16283		// next positioned parent
16284		// 2. The actual offset parent is a child of the scroll parent, and the scroll parent isn't
16285		// the document, which means that the scroll is included in the initial calculation of the
16286		// offset of the parent, and never recalculated upon drag
16287		if ( this.cssPosition === "absolute" && this.scrollParent[ 0 ] !== this.document[ 0 ] &&
16288				$.contains( this.scrollParent[ 0 ], this.offsetParent[ 0 ] ) ) {
16289			po.left += this.scrollParent.scrollLeft();
16290			po.top += this.scrollParent.scrollTop();
16291		}
16292
16293		// This needs to be actually done for all browsers, since pageX/pageY includes this
16294		// information with an ugly IE fix
16295		if ( this.offsetParent[ 0 ] === this.document[ 0 ].body ||
16296				( this.offsetParent[ 0 ].tagName &&
16297				this.offsetParent[ 0 ].tagName.toLowerCase() === "html" && $.ui.ie ) ) {
16298			po = { top: 0, left: 0 };
16299		}
16300
16301		return {
16302			top: po.top + ( parseInt( this.offsetParent.css( "borderTopWidth" ), 10 ) || 0 ),
16303			left: po.left + ( parseInt( this.offsetParent.css( "borderLeftWidth" ), 10 ) || 0 )
16304		};
16305
16306	},
16307
16308	_getRelativeOffset: function() {
16309
16310		if ( this.cssPosition === "relative" ) {
16311			var p = this.currentItem.position();
16312			return {
16313				top: p.top - ( parseInt( this.helper.css( "top" ), 10 ) || 0 ) +
16314					this.scrollParent.scrollTop(),
16315				left: p.left - ( parseInt( this.helper.css( "left" ), 10 ) || 0 ) +
16316					this.scrollParent.scrollLeft()
16317			};
16318		} else {
16319			return { top: 0, left: 0 };
16320		}
16321
16322	},
16323
16324	_cacheMargins: function() {
16325		this.margins = {
16326			left: ( parseInt( this.currentItem.css( "marginLeft" ), 10 ) || 0 ),
16327			top: ( parseInt( this.currentItem.css( "marginTop" ), 10 ) || 0 )
16328		};
16329	},
16330
16331	_cacheHelperProportions: function() {
16332		this.helperProportions = {
16333			width: this.helper.outerWidth(),
16334			height: this.helper.outerHeight()
16335		};
16336	},
16337
16338	_setContainment: function() {
16339
16340		var ce, co, over,
16341			o = this.options;
16342		if ( o.containment === "parent" ) {
16343			o.containment = this.helper[ 0 ].parentNode;
16344		}
16345		if ( o.containment === "document" || o.containment === "window" ) {
16346			this.containment = [
16347				0 - this.offset.relative.left - this.offset.parent.left,
16348				0 - this.offset.relative.top - this.offset.parent.top,
16349				o.containment === "document" ?
16350					this.document.width() :
16351					this.window.width() - this.helperProportions.width - this.margins.left,
16352				( o.containment === "document" ?
16353					( this.document.height() || document.body.parentNode.scrollHeight ) :
16354					this.window.height() || this.document[ 0 ].body.parentNode.scrollHeight
16355				) - this.helperProportions.height - this.margins.top
16356			];
16357		}
16358
16359		if ( !( /^(document|window|parent)$/ ).test( o.containment ) ) {
16360			ce = $( o.containment )[ 0 ];
vendor: 2,294 bytes, lines 16361-16421
16361			co = $( o.containment ).offset();
16362			over = ( $( ce ).css( "overflow" ) !== "hidden" );
16363
16364			this.containment = [
16365				co.left + ( parseInt( $( ce ).css( "borderLeftWidth" ), 10 ) || 0 ) +
16366					( parseInt( $( ce ).css( "paddingLeft" ), 10 ) || 0 ) - this.margins.left,
16367				co.top + ( parseInt( $( ce ).css( "borderTopWidth" ), 10 ) || 0 ) +
16368					( parseInt( $( ce ).css( "paddingTop" ), 10 ) || 0 ) - this.margins.top,
16369				co.left + ( over ? Math.max( ce.scrollWidth, ce.offsetWidth ) : ce.offsetWidth ) -
16370					( parseInt( $( ce ).css( "borderLeftWidth" ), 10 ) || 0 ) -
16371					( parseInt( $( ce ).css( "paddingRight" ), 10 ) || 0 ) -
16372					this.helperProportions.width - this.margins.left,
16373				co.top + ( over ? Math.max( ce.scrollHeight, ce.offsetHeight ) : ce.offsetHeight ) -
16374					( parseInt( $( ce ).css( "borderTopWidth" ), 10 ) || 0 ) -
16375					( parseInt( $( ce ).css( "paddingBottom" ), 10 ) || 0 ) -
16376					this.helperProportions.height - this.margins.top
16377			];
16378		}
16379
16380	},
16381
16382	_convertPositionTo: function( d, pos ) {
16383
16384		if ( !pos ) {
16385			pos = this.position;
16386		}
16387		var mod = d === "absolute" ? 1 : -1,
16388			scroll = this.cssPosition === "absolute" &&
16389				!( this.scrollParent[ 0 ] !== this.document[ 0 ] &&
16390				$.contains( this.scrollParent[ 0 ], this.offsetParent[ 0 ] ) ) ?
16391					this.offsetParent :
16392					this.scrollParent,
16393			scrollIsRootNode = ( /(html|body)/i ).test( scroll[ 0 ].tagName );
16394
16395		return {
16396			top: (
16397
16398				// The absolute mouse position
16399				pos.top	+
16400
16401				// Only for relative positioned nodes: Relative offset from element to offset parent
16402				this.offset.relative.top * mod +
16403
16404				// The offsetParent's offset without borders (offset + border)
16405				this.offset.parent.top * mod -
16406				( ( this.cssPosition === "fixed" ?
16407					-this.scrollParent.scrollTop() :
16408					( scrollIsRootNode ? 0 : scroll.scrollTop() ) ) * mod )
16409			),
16410			left: (
16411
16412				// The absolute mouse position
16413				pos.left +
16414
16415				// Only for relative positioned nodes: Relative offset from element to offset parent
16416				this.offset.relative.left * mod +
16417
16418				// The offsetParent's offset without borders (offset + border)
16419				this.offset.parent.left * mod	-
16420				( ( this.cssPosition === "fixed" ?
16421					-this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 :
vendor: 9,150 bytes, lines 16422-16706
16422					scroll.scrollLeft() ) * mod )
16423			)
16424		};
16425
16426	},
16427
16428	_generatePosition: function( event ) {
16429
16430		var top, left,
16431			o = this.options,
16432			pageX = event.pageX,
16433			pageY = event.pageY,
16434			scroll = this.cssPosition === "absolute" &&
16435				!( this.scrollParent[ 0 ] !== this.document[ 0 ] &&
16436				$.contains( this.scrollParent[ 0 ], this.offsetParent[ 0 ] ) ) ?
16437					this.offsetParent :
16438					this.scrollParent,
16439				scrollIsRootNode = ( /(html|body)/i ).test( scroll[ 0 ].tagName );
16440
16441		// This is another very weird special case that only happens for relative elements:
16442		// 1. If the css position is relative
16443		// 2. and the scroll parent is the document or similar to the offset parent
16444		// we have to refresh the relative offset during the scroll so there are no jumps
16445		if ( this.cssPosition === "relative" && !( this.scrollParent[ 0 ] !== this.document[ 0 ] &&
16446				this.scrollParent[ 0 ] !== this.offsetParent[ 0 ] ) ) {
16447			this.offset.relative = this._getRelativeOffset();
16448		}
16449
16450		/*
16451		 * - Position constraining -
16452		 * Constrain the position to a mix of grid, containment.
16453		 */
16454
16455		if ( this.originalPosition ) { //If we are not dragging yet, we won't check for options
16456
16457			if ( this.containment ) {
16458				if ( event.pageX - this.offset.click.left < this.containment[ 0 ] ) {
16459					pageX = this.containment[ 0 ] + this.offset.click.left;
16460				}
16461				if ( event.pageY - this.offset.click.top < this.containment[ 1 ] ) {
16462					pageY = this.containment[ 1 ] + this.offset.click.top;
16463				}
16464				if ( event.pageX - this.offset.click.left > this.containment[ 2 ] ) {
16465					pageX = this.containment[ 2 ] + this.offset.click.left;
16466				}
16467				if ( event.pageY - this.offset.click.top > this.containment[ 3 ] ) {
16468					pageY = this.containment[ 3 ] + this.offset.click.top;
16469				}
16470			}
16471
16472			if ( o.grid ) {
16473				top = this.originalPageY + Math.round( ( pageY - this.originalPageY ) /
16474					o.grid[ 1 ] ) * o.grid[ 1 ];
16475				pageY = this.containment ?
16476					( ( top - this.offset.click.top >= this.containment[ 1 ] &&
16477						top - this.offset.click.top <= this.containment[ 3 ] ) ?
16478							top :
16479							( ( top - this.offset.click.top >= this.containment[ 1 ] ) ?
16480								top - o.grid[ 1 ] : top + o.grid[ 1 ] ) ) :
16481								top;
16482
16483				left = this.originalPageX + Math.round( ( pageX - this.originalPageX ) /
16484					o.grid[ 0 ] ) * o.grid[ 0 ];
16485				pageX = this.containment ?
16486					( ( left - this.offset.click.left >= this.containment[ 0 ] &&
16487						left - this.offset.click.left <= this.containment[ 2 ] ) ?
16488							left :
16489							( ( left - this.offset.click.left >= this.containment[ 0 ] ) ?
16490								left - o.grid[ 0 ] : left + o.grid[ 0 ] ) ) :
16491								left;
16492			}
16493
16494		}
16495
16496		return {
16497			top: (
16498
16499				// The absolute mouse position
16500				pageY -
16501
16502				// Click offset (relative to the element)
16503				this.offset.click.top -
16504
16505				// Only for relative positioned nodes: Relative offset from element to offset parent
16506				this.offset.relative.top -
16507
16508				// The offsetParent's offset without borders (offset + border)
16509				this.offset.parent.top +
16510				( ( this.cssPosition === "fixed" ?
16511					-this.scrollParent.scrollTop() :
16512					( scrollIsRootNode ? 0 : scroll.scrollTop() ) ) )
16513			),
16514			left: (
16515
16516				// The absolute mouse position
16517				pageX -
16518
16519				// Click offset (relative to the element)
16520				this.offset.click.left -
16521
16522				// Only for relative positioned nodes: Relative offset from element to offset parent
16523				this.offset.relative.left -
16524
16525				// The offsetParent's offset without borders (offset + border)
16526				this.offset.parent.left +
16527				( ( this.cssPosition === "fixed" ?
16528					-this.scrollParent.scrollLeft() :
16529					scrollIsRootNode ? 0 : scroll.scrollLeft() ) )
16530			)
16531		};
16532
16533	},
16534
16535	_rearrange: function( event, i, a, hardRefresh ) {
16536
16537		a ? a[ 0 ].appendChild( this.placeholder[ 0 ] ) :
16538			i.item[ 0 ].parentNode.insertBefore( this.placeholder[ 0 ],
16539				( this.direction === "down" ? i.item[ 0 ] : i.item[ 0 ].nextSibling ) );
16540
16541		//Various things done here to improve the performance:
16542		// 1. we create a setTimeout, that calls refreshPositions
16543		// 2. on the instance, we have a counter variable, that get's higher after every append
16544		// 3. on the local scope, we copy the counter variable, and check in the timeout,
16545		// if it's still the same
16546		// 4. this lets only the last addition to the timeout stack through
16547		this.counter = this.counter ? ++this.counter : 1;
16548		var counter = this.counter;
16549
16550		this._delay( function() {
16551			if ( counter === this.counter ) {
16552
16553				//Precompute after each DOM insertion, NOT on mousemove
16554				this.refreshPositions( !hardRefresh );
16555			}
16556		} );
16557
16558	},
16559
16560	_clear: function( event, noPropagation ) {
16561
16562		this.reverting = false;
16563
16564		// We delay all events that have to be triggered to after the point where the placeholder
16565		// has been removed and everything else normalized again
16566		var i,
16567			delayedTriggers = [];
16568
16569		// We first have to update the dom position of the actual currentItem
16570		// Note: don't do it if the current item is already removed (by a user), or it gets
16571		// reappended (see #4088)
16572		if ( !this._noFinalSort && this.currentItem.parent().length ) {
16573			this.placeholder.before( this.currentItem );
16574		}
16575		this._noFinalSort = null;
16576
16577		if ( this.helper[ 0 ] === this.currentItem[ 0 ] ) {
16578			for ( i in this._storedCSS ) {
16579				if ( this._storedCSS[ i ] === "auto" || this._storedCSS[ i ] === "static" ) {
16580					this._storedCSS[ i ] = "";
16581				}
16582			}
16583			this.currentItem.css( this._storedCSS );
16584			this._removeClass( this.currentItem, "ui-sortable-helper" );
16585		} else {
16586			this.currentItem.show();
16587		}
16588
16589		if ( this.fromOutside && !noPropagation ) {
16590			delayedTriggers.push( function( event ) {
16591				this._trigger( "receive", event, this._uiHash( this.fromOutside ) );
16592			} );
16593		}
16594		if ( ( this.fromOutside ||
16595				this.domPosition.prev !==
16596				this.currentItem.prev().not( ".ui-sortable-helper" )[ 0 ] ||
16597				this.domPosition.parent !== this.currentItem.parent()[ 0 ] ) && !noPropagation ) {
16598
16599			// Trigger update callback if the DOM position has changed
16600			delayedTriggers.push( function( event ) {
16601				this._trigger( "update", event, this._uiHash() );
16602			} );
16603		}
16604
16605		// Check if the items Container has Changed and trigger appropriate
16606		// events.
16607		if ( this !== this.currentContainer ) {
16608			if ( !noPropagation ) {
16609				delayedTriggers.push( function( event ) {
16610					this._trigger( "remove", event, this._uiHash() );
16611				} );
16612				delayedTriggers.push( ( function( c ) {
16613					return function( event ) {
16614						c._trigger( "receive", event, this._uiHash( this ) );
16615					};
16616				} ).call( this, this.currentContainer ) );
16617				delayedTriggers.push( ( function( c ) {
16618					return function( event ) {
16619						c._trigger( "update", event, this._uiHash( this ) );
16620					};
16621				} ).call( this, this.currentContainer ) );
16622			}
16623		}
16624
16625		//Post events to containers
16626		function delayEvent( type, instance, container ) {
16627			return function( event ) {
16628				container._trigger( type, event, instance._uiHash( instance ) );
16629			};
16630		}
16631		for ( i = this.containers.length - 1; i >= 0; i-- ) {
16632			if ( !noPropagation ) {
16633				delayedTriggers.push( delayEvent( "deactivate", this, this.containers[ i ] ) );
16634			}
16635			if ( this.containers[ i ].containerCache.over ) {
16636				delayedTriggers.push( delayEvent( "out", this, this.containers[ i ] ) );
16637				this.containers[ i ].containerCache.over = 0;
16638			}
16639		}
16640
16641		//Do what was originally in plugins
16642		if ( this.storedCursor ) {
16643			this.document.find( "body" ).css( "cursor", this.storedCursor );
16644			this.storedStylesheet.remove();
16645		}
16646		if ( this._storedOpacity ) {
16647			this.helper.css( "opacity", this._storedOpacity );
16648		}
16649		if ( this._storedZIndex ) {
16650			this.helper.css( "zIndex", this._storedZIndex === "auto" ? "" : this._storedZIndex );
16651		}
16652
16653		this.dragging = false;
16654
16655		if ( !noPropagation ) {
16656			this._trigger( "beforeStop", event, this._uiHash() );
16657		}
16658
16659		//$(this.placeholder[0]).remove(); would have been the jQuery way - unfortunately,
16660		// it unbinds ALL events from the original node!
16661		this.placeholder[ 0 ].parentNode.removeChild( this.placeholder[ 0 ] );
16662
16663		if ( !this.cancelHelperRemoval ) {
16664			if ( this.helper[ 0 ] !== this.currentItem[ 0 ] ) {
16665				this.helper.remove();
16666			}
16667			this.helper = null;
16668		}
16669
16670		if ( !noPropagation ) {
16671			for ( i = 0; i < delayedTriggers.length; i++ ) {
16672
16673				// Trigger all delayed events
16674				delayedTriggers[ i ].call( this, event );
16675			}
16676			this._trigger( "stop", event, this._uiHash() );
16677		}
16678
16679		this.fromOutside = false;
16680		return !this.cancelHelperRemoval;
16681
16682	},
16683
16684	_trigger: function() {
16685		if ( $.Widget.prototype._trigger.apply( this, arguments ) === false ) {
16686			this.cancel();
16687		}
16688	},
16689
16690	_uiHash: function( _inst ) {
16691		var inst = _inst || this;
16692		return {
16693			helper: inst.helper,
16694			placeholder: inst.placeholder || $( [] ),
16695			position: inst.position,
16696			originalPosition: inst.originalPosition,
16697			offset: inst.positionAbs,
16698			item: inst.currentItem,
16699			sender: _inst ? _inst.element : null
16700		};
16701	}
16702
16703} );
16704
16705
16706/*!
vendor: 4,519 bytes, lines 16707-16873
16707 * jQuery UI Spinner 1.12.1
16708 * http://jqueryui.com
16709 *
16710 * Copyright jQuery Foundation and other contributors
16711 * Released under the MIT license.
16712 * http://jquery.org/license
16713 */
16714
16715//>>label: Spinner
16716//>>group: Widgets
16717//>>description: Displays buttons to easily input numbers via the keyboard or mouse.
16718//>>docs: http://api.jqueryui.com/spinner/
16719//>>demos: http://jqueryui.com/spinner/
16720//>>css.structure: ../../themes/base/core.css
16721//>>css.structure: ../../themes/base/spinner.css
16722//>>css.theme: ../../themes/base/theme.css
16723
16724
16725
16726function spinnerModifer( fn ) {
16727	return function() {
16728		var previous = this.element.val();
16729		fn.apply( this, arguments );
16730		this._refresh();
16731		if ( previous !== this.element.val() ) {
16732			this._trigger( "change" );
16733		}
16734	};
16735}
16736
16737$.widget( "ui.spinner", {
16738	version: "1.12.1",
16739	defaultElement: "<input>",
16740	widgetEventPrefix: "spin",
16741	options: {
16742		classes: {
16743			"ui-spinner": "ui-corner-all",
16744			"ui-spinner-down": "ui-corner-br",
16745			"ui-spinner-up": "ui-corner-tr"
16746		},
16747		culture: null,
16748		icons: {
16749			down: "ui-icon-triangle-1-s",
16750			up: "ui-icon-triangle-1-n"
16751		},
16752		incremental: true,
16753		max: null,
16754		min: null,
16755		numberFormat: null,
16756		page: 10,
16757		step: 1,
16758
16759		change: null,
16760		spin: null,
16761		start: null,
16762		stop: null
16763	},
16764
16765	_create: function() {
16766
16767		// handle string values that need to be parsed
16768		this._setOption( "max", this.options.max );
16769		this._setOption( "min", this.options.min );
16770		this._setOption( "step", this.options.step );
16771
16772		// Only format if there is a value, prevents the field from being marked
16773		// as invalid in Firefox, see #9573.
16774		if ( this.value() !== "" ) {
16775
16776			// Format the value, but don't constrain.
16777			this._value( this.element.val(), true );
16778		}
16779
16780		this._draw();
16781		this._on( this._events );
16782		this._refresh();
16783
16784		// Turning off autocomplete prevents the browser from remembering the
16785		// value when navigating through history, so we re-enable autocomplete
16786		// if the page is unloaded before the widget is destroyed. #7790
16787		this._on( this.window, {
16788			beforeunload: function() {
16789				this.element.removeAttr( "autocomplete" );
16790			}
16791		} );
16792	},
16793
16794	_getCreateOptions: function() {
16795		var options = this._super();
16796		var element = this.element;
16797
16798		$.each( [ "min", "max", "step" ], function( i, option ) {
16799			var value = element.attr( option );
16800			if ( value != null && value.length ) {
16801				options[ option ] = value;
16802			}
16803		} );
16804
16805		return options;
16806	},
16807
16808	_events: {
16809		keydown: function( event ) {
16810			if ( this._start( event ) && this._keydown( event ) ) {
16811				event.preventDefault();
16812			}
16813		},
16814		keyup: "_stop",
16815		focus: function() {
16816			this.previous = this.element.val();
16817		},
16818		blur: function( event ) {
16819			if ( this.cancelBlur ) {
16820				delete this.cancelBlur;
16821				return;
16822			}
16823
16824			this._stop();
16825			this._refresh();
16826			if ( this.previous !== this.element.val() ) {
16827				this._trigger( "change", event );
16828			}
16829		},
16830		mousewheel: function( event, delta ) {
16831			if ( !delta ) {
16832				return;
16833			}
16834			if ( !this.spinning && !this._start( event ) ) {
16835				return false;
16836			}
16837
16838			this._spin( ( delta > 0 ? 1 : -1 ) * this.options.step, event );
16839			clearTimeout( this.mousewheelTimer );
16840			this.mousewheelTimer = this._delay( function() {
16841				if ( this.spinning ) {
16842					this._stop( event );
16843				}
16844			}, 100 );
16845			event.preventDefault();
16846		},
16847		"mousedown .ui-spinner-button": function( event ) {
16848			var previous;
16849
16850			// We never want the buttons to have focus; whenever the user is
16851			// interacting with the spinner, the focus should be on the input.
16852			// If the input is focused then this.previous is properly set from
16853			// when the input first received focus. If the input is not focused
16854			// then we need to set this.previous based on the value before spinning.
16855			previous = this.element[ 0 ] === $.ui.safeActiveElement( this.document[ 0 ] ) ?
16856				this.previous : this.element.val();
16857			function checkFocus() {
16858				var isActive = this.element[ 0 ] === $.ui.safeActiveElement( this.document[ 0 ] );
16859				if ( !isActive ) {
16860					this.element.trigger( "focus" );
16861					this.previous = previous;
16862
16863					// support: IE
16864					// IE sets focus asynchronously, so we need to check if focus
16865					// moved off of the input because the user clicked on the button.
16866					this._delay( function() {
16867						this.previous = previous;
16868					} );
16869				}
16870			}
16871
16872			// Ensure focus is on (or stays on) the text field
16873			event.preventDefault();
vendor: 5,986 bytes, lines 16874-17103
16874			checkFocus.call( this );
16875
16876			// Support: IE
16877			// IE doesn't prevent moving focus even with event.preventDefault()
16878			// so we set a flag to know when we should ignore the blur event
16879			// and check (again) if focus moved off of the input.
16880			this.cancelBlur = true;
16881			this._delay( function() {
16882				delete this.cancelBlur;
16883				checkFocus.call( this );
16884			} );
16885
16886			if ( this._start( event ) === false ) {
16887				return;
16888			}
16889
16890			this._repeat( null, $( event.currentTarget )
16891				.hasClass( "ui-spinner-up" ) ? 1 : -1, event );
16892		},
16893		"mouseup .ui-spinner-button": "_stop",
16894		"mouseenter .ui-spinner-button": function( event ) {
16895
16896			// button will add ui-state-active if mouse was down while mouseleave and kept down
16897			if ( !$( event.currentTarget ).hasClass( "ui-state-active" ) ) {
16898				return;
16899			}
16900
16901			if ( this._start( event ) === false ) {
16902				return false;
16903			}
16904			this._repeat( null, $( event.currentTarget )
16905				.hasClass( "ui-spinner-up" ) ? 1 : -1, event );
16906		},
16907
16908		// TODO: do we really want to consider this a stop?
16909		// shouldn't we just stop the repeater and wait until mouseup before
16910		// we trigger the stop event?
16911		"mouseleave .ui-spinner-button": "_stop"
16912	},
16913
16914	// Support mobile enhanced option and make backcompat more sane
16915	_enhance: function() {
16916		this.uiSpinner = this.element
16917			.attr( "autocomplete", "off" )
16918			.wrap( "<span>" )
16919			.parent()
16920
16921				// Add buttons
16922				.append(
16923					"<a></a><a></a>"
16924				);
16925	},
16926
16927	_draw: function() {
16928		this._enhance();
16929
16930		this._addClass( this.uiSpinner, "ui-spinner", "ui-widget ui-widget-content" );
16931		this._addClass( "ui-spinner-input" );
16932
16933		this.element.attr( "role", "spinbutton" );
16934
16935		// Button bindings
16936		this.buttons = this.uiSpinner.children( "a" )
16937			.attr( "tabIndex", -1 )
16938			.attr( "aria-hidden", true )
16939			.button( {
16940				classes: {
16941					"ui-button": ""
16942				}
16943			} );
16944
16945		// TODO: Right now button does not support classes this is already updated in button PR
16946		this._removeClass( this.buttons, "ui-corner-all" );
16947
16948		this._addClass( this.buttons.first(), "ui-spinner-button ui-spinner-up" );
16949		this._addClass( this.buttons.last(), "ui-spinner-button ui-spinner-down" );
16950		this.buttons.first().button( {
16951			"icon": this.options.icons.up,
16952			"showLabel": false
16953		} );
16954		this.buttons.last().button( {
16955			"icon": this.options.icons.down,
16956			"showLabel": false
16957		} );
16958
16959		// IE 6 doesn't understand height: 50% for the buttons
16960		// unless the wrapper has an explicit height
16961		if ( this.buttons.height() > Math.ceil( this.uiSpinner.height() * 0.5 ) &&
16962				this.uiSpinner.height() > 0 ) {
16963			this.uiSpinner.height( this.uiSpinner.height() );
16964		}
16965	},
16966
16967	_keydown: function( event ) {
16968		var options = this.options,
16969			keyCode = $.ui.keyCode;
16970
16971		switch ( event.keyCode ) {
16972		case keyCode.UP:
16973			this._repeat( null, 1, event );
16974			return true;
16975		case keyCode.DOWN:
16976			this._repeat( null, -1, event );
16977			return true;
16978		case keyCode.PAGE_UP:
16979			this._repeat( null, options.page, event );
16980			return true;
16981		case keyCode.PAGE_DOWN:
16982			this._repeat( null, -options.page, event );
16983			return true;
16984		}
16985
16986		return false;
16987	},
16988
16989	_start: function( event ) {
16990		if ( !this.spinning && this._trigger( "start", event ) === false ) {
16991			return false;
16992		}
16993
16994		if ( !this.counter ) {
16995			this.counter = 1;
16996		}
16997		this.spinning = true;
16998		return true;
16999	},
17000
17001	_repeat: function( i, steps, event ) {
17002		i = i || 500;
17003
17004		clearTimeout( this.timer );
17005		this.timer = this._delay( function() {
17006			this._repeat( 40, steps, event );
17007		}, i );
17008
17009		this._spin( steps * this.options.step, event );
17010	},
17011
17012	_spin: function( step, event ) {
17013		var value = this.value() || 0;
17014
17015		if ( !this.counter ) {
17016			this.counter = 1;
17017		}
17018
17019		value = this._adjustValue( value + step * this._increment( this.counter ) );
17020
17021		if ( !this.spinning || this._trigger( "spin", event, { value: value } ) !== false ) {
17022			this._value( value );
17023			this.counter++;
17024		}
17025	},
17026
17027	_increment: function( i ) {
17028		var incremental = this.options.incremental;
17029
17030		if ( incremental ) {
17031			return $.isFunction( incremental ) ?
17032				incremental( i ) :
17033				Math.floor( i * i * i / 50000 - i * i / 500 + 17 * i / 200 + 1 );
17034		}
17035
17036		return 1;
17037	},
17038
17039	_precision: function() {
17040		var precision = this._precisionOf( this.options.step );
17041		if ( this.options.min !== null ) {
17042			precision = Math.max( precision, this._precisionOf( this.options.min ) );
17043		}
17044		return precision;
17045	},
17046
17047	_precisionOf: function( num ) {
17048		var str = num.toString(),
17049			decimal = str.indexOf( "." );
17050		return decimal === -1 ? 0 : str.length - decimal - 1;
17051	},
17052
17053	_adjustValue: function( value ) {
17054		var base, aboveMin,
17055			options = this.options;
17056
17057		// Make sure we're at a valid step
17058		// - find out where we are relative to the base (min or 0)
17059		base = options.min !== null ? options.min : 0;
17060		aboveMin = value - base;
17061
17062		// - round to the nearest step
17063		aboveMin = Math.round( aboveMin / options.step ) * options.step;
17064
17065		// - rounding is based on 0, so adjust back to our base
17066		value = base + aboveMin;
17067
17068		// Fix precision from bad JS floating point math
17069		value = parseFloat( value.toFixed( this._precision() ) );
17070
17071		// Clamp the value
17072		if ( options.max !== null && value > options.max ) {
17073			return options.max;
17074		}
17075		if ( options.min !== null && value < options.min ) {
17076			return options.min;
17077		}
17078
17079		return value;
17080	},
17081
17082	_stop: function( event ) {
17083		if ( !this.spinning ) {
17084			return;
17085		}
17086
17087		clearTimeout( this.timer );
17088		clearTimeout( this.mousewheelTimer );
17089		this.counter = 0;
17090		this.spinning = false;
17091		this._trigger( "stop", event );
17092	},
17093
17094	_setOption: function( key, value ) {
17095		var prevValue, first, last;
17096
17097		if ( key === "culture" || key === "numberFormat" ) {
17098			prevValue = this._parse( this.element.val() );
17099			this.options[ key ] = value;
17100			this.element.val( this._format( prevValue ) );
17101			return;
17102		}
17103
vendor: 12,860 bytes, lines 17104-17600
17104		if ( key === "max" || key === "min" || key === "step" ) {
17105			if ( typeof value === "string" ) {
17106				value = this._parse( value );
17107			}
17108		}
17109		if ( key === "icons" ) {
17110			first = this.buttons.first().find( ".ui-icon" );
17111			this._removeClass( first, null, this.options.icons.up );
17112			this._addClass( first, null, value.up );
17113			last = this.buttons.last().find( ".ui-icon" );
17114			this._removeClass( last, null, this.options.icons.down );
17115			this._addClass( last, null, value.down );
17116		}
17117
17118		this._super( key, value );
17119	},
17120
17121	_setOptionDisabled: function( value ) {
17122		this._super( value );
17123
17124		this._toggleClass( this.uiSpinner, null, "ui-state-disabled", !!value );
17125		this.element.prop( "disabled", !!value );
17126		this.buttons.button( value ? "disable" : "enable" );
17127	},
17128
17129	_setOptions: spinnerModifer( function( options ) {
17130		this._super( options );
17131	} ),
17132
17133	_parse: function( val ) {
17134		if ( typeof val === "string" && val !== "" ) {
17135			val = window.Globalize && this.options.numberFormat ?
17136				Globalize.parseFloat( val, 10, this.options.culture ) : +val;
17137		}
17138		return val === "" || isNaN( val ) ? null : val;
17139	},
17140
17141	_format: function( value ) {
17142		if ( value === "" ) {
17143			return "";
17144		}
17145		return window.Globalize && this.options.numberFormat ?
17146			Globalize.format( value, this.options.numberFormat, this.options.culture ) :
17147			value;
17148	},
17149
17150	_refresh: function() {
17151		this.element.attr( {
17152			"aria-valuemin": this.options.min,
17153			"aria-valuemax": this.options.max,
17154
17155			
17156			"aria-valuenow": this._parse( this.element.val() )
17157		} );
17158	},
17159
17160	isValid: function() {
17161		var value = this.value();
17162
17163		// Null is invalid
17164		if ( value === null ) {
17165			return false;
17166		}
17167
17168		// If value gets adjusted, it's invalid
17169		return value === this._adjustValue( value );
17170	},
17171
17172	// Update the value without triggering change
17173	_value: function( value, allowAny ) {
17174		var parsed;
17175		if ( value !== "" ) {
17176			parsed = this._parse( value );
17177			if ( parsed !== null ) {
17178				if ( !allowAny ) {
17179					parsed = this._adjustValue( parsed );
17180				}
17181				value = this._format( parsed );
17182			}
17183		}
17184		this.element.val( value );
17185		this._refresh();
17186	},
17187
17188	_destroy: function() {
17189		this.element
17190			.prop( "disabled", false )
17191			.removeAttr( "autocomplete role aria-valuemin aria-valuemax aria-valuenow" );
17192
17193		this.uiSpinner.replaceWith( this.element );
17194	},
17195
17196	stepUp: spinnerModifer( function( steps ) {
17197		this._stepUp( steps );
17198	} ),
17199	_stepUp: function( steps ) {
17200		if ( this._start() ) {
17201			this._spin( ( steps || 1 ) * this.options.step );
17202			this._stop();
17203		}
17204	},
17205
17206	stepDown: spinnerModifer( function( steps ) {
17207		this._stepDown( steps );
17208	} ),
17209	_stepDown: function( steps ) {
17210		if ( this._start() ) {
17211			this._spin( ( steps || 1 ) * -this.options.step );
17212			this._stop();
17213		}
17214	},
17215
17216	pageUp: spinnerModifer( function( pages ) {
17217		this._stepUp( ( pages || 1 ) * this.options.page );
17218	} ),
17219
17220	pageDown: spinnerModifer( function( pages ) {
17221		this._stepDown( ( pages || 1 ) * this.options.page );
17222	} ),
17223
17224	value: function( newVal ) {
17225		if ( !arguments.length ) {
17226			return this._parse( this.element.val() );
17227		}
17228		spinnerModifer( this._value ).call( this, newVal );
17229	},
17230
17231	widget: function() {
17232		return this.uiSpinner;
17233	}
17234} );
17235
17236// DEPRECATED
17237// TODO: switch return back to widget declaration at top of file when this is removed
17238if ( $.uiBackCompat !== false ) {
17239
17240	// Backcompat for spinner html extension points
17241	$.widget( "ui.spinner", $.ui.spinner, {
17242		_enhance: function() {
17243			this.uiSpinner = this.element
17244				.attr( "autocomplete", "off" )
17245				.wrap( this._uiSpinnerHtml() )
17246				.parent()
17247
17248					// Add buttons
17249					.append( this._buttonHtml() );
17250		},
17251		_uiSpinnerHtml: function() {
17252			return "<span>";
17253		},
17254
17255		_buttonHtml: function() {
17256			return "<a></a><a></a>";
17257		}
17258	} );
17259}
17260
17261var widgetsSpinner = $.ui.spinner;
17262
17263
17264/*!
17265 * jQuery UI Tabs 1.12.1
17266 * http://jqueryui.com
17267 *
17268 * Copyright jQuery Foundation and other contributors
17269 * Released under the MIT license.
17270 * http://jquery.org/license
17271 */
17272
17273//>>label: Tabs
17274//>>group: Widgets
17275//>>description: Transforms a set of container elements into a tab structure.
17276//>>docs: http://api.jqueryui.com/tabs/
17277//>>demos: http://jqueryui.com/tabs/
17278//>>css.structure: ../../themes/base/core.css
17279//>>css.structure: ../../themes/base/tabs.css
17280//>>css.theme: ../../themes/base/theme.css
17281
17282
17283
17284$.widget( "ui.tabs", {
17285	version: "1.12.1",
17286	delay: 300,
17287	options: {
17288		active: null,
17289		classes: {
17290			"ui-tabs": "ui-corner-all",
17291			"ui-tabs-nav": "ui-corner-all",
17292			"ui-tabs-panel": "ui-corner-bottom",
17293			"ui-tabs-tab": "ui-corner-top"
17294		},
17295		collapsible: false,
17296		event: "click",
17297		heightStyle: "content",
17298		hide: null,
17299		show: null,
17300
17301		// Callbacks
17302		activate: null,
17303		beforeActivate: null,
17304		beforeLoad: null,
17305		load: null
17306	},
17307
17308	_isLocal: ( function() {
17309		var rhash = /#.*$/;
17310
17311		return function( anchor ) {
17312			var anchorUrl, locationUrl;
17313
17314			anchorUrl = anchor.href.replace( rhash, "" );
17315			locationUrl = location.href.replace( rhash, "" );
17316
17317			// Decoding may throw an error if the URL isn't UTF-8 (#9518)
17318			try {
17319				anchorUrl = decodeURIComponent( anchorUrl );
17320			} catch ( error ) {}
17321			try {
17322				locationUrl = decodeURIComponent( locationUrl );
17323			} catch ( error ) {}
17324
17325			return anchor.hash.length > 1 && anchorUrl === locationUrl;
17326		};
17327	} )(),
17328
17329	_create: function() {
17330		var that = this,
17331			options = this.options;
17332
17333		this.running = false;
17334
17335		this._addClass( "ui-tabs", "ui-widget ui-widget-content" );
17336		this._toggleClass( "ui-tabs-collapsible", null, options.collapsible );
17337
17338		this._processTabs();
17339		options.active = this._initialActive();
17340
17341		// Take disabling tabs via class attribute from HTML
17342		// into account and update option properly.
17343		if ( $.isArray( options.disabled ) ) {
17344			options.disabled = $.unique( options.disabled.concat(
17345				$.map( this.tabs.filter( ".ui-state-disabled" ), function( li ) {
17346					return that.tabs.index( li );
17347				} )
17348			) ).sort();
17349		}
17350
17351		// Check for length avoids error when initializing empty list
17352		if ( this.options.active !== false && this.anchors.length ) {
17353			this.active = this._findActive( options.active );
17354		} else {
17355			this.active = $();
17356		}
17357
17358		this._refresh();
17359
17360		if ( this.active.length ) {
17361			this.load( options.active );
17362		}
17363	},
17364
17365	_initialActive: function() {
17366		var active = this.options.active,
17367			collapsible = this.options.collapsible,
17368			locationHash = location.hash.substring( 1 );
17369
17370		if ( active === null ) {
17371
17372			// check the fragment identifier in the URL
17373			if ( locationHash ) {
17374				this.tabs.each( function( i, tab ) {
17375					if ( $( tab ).attr( "aria-controls" ) === locationHash ) {
17376						active = i;
17377						return false;
17378					}
17379				} );
17380			}
17381
17382			// Check for a tab marked active via a class
17383			if ( active === null ) {
17384				active = this.tabs.index( this.tabs.filter( ".ui-tabs-active" ) );
17385			}
17386
17387			// No active tab, set to false
17388			if ( active === null || active === -1 ) {
17389				active = this.tabs.length ? 0 : false;
17390			}
17391		}
17392
17393		// Handle numbers: negative, out of range
17394		if ( active !== false ) {
17395			active = this.tabs.index( this.tabs.eq( active ) );
17396			if ( active === -1 ) {
17397				active = collapsible ? false : 0;
17398			}
17399		}
17400
17401		// Don't allow collapsible: false and active: false
17402		if ( !collapsible && active === false && this.anchors.length ) {
17403			active = 0;
17404		}
17405
17406		return active;
17407	},
17408
17409	_getCreateEventData: function() {
17410		return {
17411			tab: this.active,
17412			panel: !this.active.length ? $() : this._getPanelForTab( this.active )
17413		};
17414	},
17415
17416	_tabKeydown: function( event ) {
17417		var focusedTab = $( $.ui.safeActiveElement( this.document[ 0 ] ) ).closest( "li" ),
17418			selectedIndex = this.tabs.index( focusedTab ),
17419			goingForward = true;
17420
17421		if ( this._handlePageNav( event ) ) {
17422			return;
17423		}
17424
17425		switch ( event.keyCode ) {
17426		case $.ui.keyCode.RIGHT:
17427		case $.ui.keyCode.DOWN:
17428			selectedIndex++;
17429			break;
17430		case $.ui.keyCode.UP:
17431		case $.ui.keyCode.LEFT:
17432			goingForward = false;
17433			selectedIndex--;
17434			break;
17435		case $.ui.keyCode.END:
17436			selectedIndex = this.anchors.length - 1;
17437			break;
17438		case $.ui.keyCode.HOME:
17439			selectedIndex = 0;
17440			break;
17441		case $.ui.keyCode.SPACE:
17442
17443			// Activate only, no collapsing
17444			event.preventDefault();
17445			clearTimeout( this.activating );
17446			this._activate( selectedIndex );
17447			return;
17448		case $.ui.keyCode.ENTER:
17449
17450			// Toggle (cancel delayed activation, allow collapsing)
17451			event.preventDefault();
17452			clearTimeout( this.activating );
17453
17454			// Determine if we should collapse or activate
17455			this._activate( selectedIndex === this.options.active ? false : selectedIndex );
17456			return;
17457		default:
17458			return;
17459		}
17460
17461		// Focus the appropriate tab, based on which key was pressed
17462		event.preventDefault();
17463		clearTimeout( this.activating );
17464		selectedIndex = this._focusNextTab( selectedIndex, goingForward );
17465
17466		// Navigating with control/command key will prevent automatic activation
17467		if ( !event.ctrlKey && !event.metaKey ) {
17468
17469			// Update aria-selected immediately so that AT think the tab is already selected.
17470			// Otherwise AT may confuse the user by stating that they need to activate the tab,
17471			// but the tab will already be activated by the time the announcement finishes.
17472			focusedTab.attr( "aria-selected", "false" );
17473			this.tabs.eq( selectedIndex ).attr( "aria-selected", "true" );
17474
17475			this.activating = this._delay( function() {
17476				this.option( "active", selectedIndex );
17477			}, this.delay );
17478		}
17479	},
17480
17481	_panelKeydown: function( event ) {
17482		if ( this._handlePageNav( event ) ) {
17483			return;
17484		}
17485
17486		// Ctrl+up moves focus to the current tab
17487		if ( event.ctrlKey && event.keyCode === $.ui.keyCode.UP ) {
17488			event.preventDefault();
17489			this.active.trigger( "focus" );
17490		}
17491	},
17492
17493	// Alt+page up/down moves focus to the previous/next tab (and activates)
17494	_handlePageNav: function( event ) {
17495		if ( event.altKey && event.keyCode === $.ui.keyCode.PAGE_UP ) {
17496			this._activate( this._focusNextTab( this.options.active - 1, false ) );
17497			return true;
17498		}
17499		if ( event.altKey && event.keyCode === $.ui.keyCode.PAGE_DOWN ) {
17500			this._activate( this._focusNextTab( this.options.active + 1, true ) );
17501			return true;
17502		}
17503	},
17504
17505	_findNextTab: function( index, goingForward ) {
17506		var lastTabIndex = this.tabs.length - 1;
17507
17508		function constrain() {
17509			if ( index > lastTabIndex ) {
17510				index = 0;
17511			}
17512			if ( index < 0 ) {
17513				index = lastTabIndex;
17514			}
17515			return index;
17516		}
17517
17518		while ( $.inArray( constrain(), this.options.disabled ) !== -1 ) {
17519			index = goingForward ? index + 1 : index - 1;
17520		}
17521
17522		return index;
17523	},
17524
17525	_focusNextTab: function( index, goingForward ) {
17526		index = this._findNextTab( index, goingForward );
17527		this.tabs.eq( index ).trigger( "focus" );
17528		return index;
17529	},
17530
17531	_setOption: function( key, value ) {
17532		if ( key === "active" ) {
17533
17534			// _activate() will handle invalid values and update this.options
17535			this._activate( value );
17536			return;
17537		}
17538
17539		this._super( key, value );
17540
17541		if ( key === "collapsible" ) {
17542			this._toggleClass( "ui-tabs-collapsible", null, value );
17543
17544			// Setting collapsible: false while collapsed; open first panel
17545			if ( !value && this.options.active === false ) {
17546				this._activate( 0 );
17547			}
17548		}
17549
17550		if ( key === "event" ) {
17551			this._setupEvents( value );
17552		}
17553
17554		if ( key === "heightStyle" ) {
17555			this._setupHeightStyle( value );
17556		}
17557	},
17558
17559	_sanitizeSelector: function( hash ) {
17560		return hash ? hash.replace( /[!"$%&'()*+,.\/:;<=>?@\[\]\^`{|}~]/g, "\\$&" ) : "";
17561	},
17562
17563	refresh: function() {
17564		var options = this.options,
17565			lis = this.tablist.children( ":has(a[href])" );
17566
17567		// Get disabled tabs from class attribute from HTML
17568		// this will get converted to a boolean if needed in _refresh()
17569		options.disabled = $.map( lis.filter( ".ui-state-disabled" ), function( tab ) {
17570			return lis.index( tab );
17571		} );
17572
17573		this._processTabs();
17574
17575		// Was collapsed or no tabs
17576		if ( options.active === false || !this.anchors.length ) {
17577			options.active = false;
17578			this.active = $();
17579
17580		// was active, but active tab is gone
17581		} else if ( this.active.length && !$.contains( this.tablist[ 0 ], this.active[ 0 ] ) ) {
17582
17583			// all remaining tabs are disabled
17584			if ( this.tabs.length === options.disabled.length ) {
17585				options.active = false;
17586				this.active = $();
17587
17588			// activate previous tab
17589			} else {
17590				this._activate( this._findNextTab( Math.max( 0, options.active - 1 ), false ) );
17591			}
17592
17593		// was active, active tab still exists
17594		} else {
17595
17596			// make sure active index is correct
17597			options.active = this.tabs.index( this.active );
17598		}
17599
17600		this._refresh();
vendor: 13,454 bytes, lines 17601-18103
17601	},
17602
17603	_refresh: function() {
17604		this._setOptionDisabled( this.options.disabled );
17605		this._setupEvents( this.options.event );
17606		this._setupHeightStyle( this.options.heightStyle );
17607
17608		this.tabs.not( this.active ).attr( {
17609			"aria-selected": "false",
17610			"aria-expanded": "false",
17611			tabIndex: -1
17612		} );
17613		this.panels.not( this._getPanelForTab( this.active ) )
17614			.hide()
17615			.attr( {
17616				"aria-hidden": "true"
17617			} );
17618
17619		// Make sure one tab is in the tab order
17620		if ( !this.active.length ) {
17621			this.tabs.eq( 0 ).attr( "tabIndex", 0 );
17622		} else {
17623			this.active
17624				.attr( {
17625					"aria-selected": "true",
17626					"aria-expanded": "true",
17627					tabIndex: 0
17628				} );
17629			this._addClass( this.active, "ui-tabs-active", "ui-state-active" );
17630			this._getPanelForTab( this.active )
17631				.show()
17632				.attr( {
17633					"aria-hidden": "false"
17634				} );
17635		}
17636	},
17637
17638	_processTabs: function() {
17639		var that = this,
17640			prevTabs = this.tabs,
17641			prevAnchors = this.anchors,
17642			prevPanels = this.panels;
17643
17644		this.tablist = this._getList().attr( "role", "tablist" );
17645		this._addClass( this.tablist, "ui-tabs-nav",
17646			"ui-helper-reset ui-helper-clearfix ui-widget-header" );
17647
17648		// Prevent users from focusing disabled tabs via click
17649		this.tablist
17650			.on( "mousedown" + this.eventNamespace, "> li", function( event ) {
17651				if ( $( this ).is( ".ui-state-disabled" ) ) {
17652					event.preventDefault();
17653				}
17654			} )
17655
17656			// Support: IE <9
17657			// Preventing the default action in mousedown doesn't prevent IE
17658			// from focusing the element, so if the anchor gets focused, blur.
17659			// We don't have to worry about focusing the previously focused
17660			// element since clicking on a non-focusable element should focus
17661			// the body anyway.
17662			.on( "focus" + this.eventNamespace, ".ui-tabs-anchor", function() {
17663				if ( $( this ).closest( "li" ).is( ".ui-state-disabled" ) ) {
17664					this.blur();
17665				}
17666			} );
17667
17668		this.tabs = this.tablist.find( "> li:has(a[href])" )
17669			.attr( {
17670				role: "tab",
17671				tabIndex: -1
17672			} );
17673		this._addClass( this.tabs, "ui-tabs-tab", "ui-state-default" );
17674
17675		this.anchors = this.tabs.map( function() {
17676			return $( "a", this )[ 0 ];
17677		} )
17678			.attr( {
17679				role: "presentation",
17680				tabIndex: -1
17681			} );
17682		this._addClass( this.anchors, "ui-tabs-anchor" );
17683
17684		this.panels = $();
17685
17686		this.anchors.each( function( i, anchor ) {
17687			var selector, panel, panelId,
17688				anchorId = $( anchor ).uniqueId().attr( "id" ),
17689				tab = $( anchor ).closest( "li" ),
17690				originalAriaControls = tab.attr( "aria-controls" );
17691
17692			// Inline tab
17693			if ( that._isLocal( anchor ) ) {
17694				selector = anchor.hash;
17695				panelId = selector.substring( 1 );
17696				panel = that.element.find( that._sanitizeSelector( selector ) );
17697
17698			// remote tab
17699			} else {
17700
17701				// If the tab doesn't already have aria-controls,
17702				// generate an id by using a throw-away element
17703				panelId = tab.attr( "aria-controls" ) || $( {} ).uniqueId()[ 0 ].id;
17704				selector = "#" + panelId;
17705				panel = that.element.find( selector );
17706				if ( !panel.length ) {
17707					panel = that._createPanel( panelId );
17708					panel.insertAfter( that.panels[ i - 1 ] || that.tablist );
17709				}
17710				panel.attr( "aria-live", "polite" );
17711			}
17712
17713			if ( panel.length ) {
17714				that.panels = that.panels.add( panel );
17715			}
17716			if ( originalAriaControls ) {
17717				tab.data( "ui-tabs-aria-controls", originalAriaControls );
17718			}
17719			tab.attr( {
17720				"aria-controls": panelId,
17721				"aria-labelledby": anchorId
17722			} );
17723			panel.attr( "aria-labelledby", anchorId );
17724		} );
17725
17726		this.panels.attr( "role", "tabpanel" );
17727		this._addClass( this.panels, "ui-tabs-panel", "ui-widget-content" );
17728
17729		// Avoid memory leaks (#10056)
17730		if ( prevTabs ) {
17731			this._off( prevTabs.not( this.tabs ) );
17732			this._off( prevAnchors.not( this.anchors ) );
17733			this._off( prevPanels.not( this.panels ) );
17734		}
17735	},
17736
17737	// Allow overriding how to find the list for rare usage scenarios (#7715)
17738	_getList: function() {
17739		return this.tablist || this.element.find( "ol, ul" ).eq( 0 );
17740	},
17741
17742	_createPanel: function( id ) {
17743		return $( "<div>" )
17744			.attr( "id", id )
17745			.data( "ui-tabs-destroy", true );
17746	},
17747
17748	_setOptionDisabled: function( disabled ) {
17749		var currentItem, li, i;
17750
17751		if ( $.isArray( disabled ) ) {
17752			if ( !disabled.length ) {
17753				disabled = false;
17754			} else if ( disabled.length === this.anchors.length ) {
17755				disabled = true;
17756			}
17757		}
17758
17759		// Disable tabs
17760		for ( i = 0; ( li = this.tabs[ i ] ); i++ ) {
17761			currentItem = $( li );
17762			if ( disabled === true || $.inArray( i, disabled ) !== -1 ) {
17763				currentItem.attr( "aria-disabled", "true" );
17764				this._addClass( currentItem, null, "ui-state-disabled" );
17765			} else {
17766				currentItem.removeAttr( "aria-disabled" );
17767				this._removeClass( currentItem, null, "ui-state-disabled" );
17768			}
17769		}
17770
17771		this.options.disabled = disabled;
17772
17773		this._toggleClass( this.widget(), this.widgetFullName + "-disabled", null,
17774			disabled === true );
17775	},
17776
17777	_setupEvents: function( event ) {
17778		var events = {};
17779		if ( event ) {
17780			$.each( event.split( " " ), function( index, eventName ) {
17781				events[ eventName ] = "_eventHandler";
17782			} );
17783		}
17784
17785		this._off( this.anchors.add( this.tabs ).add( this.panels ) );
17786
17787		// Always prevent the default action, even when disabled
17788		this._on( true, this.anchors, {
17789			click: function( event ) {
17790				event.preventDefault();
17791			}
17792		} );
17793		this._on( this.anchors, events );
17794		this._on( this.tabs, { keydown: "_tabKeydown" } );
17795		this._on( this.panels, { keydown: "_panelKeydown" } );
17796
17797		this._focusable( this.tabs );
17798		this._hoverable( this.tabs );
17799	},
17800
17801	_setupHeightStyle: function( heightStyle ) {
17802		var maxHeight,
17803			parent = this.element.parent();
17804
17805		if ( heightStyle === "fill" ) {
17806			maxHeight = parent.height();
17807			maxHeight -= this.element.outerHeight() - this.element.height();
17808
17809			this.element.siblings( ":visible" ).each( function() {
17810				var elem = $( this ),
17811					position = elem.css( "position" );
17812
17813				if ( position === "absolute" || position === "fixed" ) {
17814					return;
17815				}
17816				maxHeight -= elem.outerHeight( true );
17817			} );
17818
17819			this.element.children().not( this.panels ).each( function() {
17820				maxHeight -= $( this ).outerHeight( true );
17821			} );
17822
17823			this.panels.each( function() {
17824				$( this ).height( Math.max( 0, maxHeight -
17825					$( this ).innerHeight() + $( this ).height() ) );
17826			} )
17827				.css( "overflow", "auto" );
17828		} else if ( heightStyle === "auto" ) {
17829			maxHeight = 0;
17830			this.panels.each( function() {
17831				maxHeight = Math.max( maxHeight, $( this ).height( "" ).height() );
17832			} ).height( maxHeight );
17833		}
17834	},
17835
17836	_eventHandler: function( event ) {
17837		var options = this.options,
17838			active = this.active,
17839			anchor = $( event.currentTarget ),
17840			tab = anchor.closest( "li" ),
17841			clickedIsActive = tab[ 0 ] === active[ 0 ],
17842			collapsing = clickedIsActive && options.collapsible,
17843			toShow = collapsing ? $() : this._getPanelForTab( tab ),
17844			toHide = !active.length ? $() : this._getPanelForTab( active ),
17845			eventData = {
17846				oldTab: active,
17847				oldPanel: toHide,
17848				newTab: collapsing ? $() : tab,
17849				newPanel: toShow
17850			};
17851
17852		event.preventDefault();
17853
17854		if ( tab.hasClass( "ui-state-disabled" ) ||
17855
17856				// tab is already loading
17857				tab.hasClass( "ui-tabs-loading" ) ||
17858
17859				// can't switch durning an animation
17860				this.running ||
17861
17862				// click on active header, but not collapsible
17863				( clickedIsActive && !options.collapsible ) ||
17864
17865				// allow canceling activation
17866				( this._trigger( "beforeActivate", event, eventData ) === false ) ) {
17867			return;
17868		}
17869
17870		options.active = collapsing ? false : this.tabs.index( tab );
17871
17872		this.active = clickedIsActive ? $() : tab;
17873		if ( this.xhr ) {
17874			this.xhr.abort();
17875		}
17876
17877		if ( !toHide.length && !toShow.length ) {
17878			$.error( "jQuery UI Tabs: Mismatching fragment identifier." );
17879		}
17880
17881		if ( toShow.length ) {
17882			this.load( this.tabs.index( tab ), event );
17883		}
17884		this._toggle( event, eventData );
17885	},
17886
17887	// Handles show/hide for selecting tabs
17888	_toggle: function( event, eventData ) {
17889		var that = this,
17890			toShow = eventData.newPanel,
17891			toHide = eventData.oldPanel;
17892
17893		this.running = true;
17894
17895		function complete() {
17896			that.running = false;
17897			that._trigger( "activate", event, eventData );
17898		}
17899
17900		function show() {
17901			that._addClass( eventData.newTab.closest( "li" ), "ui-tabs-active", "ui-state-active" );
17902
17903			if ( toShow.length && that.options.show ) {
17904				that._show( toShow, that.options.show, complete );
17905			} else {
17906				toShow.show();
17907				complete();
17908			}
17909		}
17910
17911		// Start out by hiding, then showing, then completing
17912		if ( toHide.length && this.options.hide ) {
17913			this._hide( toHide, this.options.hide, function() {
17914				that._removeClass( eventData.oldTab.closest( "li" ),
17915					"ui-tabs-active", "ui-state-active" );
17916				show();
17917			} );
17918		} else {
17919			this._removeClass( eventData.oldTab.closest( "li" ),
17920				"ui-tabs-active", "ui-state-active" );
17921			toHide.hide();
17922			show();
17923		}
17924
17925		toHide.attr( "aria-hidden", "true" );
17926		eventData.oldTab.attr( {
17927			"aria-selected": "false",
17928			"aria-expanded": "false"
17929		} );
17930
17931		// If we're switching tabs, remove the old tab from the tab order.
17932		// If we're opening from collapsed state, remove the previous tab from the tab order.
17933		// If we're collapsing, then keep the collapsing tab in the tab order.
17934		if ( toShow.length && toHide.length ) {
17935			eventData.oldTab.attr( "tabIndex", -1 );
17936		} else if ( toShow.length ) {
17937			this.tabs.filter( function() {
17938				return $( this ).attr( "tabIndex" ) === 0;
17939			} )
17940				.attr( "tabIndex", -1 );
17941		}
17942
17943		toShow.attr( "aria-hidden", "false" );
17944		eventData.newTab.attr( {
17945			"aria-selected": "true",
17946			"aria-expanded": "true",
17947			tabIndex: 0
17948		} );
17949	},
17950
17951	_activate: function( index ) {
17952		var anchor,
17953			active = this._findActive( index );
17954
17955		// Trying to activate the already active panel
17956		if ( active[ 0 ] === this.active[ 0 ] ) {
17957			return;
17958		}
17959
17960		// Trying to collapse, simulate a click on the current active header
17961		if ( !active.length ) {
17962			active = this.active;
17963		}
17964
17965		anchor = active.find( ".ui-tabs-anchor" )[ 0 ];
17966		this._eventHandler( {
17967			target: anchor,
17968			currentTarget: anchor,
17969			preventDefault: $.noop
17970		} );
17971	},
17972
17973	_findActive: function( index ) {
17974		return index === false ? $() : this.tabs.eq( index );
17975	},
17976
17977	_getIndex: function( index ) {
17978
17979		// meta-function to give users option to provide a href string instead of a numerical index.
17980		if ( typeof index === "string" ) {
17981			index = this.anchors.index( this.anchors.filter( "[href$='" +
17982				$.ui.escapeSelector( index ) + "']" ) );
17983		}
17984
17985		return index;
17986	},
17987
17988	_destroy: function() {
17989		if ( this.xhr ) {
17990			this.xhr.abort();
17991		}
17992
17993		this.tablist
17994			.removeAttr( "role" )
17995			.off( this.eventNamespace );
17996
17997		this.anchors
17998			.removeAttr( "role tabIndex" )
17999			.removeUniqueId();
18000
18001		this.tabs.add( this.panels ).each( function() {
18002			if ( $.data( this, "ui-tabs-destroy" ) ) {
18003				$( this ).remove();
18004			} else {
18005				$( this ).removeAttr( "role tabIndex " +
18006					"aria-live aria-busy aria-selected aria-labelledby aria-hidden aria-expanded" );
18007			}
18008		} );
18009
18010		this.tabs.each( function() {
18011			var li = $( this ),
18012				prev = li.data( "ui-tabs-aria-controls" );
18013			if ( prev ) {
18014				li
18015					.attr( "aria-controls", prev )
18016					.removeData( "ui-tabs-aria-controls" );
18017			} else {
18018				li.removeAttr( "aria-controls" );
18019			}
18020		} );
18021
18022		this.panels.show();
18023
18024		if ( this.options.heightStyle !== "content" ) {
18025			this.panels.css( "height", "" );
18026		}
18027	},
18028
18029	enable: function( index ) {
18030		var disabled = this.options.disabled;
18031		if ( disabled === false ) {
18032			return;
18033		}
18034
18035		if ( index === undefined ) {
18036			disabled = false;
18037		} else {
18038			index = this._getIndex( index );
18039			if ( $.isArray( disabled ) ) {
18040				disabled = $.map( disabled, function( num ) {
18041					return num !== index ? num : null;
18042				} );
18043			} else {
18044				disabled = $.map( this.tabs, function( li, num ) {
18045					return num !== index ? num : null;
18046				} );
18047			}
18048		}
18049		this._setOptionDisabled( disabled );
18050	},
18051
18052	disable: function( index ) {
18053		var disabled = this.options.disabled;
18054		if ( disabled === true ) {
18055			return;
18056		}
18057
18058		if ( index === undefined ) {
18059			disabled = true;
18060		} else {
18061			index = this._getIndex( index );
18062			if ( $.inArray( index, disabled ) !== -1 ) {
18063				return;
18064			}
18065			if ( $.isArray( disabled ) ) {
18066				disabled = $.merge( [ index ], disabled ).sort();
18067			} else {
18068				disabled = [ index ];
18069			}
18070		}
18071		this._setOptionDisabled( disabled );
18072	},
18073
18074	load: function( index, event ) {
18075		index = this._getIndex( index );
18076		var that = this,
18077			tab = this.tabs.eq( index ),
18078			anchor = tab.find( ".ui-tabs-anchor" ),
18079			panel = this._getPanelForTab( tab ),
18080			eventData = {
18081				tab: tab,
18082				panel: panel
18083			},
18084			complete = function( jqXHR, status ) {
18085				if ( status === "abort" ) {
18086					that.panels.stop( false, true );
18087				}
18088
18089				that._removeClass( tab, "ui-tabs-loading" );
18090				panel.removeAttr( "aria-busy" );
18091
18092				if ( jqXHR === that.xhr ) {
18093					delete that.xhr;
18094				}
18095			};
18096
18097		// Not remote
18098		if ( this._isLocal( anchor[ 0 ] ) ) {
18099			return;
18100		}
18101
18102		this.xhr = $.ajax( this._ajaxSettings( anchor, event, eventData ) );
18103
vendor: 1,665 bytes, lines 18104-18166
18104		// Support: jQuery <1.8
18105		// jQuery <1.8 returns false if the request is canceled in beforeSend,
18106		// but as of 1.8, $.ajax() always returns a jqXHR object.
18107		if ( this.xhr && this.xhr.statusText !== "canceled" ) {
18108			this._addClass( tab, "ui-tabs-loading" );
18109			panel.attr( "aria-busy", "true" );
18110
18111			this.xhr
18112				.done( function( response, status, jqXHR ) {
18113
18114					// support: jQuery <1.8
18115					// http://bugs.jquery.com/ticket/11778
18116					setTimeout( function() {
18117						panel.html( response );
18118						that._trigger( "load", event, eventData );
18119
18120						complete( jqXHR, status );
18121					}, 1 );
18122				} )
18123				.fail( function( jqXHR, status ) {
18124
18125					// support: jQuery <1.8
18126					// http://bugs.jquery.com/ticket/11778
18127					setTimeout( function() {
18128						complete( jqXHR, status );
18129					}, 1 );
18130				} );
18131		}
18132	},
18133
18134	_ajaxSettings: function( anchor, event, eventData ) {
18135		var that = this;
18136		return {
18137
18138			// Support: IE <11 only
18139			// Strip any hash that exists to prevent errors with the Ajax request
18140			url: anchor.attr( "href" ).replace( /#.*$/, "" ),
18141			beforeSend: function( jqXHR, settings ) {
18142				return that._trigger( "beforeLoad", event,
18143					$.extend( { jqXHR: jqXHR, ajaxSettings: settings }, eventData ) );
18144			}
18145		};
18146	},
18147
18148	_getPanelForTab: function( tab ) {
18149		var id = $( tab ).attr( "aria-controls" );
18150		return this.element.find( this._sanitizeSelector( "#" + id ) );
18151	}
18152} );
18153
18154
18155if ( $.uiBackCompat !== false ) {
18156
18157	$.widget( "ui.tabs", $.ui.tabs, {
18158		_processTabs: function() {
18159			this._superApply( arguments );
18160			this._addClass( this.tabs, "ui-tab" );
18161		}
18162	} );
18163}
18164
18165var widgetsTabs = $.ui.tabs;
18166}));

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.