PageSourceSearch

https://www.nasponline.org/assets/Documents/Prebuilt/js/jquery-ui-1.11.4.js

js nasponline.org collected 2026-09-25 08:34:59 UTC 470,650 bytes, 16,619 lines download raw bytes

vendor: 33,555 bytes, lines 1-1203
1/*! jQuery UI - v1.11.4 - 2015-03-11
2* http://jqueryui.com
3* Includes: core.js, widget.js, mouse.js, position.js, accordion.js, autocomplete.js, button.js, datepicker.js, dialog.js, draggable.js, droppable.js, effect.js, effect-blind.js, effect-bounce.js, effect-clip.js, effect-drop.js, effect-explode.js, effect-fade.js, effect-fold.js, effect-highlight.js, effect-puff.js, effect-pulsate.js, effect-scale.js, effect-shake.js, effect-size.js, effect-slide.js, effect-transfer.js, menu.js, progressbar.js, resizable.js, selectable.js, selectmenu.js, slider.js, sortable.js, spinner.js, tabs.js, tooltip.js
4* Copyright 2015 jQuery Foundation and other contributors; Licensed MIT */
5
6(function( factory ) {
7	if ( typeof define === "function" && define.amd ) {
8
9		// AMD. Register as an anonymous module.
10		define([ "jquery" ], factory );
11	} else {
12
13		// Browser globals
14		factory( jQuery );
15	}
16}(function( $ ) {
17/*!
18 * jQuery UI Core 1.11.4
19 * http://jqueryui.com
20 *
21 * Copyright jQuery Foundation and other contributors
22 * Released under the MIT license.
23 * http://jquery.org/license
24 *
25 * http://api.jqueryui.com/category/ui-core/
26 */
27
28
29// $.ui might exist from components with no dependencies, e.g., $.ui.position
30$.ui = $.ui || {};
31
32$.extend( $.ui, {
33	version: "1.11.4",
34
35	keyCode: {
36		BACKSPACE: 8,
37		COMMA: 188,
38		DELETE: 46,
39		DOWN: 40,
40		END: 35,
41		ENTER: 13,
42		ESCAPE: 27,
43		HOME: 36,
44		LEFT: 37,
45		PAGE_DOWN: 34,
46		PAGE_UP: 33,
47		PERIOD: 190,
48		RIGHT: 39,
49		SPACE: 32,
50		TAB: 9,
51		UP: 38
52	}
53});
54
55// plugins
56$.fn.extend({
57	scrollParent: function( includeHidden ) {
58		var position = this.css( "position" ),
59			excludeStaticParent = position === "absolute",
60			overflowRegex = includeHidden ? /(auto|scroll|hidden)/ : /(auto|scroll)/,
61			scrollParent = this.parents().filter( function() {
62				var parent = $( this );
63				if ( excludeStaticParent && parent.css( "position" ) === "static" ) {
64					return false;
65				}
66				return overflowRegex.test( parent.css( "overflow" ) + parent.css( "overflow-y" ) + parent.css( "overflow-x" ) );
67			}).eq( 0 );
68
69		return position === "fixed" || !scrollParent.length ? $( this[ 0 ].ownerDocument || document ) : scrollParent;
70	},
71
72	uniqueId: (function() {
73		var uuid = 0;
74
75		return function() {
76			return this.each(function() {
77				if ( !this.id ) {
78					this.id = "ui-id-" + ( ++uuid );
79				}
80			});
81		};
82	})(),
83
84	removeUniqueId: function() {
85		return this.each(function() {
86			if ( /^ui-id-\d+$/.test( this.id ) ) {
87				$( this ).removeAttr( "id" );
88			}
89		});
90	}
91});
92
93// selectors
94function focusable( element, isTabIndexNotNaN ) {
95	var map, mapName, img,
96		nodeName = element.nodeName.toLowerCase();
97	if ( "area" === nodeName ) {
98		map = element.parentNode;
99		mapName = map.name;
100		if ( !element.href || !mapName || map.nodeName.toLowerCase() !== "map" ) {
101			return false;
102		}
103		img = $( "img[usemap='#" + mapName + "']" )[ 0 ];
104		return !!img && visible( img );
105	}
106	return ( /^(input|select|textarea|button|object)$/.test( nodeName ) ?
107		!element.disabled :
108		"a" === nodeName ?
109			element.href || isTabIndexNotNaN :
110			isTabIndexNotNaN) &&
111		// the element and all of its ancestors must be visible
112		visible( element );
113}
114
115function visible( element ) {
116	return $.expr.filters.visible( element ) &&
117		!$( element ).parents().addBack().filter(function() {
118			return $.css( this, "visibility" ) === "hidden";
119		}).length;
120}
121
122$.extend( $.expr[ ":" ], {
123	data: $.expr.createPseudo ?
124		$.expr.createPseudo(function( dataName ) {
125			return function( elem ) {
126				return !!$.data( elem, dataName );
127			};
128		}) :
129		// support: jQuery <1.8
130		function( elem, i, match ) {
131			return !!$.data( elem, match[ 3 ] );
132		},
133
134	focusable: function( element ) {
135		return focusable( element, !isNaN( $.attr( element, "tabindex" ) ) );
136	},
137
138	tabbable: function( element ) {
139		var tabIndex = $.attr( element, "tabindex" ),
140			isTabIndexNaN = isNaN( tabIndex );
141		return ( isTabIndexNaN || tabIndex >= 0 ) && focusable( element, !isTabIndexNaN );
142	}
143});
144
145// support: jQuery <1.8
146if ( !$( "<a>" ).outerWidth( 1 ).jquery ) {
147	$.each( [ "Width", "Height" ], function( i, name ) {
148		var side = name === "Width" ? [ "Left", "Right" ] : [ "Top", "Bottom" ],
149			type = name.toLowerCase(),
150			orig = {
151				innerWidth: $.fn.innerWidth,
152				innerHeight: $.fn.innerHeight,
153				outerWidth: $.fn.outerWidth,
154				outerHeight: $.fn.outerHeight
155			};
156
157		function reduce( elem, size, border, margin ) {
158			$.each( side, function() {
159				size -= parseFloat( $.css( elem, "padding" + this ) ) || 0;
160				if ( border ) {
161					size -= parseFloat( $.css( elem, "border" + this + "Width" ) ) || 0;
162				}
163				if ( margin ) {
164					size -= parseFloat( $.css( elem, "margin" + this ) ) || 0;
165				}
166			});
167			return size;
168		}
169
170		$.fn[ "inner" + name ] = function( size ) {
171			if ( size === undefined ) {
172				return orig[ "inner" + name ].call( this );
173			}
174
175			return this.each(function() {
176				$( this ).css( type, reduce( this, size ) + "px" );
177			});
178		};
179
180		$.fn[ "outer" + name] = function( size, margin ) {
181			if ( typeof size !== "number" ) {
182				return orig[ "outer" + name ].call( this, size );
183			}
184
185			return this.each(function() {
186				$( this).css( type, reduce( this, size, true, margin ) + "px" );
187			});
188		};
189	});
190}
191
192// support: jQuery <1.8
193if ( !$.fn.addBack ) {
194	$.fn.addBack = function( selector ) {
195		return this.add( selector == null ?
196			this.prevObject : this.prevObject.filter( selector )
197		);
198	};
199}
200
201// support: jQuery 1.6.1, 1.6.2 (http://bugs.jquery.com/ticket/9413)
202if ( $( "<a>" ).data( "a-b", "a" ).removeData( "a-b" ).data( "a-b" ) ) {
203	$.fn.removeData = (function( removeData ) {
204		return function( key ) {
205			if ( arguments.length ) {
206				return removeData.call( this, $.camelCase( key ) );
207			} else {
208				return removeData.call( this );
209			}
210		};
211	})( $.fn.removeData );
212}
213
214// deprecated
215$.ui.ie = !!/msie [\w.]+/.exec( navigator.userAgent.toLowerCase() );
216
217$.fn.extend({
218	focus: (function( orig ) {
219		return function( delay, fn ) {
220			return typeof delay === "number" ?
221				this.each(function() {
222					var elem = this;
223					setTimeout(function() {
224						$( elem ).focus();
225						if ( fn ) {
226							fn.call( elem );
227						}
228					}, delay );
229				}) :
230				orig.apply( this, arguments );
231		};
232	})( $.fn.focus ),
233
234	disableSelection: (function() {
235		var eventType = "onselectstart" in document.createElement( "div" ) ?
236			"selectstart" :
237			"mousedown";
238
239		return function() {
240			return this.bind( eventType + ".ui-disableSelection", function( event ) {
241				event.preventDefault();
242			});
243		};
244	})(),
245
246	enableSelection: function() {
247		return this.unbind( ".ui-disableSelection" );
248	},
249
250	zIndex: function( zIndex ) {
251		if ( zIndex !== undefined ) {
252			return this.css( "zIndex", zIndex );
253		}
254
255		if ( this.length ) {
256			var elem = $( this[ 0 ] ), position, value;
257			while ( elem.length && elem[ 0 ] !== document ) {
258				// Ignore z-index if position is set to a value where z-index is ignored by the browser
259				// This makes behavior of this function consistent across browsers
260				// WebKit always returns auto if the element is positioned
261				position = elem.css( "position" );
262				if ( position === "absolute" || position === "relative" || position === "fixed" ) {
263					// IE returns 0 when zIndex is not specified
264					// other browsers return a string
265					// we ignore the case of nested elements with an explicit value of 0
266					// <div style="z-index: -10;"><div style="z-index: 0;"></div></div>
267					value = parseInt( elem.css( "zIndex" ), 10 );
268					if ( !isNaN( value ) && value !== 0 ) {
269						return value;
270					}
271				}
272				elem = elem.parent();
273			}
274		}
275
276		return 0;
277	}
278});
279
280// $.ui.plugin is deprecated. Use $.widget() extensions instead.
281$.ui.plugin = {
282	add: function( module, option, set ) {
283		var i,
284			proto = $.ui[ module ].prototype;
285		for ( i in set ) {
286			proto.plugins[ i ] = proto.plugins[ i ] || [];
287			proto.plugins[ i ].push( [ option, set[ i ] ] );
288		}
289	},
290	call: function( instance, name, args, allowDisconnected ) {
291		var i,
292			set = instance.plugins[ name ];
293
294		if ( !set ) {
295			return;
296		}
297
298		if ( !allowDisconnected && ( !instance.element[ 0 ].parentNode || instance.element[ 0 ].parentNode.nodeType === 11 ) ) {
299			return;
300		}
301
302		for ( i = 0; i < set.length; i++ ) {
303			if ( instance.options[ set[ i ][ 0 ] ] ) {
304				set[ i ][ 1 ].apply( instance.element, args );
305			}
306		}
307	}
308};
309
310
311/*!
312 * jQuery UI Widget 1.11.4
313 * http://jqueryui.com
314 *
315 * Copyright jQuery Foundation and other contributors
316 * Released under the MIT license.
317 * http://jquery.org/license
318 *
319 * http://api.jqueryui.com/jQuery.widget/
320 */
321
322
323var widget_uuid = 0,
324	widget_slice = Array.prototype.slice;
325
326$.cleanData = (function( orig ) {
327	return function( elems ) {
328		var events, elem, i;
329		for ( i = 0; (elem = elems[i]) != null; i++ ) {
330			try {
331
332				// Only trigger remove when necessary to save time
333				events = $._data( elem, "events" );
334				if ( events && events.remove ) {
335					$( elem ).triggerHandler( "remove" );
336				}
337
338			// http://bugs.jquery.com/ticket/8235
339			} catch ( e ) {}
340		}
341		orig( elems );
342	};
343})( $.cleanData );
344
345$.widget = function( name, base, prototype ) {
346	var fullName, existingConstructor, constructor, basePrototype,
347		// proxiedPrototype allows the provided prototype to remain unmodified
348		// so that it can be used as a mixin for multiple widgets (#8876)
349		proxiedPrototype = {},
350		namespace = name.split( "." )[ 0 ];
351
352	name = name.split( "." )[ 1 ];
353	fullName = namespace + "-" + name;
354
355	if ( !prototype ) {
356		prototype = base;
357		base = $.Widget;
358	}
359
360	// create selector for plugin
361	$.expr[ ":" ][ fullName.toLowerCase() ] = function( elem ) {
362		return !!$.data( elem, fullName );
363	};
364
365	$[ namespace ] = $[ namespace ] || {};
366	existingConstructor = $[ namespace ][ name ];
367	constructor = $[ namespace ][ name ] = function( options, element ) {
368		// allow instantiation without "new" keyword
369		if ( !this._createWidget ) {
370			return new constructor( options, element );
371		}
372
373		// allow instantiation without initializing for simple inheritance
374		// must use "new" keyword (the code above always passes args)
375		if ( arguments.length ) {
376			this._createWidget( options, element );
377		}
378	};
379	// extend with the existing constructor to carry over any static properties
380	$.extend( constructor, existingConstructor, {
381		version: prototype.version,
382		// copy the object used to create the prototype in case we need to
383		// redefine the widget later
384		_proto: $.extend( {}, prototype ),
385		// track widgets that inherit from this widget in case this widget is
386		// redefined after a widget inherits from it
387		_childConstructors: []
388	});
389
390	basePrototype = new base();
391	// we need to make the options hash a property directly on the new instance
392	// otherwise we'll modify the options hash on the prototype that we're
393	// inheriting from
394	basePrototype.options = $.widget.extend( {}, basePrototype.options );
395	$.each( prototype, function( prop, value ) {
396		if ( !$.isFunction( value ) ) {
397			proxiedPrototype[ prop ] = value;
398			return;
399		}
400		proxiedPrototype[ prop ] = (function() {
401			var _super = function() {
402					return base.prototype[ prop ].apply( this, arguments );
403				},
404				_superApply = function( args ) {
405					return base.prototype[ prop ].apply( this, args );
406				};
407			return function() {
408				var __super = this._super,
409					__superApply = this._superApply,
410					returnValue;
411
412				this._super = _super;
413				this._superApply = _superApply;
414
415				returnValue = value.apply( this, arguments );
416
417				this._super = __super;
418				this._superApply = __superApply;
419
420				return returnValue;
421			};
422		})();
423	});
424	constructor.prototype = $.widget.extend( basePrototype, {
425		// TODO: remove support for widgetEventPrefix
426		// always use the name + a colon as the prefix, e.g., draggable:start
427		// don't prefix for widgets that aren't DOM-based
428		widgetEventPrefix: existingConstructor ? (basePrototype.widgetEventPrefix || name) : name
429	}, proxiedPrototype, {
430		constructor: constructor,
431		namespace: namespace,
432		widgetName: name,
433		widgetFullName: fullName
434	});
435
436	// If this widget is being redefined then we need to find all widgets that
437	// are inheriting from it and redefine all of them so that they inherit from
438	// the new version of this widget. We're essentially trying to replace one
439	// level in the prototype chain.
440	if ( existingConstructor ) {
441		$.each( existingConstructor._childConstructors, function( i, child ) {
442			var childPrototype = child.prototype;
443
444			// redefine the child widget using the same prototype that was
445			// originally used, but inherit from the new version of the base
446			$.widget( childPrototype.namespace + "." + childPrototype.widgetName, constructor, child._proto );
447		});
448		// remove the list of existing child constructors from the old constructor
449		// so the old child constructors can be garbage collected
450		delete existingConstructor._childConstructors;
451	} else {
452		base._childConstructors.push( constructor );
453	}
454
455	$.widget.bridge( name, constructor );
456
457	return constructor;
458};
459
460$.widget.extend = function( target ) {
461	var input = widget_slice.call( arguments, 1 ),
462		inputIndex = 0,
463		inputLength = input.length,
464		key,
465		value;
466	for ( ; inputIndex < inputLength; inputIndex++ ) {
467		for ( key in input[ inputIndex ] ) {
468			value = input[ inputIndex ][ key ];
469			if ( input[ inputIndex ].hasOwnProperty( key ) && value !== undefined ) {
470				// Clone objects
471				if ( $.isPlainObject( value ) ) {
472					target[ key ] = $.isPlainObject( target[ key ] ) ?
473						$.widget.extend( {}, target[ key ], value ) :
474						// Don't extend strings, arrays, etc. with objects
475						$.widget.extend( {}, value );
476				// Copy everything else by reference
477				} else {
478					target[ key ] = value;
479				}
480			}
481		}
482	}
483	return target;
484};
485
486$.widget.bridge = function( name, object ) {
487	var fullName = object.prototype.widgetFullName || name;
488	$.fn[ name ] = function( options ) {
489		var isMethodCall = typeof options === "string",
490			args = widget_slice.call( arguments, 1 ),
491			returnValue = this;
492
493		if ( isMethodCall ) {
494			this.each(function() {
495				var methodValue,
496					instance = $.data( this, fullName );
497				if ( options === "instance" ) {
498					returnValue = instance;
499					return false;
500				}
501				if ( !instance ) {
502					return $.error( "cannot call methods on " + name + " prior to initialization; " +
503						"attempted to call method '" + options + "'" );
504				}
505				if ( !$.isFunction( instance[options] ) || options.charAt( 0 ) === "_" ) {
506					return $.error( "no such method '" + options + "' for " + name + " widget instance" );
507				}
508				methodValue = instance[ options ].apply( instance, args );
509				if ( methodValue !== instance && methodValue !== undefined ) {
510					returnValue = methodValue && methodValue.jquery ?
511						returnValue.pushStack( methodValue.get() ) :
512						methodValue;
513					return false;
514				}
515			});
516		} else {
517
518			// Allow multiple hashes to be passed on init
519			if ( args.length ) {
520				options = $.widget.extend.apply( null, [ options ].concat(args) );
521			}
522
523			this.each(function() {
524				var instance = $.data( this, fullName );
525				if ( instance ) {
526					instance.option( options || {} );
527					if ( instance._init ) {
528						instance._init();
529					}
530				} else {
531					$.data( this, fullName, new object( options, this ) );
532				}
533			});
534		}
535
536		return returnValue;
537	};
538};
539
540$.Widget = function( /* options, element */ ) {};
541$.Widget._childConstructors = [];
542
543$.Widget.prototype = {
544	widgetName: "widget",
545	widgetEventPrefix: "",
546	defaultElement: "<div>",
547	options: {
548		disabled: false,
549
550		// callbacks
551		create: null
552	},
553	_createWidget: function( options, element ) {
554		element = $( element || this.defaultElement || this )[ 0 ];
555		this.element = $( element );
556		this.uuid = widget_uuid++;
557		this.eventNamespace = "." + this.widgetName + this.uuid;
558
559		this.bindings = $();
560		this.hoverable = $();
561		this.focusable = $();
562
563		if ( element !== this ) {
564			$.data( element, this.widgetFullName, this );
565			this._on( true, this.element, {
566				remove: function( event ) {
567					if ( event.target === element ) {
568						this.destroy();
569					}
570				}
571			});
572			this.document = $( element.style ?
573				// element within the document
574				element.ownerDocument :
575				// element is window or document
576				element.document || element );
577			this.window = $( this.document[0].defaultView || this.document[0].parentWindow );
578		}
579
580		this.options = $.widget.extend( {},
581			this.options,
582			this._getCreateOptions(),
583			options );
584
585		this._create();
586		this._trigger( "create", null, this._getCreateEventData() );
587		this._init();
588	},
589	_getCreateOptions: $.noop,
590	_getCreateEventData: $.noop,
591	_create: $.noop,
592	_init: $.noop,
593
594	destroy: function() {
595		this._destroy();
596		// we can probably remove the unbind calls in 2.0
597		// all event bindings should go through this._on()
598		this.element
599			.unbind( this.eventNamespace )
600			.removeData( this.widgetFullName )
601			// support: jquery <1.6.3
602			// http://bugs.jquery.com/ticket/9413
603			.removeData( $.camelCase( this.widgetFullName ) );
604		this.widget()
605			.unbind( this.eventNamespace )
606			.removeAttr( "aria-disabled" )
607			.removeClass(
608				this.widgetFullName + "-disabled " +
609				"ui-state-disabled" );
610
611		// clean up events and states
612		this.bindings.unbind( this.eventNamespace );
613		this.hoverable.removeClass( "ui-state-hover" );
614		this.focusable.removeClass( "ui-state-focus" );
615	},
616	_destroy: $.noop,
617
618	widget: function() {
619		return this.element;
620	},
621
622	option: function( key, value ) {
623		var options = key,
624			parts,
625			curOption,
626			i;
627
628		if ( arguments.length === 0 ) {
629			// don't return a reference to the internal hash
630			return $.widget.extend( {}, this.options );
631		}
632
633		if ( typeof key === "string" ) {
634			// handle nested keys, e.g., "foo.bar" => { foo: { bar: ___ } }
635			options = {};
636			parts = key.split( "." );
637			key = parts.shift();
638			if ( parts.length ) {
639				curOption = options[ key ] = $.widget.extend( {}, this.options[ key ] );
640				for ( i = 0; i < parts.length - 1; i++ ) {
641					curOption[ parts[ i ] ] = curOption[ parts[ i ] ] || {};
642					curOption = curOption[ parts[ i ] ];
643				}
644				key = parts.pop();
645				if ( arguments.length === 1 ) {
646					return curOption[ key ] === undefined ? null : curOption[ key ];
647				}
648				curOption[ key ] = value;
649			} else {
650				if ( arguments.length === 1 ) {
651					return this.options[ key ] === undefined ? null : this.options[ key ];
652				}
653				options[ key ] = value;
654			}
655		}
656
657		this._setOptions( options );
658
659		return this;
660	},
661	_setOptions: function( options ) {
662		var key;
663
664		for ( key in options ) {
665			this._setOption( key, options[ key ] );
666		}
667
668		return this;
669	},
670	_setOption: function( key, value ) {
671		this.options[ key ] = value;
672
673		if ( key === "disabled" ) {
674			this.widget()
675				.toggleClass( this.widgetFullName + "-disabled", !!value );
676
677			// If the widget is becoming disabled, then nothing is interactive
678			if ( value ) {
679				this.hoverable.removeClass( "ui-state-hover" );
680				this.focusable.removeClass( "ui-state-focus" );
681			}
682		}
683
684		return this;
685	},
686
687	enable: function() {
688		return this._setOptions({ disabled: false });
689	},
690	disable: function() {
691		return this._setOptions({ disabled: true });
692	},
693
694	_on: function( suppressDisabledCheck, element, handlers ) {
695		var delegateElement,
696			instance = this;
697
698		// no suppressDisabledCheck flag, shuffle arguments
699		if ( typeof suppressDisabledCheck !== "boolean" ) {
700			handlers = element;
701			element = suppressDisabledCheck;
702			suppressDisabledCheck = false;
703		}
704
705		// no element argument, shuffle and use this.element
706		if ( !handlers ) {
707			handlers = element;
708			element = this.element;
709			delegateElement = this.widget();
710		} else {
711			element = delegateElement = $( element );
712			this.bindings = this.bindings.add( element );
713		}
714
715		$.each( handlers, function( event, handler ) {
716			function handlerProxy() {
717				// allow widgets to customize the disabled handling
718				// - disabled as an array instead of boolean
719				// - disabled class as method for disabling individual parts
720				if ( !suppressDisabledCheck &&
721						( instance.options.disabled === true ||
722							$( this ).hasClass( "ui-state-disabled" ) ) ) {
723					return;
724				}
725				return ( typeof handler === "string" ? instance[ handler ] : handler )
726					.apply( instance, arguments );
727			}
728
729			// copy the guid so direct unbinding works
730			if ( typeof handler !== "string" ) {
731				handlerProxy.guid = handler.guid =
732					handler.guid || handlerProxy.guid || $.guid++;
733			}
734
735			var match = event.match( /^([\w:-]*)\s*(.*)$/ ),
736				eventName = match[1] + instance.eventNamespace,
737				selector = match[2];
738			if ( selector ) {
739				delegateElement.delegate( selector, eventName, handlerProxy );
740			} else {
741				element.bind( eventName, handlerProxy );
742			}
743		});
744	},
745
746	_off: function( element, eventName ) {
747		eventName = (eventName || "").split( " " ).join( this.eventNamespace + " " ) +
748			this.eventNamespace;
749		element.unbind( eventName ).undelegate( eventName );
750
751		// Clear the stack to avoid memory leaks (#10056)
752		this.bindings = $( this.bindings.not( element ).get() );
753		this.focusable = $( this.focusable.not( element ).get() );
754		this.hoverable = $( this.hoverable.not( element ).get() );
755	},
756
757	_delay: function( handler, delay ) {
758		function handlerProxy() {
759			return ( typeof handler === "string" ? instance[ handler ] : handler )
760				.apply( instance, arguments );
761		}
762		var instance = this;
763		return setTimeout( handlerProxy, delay || 0 );
764	},
765
766	_hoverable: function( element ) {
767		this.hoverable = this.hoverable.add( element );
768		this._on( element, {
769			mouseenter: function( event ) {
770				$( event.currentTarget ).addClass( "ui-state-hover" );
771			},
772			mouseleave: function( event ) {
773				$( event.currentTarget ).removeClass( "ui-state-hover" );
774			}
775		});
776	},
777
778	_focusable: function( element ) {
779		this.focusable = this.focusable.add( element );
780		this._on( element, {
781			focusin: function( event ) {
782				$( event.currentTarget ).addClass( "ui-state-focus" );
783			},
784			focusout: function( event ) {
785				$( event.currentTarget ).removeClass( "ui-state-focus" );
786			}
787		});
788	},
789
790	_trigger: function( type, event, data ) {
791		var prop, orig,
792			callback = this.options[ type ];
793
794		data = data || {};
795		event = $.Event( event );
796		event.type = ( type === this.widgetEventPrefix ?
797			type :
798			this.widgetEventPrefix + type ).toLowerCase();
799		// the original event may come from any element
800		// so we need to reset the target on the new event
801		event.target = this.element[ 0 ];
802
803		// copy original event properties over to the new event
804		orig = event.originalEvent;
805		if ( orig ) {
806			for ( prop in orig ) {
807				if ( !( prop in event ) ) {
808					event[ prop ] = orig[ prop ];
809				}
810			}
811		}
812
813		this.element.trigger( event, data );
814		return !( $.isFunction( callback ) &&
815			callback.apply( this.element[0], [ event ].concat( data ) ) === false ||
816			event.isDefaultPrevented() );
817	}
818};
819
820$.each( { show: "fadeIn", hide: "fadeOut" }, function( method, defaultEffect ) {
821	$.Widget.prototype[ "_" + method ] = function( element, options, callback ) {
822		if ( typeof options === "string" ) {
823			options = { effect: options };
824		}
825		var hasOptions,
826			effectName = !options ?
827				method :
828				options === true || typeof options === "number" ?
829					defaultEffect :
830					options.effect || defaultEffect;
831		options = options || {};
832		if ( typeof options === "number" ) {
833			options = { duration: options };
834		}
835		hasOptions = !$.isEmptyObject( options );
836		options.complete = callback;
837		if ( options.delay ) {
838			element.delay( options.delay );
839		}
840		if ( hasOptions && $.effects && $.effects.effect[ effectName ] ) {
841			element[ method ]( options );
842		} else if ( effectName !== method && element[ effectName ] ) {
843			element[ effectName ]( options.duration, options.easing, callback );
844		} else {
845			element.queue(function( next ) {
846				$( this )[ method ]();
847				if ( callback ) {
848					callback.call( element[ 0 ] );
849				}
850				next();
851			});
852		}
853	};
854});
855
856var widget = $.widget;
857
858
859/*!
860 * jQuery UI Mouse 1.11.4
861 * http://jqueryui.com
862 *
863 * Copyright jQuery Foundation and other contributors
864 * Released under the MIT license.
865 * http://jquery.org/license
866 *
867 * http://api.jqueryui.com/mouse/
868 */
869
870
871var mouseHandled = false;
872$( document ).mouseup( function() {
873	mouseHandled = false;
874});
875
876var mouse = $.widget("ui.mouse", {
877	version: "1.11.4",
878	options: {
879		cancel: "input,textarea,button,select,option",
880		distance: 1,
881		delay: 0
882	},
883	_mouseInit: function() {
884		var that = this;
885
886		this.element
887			.bind("mousedown." + this.widgetName, function(event) {
888				return that._mouseDown(event);
889			})
890			.bind("click." + this.widgetName, function(event) {
891				if (true === $.data(event.target, that.widgetName + ".preventClickEvent")) {
892					$.removeData(event.target, that.widgetName + ".preventClickEvent");
893					event.stopImmediatePropagation();
894					return false;
895				}
896			});
897
898		this.started = false;
899	},
900
901	// TODO: make sure destroying one instance of mouse doesn't mess with
902	// other instances of mouse
903	_mouseDestroy: function() {
904		this.element.unbind("." + this.widgetName);
905		if ( this._mouseMoveDelegate ) {
906			this.document
907				.unbind("mousemove." + this.widgetName, this._mouseMoveDelegate)
908				.unbind("mouseup." + this.widgetName, this._mouseUpDelegate);
909		}
910	},
911
912	_mouseDown: function(event) {
913		// don't let more than one widget handle mouseStart
914		if ( mouseHandled ) {
915			return;
916		}
917
918		this._mouseMoved = false;
919
920		// we may have missed mouseup (out of window)
921		(this._mouseStarted && this._mouseUp(event));
922
923		this._mouseDownEvent = event;
924
925		var that = this,
926			btnIsLeft = (event.which === 1),
927			// event.target.nodeName works around a bug in IE 8 with
928			// disabled inputs (#7620)
929			elIsCancel = (typeof this.options.cancel === "string" && event.target.nodeName ? $(event.target).closest(this.options.cancel).length : false);
930		if (!btnIsLeft || elIsCancel || !this._mouseCapture(event)) {
931			return true;
932		}
933
934		this.mouseDelayMet = !this.options.delay;
935		if (!this.mouseDelayMet) {
936			this._mouseDelayTimer = setTimeout(function() {
937				that.mouseDelayMet = true;
938			}, this.options.delay);
939		}
940
941		if (this._mouseDistanceMet(event) && this._mouseDelayMet(event)) {
942			this._mouseStarted = (this._mouseStart(event) !== false);
943			if (!this._mouseStarted) {
944				event.preventDefault();
945				return true;
946			}
947		}
948
949		// Click event may never have fired (Gecko & Opera)
950		if (true === $.data(event.target, this.widgetName + ".preventClickEvent")) {
951			$.removeData(event.target, this.widgetName + ".preventClickEvent");
952		}
953
954		// these delegates are required to keep context
955		this._mouseMoveDelegate = function(event) {
956			return that._mouseMove(event);
957		};
958		this._mouseUpDelegate = function(event) {
959			return that._mouseUp(event);
960		};
961
962		this.document
963			.bind( "mousemove." + this.widgetName, this._mouseMoveDelegate )
964			.bind( "mouseup." + this.widgetName, this._mouseUpDelegate );
965
966		event.preventDefault();
967
968		mouseHandled = true;
969		return true;
970	},
971
972	_mouseMove: function(event) {
973		// Only check for mouseups outside the document if you've moved inside the document
974		// at least once. This prevents the firing of mouseup in the case of IE<9, which will
975		// fire a mousemove event if content is placed under the cursor. See #7778
976		// Support: IE <9
977		if ( this._mouseMoved ) {
978			// IE mouseup check - mouseup happened when mouse was out of window
979			if ($.ui.ie && ( !document.documentMode || document.documentMode < 9 ) && !event.button) {
980				return this._mouseUp(event);
981
982			// Iframe mouseup check - mouseup occurred in another document
983			} else if ( !event.which ) {
984				return this._mouseUp( event );
985			}
986		}
987
988		if ( event.which || event.button ) {
989			this._mouseMoved = true;
990		}
991
992		if (this._mouseStarted) {
993			this._mouseDrag(event);
994			return event.preventDefault();
995		}
996
997		if (this._mouseDistanceMet(event) && this._mouseDelayMet(event)) {
998			this._mouseStarted =
999				(this._mouseStart(this._mouseDownEvent, event) !== false);
1000			(this._mouseStarted ? this._mouseDrag(event) : this._mouseUp(event));
1001		}
1002
1003		return !this._mouseStarted;
1004	},
1005
1006	_mouseUp: function(event) {
1007		this.document
1008			.unbind( "mousemove." + this.widgetName, this._mouseMoveDelegate )
1009			.unbind( "mouseup." + this.widgetName, this._mouseUpDelegate );
1010
1011		if (this._mouseStarted) {
1012			this._mouseStarted = false;
1013
1014			if (event.target === this._mouseDownEvent.target) {
1015				$.data(event.target, this.widgetName + ".preventClickEvent", true);
1016			}
1017
1018			this._mouseStop(event);
1019		}
1020
1021		mouseHandled = false;
1022		return false;
1023	},
1024
1025	_mouseDistanceMet: function(event) {
1026		return (Math.max(
1027				Math.abs(this._mouseDownEvent.pageX - event.pageX),
1028				Math.abs(this._mouseDownEvent.pageY - event.pageY)
1029			) >= this.options.distance
1030		);
1031	},
1032
1033	_mouseDelayMet: function(/* event */) {
1034		return this.mouseDelayMet;
1035	},
1036
1037	// These are placeholder methods, to be overriden by extending plugin
1038	_mouseStart: function(/* event */) {},
1039	_mouseDrag: function(/* event */) {},
1040	_mouseStop: function(/* event */) {},
1041	_mouseCapture: function(/* event */) { return true; }
1042});
1043
1044
1045/*!
1046 * jQuery UI Position 1.11.4
1047 * http://jqueryui.com
1048 *
1049 * Copyright jQuery Foundation and other contributors
1050 * Released under the MIT license.
1051 * http://jquery.org/license
1052 *
1053 * http://api.jqueryui.com/position/
1054 */
1055
1056(function() {
1057
1058$.ui = $.ui || {};
1059
1060var cachedScrollbarWidth, supportsOffsetFractions,
1061	max = Math.max,
1062	abs = Math.abs,
1063	round = Math.round,
1064	rhorizontal = /left|center|right/,
1065	rvertical = /top|center|bottom/,
1066	roffset = /[\+\-]\d+(\.[\d]+)?%?/,
1067	rposition = /^\w+/,
1068	rpercent = /%$/,
1069	_position = $.fn.position;
1070
1071function getOffsets( offsets, width, height ) {
1072	return [
1073		parseFloat( offsets[ 0 ] ) * ( rpercent.test( offsets[ 0 ] ) ? width / 100 : 1 ),
1074		parseFloat( offsets[ 1 ] ) * ( rpercent.test( offsets[ 1 ] ) ? height / 100 : 1 )
1075	];
1076}
1077
1078function parseCss( element, property ) {
1079	return parseInt( $.css( element, property ), 10 ) || 0;
1080}
1081
1082function getDimensions( elem ) {
1083	var raw = elem[0];
1084	if ( raw.nodeType === 9 ) {
1085		return {
1086			width: elem.width(),
1087			height: elem.height(),
1088			offset: { top: 0, left: 0 }
1089		};
1090	}
1091	if ( $.isWindow( raw ) ) {
1092		return {
1093			width: elem.width(),
1094			height: elem.height(),
1095			offset: { top: elem.scrollTop(), left: elem.scrollLeft() }
1096		};
1097	}
1098	if ( raw.preventDefault ) {
1099		return {
1100			width: 0,
1101			height: 0,
1102			offset: { top: raw.pageY, left: raw.pageX }
1103		};
1104	}
1105	return {
1106		width: elem.outerWidth(),
1107		height: elem.outerHeight(),
1108		offset: elem.offset()
1109	};
1110}
1111
1112$.position = {
1113	scrollbarWidth: function() {
1114		if ( cachedScrollbarWidth !== undefined ) {
1115			return cachedScrollbarWidth;
1116		}
1117		var w1, w2,
1118			div = $( "<div style='display:block;position:absolute;width:50px;height:50px;overflow:hidden;'><div style='height:100px;width:auto;'></div></div>" ),
1119			innerDiv = div.children()[0];
1120
1121		$( "body" ).append( div );
1122		w1 = innerDiv.offsetWidth;
1123		div.css( "overflow", "scroll" );
1124
1125		w2 = innerDiv.offsetWidth;
1126
1127		if ( w1 === w2 ) {
1128			w2 = div[0].clientWidth;
1129		}
1130
1131		div.remove();
1132
1133		return (cachedScrollbarWidth = w1 - w2);
1134	},
1135	getScrollInfo: function( within ) {
1136		var overflowX = within.isWindow || within.isDocument ? "" :
1137				within.element.css( "overflow-x" ),
1138			overflowY = within.isWindow || within.isDocument ? "" :
1139				within.element.css( "overflow-y" ),
1140			hasOverflowX = overflowX === "scroll" ||
1141				( overflowX === "auto" && within.width < within.element[0].scrollWidth ),
1142			hasOverflowY = overflowY === "scroll" ||
1143				( overflowY === "auto" && within.height < within.element[0].scrollHeight );
1144		return {
1145			width: hasOverflowY ? $.position.scrollbarWidth() : 0,
1146			height: hasOverflowX ? $.position.scrollbarWidth() : 0
1147		};
1148	},
1149	getWithinInfo: function( element ) {
1150		var withinElement = $( element || window ),
1151			isWindow = $.isWindow( withinElement[0] ),
1152			isDocument = !!withinElement[ 0 ] && withinElement[ 0 ].nodeType === 9;
1153		return {
1154			element: withinElement,
1155			isWindow: isWindow,
1156			isDocument: isDocument,
1157			offset: withinElement.offset() || { left: 0, top: 0 },
1158			scrollLeft: withinElement.scrollLeft(),
1159			scrollTop: withinElement.scrollTop(),
1160
1161			// support: jQuery 1.6.x
1162			// jQuery 1.6 doesn't support .outerWidth/Height() on documents or windows
1163			width: isWindow || isDocument ? withinElement.width() : withinElement.outerWidth(),
1164			height: isWindow || isDocument ? withinElement.height() : withinElement.outerHeight()
1165		};
1166	}
1167};
1168
1169$.fn.position = function( options ) {
1170	if ( !options || !options.of ) {
1171		return _position.apply( this, arguments );
1172	}
1173
1174	// make a copy, we don't want to modify arguments
1175	options = $.extend( {}, options );
1176
1177	var atOffset, targetWidth, targetHeight, targetOffset, basePosition, dimensions,
1178		target = $( options.of ),
1179		within = $.position.getWithinInfo( options.within ),
1180		scrollInfo = $.position.getScrollInfo( within ),
1181		collision = ( options.collision || "flip" ).split( " " ),
1182		offsets = {};
1183
1184	dimensions = getDimensions( target );
1185	if ( target[0].preventDefault ) {
1186		// force left top to allow flipping
1187		options.at = "left top";
1188	}
1189	targetWidth = dimensions.width;
1190	targetHeight = dimensions.height;
1191	targetOffset = dimensions.offset;
1192	// clone to reuse original targetOffset later
1193	basePosition = $.extend( {}, targetOffset );
1194
1195	// force my and at to have valid horizontal and vertical positions
1196	// if a value is missing or invalid, it will be converted to center
1197	$.each( [ "my", "at" ], function() {
1198		var pos = ( options[ this ] || "" ).split( " " ),
1199			horizontalOffset,
1200			verticalOffset;
1201
1202		if ( pos.length === 1) {
1203			pos = rhorizontal.test( pos[ 0 ] ) ?
vendor: 4,791 bytes, lines 1204-1359
1204				pos.concat( [ "center" ] ) :
1205				rvertical.test( pos[ 0 ] ) ?
1206					[ "center" ].concat( pos ) :
1207					[ "center", "center" ];
1208		}
1209		pos[ 0 ] = rhorizontal.test( pos[ 0 ] ) ? pos[ 0 ] : "center";
1210		pos[ 1 ] = rvertical.test( pos[ 1 ] ) ? pos[ 1 ] : "center";
1211
1212		// calculate offsets
1213		horizontalOffset = roffset.exec( pos[ 0 ] );
1214		verticalOffset = roffset.exec( pos[ 1 ] );
1215		offsets[ this ] = [
1216			horizontalOffset ? horizontalOffset[ 0 ] : 0,
1217			verticalOffset ? verticalOffset[ 0 ] : 0
1218		];
1219
1220		// reduce to just the positions without the offsets
1221		options[ this ] = [
1222			rposition.exec( pos[ 0 ] )[ 0 ],
1223			rposition.exec( pos[ 1 ] )[ 0 ]
1224		];
1225	});
1226
1227	// normalize collision option
1228	if ( collision.length === 1 ) {
1229		collision[ 1 ] = collision[ 0 ];
1230	}
1231
1232	if ( options.at[ 0 ] === "right" ) {
1233		basePosition.left += targetWidth;
1234	} else if ( options.at[ 0 ] === "center" ) {
1235		basePosition.left += targetWidth / 2;
1236	}
1237
1238	if ( options.at[ 1 ] === "bottom" ) {
1239		basePosition.top += targetHeight;
1240	} else if ( options.at[ 1 ] === "center" ) {
1241		basePosition.top += targetHeight / 2;
1242	}
1243
1244	atOffset = getOffsets( offsets.at, targetWidth, targetHeight );
1245	basePosition.left += atOffset[ 0 ];
1246	basePosition.top += atOffset[ 1 ];
1247
1248	return this.each(function() {
1249		var collisionPosition, using,
1250			elem = $( this ),
1251			elemWidth = elem.outerWidth(),
1252			elemHeight = elem.outerHeight(),
1253			marginLeft = parseCss( this, "marginLeft" ),
1254			marginTop = parseCss( this, "marginTop" ),
1255			collisionWidth = elemWidth + marginLeft + parseCss( this, "marginRight" ) + scrollInfo.width,
1256			collisionHeight = elemHeight + marginTop + parseCss( this, "marginBottom" ) + scrollInfo.height,
1257			position = $.extend( {}, basePosition ),
1258			myOffset = getOffsets( offsets.my, elem.outerWidth(), elem.outerHeight() );
1259
1260		if ( options.my[ 0 ] === "right" ) {
1261			position.left -= elemWidth;
1262		} else if ( options.my[ 0 ] === "center" ) {
1263			position.left -= elemWidth / 2;
1264		}
1265
1266		if ( options.my[ 1 ] === "bottom" ) {
1267			position.top -= elemHeight;
1268		} else if ( options.my[ 1 ] === "center" ) {
1269			position.top -= elemHeight / 2;
1270		}
1271
1272		position.left += myOffset[ 0 ];
1273		position.top += myOffset[ 1 ];
1274
1275		// if the browser doesn't support fractions, then round for consistent results
1276		if ( !supportsOffsetFractions ) {
1277			position.left = round( position.left );
1278			position.top = round( position.top );
1279		}
1280
1281		collisionPosition = {
1282			marginLeft: marginLeft,
1283			marginTop: marginTop
1284		};
1285
1286		$.each( [ "left", "top" ], function( i, dir ) {
1287			if ( $.ui.position[ collision[ i ] ] ) {
1288				$.ui.position[ collision[ i ] ][ dir ]( position, {
1289					targetWidth: targetWidth,
1290					targetHeight: targetHeight,
1291					elemWidth: elemWidth,
1292					elemHeight: elemHeight,
1293					collisionPosition: collisionPosition,
1294					collisionWidth: collisionWidth,
1295					collisionHeight: collisionHeight,
1296					offset: [ atOffset[ 0 ] + myOffset[ 0 ], atOffset [ 1 ] + myOffset[ 1 ] ],
1297					my: options.my,
1298					at: options.at,
1299					within: within,
1300					elem: elem
1301				});
1302			}
1303		});
1304
1305		if ( options.using ) {
1306			// adds feedback as second argument to using callback, if present
1307			using = function( props ) {
1308				var left = targetOffset.left - position.left,
1309					right = left + targetWidth - elemWidth,
1310					top = targetOffset.top - position.top,
1311					bottom = top + targetHeight - elemHeight,
1312					feedback = {
1313						target: {
1314							element: target,
1315							left: targetOffset.left,
1316							top: targetOffset.top,
1317							width: targetWidth,
1318							height: targetHeight
1319						},
1320						element: {
1321							element: elem,
1322							left: position.left,
1323							top: position.top,
1324							width: elemWidth,
1325							height: elemHeight
1326						},
1327						horizontal: right < 0 ? "left" : left > 0 ? "right" : "center",
1328						vertical: bottom < 0 ? "top" : top > 0 ? "bottom" : "middle"
1329					};
1330				if ( targetWidth < elemWidth && abs( left + right ) < targetWidth ) {
1331					feedback.horizontal = "center";
1332				}
1333				if ( targetHeight < elemHeight && abs( top + bottom ) < targetHeight ) {
1334					feedback.vertical = "middle";
1335				}
1336				if ( max( abs( left ), abs( right ) ) > max( abs( top ), abs( bottom ) ) ) {
1337					feedback.important = "horizontal";
1338				} else {
1339					feedback.important = "vertical";
1340				}
1341				options.using.call( this, props, feedback );
1342			};
1343		}
1344
1345		elem.offset( $.extend( position, { using: using } ) );
1346	});
1347};
1348
1349$.ui.position = {
1350	fit: {
1351		left: function( position, data ) {
1352			var within = data.within,
1353				withinOffset = within.isWindow ? within.scrollLeft : within.offset.left,
1354				outerWidth = within.width,
1355				collisionPosLeft = position.left - data.collisionPosition.marginLeft,
1356				overLeft = withinOffset - collisionPosLeft,
1357				overRight = collisionPosLeft + data.collisionWidth - outerWidth - withinOffset,
1358				newOverRight;
1359
vendor: 7,320 bytes, lines 1360-1592
1360			// element is wider than within
1361			if ( data.collisionWidth > outerWidth ) {
1362				// element is initially over the left side of within
1363				if ( overLeft > 0 && overRight <= 0 ) {
1364					newOverRight = position.left + overLeft + data.collisionWidth - outerWidth - withinOffset;
1365					position.left += overLeft - newOverRight;
1366				// element is initially over right side of within
1367				} else if ( overRight > 0 && overLeft <= 0 ) {
1368					position.left = withinOffset;
1369				// element is initially over both left and right sides of within
1370				} else {
1371					if ( overLeft > overRight ) {
1372						position.left = withinOffset + outerWidth - data.collisionWidth;
1373					} else {
1374						position.left = withinOffset;
1375					}
1376				}
1377			// too far left -> align with left edge
1378			} else if ( overLeft > 0 ) {
1379				position.left += overLeft;
1380			// too far right -> align with right edge
1381			} else if ( overRight > 0 ) {
1382				position.left -= overRight;
1383			// adjust based on position and margin
1384			} else {
1385				position.left = max( position.left - collisionPosLeft, position.left );
1386			}
1387		},
1388		top: function( position, data ) {
1389			var within = data.within,
1390				withinOffset = within.isWindow ? within.scrollTop : within.offset.top,
1391				outerHeight = data.within.height,
1392				collisionPosTop = position.top - data.collisionPosition.marginTop,
1393				overTop = withinOffset - collisionPosTop,
1394				overBottom = collisionPosTop + data.collisionHeight - outerHeight - withinOffset,
1395				newOverBottom;
1396
1397			// element is taller than within
1398			if ( data.collisionHeight > outerHeight ) {
1399				// element is initially over the top of within
1400				if ( overTop > 0 && overBottom <= 0 ) {
1401					newOverBottom = position.top + overTop + data.collisionHeight - outerHeight - withinOffset;
1402					position.top += overTop - newOverBottom;
1403				// element is initially over bottom of within
1404				} else if ( overBottom > 0 && overTop <= 0 ) {
1405					position.top = withinOffset;
1406				// element is initially over both top and bottom of within
1407				} else {
1408					if ( overTop > overBottom ) {
1409						position.top = withinOffset + outerHeight - data.collisionHeight;
1410					} else {
1411						position.top = withinOffset;
1412					}
1413				}
1414			// too far up -> align with top
1415			} else if ( overTop > 0 ) {
1416				position.top += overTop;
1417			// too far down -> align with bottom edge
1418			} else if ( overBottom > 0 ) {
1419				position.top -= overBottom;
1420			// adjust based on position and margin
1421			} else {
1422				position.top = max( position.top - collisionPosTop, position.top );
1423			}
1424		}
1425	},
1426	flip: {
1427		left: function( position, data ) {
1428			var within = data.within,
1429				withinOffset = within.offset.left + within.scrollLeft,
1430				outerWidth = within.width,
1431				offsetLeft = within.isWindow ? within.scrollLeft : within.offset.left,
1432				collisionPosLeft = position.left - data.collisionPosition.marginLeft,
1433				overLeft = collisionPosLeft - offsetLeft,
1434				overRight = collisionPosLeft + data.collisionWidth - outerWidth - offsetLeft,
1435				myOffset = data.my[ 0 ] === "left" ?
1436					-data.elemWidth :
1437					data.my[ 0 ] === "right" ?
1438						data.elemWidth :
1439						0,
1440				atOffset = data.at[ 0 ] === "left" ?
1441					data.targetWidth :
1442					data.at[ 0 ] === "right" ?
1443						-data.targetWidth :
1444						0,
1445				offset = -2 * data.offset[ 0 ],
1446				newOverRight,
1447				newOverLeft;
1448
1449			if ( overLeft < 0 ) {
1450				newOverRight = position.left + myOffset + atOffset + offset + data.collisionWidth - outerWidth - withinOffset;
1451				if ( newOverRight < 0 || newOverRight < abs( overLeft ) ) {
1452					position.left += myOffset + atOffset + offset;
1453				}
1454			} else if ( overRight > 0 ) {
1455				newOverLeft = position.left - data.collisionPosition.marginLeft + myOffset + atOffset + offset - offsetLeft;
1456				if ( newOverLeft > 0 || abs( newOverLeft ) < overRight ) {
1457					position.left += myOffset + atOffset + offset;
1458				}
1459			}
1460		},
1461		top: function( position, data ) {
1462			var within = data.within,
1463				withinOffset = within.offset.top + within.scrollTop,
1464				outerHeight = within.height,
1465				offsetTop = within.isWindow ? within.scrollTop : within.offset.top,
1466				collisionPosTop = position.top - data.collisionPosition.marginTop,
1467				overTop = collisionPosTop - offsetTop,
1468				overBottom = collisionPosTop + data.collisionHeight - outerHeight - offsetTop,
1469				top = data.my[ 1 ] === "top",
1470				myOffset = top ?
1471					-data.elemHeight :
1472					data.my[ 1 ] === "bottom" ?
1473						data.elemHeight :
1474						0,
1475				atOffset = data.at[ 1 ] === "top" ?
1476					data.targetHeight :
1477					data.at[ 1 ] === "bottom" ?
1478						-data.targetHeight :
1479						0,
1480				offset = -2 * data.offset[ 1 ],
1481				newOverTop,
1482				newOverBottom;
1483			if ( overTop < 0 ) {
1484				newOverBottom = position.top + myOffset + atOffset + offset + data.collisionHeight - outerHeight - withinOffset;
1485				if ( newOverBottom < 0 || newOverBottom < abs( overTop ) ) {
1486					position.top += myOffset + atOffset + offset;
1487				}
1488			} else if ( overBottom > 0 ) {
1489				newOverTop = position.top - data.collisionPosition.marginTop + myOffset + atOffset + offset - offsetTop;
1490				if ( newOverTop > 0 || abs( newOverTop ) < overBottom ) {
1491					position.top += myOffset + atOffset + offset;
1492				}
1493			}
1494		}
1495	},
1496	flipfit: {
1497		left: function() {
1498			$.ui.position.flip.left.apply( this, arguments );
1499			$.ui.position.fit.left.apply( this, arguments );
1500		},
1501		top: function() {
1502			$.ui.position.flip.top.apply( this, arguments );
1503			$.ui.position.fit.top.apply( this, arguments );
1504		}
1505	}
1506};
1507
1508// fraction support test
1509(function() {
1510	var testElement, testElementParent, testElementStyle, offsetLeft, i,
1511		body = document.getElementsByTagName( "body" )[ 0 ],
1512		div = document.createElement( "div" );
1513
1514	//Create a "fake body" for testing based on method used in jQuery.support
1515	testElement = document.createElement( body ? "div" : "body" );
1516	testElementStyle = {
1517		visibility: "hidden",
1518		width: 0,
1519		height: 0,
1520		border: 0,
1521		margin: 0,
1522		background: "none"
1523	};
1524	if ( body ) {
1525		$.extend( testElementStyle, {
1526			position: "absolute",
1527			left: "-1000px",
1528			top: "-1000px"
1529		});
1530	}
1531	for ( i in testElementStyle ) {
1532		testElement.style[ i ] = testElementStyle[ i ];
1533	}
1534	testElement.appendChild( div );
1535	testElementParent = body || document.documentElement;
1536	testElementParent.insertBefore( testElement, testElementParent.firstChild );
1537
1538	div.style.cssText = "position: absolute; left: 10.7432222px;";
1539
1540	offsetLeft = $( div ).offset().left;
1541	supportsOffsetFractions = offsetLeft > 10 && offsetLeft < 11;
1542
1543	testElement.innerHTML = "";
1544	testElementParent.removeChild( testElement );
1545})();
1546
1547})();
1548
1549var position = $.ui.position;
1550
1551
1552/*!
1553 * jQuery UI Accordion 1.11.4
1554 * http://jqueryui.com
1555 *
1556 * Copyright jQuery Foundation and other contributors
1557 * Released under the MIT license.
1558 * http://jquery.org/license
1559 *
1560 * http://api.jqueryui.com/accordion/
1561 */
1562
1563
1564var accordion = $.widget( "ui.accordion", {
1565	version: "1.11.4",
1566	options: {
1567		active: 0,
1568		animate: {},
1569		collapsible: false,
1570		event: "click",
1571		header: "> li > :first-child,> :not(li):even",
1572		heightStyle: "auto",
1573		icons: {
1574			activeHeader: "ui-icon-triangle-1-s",
1575			header: "ui-icon-triangle-1-e"
1576		},
1577
1578		// callbacks
1579		activate: null,
1580		beforeActivate: null
1581	},
1582
1583	hideProps: {
1584		borderTopWidth: "hide",
1585		borderBottomWidth: "hide",
1586		paddingTop: "hide",
1587		paddingBottom: "hide",
1588		height: "hide"
1589	},
1590
1591	showProps: {
1592		borderTopWidth: "show",
vendor: 4,428 bytes, lines 1593-1769
1593		borderBottomWidth: "show",
1594		paddingTop: "show",
1595		paddingBottom: "show",
1596		height: "show"
1597	},
1598
1599	_create: function() {
1600		var options = this.options;
1601		this.prevShow = this.prevHide = $();
1602		this.element.addClass( "ui-accordion ui-widget ui-helper-reset" )
1603			// ARIA
1604			.attr( "role", "tablist" );
1605
1606		// don't allow collapsible: false and active: false / null
1607		if ( !options.collapsible && (options.active === false || options.active == null) ) {
1608			options.active = 0;
1609		}
1610
1611		this._processPanels();
1612		// handle negative values
1613		if ( options.active < 0 ) {
1614			options.active += this.headers.length;
1615		}
1616		this._refresh();
1617	},
1618
1619	_getCreateEventData: function() {
1620		return {
1621			header: this.active,
1622			panel: !this.active.length ? $() : this.active.next()
1623		};
1624	},
1625
1626	_createIcons: function() {
1627		var icons = this.options.icons;
1628		if ( icons ) {
1629			$( "<span>" )
1630				.addClass( "ui-accordion-header-icon ui-icon " + icons.header )
1631				.prependTo( this.headers );
1632			this.active.children( ".ui-accordion-header-icon" )
1633				.removeClass( icons.header )
1634				.addClass( icons.activeHeader );
1635			this.headers.addClass( "ui-accordion-icons" );
1636		}
1637	},
1638
1639	_destroyIcons: function() {
1640		this.headers
1641			.removeClass( "ui-accordion-icons" )
1642			.children( ".ui-accordion-header-icon" )
1643				.remove();
1644	},
1645
1646	_destroy: function() {
1647		var contents;
1648
1649		// clean up main element
1650		this.element
1651			.removeClass( "ui-accordion ui-widget ui-helper-reset" )
1652			.removeAttr( "role" );
1653
1654		// clean up headers
1655		this.headers
1656			.removeClass( "ui-accordion-header ui-accordion-header-active ui-state-default " +
1657				"ui-corner-all ui-state-active ui-state-disabled ui-corner-top" )
1658			.removeAttr( "role" )
1659			.removeAttr( "aria-expanded" )
1660			.removeAttr( "aria-selected" )
1661			.removeAttr( "aria-controls" )
1662			.removeAttr( "tabIndex" )
1663			.removeUniqueId();
1664
1665		this._destroyIcons();
1666
1667		// clean up content panels
1668		contents = this.headers.next()
1669			.removeClass( "ui-helper-reset ui-widget-content ui-corner-bottom " +
1670				"ui-accordion-content ui-accordion-content-active ui-state-disabled" )
1671			.css( "display", "" )
1672			.removeAttr( "role" )
1673			.removeAttr( "aria-hidden" )
1674			.removeAttr( "aria-labelledby" )
1675			.removeUniqueId();
1676
1677		if ( this.options.heightStyle !== "content" ) {
1678			contents.css( "height", "" );
1679		}
1680	},
1681
1682	_setOption: function( key, value ) {
1683		if ( key === "active" ) {
1684			// _activate() will handle invalid values and update this.options
1685			this._activate( value );
1686			return;
1687		}
1688
1689		if ( key === "event" ) {
1690			if ( this.options.event ) {
1691				this._off( this.headers, this.options.event );
1692			}
1693			this._setupEvents( value );
1694		}
1695
1696		this._super( key, value );
1697
1698		// setting collapsible: false while collapsed; open first panel
1699		if ( key === "collapsible" && !value && this.options.active === false ) {
1700			this._activate( 0 );
1701		}
1702
1703		if ( key === "icons" ) {
1704			this._destroyIcons();
1705			if ( value ) {
1706				this._createIcons();
1707			}
1708		}
1709
1710		// #5332 - opacity doesn't cascade to positioned elements in IE
1711		// so we need to add the disabled class to the headers and panels
1712		if ( key === "disabled" ) {
1713			this.element
1714				.toggleClass( "ui-state-disabled", !!value )
1715				.attr( "aria-disabled", value );
1716			this.headers.add( this.headers.next() )
1717				.toggleClass( "ui-state-disabled", !!value );
1718		}
1719	},
1720
1721	_keydown: function( event ) {
1722		if ( event.altKey || event.ctrlKey ) {
1723			return;
1724		}
1725
1726		var keyCode = $.ui.keyCode,
1727			length = this.headers.length,
1728			currentIndex = this.headers.index( event.target ),
1729			toFocus = false;
1730
1731		switch ( event.keyCode ) {
1732			case keyCode.RIGHT:
1733			case keyCode.DOWN:
1734				toFocus = this.headers[ ( currentIndex + 1 ) % length ];
1735				break;
1736			case keyCode.LEFT:
1737			case keyCode.UP:
1738				toFocus = this.headers[ ( currentIndex - 1 + length ) % length ];
1739				break;
1740			case keyCode.SPACE:
1741			case keyCode.ENTER:
1742				this._eventHandler( event );
1743				break;
1744			case keyCode.HOME:
1745				toFocus = this.headers[ 0 ];
1746				break;
1747			case keyCode.END:
1748				toFocus = this.headers[ length - 1 ];
1749				break;
1750		}
1751
1752		if ( toFocus ) {
1753			$( event.target ).attr( "tabIndex", -1 );
1754			$( toFocus ).attr( "tabIndex", 0 );
1755			toFocus.focus();
1756			event.preventDefault();
1757		}
1758	},
1759
1760	_panelKeyDown: function( event ) {
1761		if ( event.keyCode === $.ui.keyCode.UP && event.ctrlKey ) {
1762			$( event.currentTarget ).prev().focus();
1763		}
1764	},
1765
1766	refresh: function() {
1767		var options = this.options;
1768		this._processPanels();
1769
vendor: 17,411 bytes, lines 1770-2422
1770		// was collapsed or no panel
1771		if ( ( options.active === false && options.collapsible === true ) || !this.headers.length ) {
1772			options.active = false;
1773			this.active = $();
1774		// active false only when collapsible is true
1775		} else if ( options.active === false ) {
1776			this._activate( 0 );
1777		// was active, but active panel is gone
1778		} else if ( this.active.length && !$.contains( this.element[ 0 ], this.active[ 0 ] ) ) {
1779			// all remaining panel are disabled
1780			if ( this.headers.length === this.headers.find(".ui-state-disabled").length ) {
1781				options.active = false;
1782				this.active = $();
1783			// activate previous panel
1784			} else {
1785				this._activate( Math.max( 0, options.active - 1 ) );
1786			}
1787		// was active, active panel still exists
1788		} else {
1789			// make sure active index is correct
1790			options.active = this.headers.index( this.active );
1791		}
1792
1793		this._destroyIcons();
1794
1795		this._refresh();
1796	},
1797
1798	_processPanels: function() {
1799		var prevHeaders = this.headers,
1800			prevPanels = this.panels;
1801
1802		this.headers = this.element.find( this.options.header )
1803			.addClass( "ui-accordion-header ui-state-default ui-corner-all" );
1804
1805		this.panels = this.headers.next()
1806			.addClass( "ui-accordion-content ui-helper-reset ui-widget-content ui-corner-bottom" )
1807			.filter( ":not(.ui-accordion-content-active)" )
1808			.hide();
1809
1810		// Avoid memory leaks (#10056)
1811		if ( prevPanels ) {
1812			this._off( prevHeaders.not( this.headers ) );
1813			this._off( prevPanels.not( this.panels ) );
1814		}
1815	},
1816
1817	_refresh: function() {
1818		var maxHeight,
1819			options = this.options,
1820			heightStyle = options.heightStyle,
1821			parent = this.element.parent();
1822
1823		this.active = this._findActive( options.active )
1824			.addClass( "ui-accordion-header-active ui-state-active ui-corner-top" )
1825			.removeClass( "ui-corner-all" );
1826		this.active.next()
1827			.addClass( "ui-accordion-content-active" )
1828			.show();
1829
1830		this.headers
1831			.attr( "role", "tab" )
1832			.each(function() {
1833				var header = $( this ),
1834					headerId = header.uniqueId().attr( "id" ),
1835					panel = header.next(),
1836					panelId = panel.uniqueId().attr( "id" );
1837				header.attr( "aria-controls", panelId );
1838				panel.attr( "aria-labelledby", headerId );
1839			})
1840			.next()
1841				.attr( "role", "tabpanel" );
1842
1843		this.headers
1844			.not( this.active )
1845			.attr({
1846				"aria-selected": "false",
1847				"aria-expanded": "false",
1848				tabIndex: -1
1849			})
1850			.next()
1851				.attr({
1852					"aria-hidden": "true"
1853				})
1854				.hide();
1855
1856		// make sure at least one header is in the tab order
1857		if ( !this.active.length ) {
1858			this.headers.eq( 0 ).attr( "tabIndex", 0 );
1859		} else {
1860			this.active.attr({
1861				"aria-selected": "true",
1862				"aria-expanded": "true",
1863				tabIndex: 0
1864			})
1865			.next()
1866				.attr({
1867					"aria-hidden": "false"
1868				});
1869		}
1870
1871		this._createIcons();
1872
1873		this._setupEvents( options.event );
1874
1875		if ( heightStyle === "fill" ) {
1876			maxHeight = parent.height();
1877			this.element.siblings( ":visible" ).each(function() {
1878				var elem = $( this ),
1879					position = elem.css( "position" );
1880
1881				if ( position === "absolute" || position === "fixed" ) {
1882					return;
1883				}
1884				maxHeight -= elem.outerHeight( true );
1885			});
1886
1887			this.headers.each(function() {
1888				maxHeight -= $( this ).outerHeight( true );
1889			});
1890
1891			this.headers.next()
1892				.each(function() {
1893					$( this ).height( Math.max( 0, maxHeight -
1894						$( this ).innerHeight() + $( this ).height() ) );
1895				})
1896				.css( "overflow", "auto" );
1897		} else if ( heightStyle === "auto" ) {
1898			maxHeight = 0;
1899			this.headers.next()
1900				.each(function() {
1901					maxHeight = Math.max( maxHeight, $( this ).css( "height", "" ).height() );
1902				})
1903				.height( maxHeight );
1904		}
1905	},
1906
1907	_activate: function( index ) {
1908		var active = this._findActive( index )[ 0 ];
1909
1910		// trying to activate the already active panel
1911		if ( active === this.active[ 0 ] ) {
1912			return;
1913		}
1914
1915		// trying to collapse, simulate a click on the currently active header
1916		active = active || this.active[ 0 ];
1917
1918		this._eventHandler({
1919			target: active,
1920			currentTarget: active,
1921			preventDefault: $.noop
1922		});
1923	},
1924
1925	_findActive: function( selector ) {
1926		return typeof selector === "number" ? this.headers.eq( selector ) : $();
1927	},
1928
1929	_setupEvents: function( event ) {
1930		var events = {
1931			keydown: "_keydown"
1932		};
1933		if ( event ) {
1934			$.each( event.split( " " ), function( index, eventName ) {
1935				events[ eventName ] = "_eventHandler";
1936			});
1937		}
1938
1939		this._off( this.headers.add( this.headers.next() ) );
1940		this._on( this.headers, events );
1941		this._on( this.headers.next(), { keydown: "_panelKeyDown" });
1942		this._hoverable( this.headers );
1943		this._focusable( this.headers );
1944	},
1945
1946	_eventHandler: function( event ) {
1947		var options = this.options,
1948			active = this.active,
1949			clicked = $( event.currentTarget ),
1950			clickedIsActive = clicked[ 0 ] === active[ 0 ],
1951			collapsing = clickedIsActive && options.collapsible,
1952			toShow = collapsing ? $() : clicked.next(),
1953			toHide = active.next(),
1954			eventData = {
1955				oldHeader: active,
1956				oldPanel: toHide,
1957				newHeader: collapsing ? $() : clicked,
1958				newPanel: toShow
1959			};
1960
1961		event.preventDefault();
1962
1963		if (
1964				// click on active header, but not collapsible
1965				( clickedIsActive && !options.collapsible ) ||
1966				// allow canceling activation
1967				( this._trigger( "beforeActivate", event, eventData ) === false ) ) {
1968			return;
1969		}
1970
1971		options.active = collapsing ? false : this.headers.index( clicked );
1972
1973		// when the call to ._toggle() comes after the class changes
1974		// it causes a very odd bug in IE 8 (see #6720)
1975		this.active = clickedIsActive ? $() : clicked;
1976		this._toggle( eventData );
1977
1978		// switch classes
1979		// corner classes on the previously active header stay after the animation
1980		active.removeClass( "ui-accordion-header-active ui-state-active" );
1981		if ( options.icons ) {
1982			active.children( ".ui-accordion-header-icon" )
1983				.removeClass( options.icons.activeHeader )
1984				.addClass( options.icons.header );
1985		}
1986
1987		if ( !clickedIsActive ) {
1988			clicked
1989				.removeClass( "ui-corner-all" )
1990				.addClass( "ui-accordion-header-active ui-state-active ui-corner-top" );
1991			if ( options.icons ) {
1992				clicked.children( ".ui-accordion-header-icon" )
1993					.removeClass( options.icons.header )
1994					.addClass( options.icons.activeHeader );
1995			}
1996
1997			clicked
1998				.next()
1999				.addClass( "ui-accordion-content-active" );
2000		}
2001	},
2002
2003	_toggle: function( data ) {
2004		var toShow = data.newPanel,
2005			toHide = this.prevShow.length ? this.prevShow : data.oldPanel;
2006
2007		// handle activating a panel during the animation for another activation
2008		this.prevShow.add( this.prevHide ).stop( true, true );
2009		this.prevShow = toShow;
2010		this.prevHide = toHide;
2011
2012		if ( this.options.animate ) {
2013			this._animate( toShow, toHide, data );
2014		} else {
2015			toHide.hide();
2016			toShow.show();
2017			this._toggleComplete( data );
2018		}
2019
2020		toHide.attr({
2021			"aria-hidden": "true"
2022		});
2023		toHide.prev().attr({
2024			"aria-selected": "false",
2025			"aria-expanded": "false"
2026		});
2027		// if we're switching panels, remove the old header from the tab order
2028		// if we're opening from collapsed state, remove the previous header from the tab order
2029		// if we're collapsing, then keep the collapsing header in the tab order
2030		if ( toShow.length && toHide.length ) {
2031			toHide.prev().attr({
2032				"tabIndex": -1,
2033				"aria-expanded": "false"
2034			});
2035		} else if ( toShow.length ) {
2036			this.headers.filter(function() {
2037				return parseInt( $( this ).attr( "tabIndex" ), 10 ) === 0;
2038			})
2039			.attr( "tabIndex", -1 );
2040		}
2041
2042		toShow
2043			.attr( "aria-hidden", "false" )
2044			.prev()
2045				.attr({
2046					"aria-selected": "true",
2047					"aria-expanded": "true",
2048					tabIndex: 0
2049				});
2050	},
2051
2052	_animate: function( toShow, toHide, data ) {
2053		var total, easing, duration,
2054			that = this,
2055			adjust = 0,
2056			boxSizing = toShow.css( "box-sizing" ),
2057			down = toShow.length &&
2058				( !toHide.length || ( toShow.index() < toHide.index() ) ),
2059			animate = this.options.animate || {},
2060			options = down && animate.down || animate,
2061			complete = function() {
2062				that._toggleComplete( data );
2063			};
2064
2065		if ( typeof options === "number" ) {
2066			duration = options;
2067		}
2068		if ( typeof options === "string" ) {
2069			easing = options;
2070		}
2071		// fall back from options to animation in case of partial down settings
2072		easing = easing || options.easing || animate.easing;
2073		duration = duration || options.duration || animate.duration;
2074
2075		if ( !toHide.length ) {
2076			return toShow.animate( this.showProps, duration, easing, complete );
2077		}
2078		if ( !toShow.length ) {
2079			return toHide.animate( this.hideProps, duration, easing, complete );
2080		}
2081
2082		total = toShow.show().outerHeight();
2083		toHide.animate( this.hideProps, {
2084			duration: duration,
2085			easing: easing,
2086			step: function( now, fx ) {
2087				fx.now = Math.round( now );
2088			}
2089		});
2090		toShow
2091			.hide()
2092			.animate( this.showProps, {
2093				duration: duration,
2094				easing: easing,
2095				complete: complete,
2096				step: function( now, fx ) {
2097					fx.now = Math.round( now );
2098					if ( fx.prop !== "height" ) {
2099						if ( boxSizing === "content-box" ) {
2100							adjust += fx.now;
2101						}
2102					} else if ( that.options.heightStyle !== "content" ) {
2103						fx.now = Math.round( total - toHide.outerHeight() - adjust );
2104						adjust = 0;
2105					}
2106				}
2107			});
2108	},
2109
2110	_toggleComplete: function( data ) {
2111		var toHide = data.oldPanel;
2112
2113		toHide
2114			.removeClass( "ui-accordion-content-active" )
2115			.prev()
2116				.removeClass( "ui-corner-top" )
2117				.addClass( "ui-corner-all" );
2118
2119		// Work around for rendering bug in IE (#5421)
2120		if ( toHide.length ) {
2121			toHide.parent()[ 0 ].className = toHide.parent()[ 0 ].className;
2122		}
2123		this._trigger( "activate", null, data );
2124	}
2125});
2126
2127
2128/*!
2129 * jQuery UI Menu 1.11.4
2130 * http://jqueryui.com
2131 *
2132 * Copyright jQuery Foundation and other contributors
2133 * Released under the MIT license.
2134 * http://jquery.org/license
2135 *
2136 * http://api.jqueryui.com/menu/
2137 */
2138
2139
2140var menu = $.widget( "ui.menu", {
2141	version: "1.11.4",
2142	defaultElement: "<ul>",
2143	delay: 300,
2144	options: {
2145		icons: {
2146			submenu: "ui-icon-carat-1-e"
2147		},
2148		items: "> *",
2149		menus: "ul",
2150		position: {
2151			my: "left-1 top",
2152			at: "right top"
2153		},
2154		role: "menu",
2155
2156		// callbacks
2157		blur: null,
2158		focus: null,
2159		select: null
2160	},
2161
2162	_create: function() {
2163		this.activeMenu = this.element;
2164
2165		// Flag used to prevent firing of the click handler
2166		// as the event bubbles up through nested menus
2167		this.mouseHandled = false;
2168		this.element
2169			.uniqueId()
2170			.addClass( "ui-menu ui-widget ui-widget-content" )
2171			.toggleClass( "ui-menu-icons", !!this.element.find( ".ui-icon" ).length )
2172			.attr({
2173				role: this.options.role,
2174				tabIndex: 0
2175			});
2176
2177		if ( this.options.disabled ) {
2178			this.element
2179				.addClass( "ui-state-disabled" )
2180				.attr( "aria-disabled", "true" );
2181		}
2182
2183		this._on({
2184			// Prevent focus from sticking to links inside menu after clicking
2185			// them (focus should always stay on UL during navigation).
2186			"mousedown .ui-menu-item": function( event ) {
2187				event.preventDefault();
2188			},
2189			"click .ui-menu-item": function( event ) {
2190				var target = $( event.target );
2191				if ( !this.mouseHandled && target.not( ".ui-state-disabled" ).length ) {
2192					this.select( event );
2193
2194					// Only set the mouseHandled flag if the event will bubble, see #9469.
2195					if ( !event.isPropagationStopped() ) {
2196						this.mouseHandled = true;
2197					}
2198
2199					// Open submenu on click
2200					if ( target.has( ".ui-menu" ).length ) {
2201						this.expand( event );
2202					} else if ( !this.element.is( ":focus" ) && $( this.document[ 0 ].activeElement ).closest( ".ui-menu" ).length ) {
2203
2204						// Redirect focus to the menu
2205						this.element.trigger( "focus", [ true ] );
2206
2207						// If the active item is on the top level, let it stay active.
2208						// Otherwise, blur the active item since it is no longer visible.
2209						if ( this.active && this.active.parents( ".ui-menu" ).length === 1 ) {
2210							clearTimeout( this.timer );
2211						}
2212					}
2213				}
2214			},
2215			"mouseenter .ui-menu-item": function( event ) {
2216				// Ignore mouse events while typeahead is active, see #10458.
2217				// Prevents focusing the wrong item when typeahead causes a scroll while the mouse
2218				// is over an item in the menu
2219				if ( this.previousFilter ) {
2220					return;
2221				}
2222				var target = $( event.currentTarget );
2223				// Remove ui-state-active class from siblings of the newly focused menu item
2224				// to avoid a jump caused by adjacent elements both having a class with a border
2225				target.siblings( ".ui-state-active" ).removeClass( "ui-state-active" );
2226				this.focus( event, target );
2227			},
2228			mouseleave: "collapseAll",
2229			"mouseleave .ui-menu": "collapseAll",
2230			focus: function( event, keepActiveItem ) {
2231				// If there's already an active item, keep it active
2232				// If not, activate the first item
2233				var item = this.active || this.element.find( this.options.items ).eq( 0 );
2234
2235				if ( !keepActiveItem ) {
2236					this.focus( event, item );
2237				}
2238			},
2239			blur: function( event ) {
2240				this._delay(function() {
2241					if ( !$.contains( this.element[0], this.document[0].activeElement ) ) {
2242						this.collapseAll( event );
2243					}
2244				});
2245			},
2246			keydown: "_keydown"
2247		});
2248
2249		this.refresh();
2250
2251		// Clicks outside of a menu collapse any open menus
2252		this._on( this.document, {
2253			click: function( event ) {
2254				if ( this._closeOnDocumentClick( event ) ) {
2255					this.collapseAll( event );
2256				}
2257
2258				// Reset the mouseHandled flag
2259				this.mouseHandled = false;
2260			}
2261		});
2262	},
2263
2264	_destroy: function() {
2265		// Destroy (sub)menus
2266		this.element
2267			.removeAttr( "aria-activedescendant" )
2268			.find( ".ui-menu" ).addBack()
2269				.removeClass( "ui-menu ui-widget ui-widget-content ui-menu-icons ui-front" )
2270				.removeAttr( "role" )
2271				.removeAttr( "tabIndex" )
2272				.removeAttr( "aria-labelledby" )
2273				.removeAttr( "aria-expanded" )
2274				.removeAttr( "aria-hidden" )
2275				.removeAttr( "aria-disabled" )
2276				.removeUniqueId()
2277				.show();
2278
2279		// Destroy menu items
2280		this.element.find( ".ui-menu-item" )
2281			.removeClass( "ui-menu-item" )
2282			.removeAttr( "role" )
2283			.removeAttr( "aria-disabled" )
2284			.removeUniqueId()
2285			.removeClass( "ui-state-hover" )
2286			.removeAttr( "tabIndex" )
2287			.removeAttr( "role" )
2288			.removeAttr( "aria-haspopup" )
2289			.children().each( function() {
2290				var elem = $( this );
2291				if ( elem.data( "ui-menu-submenu-carat" ) ) {
2292					elem.remove();
2293				}
2294			});
2295
2296		// Destroy menu dividers
2297		this.element.find( ".ui-menu-divider" ).removeClass( "ui-menu-divider ui-widget-content" );
2298	},
2299
2300	_keydown: function( event ) {
2301		var match, prev, character, skip,
2302			preventDefault = true;
2303
2304		switch ( event.keyCode ) {
2305		case $.ui.keyCode.PAGE_UP:
2306			this.previousPage( event );
2307			break;
2308		case $.ui.keyCode.PAGE_DOWN:
2309			this.nextPage( event );
2310			break;
2311		case $.ui.keyCode.HOME:
2312			this._move( "first", "first", event );
2313			break;
2314		case $.ui.keyCode.END:
2315			this._move( "last", "last", event );
2316			break;
2317		case $.ui.keyCode.UP:
2318			this.previous( event );
2319			break;
2320		case $.ui.keyCode.DOWN:
2321			this.next( event );
2322			break;
2323		case $.ui.keyCode.LEFT:
2324			this.collapse( event );
2325			break;
2326		case $.ui.keyCode.RIGHT:
2327			if ( this.active && !this.active.is( ".ui-state-disabled" ) ) {
2328				this.expand( event );
2329			}
2330			break;
2331		case $.ui.keyCode.ENTER:
2332		case $.ui.keyCode.SPACE:
2333			this._activate( event );
2334			break;
2335		case $.ui.keyCode.ESCAPE:
2336			this.collapse( event );
2337			break;
2338		default:
2339			preventDefault = false;
2340			prev = this.previousFilter || "";
2341			character = String.fromCharCode( event.keyCode );
2342			skip = false;
2343
2344			clearTimeout( this.filterTimer );
2345
2346			if ( character === prev ) {
2347				skip = true;
2348			} else {
2349				character = prev + character;
2350			}
2351
2352			match = this._filterMenuItems( character );
2353			match = skip && match.index( this.active.next() ) !== -1 ?
2354				this.active.nextAll( ".ui-menu-item" ) :
2355				match;
2356
2357			// If no matches on the current filter, reset to the last character pressed
2358			// to move down the menu to the first item that starts with that character
2359			if ( !match.length ) {
2360				character = String.fromCharCode( event.keyCode );
2361				match = this._filterMenuItems( character );
2362			}
2363
2364			if ( match.length ) {
2365				this.focus( event, match );
2366				this.previousFilter = character;
2367				this.filterTimer = this._delay(function() {
2368					delete this.previousFilter;
2369				}, 1000 );
2370			} else {
2371				delete this.previousFilter;
2372			}
2373		}
2374
2375		if ( preventDefault ) {
2376			event.preventDefault();
2377		}
2378	},
2379
2380	_activate: function( event ) {
2381		if ( !this.active.is( ".ui-state-disabled" ) ) {
2382			if ( this.active.is( "[aria-haspopup='true']" ) ) {
2383				this.expand( event );
2384			} else {
2385				this.select( event );
2386			}
2387		}
2388	},
2389
2390	refresh: function() {
2391		var menus, items,
2392			that = this,
2393			icon = this.options.icons.submenu,
2394			submenus = this.element.find( this.options.menus );
2395
2396		this.element.toggleClass( "ui-menu-icons", !!this.element.find( ".ui-icon" ).length );
2397
2398		// Initialize nested menus
2399		submenus.filter( ":not(.ui-menu)" )
2400			.addClass( "ui-menu ui-widget ui-widget-content ui-front" )
2401			.hide()
2402			.attr({
2403				role: this.options.role,
2404				"aria-hidden": "true",
2405				"aria-expanded": "false"
2406			})
2407			.each(function() {
2408				var menu = $( this ),
2409					item = menu.parent(),
2410					submenuCarat = $( "<span>" )
2411						.addClass( "ui-menu-icon ui-icon " + icon )
2412						.data( "ui-menu-submenu-carat", true );
2413
2414				item
2415					.attr( "aria-haspopup", "true" )
2416					.prepend( submenuCarat );
2417				menu.attr( "aria-labelledby", item.attr( "id" ) );
2418			});
2419
2420		menus = submenus.add( this.element );
2421		items = menus.find( this.options.items );
2422
vendor: 4,109 bytes, lines 2423-2574
2423		// Initialize menu-items containing spaces and/or dashes only as dividers
2424		items.not( ".ui-menu-item" ).each(function() {
2425			var item = $( this );
2426			if ( that._isDivider( item ) ) {
2427				item.addClass( "ui-widget-content ui-menu-divider" );
2428			}
2429		});
2430
2431		// Don't refresh list items that are already adapted
2432		items.not( ".ui-menu-item, .ui-menu-divider" )
2433			.addClass( "ui-menu-item" )
2434			.uniqueId()
2435			.attr({
2436				tabIndex: -1,
2437				role: this._itemRole()
2438			});
2439
2440		// Add aria-disabled attribute to any disabled menu item
2441		items.filter( ".ui-state-disabled" ).attr( "aria-disabled", "true" );
2442
2443		// If the active item has been removed, blur the menu
2444		if ( this.active && !$.contains( this.element[ 0 ], this.active[ 0 ] ) ) {
2445			this.blur();
2446		}
2447	},
2448
2449	_itemRole: function() {
2450		return {
2451			menu: "menuitem",
2452			listbox: "option"
2453		}[ this.options.role ];
2454	},
2455
2456	_setOption: function( key, value ) {
2457		if ( key === "icons" ) {
2458			this.element.find( ".ui-menu-icon" )
2459				.removeClass( this.options.icons.submenu )
2460				.addClass( value.submenu );
2461		}
2462		if ( key === "disabled" ) {
2463			this.element
2464				.toggleClass( "ui-state-disabled", !!value )
2465				.attr( "aria-disabled", value );
2466		}
2467		this._super( key, value );
2468	},
2469
2470	focus: function( event, item ) {
2471		var nested, focused;
2472		this.blur( event, event && event.type === "focus" );
2473
2474		this._scrollIntoView( item );
2475
2476		this.active = item.first();
2477		focused = this.active.addClass( "ui-state-focus" ).removeClass( "ui-state-active" );
2478		// Only update aria-activedescendant if there's a role
2479		// otherwise we assume focus is managed elsewhere
2480		if ( this.options.role ) {
2481			this.element.attr( "aria-activedescendant", focused.attr( "id" ) );
2482		}
2483
2484		// Highlight active parent menu item, if any
2485		this.active
2486			.parent()
2487			.closest( ".ui-menu-item" )
2488			.addClass( "ui-state-active" );
2489
2490		if ( event && event.type === "keydown" ) {
2491			this._close();
2492		} else {
2493			this.timer = this._delay(function() {
2494				this._close();
2495			}, this.delay );
2496		}
2497
2498		nested = item.children( ".ui-menu" );
2499		if ( nested.length && event && ( /^mouse/.test( event.type ) ) ) {
2500			this._startOpening(nested);
2501		}
2502		this.activeMenu = item.parent();
2503
2504		this._trigger( "focus", event, { item: item } );
2505	},
2506
2507	_scrollIntoView: function( item ) {
2508		var borderTop, paddingTop, offset, scroll, elementHeight, itemHeight;
2509		if ( this._hasScroll() ) {
2510			borderTop = parseFloat( $.css( this.activeMenu[0], "borderTopWidth" ) ) || 0;
2511			paddingTop = parseFloat( $.css( this.activeMenu[0], "paddingTop" ) ) || 0;
2512			offset = item.offset().top - this.activeMenu.offset().top - borderTop - paddingTop;
2513			scroll = this.activeMenu.scrollTop();
2514			elementHeight = this.activeMenu.height();
2515			itemHeight = item.outerHeight();
2516
2517			if ( offset < 0 ) {
2518				this.activeMenu.scrollTop( scroll + offset );
2519			} else if ( offset + itemHeight > elementHeight ) {
2520				this.activeMenu.scrollTop( scroll + offset - elementHeight + itemHeight );
2521			}
2522		}
2523	},
2524
2525	blur: function( event, fromFocus ) {
2526		if ( !fromFocus ) {
2527			clearTimeout( this.timer );
2528		}
2529
2530		if ( !this.active ) {
2531			return;
2532		}
2533
2534		this.active.removeClass( "ui-state-focus" );
2535		this.active = null;
2536
2537		this._trigger( "blur", event, { item: this.active } );
2538	},
2539
2540	_startOpening: function( submenu ) {
2541		clearTimeout( this.timer );
2542
2543		// Don't open if already open fixes a Firefox bug that caused a .5 pixel
2544		// shift in the submenu position when mousing over the carat icon
2545		if ( submenu.attr( "aria-hidden" ) !== "true" ) {
2546			return;
2547		}
2548
2549		this.timer = this._delay(function() {
2550			this._close();
2551			this._open( submenu );
2552		}, this.delay );
2553	},
2554
2555	_open: function( submenu ) {
2556		var position = $.extend({
2557			of: this.active
2558		}, this.options.position );
2559
2560		clearTimeout( this.timer );
2561		this.element.find( ".ui-menu" ).not( submenu.parents( ".ui-menu" ) )
2562			.hide()
2563			.attr( "aria-hidden", "true" );
2564
2565		submenu
2566			.show()
2567			.removeAttr( "aria-hidden" )
2568			.attr( "aria-expanded", "true" )
2569			.position( position );
2570	},
2571
2572	collapseAll: function( event, all ) {
2573		clearTimeout( this.timer );
2574		this.timer = this._delay(function() {
vendor: 11,138 bytes, lines 2575-2991
2575			// If we were passed an event, look for the submenu that contains the event
2576			var currentMenu = all ? this.element :
2577				$( event && event.target ).closest( this.element.find( ".ui-menu" ) );
2578
2579			// If we found no valid submenu ancestor, use the main menu to close all sub menus anyway
2580			if ( !currentMenu.length ) {
2581				currentMenu = this.element;
2582			}
2583
2584			this._close( currentMenu );
2585
2586			this.blur( event );
2587			this.activeMenu = currentMenu;
2588		}, this.delay );
2589	},
2590
2591	// With no arguments, closes the currently active menu - if nothing is active
2592	// it closes all menus.  If passed an argument, it will search for menus BELOW
2593	_close: function( startMenu ) {
2594		if ( !startMenu ) {
2595			startMenu = this.active ? this.active.parent() : this.element;
2596		}
2597
2598		startMenu
2599			.find( ".ui-menu" )
2600				.hide()
2601				.attr( "aria-hidden", "true" )
2602				.attr( "aria-expanded", "false" )
2603			.end()
2604			.find( ".ui-state-active" ).not( ".ui-state-focus" )
2605				.removeClass( "ui-state-active" );
2606	},
2607
2608	_closeOnDocumentClick: function( event ) {
2609		return !$( event.target ).closest( ".ui-menu" ).length;
2610	},
2611
2612	_isDivider: function( item ) {
2613
2614		// Match hyphen, em dash, en dash
2615		return !/[^\-\u2014\u2013\s]/.test( item.text() );
2616	},
2617
2618	collapse: function( event ) {
2619		var newItem = this.active &&
2620			this.active.parent().closest( ".ui-menu-item", this.element );
2621		if ( newItem && newItem.length ) {
2622			this._close();
2623			this.focus( event, newItem );
2624		}
2625	},
2626
2627	expand: function( event ) {
2628		var newItem = this.active &&
2629			this.active
2630				.children( ".ui-menu " )
2631				.find( this.options.items )
2632				.first();
2633
2634		if ( newItem && newItem.length ) {
2635			this._open( newItem.parent() );
2636
2637			// Delay so Firefox will not hide activedescendant change in expanding submenu from AT
2638			this._delay(function() {
2639				this.focus( event, newItem );
2640			});
2641		}
2642	},
2643
2644	next: function( event ) {
2645		this._move( "next", "first", event );
2646	},
2647
2648	previous: function( event ) {
2649		this._move( "prev", "last", event );
2650	},
2651
2652	isFirstItem: function() {
2653		return this.active && !this.active.prevAll( ".ui-menu-item" ).length;
2654	},
2655
2656	isLastItem: function() {
2657		return this.active && !this.active.nextAll( ".ui-menu-item" ).length;
2658	},
2659
2660	_move: function( direction, filter, event ) {
2661		var next;
2662		if ( this.active ) {
2663			if ( direction === "first" || direction === "last" ) {
2664				next = this.active
2665					[ direction === "first" ? "prevAll" : "nextAll" ]( ".ui-menu-item" )
2666					.eq( -1 );
2667			} else {
2668				next = this.active
2669					[ direction + "All" ]( ".ui-menu-item" )
2670					.eq( 0 );
2671			}
2672		}
2673		if ( !next || !next.length || !this.active ) {
2674			next = this.activeMenu.find( this.options.items )[ filter ]();
2675		}
2676
2677		this.focus( event, next );
2678	},
2679
2680	nextPage: function( event ) {
2681		var item, base, height;
2682
2683		if ( !this.active ) {
2684			this.next( event );
2685			return;
2686		}
2687		if ( this.isLastItem() ) {
2688			return;
2689		}
2690		if ( this._hasScroll() ) {
2691			base = this.active.offset().top;
2692			height = this.element.height();
2693			this.active.nextAll( ".ui-menu-item" ).each(function() {
2694				item = $( this );
2695				return item.offset().top - base - height < 0;
2696			});
2697
2698			this.focus( event, item );
2699		} else {
2700			this.focus( event, this.activeMenu.find( this.options.items )
2701				[ !this.active ? "first" : "last" ]() );
2702		}
2703	},
2704
2705	previousPage: function( event ) {
2706		var item, base, height;
2707		if ( !this.active ) {
2708			this.next( event );
2709			return;
2710		}
2711		if ( this.isFirstItem() ) {
2712			return;
2713		}
2714		if ( this._hasScroll() ) {
2715			base = this.active.offset().top;
2716			height = this.element.height();
2717			this.active.prevAll( ".ui-menu-item" ).each(function() {
2718				item = $( this );
2719				return item.offset().top - base + height > 0;
2720			});
2721
2722			this.focus( event, item );
2723		} else {
2724			this.focus( event, this.activeMenu.find( this.options.items ).first() );
2725		}
2726	},
2727
2728	_hasScroll: function() {
2729		return this.element.outerHeight() < this.element.prop( "scrollHeight" );
2730	},
2731
2732	select: function( event ) {
2733		// TODO: It should never be possible to not have an active item at this
2734		// point, but the tests don't trigger mouseenter before click.
2735		this.active = this.active || $( event.target ).closest( ".ui-menu-item" );
2736		var ui = { item: this.active };
2737		if ( !this.active.has( ".ui-menu" ).length ) {
2738			this.collapseAll( event, true );
2739		}
2740		this._trigger( "select", event, ui );
2741	},
2742
2743	_filterMenuItems: function(character) {
2744		var escapedCharacter = character.replace( /[\-\[\]{}()*+?.,\\\^$|#\s]/g, "\\$&" ),
2745			regex = new RegExp( "^" + escapedCharacter, "i" );
2746
2747		return this.activeMenu
2748			.find( this.options.items )
2749
2750			// Only match on items, not dividers or other content (#10571)
2751			.filter( ".ui-menu-item" )
2752			.filter(function() {
2753				return regex.test( $.trim( $( this ).text() ) );
2754			});
2755	}
2756});
2757
2758
2759/*!
2760 * jQuery UI Autocomplete 1.11.4
2761 * http://jqueryui.com
2762 *
2763 * Copyright jQuery Foundation and other contributors
2764 * Released under the MIT license.
2765 * http://jquery.org/license
2766 *
2767 * http://api.jqueryui.com/autocomplete/
2768 */
2769
2770
2771$.widget( "ui.autocomplete", {
2772	version: "1.11.4",
2773	defaultElement: "<input>",
2774	options: {
2775		appendTo: null,
2776		autoFocus: false,
2777		delay: 300,
2778		minLength: 1,
2779		position: {
2780			my: "left top",
2781			at: "left bottom",
2782			collision: "none"
2783		},
2784		source: null,
2785
2786		// callbacks
2787		change: null,
2788		close: null,
2789		focus: null,
2790		open: null,
2791		response: null,
2792		search: null,
2793		select: null
2794	},
2795
2796	requestIndex: 0,
2797	pending: 0,
2798
2799	_create: function() {
2800		// Some browsers only repeat keydown events, not keypress events,
2801		// so we use the suppressKeyPress flag to determine if we've already
2802		// handled the keydown event. #7269
2803		// Unfortunately the code for & in keypress is the same as the up arrow,
2804		// so we use the suppressKeyPressRepeat flag to avoid handling keypress
2805		// events when we know the keydown event was used to modify the
2806		// search term. #7799
2807		var suppressKeyPress, suppressKeyPressRepeat, suppressInput,
2808			nodeName = this.element[ 0 ].nodeName.toLowerCase(),
2809			isTextarea = nodeName === "textarea",
2810			isInput = nodeName === "input";
2811
2812		this.isMultiLine =
2813			// Textareas are always multi-line
2814			isTextarea ? true :
2815			// Inputs are always single-line, even if inside a contentEditable element
2816			// IE also treats inputs as contentEditable
2817			isInput ? false :
2818			// All other element types are determined by whether or not they're contentEditable
2819			this.element.prop( "isContentEditable" );
2820
2821		this.valueMethod = this.element[ isTextarea || isInput ? "val" : "text" ];
2822		this.isNewMenu = true;
2823
2824		this.element
2825			.addClass( "ui-autocomplete-input" )
2826			.attr( "autocomplete", "off" );
2827
2828		this._on( this.element, {
2829			keydown: function( event ) {
2830				if ( this.element.prop( "readOnly" ) ) {
2831					suppressKeyPress = true;
2832					suppressInput = true;
2833					suppressKeyPressRepeat = true;
2834					return;
2835				}
2836
2837				suppressKeyPress = false;
2838				suppressInput = false;
2839				suppressKeyPressRepeat = false;
2840				var keyCode = $.ui.keyCode;
2841				switch ( event.keyCode ) {
2842				case keyCode.PAGE_UP:
2843					suppressKeyPress = true;
2844					this._move( "previousPage", event );
2845					break;
2846				case keyCode.PAGE_DOWN:
2847					suppressKeyPress = true;
2848					this._move( "nextPage", event );
2849					break;
2850				case keyCode.UP:
2851					suppressKeyPress = true;
2852					this._keyEvent( "previous", event );
2853					break;
2854				case keyCode.DOWN:
2855					suppressKeyPress = true;
2856					this._keyEvent( "next", event );
2857					break;
2858				case keyCode.ENTER:
2859					// when menu is open and has focus
2860					if ( this.menu.active ) {
2861						// #6055 - Opera still allows the keypress to occur
2862						// which causes forms to submit
2863						suppressKeyPress = true;
2864						event.preventDefault();
2865						this.menu.select( event );
2866					}
2867					break;
2868				case keyCode.TAB:
2869					if ( this.menu.active ) {
2870						this.menu.select( event );
2871					}
2872					break;
2873				case keyCode.ESCAPE:
2874					if ( this.menu.element.is( ":visible" ) ) {
2875						if ( !this.isMultiLine ) {
2876							this._value( this.term );
2877						}
2878						this.close( event );
2879						// Different browsers have different default behavior for escape
2880						// Single press can mean undo or clear
2881						// Double press in IE means clear the whole form
2882						event.preventDefault();
2883					}
2884					break;
2885				default:
2886					suppressKeyPressRepeat = true;
2887					// search timeout should be triggered before the input value is changed
2888					this._searchTimeout( event );
2889					break;
2890				}
2891			},
2892			keypress: function( event ) {
2893				if ( suppressKeyPress ) {
2894					suppressKeyPress = false;
2895					if ( !this.isMultiLine || this.menu.element.is( ":visible" ) ) {
2896						event.preventDefault();
2897					}
2898					return;
2899				}
2900				if ( suppressKeyPressRepeat ) {
2901					return;
2902				}
2903
2904				// replicate some key handlers to allow them to repeat in Firefox and Opera
2905				var keyCode = $.ui.keyCode;
2906				switch ( event.keyCode ) {
2907				case keyCode.PAGE_UP:
2908					this._move( "previousPage", event );
2909					break;
2910				case keyCode.PAGE_DOWN:
2911					this._move( "nextPage", event );
2912					break;
2913				case keyCode.UP:
2914					this._keyEvent( "previous", event );
2915					break;
2916				case keyCode.DOWN:
2917					this._keyEvent( "next", event );
2918					break;
2919				}
2920			},
2921			input: function( event ) {
2922				if ( suppressInput ) {
2923					suppressInput = false;
2924					event.preventDefault();
2925					return;
2926				}
2927				this._searchTimeout( event );
2928			},
2929			focus: function() {
2930				this.selectedItem = null;
2931				this.previous = this._value();
2932			},
2933			blur: function( event ) {
2934				if ( this.cancelBlur ) {
2935					delete this.cancelBlur;
2936					return;
2937				}
2938
2939				clearTimeout( this.searching );
2940				this.close( event );
2941				this._change( event );
2942			}
2943		});
2944
2945		this._initSource();
2946		this.menu = $( "<ul>" )
2947			.addClass( "ui-autocomplete ui-front" )
2948			.appendTo( this._appendTo() )
2949			.menu({
2950				// disable ARIA support, the live region takes care of that
2951				role: null
2952			})
2953			.hide()
2954			.menu( "instance" );
2955
2956		this._on( this.menu.element, {
2957			mousedown: function( event ) {
2958				// prevent moving focus out of the text field
2959				event.preventDefault();
2960
2961				// IE doesn't prevent moving focus even with event.preventDefault()
2962				// so we set a flag to know when we should ignore the blur event
2963				this.cancelBlur = true;
2964				this._delay(function() {
2965					delete this.cancelBlur;
2966				});
2967
2968				// clicking on the scrollbar causes focus to shift to the body
2969				// but we can't detect a mouseup or a click immediately afterward
2970				// so we have to track the next mousedown and close the menu if
2971				// the user clicks somewhere outside of the autocomplete
2972				var menuElement = this.menu.element[ 0 ];
2973				if ( !$( event.target ).closest( ".ui-menu-item" ).length ) {
2974					this._delay(function() {
2975						var that = this;
2976						this.document.one( "mousedown", function( event ) {
2977							if ( event.target !== that.element[ 0 ] &&
2978									event.target !== menuElement &&
2979									!$.contains( menuElement, event.target ) ) {
2980								that.close();
2981							}
2982						});
2983					});
2984				}
2985			},
2986			menufocus: function( event, ui ) {
2987				var label, item;
2988				// support: Firefox
2989				// Prevent accidental activation of menu items in Firefox (#7024 #9118)
2990				if ( this.isNewMenu ) {
2991					this.isNewMenu = false;
vendor: 4,086 bytes, lines 2992-3142
2992					if ( event.originalEvent && /^mouse/.test( event.originalEvent.type ) ) {
2993						this.menu.blur();
2994
2995						this.document.one( "mousemove", function() {
2996							$( event.target ).trigger( event.originalEvent );
2997						});
2998
2999						return;
3000					}
3001				}
3002
3003				item = ui.item.data( "ui-autocomplete-item" );
3004				if ( false !== this._trigger( "focus", event, { item: item } ) ) {
3005					// use value to match what will end up in the input, if it was a key event
3006					if ( event.originalEvent && /^key/.test( event.originalEvent.type ) ) {
3007						this._value( item.value );
3008					}
3009				}
3010
3011				// Announce the value in the liveRegion
3012				label = ui.item.attr( "aria-label" ) || item.value;
3013				if ( label && $.trim( label ).length ) {
3014					this.liveRegion.children().hide();
3015					$( "<div>" ).text( label ).appendTo( this.liveRegion );
3016				}
3017			},
3018			menuselect: function( event, ui ) {
3019				var item = ui.item.data( "ui-autocomplete-item" ),
3020					previous = this.previous;
3021
3022				// only trigger when focus was lost (click on menu)
3023				if ( this.element[ 0 ] !== this.document[ 0 ].activeElement ) {
3024					this.element.focus();
3025					this.previous = previous;
3026					// #6109 - IE triggers two focus events and the second
3027					// is asynchronous, so we need to reset the previous
3028					// term synchronously and asynchronously :-(
3029					this._delay(function() {
3030						this.previous = previous;
3031						this.selectedItem = item;
3032					});
3033				}
3034
3035				if ( false !== this._trigger( "select", event, { item: item } ) ) {
3036					this._value( item.value );
3037				}
3038				// reset the term after the select event
3039				// this allows custom select handling to work properly
3040				this.term = this._value();
3041
3042				this.close( event );
3043				this.selectedItem = item;
3044			}
3045		});
3046
3047		this.liveRegion = $( "<span>", {
3048				role: "status",
3049				"aria-live": "assertive",
3050				"aria-relevant": "additions"
3051			})
3052			.addClass( "ui-helper-hidden-accessible" )
3053			.appendTo( this.document[ 0 ].body );
3054
3055		// turning off autocomplete prevents the browser from remembering the
3056		// value when navigating through history, so we re-enable autocomplete
3057		// if the page is unloaded before the widget is destroyed. #7790
3058		this._on( this.window, {
3059			beforeunload: function() {
3060				this.element.removeAttr( "autocomplete" );
3061			}
3062		});
3063	},
3064
3065	_destroy: function() {
3066		clearTimeout( this.searching );
3067		this.element
3068			.removeClass( "ui-autocomplete-input" )
3069			.removeAttr( "autocomplete" );
3070		this.menu.element.remove();
3071		this.liveRegion.remove();
3072	},
3073
3074	_setOption: function( key, value ) {
3075		this._super( key, value );
3076		if ( key === "source" ) {
3077			this._initSource();
3078		}
3079		if ( key === "appendTo" ) {
3080			this.menu.element.appendTo( this._appendTo() );
3081		}
3082		if ( key === "disabled" && value && this.xhr ) {
3083			this.xhr.abort();
3084		}
3085	},
3086
3087	_appendTo: function() {
3088		var element = this.options.appendTo;
3089
3090		if ( element ) {
3091			element = element.jquery || element.nodeType ?
3092				$( element ) :
3093				this.document.find( element ).eq( 0 );
3094		}
3095
3096		if ( !element || !element[ 0 ] ) {
3097			element = this.element.closest( ".ui-front" );
3098		}
3099
3100		if ( !element.length ) {
3101			element = this.document[ 0 ].body;
3102		}
3103
3104		return element;
3105	},
3106
3107	_initSource: function() {
3108		var array, url,
3109			that = this;
3110		if ( $.isArray( this.options.source ) ) {
3111			array = this.options.source;
3112			this.source = function( request, response ) {
3113				response( $.ui.autocomplete.filter( array, request.term ) );
3114			};
3115		} else if ( typeof this.options.source === "string" ) {
3116			url = this.options.source;
3117			this.source = function( request, response ) {
3118				if ( that.xhr ) {
3119					that.xhr.abort();
3120				}
3121				that.xhr = $.ajax({
3122					url: url,
3123					data: request,
3124					dataType: "json",
3125					success: function( data ) {
3126						response( data );
3127					},
3128					error: function() {
3129						response([]);
3130					}
3131				});
3132			};
3133		} else {
3134			this.source = this.options.source;
3135		}
3136	},
3137
3138	_searchTimeout: function( event ) {
3139		clearTimeout( this.searching );
3140		this.searching = this._delay(function() {
3141
3142			// Search if the value has changed, or if the user retypes the same value (see #7434)
vendor: 8,850 bytes, lines 3143-3491
3143			var equalValues = this.term === this._value(),
3144				menuVisible = this.menu.element.is( ":visible" ),
3145				modifierKey = event.altKey || event.ctrlKey || event.metaKey || event.shiftKey;
3146
3147			if ( !equalValues || ( equalValues && !menuVisible && !modifierKey ) ) {
3148				this.selectedItem = null;
3149				this.search( null, event );
3150			}
3151		}, this.options.delay );
3152	},
3153
3154	search: function( value, event ) {
3155		value = value != null ? value : this._value();
3156
3157		// always save the actual value, not the one passed as an argument
3158		this.term = this._value();
3159
3160		if ( value.length < this.options.minLength ) {
3161			return this.close( event );
3162		}
3163
3164		if ( this._trigger( "search", event ) === false ) {
3165			return;
3166		}
3167
3168		return this._search( value );
3169	},
3170
3171	_search: function( value ) {
3172		this.pending++;
3173		this.element.addClass( "ui-autocomplete-loading" );
3174		this.cancelSearch = false;
3175
3176		this.source( { term: value }, this._response() );
3177	},
3178
3179	_response: function() {
3180		var index = ++this.requestIndex;
3181
3182		return $.proxy(function( content ) {
3183			if ( index === this.requestIndex ) {
3184				this.__response( content );
3185			}
3186
3187			this.pending--;
3188			if ( !this.pending ) {
3189				this.element.removeClass( "ui-autocomplete-loading" );
3190			}
3191		}, this );
3192	},
3193
3194	__response: function( content ) {
3195		if ( content ) {
3196			content = this._normalize( content );
3197		}
3198		this._trigger( "response", null, { content: content } );
3199		if ( !this.options.disabled && content && content.length && !this.cancelSearch ) {
3200			this._suggest( content );
3201			this._trigger( "open" );
3202		} else {
3203			// use ._close() instead of .close() so we don't cancel future searches
3204			this._close();
3205		}
3206	},
3207
3208	close: function( event ) {
3209		this.cancelSearch = true;
3210		this._close( event );
3211	},
3212
3213	_close: function( event ) {
3214		if ( this.menu.element.is( ":visible" ) ) {
3215			this.menu.element.hide();
3216			this.menu.blur();
3217			this.isNewMenu = true;
3218			this._trigger( "close", event );
3219		}
3220	},
3221
3222	_change: function( event ) {
3223		if ( this.previous !== this._value() ) {
3224			this._trigger( "change", event, { item: this.selectedItem } );
3225		}
3226	},
3227
3228	_normalize: function( items ) {
3229		// assume all items have the right format when the first item is complete
3230		if ( items.length && items[ 0 ].label && items[ 0 ].value ) {
3231			return items;
3232		}
3233		return $.map( items, function( item ) {
3234			if ( typeof item === "string" ) {
3235				return {
3236					label: item,
3237					value: item
3238				};
3239			}
3240			return $.extend( {}, item, {
3241				label: item.label || item.value,
3242				value: item.value || item.label
3243			});
3244		});
3245	},
3246
3247	_suggest: function( items ) {
3248		var ul = this.menu.element.empty();
3249		this._renderMenu( ul, items );
3250		this.isNewMenu = true;
3251		this.menu.refresh();
3252
3253		// size and position menu
3254		ul.show();
3255		this._resizeMenu();
3256		ul.position( $.extend({
3257			of: this.element
3258		}, this.options.position ) );
3259
3260		if ( this.options.autoFocus ) {
3261			this.menu.next();
3262		}
3263	},
3264
3265	_resizeMenu: function() {
3266		var ul = this.menu.element;
3267		ul.outerWidth( Math.max(
3268			// Firefox wraps long text (possibly a rounding bug)
3269			// so we add 1px to avoid the wrapping (#7513)
3270			ul.width( "" ).outerWidth() + 1,
3271			this.element.outerWidth()
3272		) );
3273	},
3274
3275	_renderMenu: function( ul, items ) {
3276		var that = this;
3277		$.each( items, function( index, item ) {
3278			that._renderItemData( ul, item );
3279		});
3280	},
3281
3282	_renderItemData: function( ul, item ) {
3283		return this._renderItem( ul, item ).data( "ui-autocomplete-item", item );
3284	},
3285
3286	_renderItem: function( ul, item ) {
3287		return $( "<li>" ).text( item.label ).appendTo( ul );
3288	},
3289
3290	_move: function( direction, event ) {
3291		if ( !this.menu.element.is( ":visible" ) ) {
3292			this.search( null, event );
3293			return;
3294		}
3295		if ( this.menu.isFirstItem() && /^previous/.test( direction ) ||
3296				this.menu.isLastItem() && /^next/.test( direction ) ) {
3297
3298			if ( !this.isMultiLine ) {
3299				this._value( this.term );
3300			}
3301
3302			this.menu.blur();
3303			return;
3304		}
3305		this.menu[ direction ]( event );
3306	},
3307
3308	widget: function() {
3309		return this.menu.element;
3310	},
3311
3312	_value: function() {
3313		return this.valueMethod.apply( this.element, arguments );
3314	},
3315
3316	_keyEvent: function( keyEvent, event ) {
3317		if ( !this.isMultiLine || this.menu.element.is( ":visible" ) ) {
3318			this._move( keyEvent, event );
3319
3320			// prevents moving cursor to beginning/end of the text field in some browsers
3321			event.preventDefault();
3322		}
3323	}
3324});
3325
3326$.extend( $.ui.autocomplete, {
3327	escapeRegex: function( value ) {
3328		return value.replace( /[\-\[\]{}()*+?.,\\\^$|#\s]/g, "\\$&" );
3329	},
3330	filter: function( array, term ) {
3331		var matcher = new RegExp( $.ui.autocomplete.escapeRegex( term ), "i" );
3332		return $.grep( array, function( value ) {
3333			return matcher.test( value.label || value.value || value );
3334		});
3335	}
3336});
3337
3338// live region extension, adding a `messages` option
3339// NOTE: This is an experimental API. We are still investigating
3340// a full solution for string manipulation and internationalization.
3341$.widget( "ui.autocomplete", $.ui.autocomplete, {
3342	options: {
3343		messages: {
3344			noResults: "No search results.",
3345			results: function( amount ) {
3346				return amount + ( amount > 1 ? " results are" : " result is" ) +
3347					" available, use up and down arrow keys to navigate.";
3348			}
3349		}
3350	},
3351
3352	__response: function( content ) {
3353		var message;
3354		this._superApply( arguments );
3355		if ( this.options.disabled || this.cancelSearch ) {
3356			return;
3357		}
3358		if ( content && content.length ) {
3359			message = this.options.messages.results( content.length );
3360		} else {
3361			message = this.options.messages.noResults;
3362		}
3363		this.liveRegion.children().hide();
3364		$( "<div>" ).text( message ).appendTo( this.liveRegion );
3365	}
3366});
3367
3368var autocomplete = $.ui.autocomplete;
3369
3370
3371/*!
3372 * jQuery UI Button 1.11.4
3373 * http://jqueryui.com
3374 *
3375 * Copyright jQuery Foundation and other contributors
3376 * Released under the MIT license.
3377 * http://jquery.org/license
3378 *
3379 * http://api.jqueryui.com/button/
3380 */
3381
3382
3383var lastActive,
3384	baseClasses = "ui-button ui-widget ui-state-default ui-corner-all",
3385	typeClasses = "ui-button-icons-only ui-button-icon-only ui-button-text-icons ui-button-text-icon-primary ui-button-text-icon-secondary ui-button-text-only",
3386	formResetHandler = function() {
3387		var form = $( this );
3388		setTimeout(function() {
3389			form.find( ":ui-button" ).button( "refresh" );
3390		}, 1 );
3391	},
3392	radioGroup = function( radio ) {
3393		var name = radio.name,
3394			form = radio.form,
3395			radios = $( [] );
3396		if ( name ) {
3397			name = name.replace( /'/g, "\\'" );
3398			if ( form ) {
3399				radios = $( form ).find( "[name='" + name + "'][type=radio]" );
3400			} else {
3401				radios = $( "[name='" + name + "'][type=radio]", radio.ownerDocument )
3402					.filter(function() {
3403						return !this.form;
3404					});
3405			}
3406		}
3407		return radios;
3408	};
3409
3410$.widget( "ui.button", {
3411	version: "1.11.4",
3412	defaultElement: "<button>",
3413	options: {
3414		disabled: null,
3415		text: true,
3416		label: null,
3417		icons: {
3418			primary: null,
3419			secondary: null
3420		}
3421	},
3422	_create: function() {
3423		this.element.closest( "form" )
3424			.unbind( "reset" + this.eventNamespace )
3425			.bind( "reset" + this.eventNamespace, formResetHandler );
3426
3427		if ( typeof this.options.disabled !== "boolean" ) {
3428			this.options.disabled = !!this.element.prop( "disabled" );
3429		} else {
3430			this.element.prop( "disabled", this.options.disabled );
3431		}
3432
3433		this._determineButtonType();
3434		this.hasTitle = !!this.buttonElement.attr( "title" );
3435
3436		var that = this,
3437			options = this.options,
3438			toggleButton = this.type === "checkbox" || this.type === "radio",
3439			activeClass = !toggleButton ? "ui-state-active" : "";
3440
3441		if ( options.label === null ) {
3442			options.label = (this.type === "input" ? this.buttonElement.val() : this.buttonElement.html());
3443		}
3444
3445		this._hoverable( this.buttonElement );
3446
3447		this.buttonElement
3448			.addClass( baseClasses )
3449			.attr( "role", "button" )
3450			.bind( "mouseenter" + this.eventNamespace, function() {
3451				if ( options.disabled ) {
3452					return;
3453				}
3454				if ( this === lastActive ) {
3455					$( this ).addClass( "ui-state-active" );
3456				}
3457			})
3458			.bind( "mouseleave" + this.eventNamespace, function() {
3459				if ( options.disabled ) {
3460					return;
3461				}
3462				$( this ).removeClass( activeClass );
3463			})
3464			.bind( "click" + this.eventNamespace, function( event ) {
3465				if ( options.disabled ) {
3466					event.preventDefault();
3467					event.stopImmediatePropagation();
3468				}
3469			});
3470
3471		// Can't use _focusable() because the element that receives focus
3472		// and the element that gets the ui-state-focus class are different
3473		this._on({
3474			focus: function() {
3475				this.buttonElement.addClass( "ui-state-focus" );
3476			},
3477			blur: function() {
3478				this.buttonElement.removeClass( "ui-state-focus" );
3479			}
3480		});
3481
3482		if ( toggleButton ) {
3483			this.element.bind( "change" + this.eventNamespace, function() {
3484				that.refresh();
3485			});
3486		}
3487
3488		if ( this.type === "checkbox" ) {
3489			this.buttonElement.bind( "click" + this.eventNamespace, function() {
3490				if ( options.disabled ) {
3491					return false;
vendor: 5,528 bytes, lines 3492-3676
3492				}
3493			});
3494		} else if ( this.type === "radio" ) {
3495			this.buttonElement.bind( "click" + this.eventNamespace, function() {
3496				if ( options.disabled ) {
3497					return false;
3498				}
3499				$( this ).addClass( "ui-state-active" );
3500				that.buttonElement.attr( "aria-pressed", "true" );
3501
3502				var radio = that.element[ 0 ];
3503				radioGroup( radio )
3504					.not( radio )
3505					.map(function() {
3506						return $( this ).button( "widget" )[ 0 ];
3507					})
3508					.removeClass( "ui-state-active" )
3509					.attr( "aria-pressed", "false" );
3510			});
3511		} else {
3512			this.buttonElement
3513				.bind( "mousedown" + this.eventNamespace, function() {
3514					if ( options.disabled ) {
3515						return false;
3516					}
3517					$( this ).addClass( "ui-state-active" );
3518					lastActive = this;
3519					that.document.one( "mouseup", function() {
3520						lastActive = null;
3521					});
3522				})
3523				.bind( "mouseup" + this.eventNamespace, function() {
3524					if ( options.disabled ) {
3525						return false;
3526					}
3527					$( this ).removeClass( "ui-state-active" );
3528				})
3529				.bind( "keydown" + this.eventNamespace, function(event) {
3530					if ( options.disabled ) {
3531						return false;
3532					}
3533					if ( event.keyCode === $.ui.keyCode.SPACE || event.keyCode === $.ui.keyCode.ENTER ) {
3534						$( this ).addClass( "ui-state-active" );
3535					}
3536				})
3537				// see #8559, we bind to blur here in case the button element loses
3538				// focus between keydown and keyup, it would be left in an "active" state
3539				.bind( "keyup" + this.eventNamespace + " blur" + this.eventNamespace, function() {
3540					$( this ).removeClass( "ui-state-active" );
3541				});
3542
3543			if ( this.buttonElement.is("a") ) {
3544				this.buttonElement.keyup(function(event) {
3545					if ( event.keyCode === $.ui.keyCode.SPACE ) {
3546						// TODO pass through original event correctly (just as 2nd argument doesn't work)
3547						$( this ).click();
3548					}
3549				});
3550			}
3551		}
3552
3553		this._setOption( "disabled", options.disabled );
3554		this._resetButton();
3555	},
3556
3557	_determineButtonType: function() {
3558		var ancestor, labelSelector, checked;
3559
3560		if ( this.element.is("[type=checkbox]") ) {
3561			this.type = "checkbox";
3562		} else if ( this.element.is("[type=radio]") ) {
3563			this.type = "radio";
3564		} else if ( this.element.is("input") ) {
3565			this.type = "input";
3566		} else {
3567			this.type = "button";
3568		}
3569
3570		if ( this.type === "checkbox" || this.type === "radio" ) {
3571			// we don't search against the document in case the element
3572			// is disconnected from the DOM
3573			ancestor = this.element.parents().last();
3574			labelSelector = "label[for='" + this.element.attr("id") + "']";
3575			this.buttonElement = ancestor.find( labelSelector );
3576			if ( !this.buttonElement.length ) {
3577				ancestor = ancestor.length ? ancestor.siblings() : this.element.siblings();
3578				this.buttonElement = ancestor.filter( labelSelector );
3579				if ( !this.buttonElement.length ) {
3580					this.buttonElement = ancestor.find( labelSelector );
3581				}
3582			}
3583			this.element.addClass( "ui-helper-hidden-accessible" );
3584
3585			checked = this.element.is( ":checked" );
3586			if ( checked ) {
3587				this.buttonElement.addClass( "ui-state-active" );
3588			}
3589			this.buttonElement.prop( "aria-pressed", checked );
3590		} else {
3591			this.buttonElement = this.element;
3592		}
3593	},
3594
3595	widget: function() {
3596		return this.buttonElement;
3597	},
3598
3599	_destroy: function() {
3600		this.element
3601			.removeClass( "ui-helper-hidden-accessible" );
3602		this.buttonElement
3603			.removeClass( baseClasses + " ui-state-active " + typeClasses )
3604			.removeAttr( "role" )
3605			.removeAttr( "aria-pressed" )
3606			.html( this.buttonElement.find(".ui-button-text").html() );
3607
3608		if ( !this.hasTitle ) {
3609			this.buttonElement.removeAttr( "title" );
3610		}
3611	},
3612
3613	_setOption: function( key, value ) {
3614		this._super( key, value );
3615		if ( key === "disabled" ) {
3616			this.widget().toggleClass( "ui-state-disabled", !!value );
3617			this.element.prop( "disabled", !!value );
3618			if ( value ) {
3619				if ( this.type === "checkbox" || this.type === "radio" ) {
3620					this.buttonElement.removeClass( "ui-state-focus" );
3621				} else {
3622					this.buttonElement.removeClass( "ui-state-focus ui-state-active" );
3623				}
3624			}
3625			return;
3626		}
3627		this._resetButton();
3628	},
3629
3630	refresh: function() {
3631		//See #8237 & #8828
3632		var isDisabled = this.element.is( "input, button" ) ? this.element.is( ":disabled" ) : this.element.hasClass( "ui-button-disabled" );
3633
3634		if ( isDisabled !== this.options.disabled ) {
3635			this._setOption( "disabled", isDisabled );
3636		}
3637		if ( this.type === "radio" ) {
3638			radioGroup( this.element[0] ).each(function() {
3639				if ( $( this ).is( ":checked" ) ) {
3640					$( this ).button( "widget" )
3641						.addClass( "ui-state-active" )
3642						.attr( "aria-pressed", "true" );
3643				} else {
3644					$( this ).button( "widget" )
3645						.removeClass( "ui-state-active" )
3646						.attr( "aria-pressed", "false" );
3647				}
3648			});
3649		} else if ( this.type === "checkbox" ) {
3650			if ( this.element.is( ":checked" ) ) {
3651				this.buttonElement
3652					.addClass( "ui-state-active" )
3653					.attr( "aria-pressed", "true" );
3654			} else {
3655				this.buttonElement
3656					.removeClass( "ui-state-active" )
3657					.attr( "aria-pressed", "false" );
3658			}
3659		}
3660	},
3661
3662	_resetButton: function() {
3663		if ( this.type === "input" ) {
3664			if ( this.options.label ) {
3665				this.element.val( this.options.label );
3666			}
3667			return;
3668		}
3669		var buttonElement = this.buttonElement.removeClass( typeClasses ),
3670			buttonText = $( "<span></span>", this.document[0] )
3671				.addClass( "ui-button-text" )
3672				.html( this.options.label )
3673				.appendTo( buttonElement.empty() )
3674				.text(),
3675			icons = this.options.icons,
3676			multipleIcons = icons.primary && icons.secondary,
vendor: 6,515 bytes, lines 3677-3847
3677			buttonClasses = [];
3678
3679		if ( icons.primary || icons.secondary ) {
3680			if ( this.options.text ) {
3681				buttonClasses.push( "ui-button-text-icon" + ( multipleIcons ? "s" : ( icons.primary ? "-primary" : "-secondary" ) ) );
3682			}
3683
3684			if ( icons.primary ) {
3685				buttonElement.prepend( "<span class='ui-button-icon-primary ui-icon " + icons.primary + "'></span>" );
3686			}
3687
3688			if ( icons.secondary ) {
3689				buttonElement.append( "<span class='ui-button-icon-secondary ui-icon " + icons.secondary + "'></span>" );
3690			}
3691
3692			if ( !this.options.text ) {
3693				buttonClasses.push( multipleIcons ? "ui-button-icons-only" : "ui-button-icon-only" );
3694
3695				if ( !this.hasTitle ) {
3696					buttonElement.attr( "title", $.trim( buttonText ) );
3697				}
3698			}
3699		} else {
3700			buttonClasses.push( "ui-button-text-only" );
3701		}
3702		buttonElement.addClass( buttonClasses.join( " " ) );
3703	}
3704});
3705
3706$.widget( "ui.buttonset", {
3707	version: "1.11.4",
3708	options: {
3709		items: "button, input[type=button], input[type=submit], input[type=reset], input[type=checkbox], input[type=radio], a, :data(ui-button)"
3710	},
3711
3712	_create: function() {
3713		this.element.addClass( "ui-buttonset" );
3714	},
3715
3716	_init: function() {
3717		this.refresh();
3718	},
3719
3720	_setOption: function( key, value ) {
3721		if ( key === "disabled" ) {
3722			this.buttons.button( "option", key, value );
3723		}
3724
3725		this._super( key, value );
3726	},
3727
3728	refresh: function() {
3729		var rtl = this.element.css( "direction" ) === "rtl",
3730			allButtons = this.element.find( this.options.items ),
3731			existingButtons = allButtons.filter( ":ui-button" );
3732
3733		// Initialize new buttons
3734		allButtons.not( ":ui-button" ).button();
3735
3736		// Refresh existing buttons
3737		existingButtons.button( "refresh" );
3738
3739		this.buttons = allButtons
3740			.map(function() {
3741				return $( this ).button( "widget" )[ 0 ];
3742			})
3743				.removeClass( "ui-corner-all ui-corner-left ui-corner-right" )
3744				.filter( ":first" )
3745					.addClass( rtl ? "ui-corner-right" : "ui-corner-left" )
3746				.end()
3747				.filter( ":last" )
3748					.addClass( rtl ? "ui-corner-left" : "ui-corner-right" )
3749				.end()
3750			.end();
3751	},
3752
3753	_destroy: function() {
3754		this.element.removeClass( "ui-buttonset" );
3755		this.buttons
3756			.map(function() {
3757				return $( this ).button( "widget" )[ 0 ];
3758			})
3759				.removeClass( "ui-corner-left ui-corner-right" )
3760			.end()
3761			.button( "destroy" );
3762	}
3763});
3764
3765var button = $.ui.button;
3766
3767
3768/*!
3769 * jQuery UI Datepicker 1.11.4
3770 * http://jqueryui.com
3771 *
3772 * Copyright jQuery Foundation and other contributors
3773 * Released under the MIT license.
3774 * http://jquery.org/license
3775 *
3776 * http://api.jqueryui.com/datepicker/
3777 */
3778
3779
3780$.extend($.ui, { datepicker: { version: "1.11.4" } });
3781
3782var datepicker_instActive;
3783
3784function datepicker_getZindex( elem ) {
3785	var position, value;
3786	while ( elem.length && elem[ 0 ] !== document ) {
3787		// Ignore z-index if position is set to a value where z-index is ignored by the browser
3788		// This makes behavior of this function consistent across browsers
3789		// WebKit always returns auto if the element is positioned
3790		position = elem.css( "position" );
3791		if ( position === "absolute" || position === "relative" || position === "fixed" ) {
3792			// IE returns 0 when zIndex is not specified
3793			// other browsers return a string
3794			// we ignore the case of nested elements with an explicit value of 0
3795			// <div style="z-index: -10;"><div style="z-index: 0;"></div></div>
3796			value = parseInt( elem.css( "zIndex" ), 10 );
3797			if ( !isNaN( value ) && value !== 0 ) {
3798				return value;
3799			}
3800		}
3801		elem = elem.parent();
3802	}
3803
3804	return 0;
3805}
3806/* Date picker manager.
3807   Use the singleton instance of this class, $.datepicker, to interact with the date picker.
3808   Settings for (groups of) date pickers are maintained in an instance object,
3809   allowing multiple different settings on the same page. */
3810
3811function Datepicker() {
3812	this._curInst = null; // The current instance in use
3813	this._keyEvent = false; // If the last event was a key event
3814	this._disabledInputs = []; // List of date picker inputs that have been disabled
3815	this._datepickerShowing = false; // True if the popup picker is showing , false if not
3816	this._inDialog = false; // True if showing within a "dialog", false if not
3817	this._mainDivId = "ui-datepicker-div"; // The ID of the main datepicker division
3818	this._inlineClass = "ui-datepicker-inline"; // The name of the inline marker class
3819	this._appendClass = "ui-datepicker-append"; // The name of the append marker class
3820	this._triggerClass = "ui-datepicker-trigger"; // The name of the trigger marker class
3821	this._dialogClass = "ui-datepicker-dialog"; // The name of the dialog marker class
3822	this._disableClass = "ui-datepicker-disabled"; // The name of the disabled covering marker class
3823	this._unselectableClass = "ui-datepicker-unselectable"; // The name of the unselectable cell marker class
3824	this._currentClass = "ui-datepicker-current-day"; // The name of the current day marker class
3825	this._dayOverClass = "ui-datepicker-days-cell-over"; // The name of the day hover marker class
3826	this.regional = []; // Available regional settings, indexed by language code
3827	this.regional[""] = { // Default regional settings
3828		closeText: "Done", // Display text for close link
3829		prevText: "Prev", // Display text for previous month link
3830		nextText: "Next", // Display text for next month link
3831		currentText: "Today", // Display text for current month link
3832		monthNames: ["January","February","March","April","May","June",
3833			"July","August","September","October","November","December"], // Names of months for drop-down and formatting
3834		monthNamesShort: ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"], // For formatting
3835		dayNames: ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"], // For formatting
3836		dayNamesShort: ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"], // For formatting
3837		dayNamesMin: ["Su","Mo","Tu","We","Th","Fr","Sa"], // Column headings for days starting at Sunday
3838		weekHeader: "Wk", // Column header for week of the year
3839		dateFormat: "mm/dd/yy", // See format options on parseDate
3840		firstDay: 0, // The first day of the week, Sun = 0, Mon = 1, ...
3841		isRTL: false, // True if right-to-left language, false if left-to-right
3842		showMonthAfterYear: false, // True if the year select precedes month, false for month then year
3843		yearSuffix: "" // Additional text to append to the year in the month headers
3844	};
3845	this._defaults = { // Global defaults for all the date picker instances
3846		showOn: "focus", // "focus" for popup on focus,
3847			// "button" for trigger button, or "both" for either
vendor: 73,430 bytes, lines 3848-5832
3848		showAnim: "fadeIn", // Name of jQuery animation for popup
3849		showOptions: {}, // Options for enhanced animations
3850		defaultDate: null, // Used when field is blank: actual date,
3851			// +/-number for offset from today, null for today
3852		appendText: "", // Display text following the input box, e.g. showing the format
3853		buttonText: "...", // Text for trigger button
3854		buttonImage: "", // URL for trigger button image
3855		buttonImageOnly: false, // True if the image appears alone, false if it appears on a button
3856		hideIfNoPrevNext: false, // True to hide next/previous month links
3857			// if not applicable, false to just disable them
3858		navigationAsDateFormat: false, // True if date formatting applied to prev/today/next links
3859		gotoCurrent: false, // True if today link goes back to current selection instead
3860		changeMonth: false, // True if month can be selected directly, false if only prev/next
3861		changeYear: false, // True if year can be selected directly, false if only prev/next
3862		yearRange: "c-10:c+10", // Range of years to display in drop-down,
3863			// either relative to today's year (-nn:+nn), relative to currently displayed year
3864			// (c-nn:c+nn), absolute (nnnn:nnnn), or a combination of the above (nnnn:-n)
3865		showOtherMonths: false, // True to show dates in other months, false to leave blank
3866		selectOtherMonths: false, // True to allow selection of dates in other months, false for unselectable
3867		showWeek: false, // True to show week of the year, false to not show it
3868		calculateWeek: this.iso8601Week, // How to calculate the week of the year,
3869			// takes a Date and returns the number of the week for it
3870		shortYearCutoff: "+10", // Short year values < this are in the current century,
3871			// > this are in the previous century,
3872			// string value starting with "+" for current year + value
3873		minDate: null, // The earliest selectable date, or null for no limit
3874		maxDate: null, // The latest selectable date, or null for no limit
3875		duration: "fast", // Duration of display/closure
3876		beforeShowDay: null, // Function that takes a date and returns an array with
3877			// [0] = true if selectable, false if not, [1] = custom CSS class name(s) or "",
3878			// [2] = cell title (optional), e.g. $.datepicker.noWeekends
3879		beforeShow: null, // Function that takes an input field and
3880			// returns a set of custom settings for the date picker
3881		onSelect: null, // Define a callback function when a date is selected
3882		onChangeMonthYear: null, // Define a callback function when the month or year is changed
3883		onClose: null, // Define a callback function when the datepicker is closed
3884		numberOfMonths: 1, // Number of months to show at a time
3885		showCurrentAtPos: 0, // The position in multipe months at which to show the current month (starting at 0)
3886		stepMonths: 1, // Number of months to step back/forward
3887		stepBigMonths: 12, // Number of months to step back/forward for the big links
3888		altField: "", // Selector for an alternate field to store selected dates into
3889		altFormat: "", // The date format to use for the alternate field
3890		constrainInput: true, // The input is constrained by the current date format
3891		showButtonPanel: false, // True to show button panel, false to not show it
3892		autoSize: false, // True to size the input for the date format, false to leave as is
3893		disabled: false // The initial disabled state
3894	};
3895	$.extend(this._defaults, this.regional[""]);
3896	this.regional.en = $.extend( true, {}, this.regional[ "" ]);
3897	this.regional[ "en-US" ] = $.extend( true, {}, this.regional.en );
3898	this.dpDiv = datepicker_bindHover($("<div id='" + this._mainDivId + "' class='ui-datepicker ui-widget ui-widget-content ui-helper-clearfix ui-corner-all'></div>"));
3899}
3900
3901$.extend(Datepicker.prototype, {
3902	/* Class name added to elements to indicate already configured with a date picker. */
3903	markerClassName: "hasDatepicker",
3904
3905	//Keep track of the maximum number of rows displayed (see #7043)
3906	maxRows: 4,
3907
3908	// TODO rename to "widget" when switching to widget factory
3909	_widgetDatepicker: function() {
3910		return this.dpDiv;
3911	},
3912
3913	/* Override the default settings for all instances of the date picker.
3914	 * @param  settings  object - the new settings to use as defaults (anonymous object)
3915	 * @return the manager object
3916	 */
3917	setDefaults: function(settings) {
3918		datepicker_extendRemove(this._defaults, settings || {});
3919		return this;
3920	},
3921
3922	/* Attach the date picker to a jQuery selection.
3923	 * @param  target	element - the target input field or division or span
3924	 * @param  settings  object - the new settings to use for this date picker instance (anonymous)
3925	 */
3926	_attachDatepicker: function(target, settings) {
3927		var nodeName, inline, inst;
3928		nodeName = target.nodeName.toLowerCase();
3929		inline = (nodeName === "div" || nodeName === "span");
3930		if (!target.id) {
3931			this.uuid += 1;
3932			target.id = "dp" + this.uuid;
3933		}
3934		inst = this._newInst($(target), inline);
3935		inst.settings = $.extend({}, settings || {});
3936		if (nodeName === "input") {
3937			this._connectDatepicker(target, inst);
3938		} else if (inline) {
3939			this._inlineDatepicker(target, inst);
3940		}
3941	},
3942
3943	/* Create a new instance object. */
3944	_newInst: function(target, inline) {
3945		var id = target[0].id.replace(/([^A-Za-z0-9_\-])/g, "\\\\$1"); // escape jQuery meta chars
3946		return {id: id, input: target, // associated target
3947			selectedDay: 0, selectedMonth: 0, selectedYear: 0, // current selection
3948			drawMonth: 0, drawYear: 0, // month being drawn
3949			inline: inline, // is datepicker inline or not
3950			dpDiv: (!inline ? this.dpDiv : // presentation div
3951			datepicker_bindHover($("<div class='" + this._inlineClass + " ui-datepicker ui-widget ui-widget-content ui-helper-clearfix ui-corner-all'></div>")))};
3952	},
3953
3954	/* Attach the date picker to an input field. */
3955	_connectDatepicker: function(target, inst) {
3956		var input = $(target);
3957		inst.append = $([]);
3958		inst.trigger = $([]);
3959		if (input.hasClass(this.markerClassName)) {
3960			return;
3961		}
3962		this._attachments(input, inst);
3963		input.addClass(this.markerClassName).keydown(this._doKeyDown).
3964			keypress(this._doKeyPress).keyup(this._doKeyUp);
3965		this._autoSize(inst);
3966		$.data(target, "datepicker", inst);
3967		//If disabled option is true, disable the datepicker once it has been attached to the input (see ticket #5665)
3968		if( inst.settings.disabled ) {
3969			this._disableDatepicker( target );
3970		}
3971	},
3972
3973	/* Make attachments based on settings. */
3974	_attachments: function(input, inst) {
3975		var showOn, buttonText, buttonImage,
3976			appendText = this._get(inst, "appendText"),
3977			isRTL = this._get(inst, "isRTL");
3978
3979		if (inst.append) {
3980			inst.append.remove();
3981		}
3982		if (appendText) {
3983			inst.append = $("<span class='" + this._appendClass + "'>" + appendText + "</span>");
3984			input[isRTL ? "before" : "after"](inst.append);
3985		}
3986
3987		input.unbind("focus", this._showDatepicker);
3988
3989		if (inst.trigger) {
3990			inst.trigger.remove();
3991		}
3992
3993		showOn = this._get(inst, "showOn");
3994		if (showOn === "focus" || showOn === "both") { // pop-up date picker when in the marked field
3995			input.focus(this._showDatepicker);
3996		}
3997		if (showOn === "button" || showOn === "both") { // pop-up date picker when button clicked
3998			buttonText = this._get(inst, "buttonText");
3999			buttonImage = this._get(inst, "buttonImage");
4000			inst.trigger = $(this._get(inst, "buttonImageOnly") ?
4001				$("<img/>").addClass(this._triggerClass).
4002					attr({ src: buttonImage, alt: buttonText, title: buttonText }) :
4003				$("<button type='button'></button>").addClass(this._triggerClass).
4004					html(!buttonImage ? buttonText : $("<img/>").attr(
4005					{ src:buttonImage, alt:buttonText, title:buttonText })));
4006			input[isRTL ? "before" : "after"](inst.trigger);
4007			inst.trigger.click(function() {
4008				if ($.datepicker._datepickerShowing && $.datepicker._lastInput === input[0]) {
4009					$.datepicker._hideDatepicker();
4010				} else if ($.datepicker._datepickerShowing && $.datepicker._lastInput !== input[0]) {
4011					$.datepicker._hideDatepicker();
4012					$.datepicker._showDatepicker(input[0]);
4013				} else {
4014					$.datepicker._showDatepicker(input[0]);
4015				}
4016				return false;
4017			});
4018		}
4019	},
4020
4021	/* Apply the maximum length for the date format. */
4022	_autoSize: function(inst) {
4023		if (this._get(inst, "autoSize") && !inst.inline) {
4024			var findMax, max, maxI, i,
4025				date = new Date(2009, 12 - 1, 20), // Ensure double digits
4026				dateFormat = this._get(inst, "dateFormat");
4027
4028			if (dateFormat.match(/[DM]/)) {
4029				findMax = function(names) {
4030					max = 0;
4031					maxI = 0;
4032					for (i = 0; i < names.length; i++) {
4033						if (names[i].length > max) {
4034							max = names[i].length;
4035							maxI = i;
4036						}
4037					}
4038					return maxI;
4039				};
4040				date.setMonth(findMax(this._get(inst, (dateFormat.match(/MM/) ?
4041					"monthNames" : "monthNamesShort"))));
4042				date.setDate(findMax(this._get(inst, (dateFormat.match(/DD/) ?
4043					"dayNames" : "dayNamesShort"))) + 20 - date.getDay());
4044			}
4045			inst.input.attr("size", this._formatDate(inst, date).length);
4046		}
4047	},
4048
4049	/* Attach an inline date picker to a div. */
4050	_inlineDatepicker: function(target, inst) {
4051		var divSpan = $(target);
4052		if (divSpan.hasClass(this.markerClassName)) {
4053			return;
4054		}
4055		divSpan.addClass(this.markerClassName).append(inst.dpDiv);
4056		$.data(target, "datepicker", inst);
4057		this._setDate(inst, this._getDefaultDate(inst), true);
4058		this._updateDatepicker(inst);
4059		this._updateAlternate(inst);
4060		//If disabled option is true, disable the datepicker before showing it (see ticket #5665)
4061		if( inst.settings.disabled ) {
4062			this._disableDatepicker( target );
4063		}
4064		// Set display:block in place of inst.dpDiv.show() which won't work on disconnected elements
4065		// http://bugs.jqueryui.com/ticket/7552 - A Datepicker created on a detached div has zero height
4066		inst.dpDiv.css( "display", "block" );
4067	},
4068
4069	/* Pop-up the date picker in a "dialog" box.
4070	 * @param  input element - ignored
4071	 * @param  date	string or Date - the initial date to display
4072	 * @param  onSelect  function - the function to call when a date is selected
4073	 * @param  settings  object - update the dialog date picker instance's settings (anonymous object)
4074	 * @param  pos int[2] - coordinates for the dialog's position within the screen or
4075	 *					event - with x/y coordinates or
4076	 *					leave empty for default (screen centre)
4077	 * @return the manager object
4078	 */
4079	_dialogDatepicker: function(input, date, onSelect, settings, pos) {
4080		var id, browserWidth, browserHeight, scrollX, scrollY,
4081			inst = this._dialogInst; // internal instance
4082
4083		if (!inst) {
4084			this.uuid += 1;
4085			id = "dp" + this.uuid;
4086			this._dialogInput = $("<input type='text' id='" + id +
4087				"' style='position: absolute; top: -100px; width: 0px;'/>");
4088			this._dialogInput.keydown(this._doKeyDown);
4089			$("body").append(this._dialogInput);
4090			inst = this._dialogInst = this._newInst(this._dialogInput, false);
4091			inst.settings = {};
4092			$.data(this._dialogInput[0], "datepicker", inst);
4093		}
4094		datepicker_extendRemove(inst.settings, settings || {});
4095		date = (date && date.constructor === Date ? this._formatDate(inst, date) : date);
4096		this._dialogInput.val(date);
4097
4098		this._pos = (pos ? (pos.length ? pos : [pos.pageX, pos.pageY]) : null);
4099		if (!this._pos) {
4100			browserWidth = document.documentElement.clientWidth;
4101			browserHeight = document.documentElement.clientHeight;
4102			scrollX = document.documentElement.scrollLeft || document.body.scrollLeft;
4103			scrollY = document.documentElement.scrollTop || document.body.scrollTop;
4104			this._pos = // should use actual width/height below
4105				[(browserWidth / 2) - 100 + scrollX, (browserHeight / 2) - 150 + scrollY];
4106		}
4107
4108		// move input on screen for focus, but hidden behind dialog
4109		this._dialogInput.css("left", (this._pos[0] + 20) + "px").css("top", this._pos[1] + "px");
4110		inst.settings.onSelect = onSelect;
4111		this._inDialog = true;
4112		this.dpDiv.addClass(this._dialogClass);
4113		this._showDatepicker(this._dialogInput[0]);
4114		if ($.blockUI) {
4115			$.blockUI(this.dpDiv);
4116		}
4117		$.data(this._dialogInput[0], "datepicker", inst);
4118		return this;
4119	},
4120
4121	/* Detach a datepicker from its control.
4122	 * @param  target	element - the target input field or division or span
4123	 */
4124	_destroyDatepicker: function(target) {
4125		var nodeName,
4126			$target = $(target),
4127			inst = $.data(target, "datepicker");
4128
4129		if (!$target.hasClass(this.markerClassName)) {
4130			return;
4131		}
4132
4133		nodeName = target.nodeName.toLowerCase();
4134		$.removeData(target, "datepicker");
4135		if (nodeName === "input") {
4136			inst.append.remove();
4137			inst.trigger.remove();
4138			$target.removeClass(this.markerClassName).
4139				unbind("focus", this._showDatepicker).
4140				unbind("keydown", this._doKeyDown).
4141				unbind("keypress", this._doKeyPress).
4142				unbind("keyup", this._doKeyUp);
4143		} else if (nodeName === "div" || nodeName === "span") {
4144			$target.removeClass(this.markerClassName).empty();
4145		}
4146
4147		if ( datepicker_instActive === inst ) {
4148			datepicker_instActive = null;
4149		}
4150	},
4151
4152	/* Enable the date picker to a jQuery selection.
4153	 * @param  target	element - the target input field or division or span
4154	 */
4155	_enableDatepicker: function(target) {
4156		var nodeName, inline,
4157			$target = $(target),
4158			inst = $.data(target, "datepicker");
4159
4160		if (!$target.hasClass(this.markerClassName)) {
4161			return;
4162		}
4163
4164		nodeName = target.nodeName.toLowerCase();
4165		if (nodeName === "input") {
4166			target.disabled = false;
4167			inst.trigger.filter("button").
4168				each(function() { this.disabled = false; }).end().
4169				filter("img").css({opacity: "1.0", cursor: ""});
4170		} else if (nodeName === "div" || nodeName === "span") {
4171			inline = $target.children("." + this._inlineClass);
4172			inline.children().removeClass("ui-state-disabled");
4173			inline.find("select.ui-datepicker-month, select.ui-datepicker-year").
4174				prop("disabled", false);
4175		}
4176		this._disabledInputs = $.map(this._disabledInputs,
4177			function(value) { return (value === target ? null : value); }); // delete entry
4178	},
4179
4180	/* Disable the date picker to a jQuery selection.
4181	 * @param  target	element - the target input field or division or span
4182	 */
4183	_disableDatepicker: function(target) {
4184		var nodeName, inline,
4185			$target = $(target),
4186			inst = $.data(target, "datepicker");
4187
4188		if (!$target.hasClass(this.markerClassName)) {
4189			return;
4190		}
4191
4192		nodeName = target.nodeName.toLowerCase();
4193		if (nodeName === "input") {
4194			target.disabled = true;
4195			inst.trigger.filter("button").
4196				each(function() { this.disabled = true; }).end().
4197				filter("img").css({opacity: "0.5", cursor: "default"});
4198		} else if (nodeName === "div" || nodeName === "span") {
4199			inline = $target.children("." + this._inlineClass);
4200			inline.children().addClass("ui-state-disabled");
4201			inline.find("select.ui-datepicker-month, select.ui-datepicker-year").
4202				prop("disabled", true);
4203		}
4204		this._disabledInputs = $.map(this._disabledInputs,
4205			function(value) { return (value === target ? null : value); }); // delete entry
4206		this._disabledInputs[this._disabledInputs.length] = target;
4207	},
4208
4209	/* Is the first field in a jQuery collection disabled as a datepicker?
4210	 * @param  target	element - the target input field or division or span
4211	 * @return boolean - true if disabled, false if enabled
4212	 */
4213	_isDisabledDatepicker: function(target) {
4214		if (!target) {
4215			return false;
4216		}
4217		for (var i = 0; i < this._disabledInputs.length; i++) {
4218			if (this._disabledInputs[i] === target) {
4219				return true;
4220			}
4221		}
4222		return false;
4223	},
4224
4225	/* Retrieve the instance data for the target control.
4226	 * @param  target  element - the target input field or division or span
4227	 * @return  object - the associated instance data
4228	 * @throws  error if a jQuery problem getting data
4229	 */
4230	_getInst: function(target) {
4231		try {
4232			return $.data(target, "datepicker");
4233		}
4234		catch (err) {
4235			throw "Missing instance data for this datepicker";
4236		}
4237	},
4238
4239	/* Update or retrieve the settings for a date picker attached to an input field or division.
4240	 * @param  target  element - the target input field or division or span
4241	 * @param  name	object - the new settings to update or
4242	 *				string - the name of the setting to change or retrieve,
4243	 *				when retrieving also "all" for all instance settings or
4244	 *				"defaults" for all global defaults
4245	 * @param  value   any - the new value for the setting
4246	 *				(omit if above is an object or to retrieve a value)
4247	 */
4248	_optionDatepicker: function(target, name, value) {
4249		var settings, date, minDate, maxDate,
4250			inst = this._getInst(target);
4251
4252		if (arguments.length === 2 && typeof name === "string") {
4253			return (name === "defaults" ? $.extend({}, $.datepicker._defaults) :
4254				(inst ? (name === "all" ? $.extend({}, inst.settings) :
4255				this._get(inst, name)) : null));
4256		}
4257
4258		settings = name || {};
4259		if (typeof name === "string") {
4260			settings = {};
4261			settings[name] = value;
4262		}
4263
4264		if (inst) {
4265			if (this._curInst === inst) {
4266				this._hideDatepicker();
4267			}
4268
4269			date = this._getDateDatepicker(target, true);
4270			minDate = this._getMinMaxDate(inst, "min");
4271			maxDate = this._getMinMaxDate(inst, "max");
4272			datepicker_extendRemove(inst.settings, settings);
4273			// reformat the old minDate/maxDate values if dateFormat changes and a new minDate/maxDate isn't provided
4274			if (minDate !== null && settings.dateFormat !== undefined && settings.minDate === undefined) {
4275				inst.settings.minDate = this._formatDate(inst, minDate);
4276			}
4277			if (maxDate !== null && settings.dateFormat !== undefined && settings.maxDate === undefined) {
4278				inst.settings.maxDate = this._formatDate(inst, maxDate);
4279			}
4280			if ( "disabled" in settings ) {
4281				if ( settings.disabled ) {
4282					this._disableDatepicker(target);
4283				} else {
4284					this._enableDatepicker(target);
4285				}
4286			}
4287			this._attachments($(target), inst);
4288			this._autoSize(inst);
4289			this._setDate(inst, date);
4290			this._updateAlternate(inst);
4291			this._updateDatepicker(inst);
4292		}
4293	},
4294
4295	// change method deprecated
4296	_changeDatepicker: function(target, name, value) {
4297		this._optionDatepicker(target, name, value);
4298	},
4299
4300	/* Redraw the date picker attached to an input field or division.
4301	 * @param  target  element - the target input field or division or span
4302	 */
4303	_refreshDatepicker: function(target) {
4304		var inst = this._getInst(target);
4305		if (inst) {
4306			this._updateDatepicker(inst);
4307		}
4308	},
4309
4310	/* Set the dates for a jQuery selection.
4311	 * @param  target element - the target input field or division or span
4312	 * @param  date	Date - the new date
4313	 */
4314	_setDateDatepicker: function(target, date) {
4315		var inst = this._getInst(target);
4316		if (inst) {
4317			this._setDate(inst, date);
4318			this._updateDatepicker(inst);
4319			this._updateAlternate(inst);
4320		}
4321	},
4322
4323	/* Get the date(s) for the first entry in a jQuery selection.
4324	 * @param  target element - the target input field or division or span
4325	 * @param  noDefault boolean - true if no default date is to be used
4326	 * @return Date - the current date
4327	 */
4328	_getDateDatepicker: function(target, noDefault) {
4329		var inst = this._getInst(target);
4330		if (inst && !inst.inline) {
4331			this._setDateFromField(inst, noDefault);
4332		}
4333		return (inst ? this._getDate(inst) : null);
4334	},
4335
4336	/* Handle keystrokes. */
4337	_doKeyDown: function(event) {
4338		var onSelect, dateStr, sel,
4339			inst = $.datepicker._getInst(event.target),
4340			handled = true,
4341			isRTL = inst.dpDiv.is(".ui-datepicker-rtl");
4342
4343		inst._keyEvent = true;
4344		if ($.datepicker._datepickerShowing) {
4345			switch (event.keyCode) {
4346				case 9: $.datepicker._hideDatepicker();
4347						handled = false;
4348						break; // hide on tab out
4349				case 13: sel = $("td." + $.datepicker._dayOverClass + ":not(." +
4350									$.datepicker._currentClass + ")", inst.dpDiv);
4351						if (sel[0]) {
4352							$.datepicker._selectDay(event.target, inst.selectedMonth, inst.selectedYear, sel[0]);
4353						}
4354
4355						onSelect = $.datepicker._get(inst, "onSelect");
4356						if (onSelect) {
4357							dateStr = $.datepicker._formatDate(inst);
4358
4359							// trigger custom callback
4360							onSelect.apply((inst.input ? inst.input[0] : null), [dateStr, inst]);
4361						} else {
4362							$.datepicker._hideDatepicker();
4363						}
4364
4365						return false; // don't submit the form
4366				case 27: $.datepicker._hideDatepicker();
4367						break; // hide on escape
4368				case 33: $.datepicker._adjustDate(event.target, (event.ctrlKey ?
4369							-$.datepicker._get(inst, "stepBigMonths") :
4370							-$.datepicker._get(inst, "stepMonths")), "M");
4371						break; // previous month/year on page up/+ ctrl
4372				case 34: $.datepicker._adjustDate(event.target, (event.ctrlKey ?
4373							+$.datepicker._get(inst, "stepBigMonths") :
4374							+$.datepicker._get(inst, "stepMonths")), "M");
4375						break; // next month/year on page down/+ ctrl
4376				case 35: if (event.ctrlKey || event.metaKey) {
4377							$.datepicker._clearDate(event.target);
4378						}
4379						handled = event.ctrlKey || event.metaKey;
4380						break; // clear on ctrl or command +end
4381				case 36: if (event.ctrlKey || event.metaKey) {
4382							$.datepicker._gotoToday(event.target);
4383						}
4384						handled = event.ctrlKey || event.metaKey;
4385						break; // current on ctrl or command +home
4386				case 37: if (event.ctrlKey || event.metaKey) {
4387							$.datepicker._adjustDate(event.target, (isRTL ? +1 : -1), "D");
4388						}
4389						handled = event.ctrlKey || event.metaKey;
4390						// -1 day on ctrl or command +left
4391						if (event.originalEvent.altKey) {
4392							$.datepicker._adjustDate(event.target, (event.ctrlKey ?
4393								-$.datepicker._get(inst, "stepBigMonths") :
4394								-$.datepicker._get(inst, "stepMonths")), "M");
4395						}
4396						// next month/year on alt +left on Mac
4397						break;
4398				case 38: if (event.ctrlKey || event.metaKey) {
4399							$.datepicker._adjustDate(event.target, -7, "D");
4400						}
4401						handled = event.ctrlKey || event.metaKey;
4402						break; // -1 week on ctrl or command +up
4403				case 39: if (event.ctrlKey || event.metaKey) {
4404							$.datepicker._adjustDate(event.target, (isRTL ? -1 : +1), "D");
4405						}
4406						handled = event.ctrlKey || event.metaKey;
4407						// +1 day on ctrl or command +right
4408						if (event.originalEvent.altKey) {
4409							$.datepicker._adjustDate(event.target, (event.ctrlKey ?
4410								+$.datepicker._get(inst, "stepBigMonths") :
4411								+$.datepicker._get(inst, "stepMonths")), "M");
4412						}
4413						// next month/year on alt +right
4414						break;
4415				case 40: if (event.ctrlKey || event.metaKey) {
4416							$.datepicker._adjustDate(event.target, +7, "D");
4417						}
4418						handled = event.ctrlKey || event.metaKey;
4419						break; // +1 week on ctrl or command +down
4420				default: handled = false;
4421			}
4422		} else if (event.keyCode === 36 && event.ctrlKey) { // display the date picker on ctrl+home
4423			$.datepicker._showDatepicker(this);
4424		} else {
4425			handled = false;
4426		}
4427
4428		if (handled) {
4429			event.preventDefault();
4430			event.stopPropagation();
4431		}
4432	},
4433
4434	/* Filter entered characters - based on date format. */
4435	_doKeyPress: function(event) {
4436		var chars, chr,
4437			inst = $.datepicker._getInst(event.target);
4438
4439		if ($.datepicker._get(inst, "constrainInput")) {
4440			chars = $.datepicker._possibleChars($.datepicker._get(inst, "dateFormat"));
4441			chr = String.fromCharCode(event.charCode == null ? event.keyCode : event.charCode);
4442			return event.ctrlKey || event.metaKey || (chr < " " || !chars || chars.indexOf(chr) > -1);
4443		}
4444	},
4445
4446	/* Synchronise manual entry and field/alternate field. */
4447	_doKeyUp: function(event) {
4448		var date,
4449			inst = $.datepicker._getInst(event.target);
4450
4451		if (inst.input.val() !== inst.lastVal) {
4452			try {
4453				date = $.datepicker.parseDate($.datepicker._get(inst, "dateFormat"),
4454					(inst.input ? inst.input.val() : null),
4455					$.datepicker._getFormatConfig(inst));
4456
4457				if (date) { // only if valid
4458					$.datepicker._setDateFromField(inst);
4459					$.datepicker._updateAlternate(inst);
4460					$.datepicker._updateDatepicker(inst);
4461				}
4462			}
4463			catch (err) {
4464			}
4465		}
4466		return true;
4467	},
4468
4469	/* Pop-up the date picker for a given input field.
4470	 * If false returned from beforeShow event handler do not show.
4471	 * @param  input  element - the input field attached to the date picker or
4472	 *					event - if triggered by focus
4473	 */
4474	_showDatepicker: function(input) {
4475		input = input.target || input;
4476		if (input.nodeName.toLowerCase() !== "input") { // find from button/image trigger
4477			input = $("input", input.parentNode)[0];
4478		}
4479
4480		if ($.datepicker._isDisabledDatepicker(input) || $.datepicker._lastInput === input) { // already here
4481			return;
4482		}
4483
4484		var inst, beforeShow, beforeShowSettings, isFixed,
4485			offset, showAnim, duration;
4486
4487		inst = $.datepicker._getInst(input);
4488		if ($.datepicker._curInst && $.datepicker._curInst !== inst) {
4489			$.datepicker._curInst.dpDiv.stop(true, true);
4490			if ( inst && $.datepicker._datepickerShowing ) {
4491				$.datepicker._hideDatepicker( $.datepicker._curInst.input[0] );
4492			}
4493		}
4494
4495		beforeShow = $.datepicker._get(inst, "beforeShow");
4496		beforeShowSettings = beforeShow ? beforeShow.apply(input, [input, inst]) : {};
4497		if(beforeShowSettings === false){
4498			return;
4499		}
4500		datepicker_extendRemove(inst.settings, beforeShowSettings);
4501
4502		inst.lastVal = null;
4503		$.datepicker._lastInput = input;
4504		$.datepicker._setDateFromField(inst);
4505
4506		if ($.datepicker._inDialog) { // hide cursor
4507			input.value = "";
4508		}
4509		if (!$.datepicker._pos) { // position below input
4510			$.datepicker._pos = $.datepicker._findPos(input);
4511			$.datepicker._pos[1] += input.offsetHeight; // add the height
4512		}
4513
4514		isFixed = false;
4515		$(input).parents().each(function() {
4516			isFixed |= $(this).css("position") === "fixed";
4517			return !isFixed;
4518		});
4519
4520		offset = {left: $.datepicker._pos[0], top: $.datepicker._pos[1]};
4521		$.datepicker._pos = null;
4522		//to avoid flashes on Firefox
4523		inst.dpDiv.empty();
4524		// determine sizing offscreen
4525		inst.dpDiv.css({position: "absolute", display: "block", top: "-1000px"});
4526		$.datepicker._updateDatepicker(inst);
4527		// fix width for dynamic number of date pickers
4528		// and adjust position before showing
4529		offset = $.datepicker._checkOffset(inst, offset, isFixed);
4530		inst.dpDiv.css({position: ($.datepicker._inDialog && $.blockUI ?
4531			"static" : (isFixed ? "fixed" : "absolute")), display: "none",
4532			left: offset.left + "px", top: offset.top + "px"});
4533
4534		if (!inst.inline) {
4535			showAnim = $.datepicker._get(inst, "showAnim");
4536			duration = $.datepicker._get(inst, "duration");
4537			inst.dpDiv.css( "z-index", datepicker_getZindex( $( input ) ) + 1 );
4538			$.datepicker._datepickerShowing = true;
4539
4540			if ( $.effects && $.effects.effect[ showAnim ] ) {
4541				inst.dpDiv.show(showAnim, $.datepicker._get(inst, "showOptions"), duration);
4542			} else {
4543				inst.dpDiv[showAnim || "show"](showAnim ? duration : null);
4544			}
4545
4546			if ( $.datepicker._shouldFocusInput( inst ) ) {
4547				inst.input.focus();
4548			}
4549
4550			$.datepicker._curInst = inst;
4551		}
4552	},
4553
4554	/* Generate the date picker content. */
4555	_updateDatepicker: function(inst) {
4556		this.maxRows = 4; //Reset the max number of rows being displayed (see #7043)
4557		datepicker_instActive = inst; // for delegate hover events
4558		inst.dpDiv.empty().append(this._generateHTML(inst));
4559		this._attachHandlers(inst);
4560
4561		var origyearshtml,
4562			numMonths = this._getNumberOfMonths(inst),
4563			cols = numMonths[1],
4564			width = 17,
4565			activeCell = inst.dpDiv.find( "." + this._dayOverClass + " a" );
4566
4567		if ( activeCell.length > 0 ) {
4568			datepicker_handleMouseover.apply( activeCell.get( 0 ) );
4569		}
4570
4571		inst.dpDiv.removeClass("ui-datepicker-multi-2 ui-datepicker-multi-3 ui-datepicker-multi-4").width("");
4572		if (cols > 1) {
4573			inst.dpDiv.addClass("ui-datepicker-multi-" + cols).css("width", (width * cols) + "em");
4574		}
4575		inst.dpDiv[(numMonths[0] !== 1 || numMonths[1] !== 1 ? "add" : "remove") +
4576			"Class"]("ui-datepicker-multi");
4577		inst.dpDiv[(this._get(inst, "isRTL") ? "add" : "remove") +
4578			"Class"]("ui-datepicker-rtl");
4579
4580		if (inst === $.datepicker._curInst && $.datepicker._datepickerShowing && $.datepicker._shouldFocusInput( inst ) ) {
4581			inst.input.focus();
4582		}
4583
4584		// deffered render of the years select (to avoid flashes on Firefox)
4585		if( inst.yearshtml ){
4586			origyearshtml = inst.yearshtml;
4587			setTimeout(function(){
4588				//assure that inst.yearshtml didn't change.
4589				if( origyearshtml === inst.yearshtml && inst.yearshtml ){
4590					inst.dpDiv.find("select.ui-datepicker-year:first").replaceWith(inst.yearshtml);
4591				}
4592				origyearshtml = inst.yearshtml = null;
4593			}, 0);
4594		}
4595	},
4596
4597	// #6694 - don't focus the input if it's already focused
4598	// this breaks the change event in IE
4599	// Support: IE and jQuery <1.9
4600	_shouldFocusInput: function( inst ) {
4601		return inst.input && inst.input.is( ":visible" ) && !inst.input.is( ":disabled" ) && !inst.input.is( ":focus" );
4602	},
4603
4604	/* Check positioning to remain on screen. */
4605	_checkOffset: function(inst, offset, isFixed) {
4606		var dpWidth = inst.dpDiv.outerWidth(),
4607			dpHeight = inst.dpDiv.outerHeight(),
4608			inputWidth = inst.input ? inst.input.outerWidth() : 0,
4609			inputHeight = inst.input ? inst.input.outerHeight() : 0,
4610			viewWidth = document.documentElement.clientWidth + (isFixed ? 0 : $(document).scrollLeft()),
4611			viewHeight = document.documentElement.clientHeight + (isFixed ? 0 : $(document).scrollTop());
4612
4613		offset.left -= (this._get(inst, "isRTL") ? (dpWidth - inputWidth) : 0);
4614		offset.left -= (isFixed && offset.left === inst.input.offset().left) ? $(document).scrollLeft() : 0;
4615		offset.top -= (isFixed && offset.top === (inst.input.offset().top + inputHeight)) ? $(document).scrollTop() : 0;
4616
4617		// now check if datepicker is showing outside window viewport - move to a better place if so.
4618		offset.left -= Math.min(offset.left, (offset.left + dpWidth > viewWidth && viewWidth > dpWidth) ?
4619			Math.abs(offset.left + dpWidth - viewWidth) : 0);
4620		offset.top -= Math.min(offset.top, (offset.top + dpHeight > viewHeight && viewHeight > dpHeight) ?
4621			Math.abs(dpHeight + inputHeight) : 0);
4622
4623		return offset;
4624	},
4625
4626	/* Find an object's position on the screen. */
4627	_findPos: function(obj) {
4628		var position,
4629			inst = this._getInst(obj),
4630			isRTL = this._get(inst, "isRTL");
4631
4632		while (obj && (obj.type === "hidden" || obj.nodeType !== 1 || $.expr.filters.hidden(obj))) {
4633			obj = obj[isRTL ? "previousSibling" : "nextSibling"];
4634		}
4635
4636		position = $(obj).offset();
4637		return [position.left, position.top];
4638	},
4639
4640	/* Hide the date picker from view.
4641	 * @param  input  element - the input field attached to the date picker
4642	 */
4643	_hideDatepicker: function(input) {
4644		var showAnim, duration, postProcess, onClose,
4645			inst = this._curInst;
4646
4647		if (!inst || (input && inst !== $.data(input, "datepicker"))) {
4648			return;
4649		}
4650
4651		if (this._datepickerShowing) {
4652			showAnim = this._get(inst, "showAnim");
4653			duration = this._get(inst, "duration");
4654			postProcess = function() {
4655				$.datepicker._tidyDialog(inst);
4656			};
4657
4658			// DEPRECATED: after BC for 1.8.x $.effects[ showAnim ] is not needed
4659			if ( $.effects && ( $.effects.effect[ showAnim ] || $.effects[ showAnim ] ) ) {
4660				inst.dpDiv.hide(showAnim, $.datepicker._get(inst, "showOptions"), duration, postProcess);
4661			} else {
4662				inst.dpDiv[(showAnim === "slideDown" ? "slideUp" :
4663					(showAnim === "fadeIn" ? "fadeOut" : "hide"))]((showAnim ? duration : null), postProcess);
4664			}
4665
4666			if (!showAnim) {
4667				postProcess();
4668			}
4669			this._datepickerShowing = false;
4670
4671			onClose = this._get(inst, "onClose");
4672			if (onClose) {
4673				onClose.apply((inst.input ? inst.input[0] : null), [(inst.input ? inst.input.val() : ""), inst]);
4674			}
4675
4676			this._lastInput = null;
4677			if (this._inDialog) {
4678				this._dialogInput.css({ position: "absolute", left: "0", top: "-100px" });
4679				if ($.blockUI) {
4680					$.unblockUI();
4681					$("body").append(this.dpDiv);
4682				}
4683			}
4684			this._inDialog = false;
4685		}
4686	},
4687
4688	/* Tidy up after a dialog display. */
4689	_tidyDialog: function(inst) {
4690		inst.dpDiv.removeClass(this._dialogClass).unbind(".ui-datepicker-calendar");
4691	},
4692
4693	/* Close date picker if clicked elsewhere. */
4694	_checkExternalClick: function(event) {
4695		if (!$.datepicker._curInst) {
4696			return;
4697		}
4698
4699		var $target = $(event.target),
4700			inst = $.datepicker._getInst($target[0]);
4701
4702		if ( ( ( $target[0].id !== $.datepicker._mainDivId &&
4703				$target.parents("#" + $.datepicker._mainDivId).length === 0 &&
4704				!$target.hasClass($.datepicker.markerClassName) &&
4705				!$target.closest("." + $.datepicker._triggerClass).length &&
4706				$.datepicker._datepickerShowing && !($.datepicker._inDialog && $.blockUI) ) ) ||
4707			( $target.hasClass($.datepicker.markerClassName) && $.datepicker._curInst !== inst ) ) {
4708				$.datepicker._hideDatepicker();
4709		}
4710	},
4711
4712	/* Adjust one of the date sub-fields. */
4713	_adjustDate: function(id, offset, period) {
4714		var target = $(id),
4715			inst = this._getInst(target[0]);
4716
4717		if (this._isDisabledDatepicker(target[0])) {
4718			return;
4719		}
4720		this._adjustInstDate(inst, offset +
4721			(period === "M" ? this._get(inst, "showCurrentAtPos") : 0), // undo positioning
4722			period);
4723		this._updateDatepicker(inst);
4724	},
4725
4726	/* Action for current link. */
4727	_gotoToday: function(id) {
4728		var date,
4729			target = $(id),
4730			inst = this._getInst(target[0]);
4731
4732		if (this._get(inst, "gotoCurrent") && inst.currentDay) {
4733			inst.selectedDay = inst.currentDay;
4734			inst.drawMonth = inst.selectedMonth = inst.currentMonth;
4735			inst.drawYear = inst.selectedYear = inst.currentYear;
4736		} else {
4737			date = new Date();
4738			inst.selectedDay = date.getDate();
4739			inst.drawMonth = inst.selectedMonth = date.getMonth();
4740			inst.drawYear = inst.selectedYear = date.getFullYear();
4741		}
4742		this._notifyChange(inst);
4743		this._adjustDate(target);
4744	},
4745
4746	/* Action for selecting a new month/year. */
4747	_selectMonthYear: function(id, select, period) {
4748		var target = $(id),
4749			inst = this._getInst(target[0]);
4750
4751		inst["selected" + (period === "M" ? "Month" : "Year")] =
4752		inst["draw" + (period === "M" ? "Month" : "Year")] =
4753			parseInt(select.options[select.selectedIndex].value,10);
4754
4755		this._notifyChange(inst);
4756		this._adjustDate(target);
4757	},
4758
4759	/* Action for selecting a day. */
4760	_selectDay: function(id, month, year, td) {
4761		var inst,
4762			target = $(id);
4763
4764		if ($(td).hasClass(this._unselectableClass) || this._isDisabledDatepicker(target[0])) {
4765			return;
4766		}
4767
4768		inst = this._getInst(target[0]);
4769		inst.selectedDay = inst.currentDay = $("a", td).html();
4770		inst.selectedMonth = inst.currentMonth = month;
4771		inst.selectedYear = inst.currentYear = year;
4772		this._selectDate(id, this._formatDate(inst,
4773			inst.currentDay, inst.currentMonth, inst.currentYear));
4774	},
4775
4776	/* Erase the input field and hide the date picker. */
4777	_clearDate: function(id) {
4778		var target = $(id);
4779		this._selectDate(target, "");
4780	},
4781
4782	/* Update the input field with the selected date. */
4783	_selectDate: function(id, dateStr) {
4784		var onSelect,
4785			target = $(id),
4786			inst = this._getInst(target[0]);
4787
4788		dateStr = (dateStr != null ? dateStr : this._formatDate(inst));
4789		if (inst.input) {
4790			inst.input.val(dateStr);
4791		}
4792		this._updateAlternate(inst);
4793
4794		onSelect = this._get(inst, "onSelect");
4795		if (onSelect) {
4796			onSelect.apply((inst.input ? inst.input[0] : null), [dateStr, inst]);  // trigger custom callback
4797		} else if (inst.input) {
4798			inst.input.trigger("change"); // fire the change event
4799		}
4800
4801		if (inst.inline){
4802			this._updateDatepicker(inst);
4803		} else {
4804			this._hideDatepicker();
4805			this._lastInput = inst.input[0];
4806			if (typeof(inst.input[0]) !== "object") {
4807				inst.input.focus(); // restore focus
4808			}
4809			this._lastInput = null;
4810		}
4811	},
4812
4813	/* Update any alternate field to synchronise with the main field. */
4814	_updateAlternate: function(inst) {
4815		var altFormat, date, dateStr,
4816			altField = this._get(inst, "altField");
4817
4818		if (altField) { // update alternate field too
4819			altFormat = this._get(inst, "altFormat") || this._get(inst, "dateFormat");
4820			date = this._getDate(inst);
4821			dateStr = this.formatDate(altFormat, date, this._getFormatConfig(inst));
4822			$(altField).each(function() { $(this).val(dateStr); });
4823		}
4824	},
4825
4826	/* Set as beforeShowDay function to prevent selection of weekends.
4827	 * @param  date  Date - the date to customise
4828	 * @return [boolean, string] - is this date selectable?, what is its CSS class?
4829	 */
4830	noWeekends: function(date) {
4831		var day = date.getDay();
4832		return [(day > 0 && day < 6), ""];
4833	},
4834
4835	/* Set as calculateWeek to determine the week of the year based on the ISO 8601 definition.
4836	 * @param  date  Date - the date to get the week for
4837	 * @return  number - the number of the week within the year that contains this date
4838	 */
4839	iso8601Week: function(date) {
4840		var time,
4841			checkDate = new Date(date.getTime());
4842
4843		// Find Thursday of this week starting on Monday
4844		checkDate.setDate(checkDate.getDate() + 4 - (checkDate.getDay() || 7));
4845
4846		time = checkDate.getTime();
4847		checkDate.setMonth(0); // Compare with Jan 1
4848		checkDate.setDate(1);
4849		return Math.floor(Math.round((time - checkDate) / 86400000) / 7) + 1;
4850	},
4851
4852	/* Parse a string value into a date object.
4853	 * See formatDate below for the possible formats.
4854	 *
4855	 * @param  format string - the expected format of the date
4856	 * @param  value string - the date in the above format
4857	 * @param  settings Object - attributes include:
4858	 *					shortYearCutoff  number - the cutoff year for determining the century (optional)
4859	 *					dayNamesShort	string[7] - abbreviated names of the days from Sunday (optional)
4860	 *					dayNames		string[7] - names of the days from Sunday (optional)
4861	 *					monthNamesShort string[12] - abbreviated names of the months (optional)
4862	 *					monthNames		string[12] - names of the months (optional)
4863	 * @return  Date - the extracted date value or null if value is blank
4864	 */
4865	parseDate: function (format, value, settings) {
4866		if (format == null || value == null) {
4867			throw "Invalid arguments";
4868		}
4869
4870		value = (typeof value === "object" ? value.toString() : value + "");
4871		if (value === "") {
4872			return null;
4873		}
4874
4875		var iFormat, dim, extra,
4876			iValue = 0,
4877			shortYearCutoffTemp = (settings ? settings.shortYearCutoff : null) || this._defaults.shortYearCutoff,
4878			shortYearCutoff = (typeof shortYearCutoffTemp !== "string" ? shortYearCutoffTemp :
4879				new Date().getFullYear() % 100 + parseInt(shortYearCutoffTemp, 10)),
4880			dayNamesShort = (settings ? settings.dayNamesShort : null) || this._defaults.dayNamesShort,
4881			dayNames = (settings ? settings.dayNames : null) || this._defaults.dayNames,
4882			monthNamesShort = (settings ? settings.monthNamesShort : null) || this._defaults.monthNamesShort,
4883			monthNames = (settings ? settings.monthNames : null) || this._defaults.monthNames,
4884			year = -1,
4885			month = -1,
4886			day = -1,
4887			doy = -1,
4888			literal = false,
4889			date,
4890			// Check whether a format character is doubled
4891			lookAhead = function(match) {
4892				var matches = (iFormat + 1 < format.length && format.charAt(iFormat + 1) === match);
4893				if (matches) {
4894					iFormat++;
4895				}
4896				return matches;
4897			},
4898			// Extract a number from the string value
4899			getNumber = function(match) {
4900				var isDoubled = lookAhead(match),
4901					size = (match === "@" ? 14 : (match === "!" ? 20 :
4902					(match === "y" && isDoubled ? 4 : (match === "o" ? 3 : 2)))),
4903					minSize = (match === "y" ? size : 1),
4904					digits = new RegExp("^\\d{" + minSize + "," + size + "}"),
4905					num = value.substring(iValue).match(digits);
4906				if (!num) {
4907					throw "Missing number at position " + iValue;
4908				}
4909				iValue += num[0].length;
4910				return parseInt(num[0], 10);
4911			},
4912			// Extract a name from the string value and convert to an index
4913			getName = function(match, shortNames, longNames) {
4914				var index = -1,
4915					names = $.map(lookAhead(match) ? longNames : shortNames, function (v, k) {
4916						return [ [k, v] ];
4917					}).sort(function (a, b) {
4918						return -(a[1].length - b[1].length);
4919					});
4920
4921				$.each(names, function (i, pair) {
4922					var name = pair[1];
4923					if (value.substr(iValue, name.length).toLowerCase() === name.toLowerCase()) {
4924						index = pair[0];
4925						iValue += name.length;
4926						return false;
4927					}
4928				});
4929				if (index !== -1) {
4930					return index + 1;
4931				} else {
4932					throw "Unknown name at position " + iValue;
4933				}
4934			},
4935			// Confirm that a literal character matches the string value
4936			checkLiteral = function() {
4937				if (value.charAt(iValue) !== format.charAt(iFormat)) {
4938					throw "Unexpected literal at position " + iValue;
4939				}
4940				iValue++;
4941			};
4942
4943		for (iFormat = 0; iFormat < format.length; iFormat++) {
4944			if (literal) {
4945				if (format.charAt(iFormat) === "'" && !lookAhead("'")) {
4946					literal = false;
4947				} else {
4948					checkLiteral();
4949				}
4950			} else {
4951				switch (format.charAt(iFormat)) {
4952					case "d":
4953						day = getNumber("d");
4954						break;
4955					case "D":
4956						getName("D", dayNamesShort, dayNames);
4957						break;
4958					case "o":
4959						doy = getNumber("o");
4960						break;
4961					case "m":
4962						month = getNumber("m");
4963						break;
4964					case "M":
4965						month = getName("M", monthNamesShort, monthNames);
4966						break;
4967					case "y":
4968						year = getNumber("y");
4969						break;
4970					case "@":
4971						date = new Date(getNumber("@"));
4972						year = date.getFullYear();
4973						month = date.getMonth() + 1;
4974						day = date.getDate();
4975						break;
4976					case "!":
4977						date = new Date((getNumber("!") - this._ticksTo1970) / 10000);
4978						year = date.getFullYear();
4979						month = date.getMonth() + 1;
4980						day = date.getDate();
4981						break;
4982					case "'":
4983						if (lookAhead("'")){
4984							checkLiteral();
4985						} else {
4986							literal = true;
4987						}
4988						break;
4989					default:
4990						checkLiteral();
4991				}
4992			}
4993		}
4994
4995		if (iValue < value.length){
4996			extra = value.substr(iValue);
4997			if (!/^\s+/.test(extra)) {
4998				throw "Extra/unparsed characters found in date: " + extra;
4999			}
5000		}
5001
5002		if (year === -1) {
5003			year = new Date().getFullYear();
5004		} else if (year < 100) {
5005			year += new Date().getFullYear() - new Date().getFullYear() % 100 +
5006				(year <= shortYearCutoff ? 0 : -100);
5007		}
5008
5009		if (doy > -1) {
5010			month = 1;
5011			day = doy;
5012			do {
5013				dim = this._getDaysInMonth(year, month - 1);
5014				if (day <= dim) {
5015					break;
5016				}
5017				month++;
5018				day -= dim;
5019			} while (true);
5020		}
5021
5022		date = this._daylightSavingAdjust(new Date(year, month - 1, day));
5023		if (date.getFullYear() !== year || date.getMonth() + 1 !== month || date.getDate() !== day) {
5024			throw "Invalid date"; // E.g. 31/02/00
5025		}
5026		return date;
5027	},
5028
5029	/* Standard date formats. */
5030	ATOM: "yy-mm-dd", // RFC 3339 (ISO 8601)
5031	COOKIE: "D, dd M yy",
5032	ISO_8601: "yy-mm-dd",
5033	RFC_822: "D, d M y",
5034	RFC_850: "DD, dd-M-y",
5035	RFC_1036: "D, d M y",
5036	RFC_1123: "D, d M yy",
5037	RFC_2822: "D, d M yy",
5038	RSS: "D, d M y", // RFC 822
5039	TICKS: "!",
5040	TIMESTAMP: "@",
5041	W3C: "yy-mm-dd", // ISO 8601
5042
5043	_ticksTo1970: (((1970 - 1) * 365 + Math.floor(1970 / 4) - Math.floor(1970 / 100) +
5044		Math.floor(1970 / 400)) * 24 * 60 * 60 * 10000000),
5045
5046	/* Format a date object into a string value.
5047	 * The format can be combinations of the following:
5048	 * d  - day of month (no leading zero)
5049	 * dd - day of month (two digit)
5050	 * o  - day of year (no leading zeros)
5051	 * oo - day of year (three digit)
5052	 * D  - day name short
5053	 * DD - day name long
5054	 * m  - month of year (no leading zero)
5055	 * mm - month of year (two digit)
5056	 * M  - month name short
5057	 * MM - month name long
5058	 * y  - year (two digit)
5059	 * yy - year (four digit)
5060	 * @ - Unix timestamp (ms since 01/01/1970)
5061	 * ! - Windows ticks (100ns since 01/01/0001)
5062	 * "..." - literal text
5063	 * '' - single quote
5064	 *
5065	 * @param  format string - the desired format of the date
5066	 * @param  date Date - the date value to format
5067	 * @param  settings Object - attributes include:
5068	 *					dayNamesShort	string[7] - abbreviated names of the days from Sunday (optional)
5069	 *					dayNames		string[7] - names of the days from Sunday (optional)
5070	 *					monthNamesShort string[12] - abbreviated names of the months (optional)
5071	 *					monthNames		string[12] - names of the months (optional)
5072	 * @return  string - the date in the above format
5073	 */
5074	formatDate: function (format, date, settings) {
5075		if (!date) {
5076			return "";
5077		}
5078
5079		var iFormat,
5080			dayNamesShort = (settings ? settings.dayNamesShort : null) || this._defaults.dayNamesShort,
5081			dayNames = (settings ? settings.dayNames : null) || this._defaults.dayNames,
5082			monthNamesShort = (settings ? settings.monthNamesShort : null) || this._defaults.monthNamesShort,
5083			monthNames = (settings ? settings.monthNames : null) || this._defaults.monthNames,
5084			// Check whether a format character is doubled
5085			lookAhead = function(match) {
5086				var matches = (iFormat + 1 < format.length && format.charAt(iFormat + 1) === match);
5087				if (matches) {
5088					iFormat++;
5089				}
5090				return matches;
5091			},
5092			// Format a number, with leading zero if necessary
5093			formatNumber = function(match, value, len) {
5094				var num = "" + value;
5095				if (lookAhead(match)) {
5096					while (num.length < len) {
5097						num = "0" + num;
5098					}
5099				}
5100				return num;
5101			},
5102			// Format a name, short or long as requested
5103			formatName = function(match, value, shortNames, longNames) {
5104				return (lookAhead(match) ? longNames[value] : shortNames[value]);
5105			},
5106			output = "",
5107			literal = false;
5108
5109		if (date) {
5110			for (iFormat = 0; iFormat < format.length; iFormat++) {
5111				if (literal) {
5112					if (format.charAt(iFormat) === "'" && !lookAhead("'")) {
5113						literal = false;
5114					} else {
5115						output += format.charAt(iFormat);
5116					}
5117				} else {
5118					switch (format.charAt(iFormat)) {
5119						case "d":
5120							output += formatNumber("d", date.getDate(), 2);
5121							break;
5122						case "D":
5123							output += formatName("D", date.getDay(), dayNamesShort, dayNames);
5124							break;
5125						case "o":
5126							output += formatNumber("o",
5127								Math.round((new Date(date.getFullYear(), date.getMonth(), date.getDate()).getTime() - new Date(date.getFullYear(), 0, 0).getTime()) / 86400000), 3);
5128							break;
5129						case "m":
5130							output += formatNumber("m", date.getMonth() + 1, 2);
5131							break;
5132						case "M":
5133							output += formatName("M", date.getMonth(), monthNamesShort, monthNames);
5134							break;
5135						case "y":
5136							output += (lookAhead("y") ? date.getFullYear() :
5137								(date.getYear() % 100 < 10 ? "0" : "") + date.getYear() % 100);
5138							break;
5139						case "@":
5140							output += date.getTime();
5141							break;
5142						case "!":
5143							output += date.getTime() * 10000 + this._ticksTo1970;
5144							break;
5145						case "'":
5146							if (lookAhead("'")) {
5147								output += "'";
5148							} else {
5149								literal = true;
5150							}
5151							break;
5152						default:
5153							output += format.charAt(iFormat);
5154					}
5155				}
5156			}
5157		}
5158		return output;
5159	},
5160
5161	/* Extract all possible characters from the date format. */
5162	_possibleChars: function (format) {
5163		var iFormat,
5164			chars = "",
5165			literal = false,
5166			// Check whether a format character is doubled
5167			lookAhead = function(match) {
5168				var matches = (iFormat + 1 < format.length && format.charAt(iFormat + 1) === match);
5169				if (matches) {
5170					iFormat++;
5171				}
5172				return matches;
5173			};
5174
5175		for (iFormat = 0; iFormat < format.length; iFormat++) {
5176			if (literal) {
5177				if (format.charAt(iFormat) === "'" && !lookAhead("'")) {
5178					literal = false;
5179				} else {
5180					chars += format.charAt(iFormat);
5181				}
5182			} else {
5183				switch (format.charAt(iFormat)) {
5184					case "d": case "m": case "y": case "@":
5185						chars += "0123456789";
5186						break;
5187					case "D": case "M":
5188						return null; // Accept anything
5189					case "'":
5190						if (lookAhead("'")) {
5191							chars += "'";
5192						} else {
5193							literal = true;
5194						}
5195						break;
5196					default:
5197						chars += format.charAt(iFormat);
5198				}
5199			}
5200		}
5201		return chars;
5202	},
5203
5204	/* Get a setting value, defaulting if necessary. */
5205	_get: function(inst, name) {
5206		return inst.settings[name] !== undefined ?
5207			inst.settings[name] : this._defaults[name];
5208	},
5209
5210	/* Parse existing date and initialise date picker. */
5211	_setDateFromField: function(inst, noDefault) {
5212		if (inst.input.val() === inst.lastVal) {
5213			return;
5214		}
5215
5216		var dateFormat = this._get(inst, "dateFormat"),
5217			dates = inst.lastVal = inst.input ? inst.input.val() : null,
5218			defaultDate = this._getDefaultDate(inst),
5219			date = defaultDate,
5220			settings = this._getFormatConfig(inst);
5221
5222		try {
5223			date = this.parseDate(dateFormat, dates, settings) || defaultDate;
5224		} catch (event) {
5225			dates = (noDefault ? "" : dates);
5226		}
5227		inst.selectedDay = date.getDate();
5228		inst.drawMonth = inst.selectedMonth = date.getMonth();
5229		inst.drawYear = inst.selectedYear = date.getFullYear();
5230		inst.currentDay = (dates ? date.getDate() : 0);
5231		inst.currentMonth = (dates ? date.getMonth() : 0);
5232		inst.currentYear = (dates ? date.getFullYear() : 0);
5233		this._adjustInstDate(inst);
5234	},
5235
5236	/* Retrieve the default date shown on opening. */
5237	_getDefaultDate: function(inst) {
5238		return this._restrictMinMax(inst,
5239			this._determineDate(inst, this._get(inst, "defaultDate"), new Date()));
5240	},
5241
5242	/* A date may be specified as an exact value or a relative one. */
5243	_determineDate: function(inst, date, defaultDate) {
5244		var offsetNumeric = function(offset) {
5245				var date = new Date();
5246				date.setDate(date.getDate() + offset);
5247				return date;
5248			},
5249			offsetString = function(offset) {
5250				try {
5251					return $.datepicker.parseDate($.datepicker._get(inst, "dateFormat"),
5252						offset, $.datepicker._getFormatConfig(inst));
5253				}
5254				catch (e) {
5255					// Ignore
5256				}
5257
5258				var date = (offset.toLowerCase().match(/^c/) ?
5259					$.datepicker._getDate(inst) : null) || new Date(),
5260					year = date.getFullYear(),
5261					month = date.getMonth(),
5262					day = date.getDate(),
5263					pattern = /([+\-]?[0-9]+)\s*(d|D|w|W|m|M|y|Y)?/g,
5264					matches = pattern.exec(offset);
5265
5266				while (matches) {
5267					switch (matches[2] || "d") {
5268						case "d" : case "D" :
5269							day += parseInt(matches[1],10); break;
5270						case "w" : case "W" :
5271							day += parseInt(matches[1],10) * 7; break;
5272						case "m" : case "M" :
5273							month += parseInt(matches[1],10);
5274							day = Math.min(day, $.datepicker._getDaysInMonth(year, month));
5275							break;
5276						case "y": case "Y" :
5277							year += parseInt(matches[1],10);
5278							day = Math.min(day, $.datepicker._getDaysInMonth(year, month));
5279							break;
5280					}
5281					matches = pattern.exec(offset);
5282				}
5283				return new Date(year, month, day);
5284			},
5285			newDate = (date == null || date === "" ? defaultDate : (typeof date === "string" ? offsetString(date) :
5286				(typeof date === "number" ? (isNaN(date) ? defaultDate : offsetNumeric(date)) : new Date(date.getTime()))));
5287
5288		newDate = (newDate && newDate.toString() === "Invalid Date" ? defaultDate : newDate);
5289		if (newDate) {
5290			newDate.setHours(0);
5291			newDate.setMinutes(0);
5292			newDate.setSeconds(0);
5293			newDate.setMilliseconds(0);
5294		}
5295		return this._daylightSavingAdjust(newDate);
5296	},
5297
5298	/* Handle switch to/from daylight saving.
5299	 * Hours may be non-zero on daylight saving cut-over:
5300	 * > 12 when midnight changeover, but then cannot generate
5301	 * midnight datetime, so jump to 1AM, otherwise reset.
5302	 * @param  date  (Date) the date to check
5303	 * @return  (Date) the corrected date
5304	 */
5305	_daylightSavingAdjust: function(date) {
5306		if (!date) {
5307			return null;
5308		}
5309		date.setHours(date.getHours() > 12 ? date.getHours() + 2 : 0);
5310		return date;
5311	},
5312
5313	/* Set the date(s) directly. */
5314	_setDate: function(inst, date, noChange) {
5315		var clear = !date,
5316			origMonth = inst.selectedMonth,
5317			origYear = inst.selectedYear,
5318			newDate = this._restrictMinMax(inst, this._determineDate(inst, date, new Date()));
5319
5320		inst.selectedDay = inst.currentDay = newDate.getDate();
5321		inst.drawMonth = inst.selectedMonth = inst.currentMonth = newDate.getMonth();
5322		inst.drawYear = inst.selectedYear = inst.currentYear = newDate.getFullYear();
5323		if ((origMonth !== inst.selectedMonth || origYear !== inst.selectedYear) && !noChange) {
5324			this._notifyChange(inst);
5325		}
5326		this._adjustInstDate(inst);
5327		if (inst.input) {
5328			inst.input.val(clear ? "" : this._formatDate(inst));
5329		}
5330	},
5331
5332	/* Retrieve the date(s) directly. */
5333	_getDate: function(inst) {
5334		var startDate = (!inst.currentYear || (inst.input && inst.input.val() === "") ? null :
5335			this._daylightSavingAdjust(new Date(
5336			inst.currentYear, inst.currentMonth, inst.currentDay)));
5337			return startDate;
5338	},
5339
5340	/* Attach the onxxx handlers.  These are declared statically so
5341	 * they work with static code transformers like Caja.
5342	 */
5343	_attachHandlers: function(inst) {
5344		var stepMonths = this._get(inst, "stepMonths"),
5345			id = "#" + inst.id.replace( /\\\\/g, "\\" );
5346		inst.dpDiv.find("[data-handler]").map(function () {
5347			var handler = {
5348				prev: function () {
5349					$.datepicker._adjustDate(id, -stepMonths, "M");
5350				},
5351				next: function () {
5352					$.datepicker._adjustDate(id, +stepMonths, "M");
5353				},
5354				hide: function () {
5355					$.datepicker._hideDatepicker();
5356				},
5357				today: function () {
5358					$.datepicker._gotoToday(id);
5359				},
5360				selectDay: function () {
5361					$.datepicker._selectDay(id, +this.getAttribute("data-month"), +this.getAttribute("data-year"), this);
5362					return false;
5363				},
5364				selectMonth: function () {
5365					$.datepicker._selectMonthYear(id, this, "M");
5366					return false;
5367				},
5368				selectYear: function () {
5369					$.datepicker._selectMonthYear(id, this, "Y");
5370					return false;
5371				}
5372			};
5373			$(this).bind(this.getAttribute("data-event"), handler[this.getAttribute("data-handler")]);
5374		});
5375	},
5376
5377	/* Generate the HTML for the current state of the date picker. */
5378	_generateHTML: function(inst) {
5379		var maxDraw, prevText, prev, nextText, next, currentText, gotoDate,
5380			controls, buttonPanel, firstDay, showWeek, dayNames, dayNamesMin,
5381			monthNames, monthNamesShort, beforeShowDay, showOtherMonths,
5382			selectOtherMonths, defaultDate, html, dow, row, group, col, selectedDate,
5383			cornerClass, calender, thead, day, daysInMonth, leadDays, curRows, numRows,
5384			printDate, dRow, tbody, daySettings, otherMonth, unselectable,
5385			tempDate = new Date(),
5386			today = this._daylightSavingAdjust(
5387				new Date(tempDate.getFullYear(), tempDate.getMonth(), tempDate.getDate())), // clear time
5388			isRTL = this._get(inst, "isRTL"),
5389			showButtonPanel = this._get(inst, "showButtonPanel"),
5390			hideIfNoPrevNext = this._get(inst, "hideIfNoPrevNext"),
5391			navigationAsDateFormat = this._get(inst, "navigationAsDateFormat"),
5392			numMonths = this._getNumberOfMonths(inst),
5393			showCurrentAtPos = this._get(inst, "showCurrentAtPos"),
5394			stepMonths = this._get(inst, "stepMonths"),
5395			isMultiMonth = (numMonths[0] !== 1 || numMonths[1] !== 1),
5396			currentDate = this._daylightSavingAdjust((!inst.currentDay ? new Date(9999, 9, 9) :
5397				new Date(inst.currentYear, inst.currentMonth, inst.currentDay))),
5398			minDate = this._getMinMaxDate(inst, "min"),
5399			maxDate = this._getMinMaxDate(inst, "max"),
5400			drawMonth = inst.drawMonth - showCurrentAtPos,
5401			drawYear = inst.drawYear;
5402
5403		if (drawMonth < 0) {
5404			drawMonth += 12;
5405			drawYear--;
5406		}
5407		if (maxDate) {
5408			maxDraw = this._daylightSavingAdjust(new Date(maxDate.getFullYear(),
5409				maxDate.getMonth() - (numMonths[0] * numMonths[1]) + 1, maxDate.getDate()));
5410			maxDraw = (minDate && maxDraw < minDate ? minDate : maxDraw);
5411			while (this._daylightSavingAdjust(new Date(drawYear, drawMonth, 1)) > maxDraw) {
5412				drawMonth--;
5413				if (drawMonth < 0) {
5414					drawMonth = 11;
5415					drawYear--;
5416				}
5417			}
5418		}
5419		inst.drawMonth = drawMonth;
5420		inst.drawYear = drawYear;
5421
5422		prevText = this._get(inst, "prevText");
5423		prevText = (!navigationAsDateFormat ? prevText : this.formatDate(prevText,
5424			this._daylightSavingAdjust(new Date(drawYear, drawMonth - stepMonths, 1)),
5425			this._getFormatConfig(inst)));
5426
5427		prev = (this._canAdjustMonth(inst, -1, drawYear, drawMonth) ?
5428			"<a class='ui-datepicker-prev ui-corner-all' data-handler='prev' data-event='click'" +
5429			" title='" + prevText + "'><span class='ui-icon ui-icon-circle-triangle-" + ( isRTL ? "e" : "w") + "'>" + prevText + "</span></a>" :
5430			(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>"));
5431
5432		nextText = this._get(inst, "nextText");
5433		nextText = (!navigationAsDateFormat ? nextText : this.formatDate(nextText,
5434			this._daylightSavingAdjust(new Date(drawYear, drawMonth + stepMonths, 1)),
5435			this._getFormatConfig(inst)));
5436
5437		next = (this._canAdjustMonth(inst, +1, drawYear, drawMonth) ?
5438			"<a class='ui-datepicker-next ui-corner-all' data-handler='next' data-event='click'" +
5439			" title='" + nextText + "'><span class='ui-icon ui-icon-circle-triangle-" + ( isRTL ? "w" : "e") + "'>" + nextText + "</span></a>" :
5440			(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>"));
5441
5442		currentText = this._get(inst, "currentText");
5443		gotoDate = (this._get(inst, "gotoCurrent") && inst.currentDay ? currentDate : today);
5444		currentText = (!navigationAsDateFormat ? currentText :
5445			this.formatDate(currentText, gotoDate, this._getFormatConfig(inst)));
5446
5447		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'>" +
5448			this._get(inst, "closeText") + "</button>" : "");
5449
5450		buttonPanel = (showButtonPanel) ? "<div class='ui-datepicker-buttonpane ui-widget-content'>" + (isRTL ? controls : "") +
5451			(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'" +
5452			">" + currentText + "</button>" : "") + (isRTL ? "" : controls) + "</div>" : "";
5453
5454		firstDay = parseInt(this._get(inst, "firstDay"),10);
5455		firstDay = (isNaN(firstDay) ? 0 : firstDay);
5456
5457		showWeek = this._get(inst, "showWeek");
5458		dayNames = this._get(inst, "dayNames");
5459		dayNamesMin = this._get(inst, "dayNamesMin");
5460		monthNames = this._get(inst, "monthNames");
5461		monthNamesShort = this._get(inst, "monthNamesShort");
5462		beforeShowDay = this._get(inst, "beforeShowDay");
5463		showOtherMonths = this._get(inst, "showOtherMonths");
5464		selectOtherMonths = this._get(inst, "selectOtherMonths");
5465		defaultDate = this._getDefaultDate(inst);
5466		html = "";
5467		dow;
5468		for (row = 0; row < numMonths[0]; row++) {
5469			group = "";
5470			this.maxRows = 4;
5471			for (col = 0; col < numMonths[1]; col++) {
5472				selectedDate = this._daylightSavingAdjust(new Date(drawYear, drawMonth, inst.selectedDay));
5473				cornerClass = " ui-corner-all";
5474				calender = "";
5475				if (isMultiMonth) {
5476					calender += "<div class='ui-datepicker-group";
5477					if (numMonths[1] > 1) {
5478						switch (col) {
5479							case 0: calender += " ui-datepicker-group-first";
5480								cornerClass = " ui-corner-" + (isRTL ? "right" : "left"); break;
5481							case numMonths[1]-1: calender += " ui-datepicker-group-last";
5482								cornerClass = " ui-corner-" + (isRTL ? "left" : "right"); break;
5483							default: calender += " ui-datepicker-group-middle"; cornerClass = ""; break;
5484						}
5485					}
5486					calender += "'>";
5487				}
5488				calender += "<div class='ui-datepicker-header ui-widget-header ui-helper-clearfix" + cornerClass + "'>" +
5489					(/all|left/.test(cornerClass) && row === 0 ? (isRTL ? next : prev) : "") +
5490					(/all|right/.test(cornerClass) && row === 0 ? (isRTL ? prev : next) : "") +
5491					this._generateMonthYearHeader(inst, drawMonth, drawYear, minDate, maxDate,
5492					row > 0 || col > 0, monthNames, monthNamesShort) + // draw month headers
5493					"</div><table class='ui-datepicker-calendar'><thead>" +
5494					"<tr>";
5495				thead = (showWeek ? "<th class='ui-datepicker-week-col'>" + this._get(inst, "weekHeader") + "</th>" : "");
5496				for (dow = 0; dow < 7; dow++) { // days of the week
5497					day = (dow + firstDay) % 7;
5498					thead += "<th scope='col'" + ((dow + firstDay + 6) % 7 >= 5 ? " class='ui-datepicker-week-end'" : "") + ">" +
5499						"<span title='" + dayNames[day] + "'>" + dayNamesMin[day] + "</span></th>";
5500				}
5501				calender += thead + "</tr></thead><tbody>";
5502				daysInMonth = this._getDaysInMonth(drawYear, drawMonth);
5503				if (drawYear === inst.selectedYear && drawMonth === inst.selectedMonth) {
5504					inst.selectedDay = Math.min(inst.selectedDay, daysInMonth);
5505				}
5506				leadDays = (this._getFirstDayOfMonth(drawYear, drawMonth) - firstDay + 7) % 7;
5507				curRows = Math.ceil((leadDays + daysInMonth) / 7); // calculate the number of rows to generate
5508				numRows = (isMultiMonth ? this.maxRows > curRows ? this.maxRows : curRows : curRows); //If multiple months, use the higher number of rows (see #7043)
5509				this.maxRows = numRows;
5510				printDate = this._daylightSavingAdjust(new Date(drawYear, drawMonth, 1 - leadDays));
5511				for (dRow = 0; dRow < numRows; dRow++) { // create date picker rows
5512					calender += "<tr>";
5513					tbody = (!showWeek ? "" : "<td class='ui-datepicker-week-col'>" +
5514						this._get(inst, "calculateWeek")(printDate) + "</td>");
5515					for (dow = 0; dow < 7; dow++) { // create date picker days
5516						daySettings = (beforeShowDay ?
5517							beforeShowDay.apply((inst.input ? inst.input[0] : null), [printDate]) : [true, ""]);
5518						otherMonth = (printDate.getMonth() !== drawMonth);
5519						unselectable = (otherMonth && !selectOtherMonths) || !daySettings[0] ||
5520							(minDate && printDate < minDate) || (maxDate && printDate > maxDate);
5521						tbody += "<td class='" +
5522							((dow + firstDay + 6) % 7 >= 5 ? " ui-datepicker-week-end" : "") + // highlight weekends
5523							(otherMonth ? " ui-datepicker-other-month" : "") + // highlight days from other months
5524							((printDate.getTime() === selectedDate.getTime() && drawMonth === inst.selectedMonth && inst._keyEvent) || // user pressed key
5525							(defaultDate.getTime() === printDate.getTime() && defaultDate.getTime() === selectedDate.getTime()) ?
5526							// or defaultDate is current printedDate and defaultDate is selectedDate
5527							" " + this._dayOverClass : "") + // highlight selected day
5528							(unselectable ? " " + this._unselectableClass + " ui-state-disabled": "") +  // highlight unselectable days
5529							(otherMonth && !showOtherMonths ? "" : " " + daySettings[1] + // highlight custom dates
5530							(printDate.getTime() === currentDate.getTime() ? " " + this._currentClass : "") + // highlight selected day
5531							(printDate.getTime() === today.getTime() ? " ui-datepicker-today" : "")) + "'" + // highlight today (if different)
5532							((!otherMonth || showOtherMonths) && daySettings[2] ? " title='" + daySettings[2].replace(/'/g, "&#39;") + "'" : "") + // cell title
5533							(unselectable ? "" : " data-handler='selectDay' data-event='click' data-month='" + printDate.getMonth() + "' data-year='" + printDate.getFullYear() + "'") + ">" + // actions
5534							(otherMonth && !showOtherMonths ? "&#xa0;" : // display for other months
5535							(unselectable ? "<span class='ui-state-default'>" + printDate.getDate() + "</span>" : "<a class='ui-state-default" +
5536							(printDate.getTime() === today.getTime() ? " ui-state-highlight" : "") +
5537							(printDate.getTime() === currentDate.getTime() ? " ui-state-active" : "") + // highlight selected day
5538							(otherMonth ? " ui-priority-secondary" : "") + // distinguish dates from other months
5539							"' href='#'>" + printDate.getDate() + "</a>")) + "</td>"; // display selectable date
5540						printDate.setDate(printDate.getDate() + 1);
5541						printDate = this._daylightSavingAdjust(printDate);
5542					}
5543					calender += tbody + "</tr>";
5544				}
5545				drawMonth++;
5546				if (drawMonth > 11) {
5547					drawMonth = 0;
5548					drawYear++;
5549				}
5550				calender += "</tbody></table>" + (isMultiMonth ? "</div>" +
5551							((numMonths[0] > 0 && col === numMonths[1]-1) ? "<div class='ui-datepicker-row-break'></div>" : "") : "");
5552				group += calender;
5553			}
5554			html += group;
5555		}
5556		html += buttonPanel;
5557		inst._keyEvent = false;
5558		return html;
5559	},
5560
5561	/* Generate the month and year header. */
5562	_generateMonthYearHeader: function(inst, drawMonth, drawYear, minDate, maxDate,
5563			secondary, monthNames, monthNamesShort) {
5564
5565		var inMinYear, inMaxYear, month, years, thisYear, determineYear, year, endYear,
5566			changeMonth = this._get(inst, "changeMonth"),
5567			changeYear = this._get(inst, "changeYear"),
5568			showMonthAfterYear = this._get(inst, "showMonthAfterYear"),
5569			html = "<div class='ui-datepicker-title'>",
5570			monthHtml = "";
5571
5572		// month selection
5573		if (secondary || !changeMonth) {
5574			monthHtml += "<span class='ui-datepicker-month'>" + monthNames[drawMonth] + "</span>";
5575		} else {
5576			inMinYear = (minDate && minDate.getFullYear() === drawYear);
5577			inMaxYear = (maxDate && maxDate.getFullYear() === drawYear);
5578			monthHtml += "<select class='ui-datepicker-month' data-handler='selectMonth' data-event='change'>";
5579			for ( month = 0; month < 12; month++) {
5580				if ((!inMinYear || month >= minDate.getMonth()) && (!inMaxYear || month <= maxDate.getMonth())) {
5581					monthHtml += "<option value='" + month + "'" +
5582						(month === drawMonth ? " selected='selected'" : "") +
5583						">" + monthNamesShort[month] + "</option>";
5584				}
5585			}
5586			monthHtml += "</select>";
5587		}
5588
5589		if (!showMonthAfterYear) {
5590			html += monthHtml + (secondary || !(changeMonth && changeYear) ? "&#xa0;" : "");
5591		}
5592
5593		// year selection
5594		if ( !inst.yearshtml ) {
5595			inst.yearshtml = "";
5596			if (secondary || !changeYear) {
5597				html += "<span class='ui-datepicker-year'>" + drawYear + "</span>";
5598			} else {
5599				// determine range of years to display
5600				years = this._get(inst, "yearRange").split(":");
5601				thisYear = new Date().getFullYear();
5602				determineYear = function(value) {
5603					var year = (value.match(/c[+\-].*/) ? drawYear + parseInt(value.substring(1), 10) :
5604						(value.match(/[+\-].*/) ? thisYear + parseInt(value, 10) :
5605						parseInt(value, 10)));
5606					return (isNaN(year) ? thisYear : year);
5607				};
5608				year = determineYear(years[0]);
5609				endYear = Math.max(year, determineYear(years[1] || ""));
5610				year = (minDate ? Math.max(year, minDate.getFullYear()) : year);
5611				endYear = (maxDate ? Math.min(endYear, maxDate.getFullYear()) : endYear);
5612				inst.yearshtml += "<select class='ui-datepicker-year' data-handler='selectYear' data-event='change'>";
5613				for (; year <= endYear; year++) {
5614					inst.yearshtml += "<option value='" + year + "'" +
5615						(year === drawYear ? " selected='selected'" : "") +
5616						">" + year + "</option>";
5617				}
5618				inst.yearshtml += "</select>";
5619
5620				html += inst.yearshtml;
5621				inst.yearshtml = null;
5622			}
5623		}
5624
5625		html += this._get(inst, "yearSuffix");
5626		if (showMonthAfterYear) {
5627			html += (secondary || !(changeMonth && changeYear) ? "&#xa0;" : "") + monthHtml;
5628		}
5629		html += "</div>"; // Close datepicker_header
5630		return html;
5631	},
5632
5633	/* Adjust one of the date sub-fields. */
5634	_adjustInstDate: function(inst, offset, period) {
5635		var year = inst.drawYear + (period === "Y" ? offset : 0),
5636			month = inst.drawMonth + (period === "M" ? offset : 0),
5637			day = Math.min(inst.selectedDay, this._getDaysInMonth(year, month)) + (period === "D" ? offset : 0),
5638			date = this._restrictMinMax(inst, this._daylightSavingAdjust(new Date(year, month, day)));
5639
5640		inst.selectedDay = date.getDate();
5641		inst.drawMonth = inst.selectedMonth = date.getMonth();
5642		inst.drawYear = inst.selectedYear = date.getFullYear();
5643		if (period === "M" || period === "Y") {
5644			this._notifyChange(inst);
5645		}
5646	},
5647
5648	/* Ensure a date is within any min/max bounds. */
5649	_restrictMinMax: function(inst, date) {
5650		var minDate = this._getMinMaxDate(inst, "min"),
5651			maxDate = this._getMinMaxDate(inst, "max"),
5652			newDate = (minDate && date < minDate ? minDate : date);
5653		return (maxDate && newDate > maxDate ? maxDate : newDate);
5654	},
5655
5656	/* Notify change of month/year. */
5657	_notifyChange: function(inst) {
5658		var onChange = this._get(inst, "onChangeMonthYear");
5659		if (onChange) {
5660			onChange.apply((inst.input ? inst.input[0] : null),
5661				[inst.selectedYear, inst.selectedMonth + 1, inst]);
5662		}
5663	},
5664
5665	/* Determine the number of months to show. */
5666	_getNumberOfMonths: function(inst) {
5667		var numMonths = this._get(inst, "numberOfMonths");
5668		return (numMonths == null ? [1, 1] : (typeof numMonths === "number" ? [1, numMonths] : numMonths));
5669	},
5670
5671	/* Determine the current maximum date - ensure no time components are set. */
5672	_getMinMaxDate: function(inst, minMax) {
5673		return this._determineDate(inst, this._get(inst, minMax + "Date"), null);
5674	},
5675
5676	/* Find the number of days in a given month. */
5677	_getDaysInMonth: function(year, month) {
5678		return 32 - this._daylightSavingAdjust(new Date(year, month, 32)).getDate();
5679	},
5680
5681	/* Find the day of the week of the first of a month. */
5682	_getFirstDayOfMonth: function(year, month) {
5683		return new Date(year, month, 1).getDay();
5684	},
5685
5686	/* Determines if we should allow a "next/prev" month display change. */
5687	_canAdjustMonth: function(inst, offset, curYear, curMonth) {
5688		var numMonths = this._getNumberOfMonths(inst),
5689			date = this._daylightSavingAdjust(new Date(curYear,
5690			curMonth + (offset < 0 ? offset : numMonths[0] * numMonths[1]), 1));
5691
5692		if (offset < 0) {
5693			date.setDate(this._getDaysInMonth(date.getFullYear(), date.getMonth()));
5694		}
5695		return this._isInRange(inst, date);
5696	},
5697
5698	/* Is the given date in the accepted range? */
5699	_isInRange: function(inst, date) {
5700		var yearSplit, currentYear,
5701			minDate = this._getMinMaxDate(inst, "min"),
5702			maxDate = this._getMinMaxDate(inst, "max"),
5703			minYear = null,
5704			maxYear = null,
5705			years = this._get(inst, "yearRange");
5706			if (years){
5707				yearSplit = years.split(":");
5708				currentYear = new Date().getFullYear();
5709				minYear = parseInt(yearSplit[0], 10);
5710				maxYear = parseInt(yearSplit[1], 10);
5711				if ( yearSplit[0].match(/[+\-].*/) ) {
5712					minYear += currentYear;
5713				}
5714				if ( yearSplit[1].match(/[+\-].*/) ) {
5715					maxYear += currentYear;
5716				}
5717			}
5718
5719		return ((!minDate || date.getTime() >= minDate.getTime()) &&
5720			(!maxDate || date.getTime() <= maxDate.getTime()) &&
5721			(!minYear || date.getFullYear() >= minYear) &&
5722			(!maxYear || date.getFullYear() <= maxYear));
5723	},
5724
5725	/* Provide the configuration settings for formatting/parsing. */
5726	_getFormatConfig: function(inst) {
5727		var shortYearCutoff = this._get(inst, "shortYearCutoff");
5728		shortYearCutoff = (typeof shortYearCutoff !== "string" ? shortYearCutoff :
5729			new Date().getFullYear() % 100 + parseInt(shortYearCutoff, 10));
5730		return {shortYearCutoff: shortYearCutoff,
5731			dayNamesShort: this._get(inst, "dayNamesShort"), dayNames: this._get(inst, "dayNames"),
5732			monthNamesShort: this._get(inst, "monthNamesShort"), monthNames: this._get(inst, "monthNames")};
5733	},
5734
5735	/* Format the given date for display. */
5736	_formatDate: function(inst, day, month, year) {
5737		if (!day) {
5738			inst.currentDay = inst.selectedDay;
5739			inst.currentMonth = inst.selectedMonth;
5740			inst.currentYear = inst.selectedYear;
5741		}
5742		var date = (day ? (typeof day === "object" ? day :
5743			this._daylightSavingAdjust(new Date(year, month, day))) :
5744			this._daylightSavingAdjust(new Date(inst.currentYear, inst.currentMonth, inst.currentDay)));
5745		return this.formatDate(this._get(inst, "dateFormat"), date, this._getFormatConfig(inst));
5746	}
5747});
5748
5749/*
5750 * Bind hover events for datepicker elements.
5751 * Done via delegate so the binding only occurs once in the lifetime of the parent div.
5752 * Global datepicker_instActive, set by _updateDatepicker allows the handlers to find their way back to the active picker.
5753 */
5754function datepicker_bindHover(dpDiv) {
5755	var selector = "button, .ui-datepicker-prev, .ui-datepicker-next, .ui-datepicker-calendar td a";
5756	return dpDiv.delegate(selector, "mouseout", function() {
5757			$(this).removeClass("ui-state-hover");
5758			if (this.className.indexOf("ui-datepicker-prev") !== -1) {
5759				$(this).removeClass("ui-datepicker-prev-hover");
5760			}
5761			if (this.className.indexOf("ui-datepicker-next") !== -1) {
5762				$(this).removeClass("ui-datepicker-next-hover");
5763			}
5764		})
5765		.delegate( selector, "mouseover", datepicker_handleMouseover );
5766}
5767
5768function datepicker_handleMouseover() {
5769	if (!$.datepicker._isDisabledDatepicker( datepicker_instActive.inline? datepicker_instActive.dpDiv.parent()[0] : datepicker_instActive.input[0])) {
5770		$(this).parents(".ui-datepicker-calendar").find("a").removeClass("ui-state-hover");
5771		$(this).addClass("ui-state-hover");
5772		if (this.className.indexOf("ui-datepicker-prev") !== -1) {
5773			$(this).addClass("ui-datepicker-prev-hover");
5774		}
5775		if (this.className.indexOf("ui-datepicker-next") !== -1) {
5776			$(this).addClass("ui-datepicker-next-hover");
5777		}
5778	}
5779}
5780
5781/* jQuery extend now ignores nulls! */
5782function datepicker_extendRemove(target, props) {
5783	$.extend(target, props);
5784	for (var name in props) {
5785		if (props[name] == null) {
5786			target[name] = props[name];
5787		}
5788	}
5789	return target;
5790}
5791
5792/* Invoke the datepicker functionality.
5793   @param  options  string - a command, optionally followed by additional parameters or
5794					Object - settings for attaching new datepicker functionality
5795   @return  jQuery object */
5796$.fn.datepicker = function(options){
5797
5798	/* Verify an empty collection wasn't passed - Fixes #6976 */
5799	if ( !this.length ) {
5800		return this;
5801	}
5802
5803	/* Initialise the date picker. */
5804	if (!$.datepicker.initialized) {
5805		$(document).mousedown($.datepicker._checkExternalClick);
5806		$.datepicker.initialized = true;
5807	}
5808
5809	/* Append datepicker main container to body if not exist. */
5810	if ($("#"+$.datepicker._mainDivId).length === 0) {
5811		$("body").append($.datepicker.dpDiv);
5812	}
5813
5814	var otherArgs = Array.prototype.slice.call(arguments, 1);
5815	if (typeof options === "string" && (options === "isDisabled" || options === "getDate" || options === "widget")) {
5816		return $.datepicker["_" + options + "Datepicker"].
5817			apply($.datepicker, [this[0]].concat(otherArgs));
5818	}
5819	if (options === "option" && arguments.length === 2 && typeof arguments[1] === "string") {
5820		return $.datepicker["_" + options + "Datepicker"].
5821			apply($.datepicker, [this[0]].concat(otherArgs));
5822	}
5823	return this.each(function() {
5824		typeof options === "string" ?
5825			$.datepicker["_" + options + "Datepicker"].
5826				apply($.datepicker, [this].concat(otherArgs)) :
5827			$.datepicker._attachDatepicker(this, options);
5828	});
5829};
5830
5831$.datepicker = new Datepicker(); // singleton instance
5832$.datepicker.initialized = false;
vendor: 44,343 bytes, lines 5833-7353
5833$.datepicker.uuid = new Date().getTime();
5834$.datepicker.version = "1.11.4";
5835
5836var datepicker = $.datepicker;
5837
5838
5839/*!
5840 * jQuery UI Draggable 1.11.4
5841 * http://jqueryui.com
5842 *
5843 * Copyright jQuery Foundation and other contributors
5844 * Released under the MIT license.
5845 * http://jquery.org/license
5846 *
5847 * http://api.jqueryui.com/draggable/
5848 */
5849
5850
5851$.widget("ui.draggable", $.ui.mouse, {
5852	version: "1.11.4",
5853	widgetEventPrefix: "drag",
5854	options: {
5855		addClasses: true,
5856		appendTo: "parent",
5857		axis: false,
5858		connectToSortable: false,
5859		containment: false,
5860		cursor: "auto",
5861		cursorAt: false,
5862		grid: false,
5863		handle: false,
5864		helper: "original",
5865		iframeFix: false,
5866		opacity: false,
5867		refreshPositions: false,
5868		revert: false,
5869		revertDuration: 500,
5870		scope: "default",
5871		scroll: true,
5872		scrollSensitivity: 20,
5873		scrollSpeed: 20,
5874		snap: false,
5875		snapMode: "both",
5876		snapTolerance: 20,
5877		stack: false,
5878		zIndex: false,
5879
5880		// callbacks
5881		drag: null,
5882		start: null,
5883		stop: null
5884	},
5885	_create: function() {
5886
5887		if ( this.options.helper === "original" ) {
5888			this._setPositionRelative();
5889		}
5890		if (this.options.addClasses){
5891			this.element.addClass("ui-draggable");
5892		}
5893		if (this.options.disabled){
5894			this.element.addClass("ui-draggable-disabled");
5895		}
5896		this._setHandleClassName();
5897
5898		this._mouseInit();
5899	},
5900
5901	_setOption: function( key, value ) {
5902		this._super( key, value );
5903		if ( key === "handle" ) {
5904			this._removeHandleClassName();
5905			this._setHandleClassName();
5906		}
5907	},
5908
5909	_destroy: function() {
5910		if ( ( this.helper || this.element ).is( ".ui-draggable-dragging" ) ) {
5911			this.destroyOnClear = true;
5912			return;
5913		}
5914		this.element.removeClass( "ui-draggable ui-draggable-dragging ui-draggable-disabled" );
5915		this._removeHandleClassName();
5916		this._mouseDestroy();
5917	},
5918
5919	_mouseCapture: function(event) {
5920		var o = this.options;
5921
5922		this._blurActiveElement( event );
5923
5924		// among others, prevent a drag on a resizable-handle
5925		if (this.helper || o.disabled || $(event.target).closest(".ui-resizable-handle").length > 0) {
5926			return false;
5927		}
5928
5929		//Quit if we're not on a valid handle
5930		this.handle = this._getHandle(event);
5931		if (!this.handle) {
5932			return false;
5933		}
5934
5935		this._blockFrames( o.iframeFix === true ? "iframe" : o.iframeFix );
5936
5937		return true;
5938
5939	},
5940
5941	_blockFrames: function( selector ) {
5942		this.iframeBlocks = this.document.find( selector ).map(function() {
5943			var iframe = $( this );
5944
5945			return $( "<div>" )
5946				.css( "position", "absolute" )
5947				.appendTo( iframe.parent() )
5948				.outerWidth( iframe.outerWidth() )
5949				.outerHeight( iframe.outerHeight() )
5950				.offset( iframe.offset() )[ 0 ];
5951		});
5952	},
5953
5954	_unblockFrames: function() {
5955		if ( this.iframeBlocks ) {
5956			this.iframeBlocks.remove();
5957			delete this.iframeBlocks;
5958		}
5959	},
5960
5961	_blurActiveElement: function( event ) {
5962		var document = this.document[ 0 ];
5963
5964		// Only need to blur if the event occurred on the draggable itself, see #10527
5965		if ( !this.handleElement.is( event.target ) ) {
5966			return;
5967		}
5968
5969		// support: IE9
5970		// IE9 throws an "Unspecified error" accessing document.activeElement from an <iframe>
5971		try {
5972
5973			// Support: IE9, IE10
5974			// If the <body> is blurred, IE will switch windows, see #9520
5975			if ( document.activeElement && document.activeElement.nodeName.toLowerCase() !== "body" ) {
5976
5977				// Blur any element that currently has focus, see #4261
5978				$( document.activeElement ).blur();
5979			}
5980		} catch ( error ) {}
5981	},
5982
5983	_mouseStart: function(event) {
5984
5985		var o = this.options;
5986
5987		//Create and append the visible helper
5988		this.helper = this._createHelper(event);
5989
5990		this.helper.addClass("ui-draggable-dragging");
5991
5992		//Cache the helper size
5993		this._cacheHelperProportions();
5994
5995		//If ddmanager is used for droppables, set the global draggable
5996		if ($.ui.ddmanager) {
5997			$.ui.ddmanager.current = this;
5998		}
5999
6000		/*
6001		 * - Position generation -
6002		 * This block generates everything position related - it's the core of draggables.
6003		 */
6004
6005		//Cache the margins of the original element
6006		this._cacheMargins();
6007
6008		//Store the helper's css position
6009		this.cssPosition = this.helper.css( "position" );
6010		this.scrollParent = this.helper.scrollParent( true );
6011		this.offsetParent = this.helper.offsetParent();
6012		this.hasFixedAncestor = this.helper.parents().filter(function() {
6013				return $( this ).css( "position" ) === "fixed";
6014			}).length > 0;
6015
6016		//The element's absolute position on the page minus margins
6017		this.positionAbs = this.element.offset();
6018		this._refreshOffsets( event );
6019
6020		//Generate the original position
6021		this.originalPosition = this.position = this._generatePosition( event, false );
6022		this.originalPageX = event.pageX;
6023		this.originalPageY = event.pageY;
6024
6025		//Adjust the mouse offset relative to the helper if "cursorAt" is supplied
6026		(o.cursorAt && this._adjustOffsetFromHelper(o.cursorAt));
6027
6028		//Set a containment if given in the options
6029		this._setContainment();
6030
6031		//Trigger event + callbacks
6032		if (this._trigger("start", event) === false) {
6033			this._clear();
6034			return false;
6035		}
6036
6037		//Recache the helper size
6038		this._cacheHelperProportions();
6039
6040		//Prepare the droppable offsets
6041		if ($.ui.ddmanager && !o.dropBehaviour) {
6042			$.ui.ddmanager.prepareOffsets(this, event);
6043		}
6044
6045		// Reset helper's right/bottom css if they're set and set explicit width/height instead
6046		// as this prevents resizing of elements with right/bottom set (see #7772)
6047		this._normalizeRightBottom();
6048
6049		this._mouseDrag(event, true); //Execute the drag once - this causes the helper not to be visible before getting its correct position
6050
6051		//If the ddmanager is used for droppables, inform the manager that dragging has started (see #5003)
6052		if ( $.ui.ddmanager ) {
6053			$.ui.ddmanager.dragStart(this, event);
6054		}
6055
6056		return true;
6057	},
6058
6059	_refreshOffsets: function( event ) {
6060		this.offset = {
6061			top: this.positionAbs.top - this.margins.top,
6062			left: this.positionAbs.left - this.margins.left,
6063			scroll: false,
6064			parent: this._getParentOffset(),
6065			relative: this._getRelativeOffset()
6066		};
6067
6068		this.offset.click = {
6069			left: event.pageX - this.offset.left,
6070			top: event.pageY - this.offset.top
6071		};
6072	},
6073
6074	_mouseDrag: function(event, noPropagation) {
6075		// reset any necessary cached properties (see #5009)
6076		if ( this.hasFixedAncestor ) {
6077			this.offset.parent = this._getParentOffset();
6078		}
6079
6080		//Compute the helpers position
6081		this.position = this._generatePosition( event, true );
6082		this.positionAbs = this._convertPositionTo("absolute");
6083
6084		//Call plugins and callbacks and use the resulting position if something is returned
6085		if (!noPropagation) {
6086			var ui = this._uiHash();
6087			if (this._trigger("drag", event, ui) === false) {
6088				this._mouseUp({});
6089				return false;
6090			}
6091			this.position = ui.position;
6092		}
6093
6094		this.helper[ 0 ].style.left = this.position.left + "px";
6095		this.helper[ 0 ].style.top = this.position.top + "px";
6096
6097		if ($.ui.ddmanager) {
6098			$.ui.ddmanager.drag(this, event);
6099		}
6100
6101		return false;
6102	},
6103
6104	_mouseStop: function(event) {
6105
6106		//If we are using droppables, inform the manager about the drop
6107		var that = this,
6108			dropped = false;
6109		if ($.ui.ddmanager && !this.options.dropBehaviour) {
6110			dropped = $.ui.ddmanager.drop(this, event);
6111		}
6112
6113		//if a drop comes from outside (a sortable)
6114		if (this.dropped) {
6115			dropped = this.dropped;
6116			this.dropped = false;
6117		}
6118
6119		if ((this.options.revert === "invalid" && !dropped) || (this.options.revert === "valid" && dropped) || this.options.revert === true || ($.isFunction(this.options.revert) && this.options.revert.call(this.element, dropped))) {
6120			$(this.helper).animate(this.originalPosition, parseInt(this.options.revertDuration, 10), function() {
6121				if (that._trigger("stop", event) !== false) {
6122					that._clear();
6123				}
6124			});
6125		} else {
6126			if (this._trigger("stop", event) !== false) {
6127				this._clear();
6128			}
6129		}
6130
6131		return false;
6132	},
6133
6134	_mouseUp: function( event ) {
6135		this._unblockFrames();
6136
6137		//If the ddmanager is used for droppables, inform the manager that dragging has stopped (see #5003)
6138		if ( $.ui.ddmanager ) {
6139			$.ui.ddmanager.dragStop(this, event);
6140		}
6141
6142		// Only need to focus if the event occurred on the draggable itself, see #10527
6143		if ( this.handleElement.is( event.target ) ) {
6144			// The interaction is over; whether or not the click resulted in a drag, focus the element
6145			this.element.focus();
6146		}
6147
6148		return $.ui.mouse.prototype._mouseUp.call(this, event);
6149	},
6150
6151	cancel: function() {
6152
6153		if (this.helper.is(".ui-draggable-dragging")) {
6154			this._mouseUp({});
6155		} else {
6156			this._clear();
6157		}
6158
6159		return this;
6160
6161	},
6162
6163	_getHandle: function(event) {
6164		return this.options.handle ?
6165			!!$( event.target ).closest( this.element.find( this.options.handle ) ).length :
6166			true;
6167	},
6168
6169	_setHandleClassName: function() {
6170		this.handleElement = this.options.handle ?
6171			this.element.find( this.options.handle ) : this.element;
6172		this.handleElement.addClass( "ui-draggable-handle" );
6173	},
6174
6175	_removeHandleClassName: function() {
6176		this.handleElement.removeClass( "ui-draggable-handle" );
6177	},
6178
6179	_createHelper: function(event) {
6180
6181		var o = this.options,
6182			helperIsFunction = $.isFunction( o.helper ),
6183			helper = helperIsFunction ?
6184				$( o.helper.apply( this.element[ 0 ], [ event ] ) ) :
6185				( o.helper === "clone" ?
6186					this.element.clone().removeAttr( "id" ) :
6187					this.element );
6188
6189		if (!helper.parents("body").length) {
6190			helper.appendTo((o.appendTo === "parent" ? this.element[0].parentNode : o.appendTo));
6191		}
6192
6193		// http://bugs.jqueryui.com/ticket/9446
6194		// a helper function can return the original element
6195		// which wouldn't have been set to relative in _create
6196		if ( helperIsFunction && helper[ 0 ] === this.element[ 0 ] ) {
6197			this._setPositionRelative();
6198		}
6199
6200		if (helper[0] !== this.element[0] && !(/(fixed|absolute)/).test(helper.css("position"))) {
6201			helper.css("position", "absolute");
6202		}
6203
6204		return helper;
6205
6206	},
6207
6208	_setPositionRelative: function() {
6209		if ( !( /^(?:r|a|f)/ ).test( this.element.css( "position" ) ) ) {
6210			this.element[ 0 ].style.position = "relative";
6211		}
6212	},
6213
6214	_adjustOffsetFromHelper: function(obj) {
6215		if (typeof obj === "string") {
6216			obj = obj.split(" ");
6217		}
6218		if ($.isArray(obj)) {
6219			obj = { left: +obj[0], top: +obj[1] || 0 };
6220		}
6221		if ("left" in obj) {
6222			this.offset.click.left = obj.left + this.margins.left;
6223		}
6224		if ("right" in obj) {
6225			this.offset.click.left = this.helperProportions.width - obj.right + this.margins.left;
6226		}
6227		if ("top" in obj) {
6228			this.offset.click.top = obj.top + this.margins.top;
6229		}
6230		if ("bottom" in obj) {
6231			this.offset.click.top = this.helperProportions.height - obj.bottom + this.margins.top;
6232		}
6233	},
6234
6235	_isRootNode: function( element ) {
6236		return ( /(html|body)/i ).test( element.tagName ) || element === this.document[ 0 ];
6237	},
6238
6239	_getParentOffset: function() {
6240
6241		//Get the offsetParent and cache its position
6242		var po = this.offsetParent.offset(),
6243			document = this.document[ 0 ];
6244
6245		// This is a special case where we need to modify a offset calculated on start, since the following happened:
6246		// 1. The position of the helper is absolute, so it's position is calculated based on the next positioned parent
6247		// 2. The actual offset parent is a child of the scroll parent, and the scroll parent isn't the document, which means that
6248		//    the scroll is included in the initial calculation of the offset of the parent, and never recalculated upon drag
6249		if (this.cssPosition === "absolute" && this.scrollParent[0] !== document && $.contains(this.scrollParent[0], this.offsetParent[0])) {
6250			po.left += this.scrollParent.scrollLeft();
6251			po.top += this.scrollParent.scrollTop();
6252		}
6253
6254		if ( this._isRootNode( this.offsetParent[ 0 ] ) ) {
6255			po = { top: 0, left: 0 };
6256		}
6257
6258		return {
6259			top: po.top + (parseInt(this.offsetParent.css("borderTopWidth"), 10) || 0),
6260			left: po.left + (parseInt(this.offsetParent.css("borderLeftWidth"), 10) || 0)
6261		};
6262
6263	},
6264
6265	_getRelativeOffset: function() {
6266		if ( this.cssPosition !== "relative" ) {
6267			return { top: 0, left: 0 };
6268		}
6269
6270		var p = this.element.position(),
6271			scrollIsRootNode = this._isRootNode( this.scrollParent[ 0 ] );
6272
6273		return {
6274			top: p.top - ( parseInt(this.helper.css( "top" ), 10) || 0 ) + ( !scrollIsRootNode ? this.scrollParent.scrollTop() : 0 ),
6275			left: p.left - ( parseInt(this.helper.css( "left" ), 10) || 0 ) + ( !scrollIsRootNode ? this.scrollParent.scrollLeft() : 0 )
6276		};
6277
6278	},
6279
6280	_cacheMargins: function() {
6281		this.margins = {
6282			left: (parseInt(this.element.css("marginLeft"), 10) || 0),
6283			top: (parseInt(this.element.css("marginTop"), 10) || 0),
6284			right: (parseInt(this.element.css("marginRight"), 10) || 0),
6285			bottom: (parseInt(this.element.css("marginBottom"), 10) || 0)
6286		};
6287	},
6288
6289	_cacheHelperProportions: function() {
6290		this.helperProportions = {
6291			width: this.helper.outerWidth(),
6292			height: this.helper.outerHeight()
6293		};
6294	},
6295
6296	_setContainment: function() {
6297
6298		var isUserScrollable, c, ce,
6299			o = this.options,
6300			document = this.document[ 0 ];
6301
6302		this.relativeContainer = null;
6303
6304		if ( !o.containment ) {
6305			this.containment = null;
6306			return;
6307		}
6308
6309		if ( o.containment === "window" ) {
6310			this.containment = [
6311				$( window ).scrollLeft() - this.offset.relative.left - this.offset.parent.left,
6312				$( window ).scrollTop() - this.offset.relative.top - this.offset.parent.top,
6313				$( window ).scrollLeft() + $( window ).width() - this.helperProportions.width - this.margins.left,
6314				$( window ).scrollTop() + ( $( window ).height() || document.body.parentNode.scrollHeight ) - this.helperProportions.height - this.margins.top
6315			];
6316			return;
6317		}
6318
6319		if ( o.containment === "document") {
6320			this.containment = [
6321				0,
6322				0,
6323				$( document ).width() - this.helperProportions.width - this.margins.left,
6324				( $( document ).height() || document.body.parentNode.scrollHeight ) - this.helperProportions.height - this.margins.top
6325			];
6326			return;
6327		}
6328
6329		if ( o.containment.constructor === Array ) {
6330			this.containment = o.containment;
6331			return;
6332		}
6333
6334		if ( o.containment === "parent" ) {
6335			o.containment = this.helper[ 0 ].parentNode;
6336		}
6337
6338		c = $( o.containment );
6339		ce = c[ 0 ];
6340
6341		if ( !ce ) {
6342			return;
6343		}
6344
6345		isUserScrollable = /(scroll|auto)/.test( c.css( "overflow" ) );
6346
6347		this.containment = [
6348			( parseInt( c.css( "borderLeftWidth" ), 10 ) || 0 ) + ( parseInt( c.css( "paddingLeft" ), 10 ) || 0 ),
6349			( parseInt( c.css( "borderTopWidth" ), 10 ) || 0 ) + ( parseInt( c.css( "paddingTop" ), 10 ) || 0 ),
6350			( isUserScrollable ? Math.max( ce.scrollWidth, ce.offsetWidth ) : ce.offsetWidth ) -
6351				( parseInt( c.css( "borderRightWidth" ), 10 ) || 0 ) -
6352				( parseInt( c.css( "paddingRight" ), 10 ) || 0 ) -
6353				this.helperProportions.width -
6354				this.margins.left -
6355				this.margins.right,
6356			( isUserScrollable ? Math.max( ce.scrollHeight, ce.offsetHeight ) : ce.offsetHeight ) -
6357				( parseInt( c.css( "borderBottomWidth" ), 10 ) || 0 ) -
6358				( parseInt( c.css( "paddingBottom" ), 10 ) || 0 ) -
6359				this.helperProportions.height -
6360				this.margins.top -
6361				this.margins.bottom
6362		];
6363		this.relativeContainer = c;
6364	},
6365
6366	_convertPositionTo: function(d, pos) {
6367
6368		if (!pos) {
6369			pos = this.position;
6370		}
6371
6372		var mod = d === "absolute" ? 1 : -1,
6373			scrollIsRootNode = this._isRootNode( this.scrollParent[ 0 ] );
6374
6375		return {
6376			top: (
6377				pos.top	+																// The absolute mouse position
6378				this.offset.relative.top * mod +										// Only for relative positioned nodes: Relative offset from element to offset parent
6379				this.offset.parent.top * mod -										// The offsetParent's offset without borders (offset + border)
6380				( ( this.cssPosition === "fixed" ? -this.offset.scroll.top : ( scrollIsRootNode ? 0 : this.offset.scroll.top ) ) * mod)
6381			),
6382			left: (
6383				pos.left +																// The absolute mouse position
6384				this.offset.relative.left * mod +										// Only for relative positioned nodes: Relative offset from element to offset parent
6385				this.offset.parent.left * mod	-										// The offsetParent's offset without borders (offset + border)
6386				( ( this.cssPosition === "fixed" ? -this.offset.scroll.left : ( scrollIsRootNode ? 0 : this.offset.scroll.left ) ) * mod)
6387			)
6388		};
6389
6390	},
6391
6392	_generatePosition: function( event, constrainPosition ) {
6393
6394		var containment, co, top, left,
6395			o = this.options,
6396			scrollIsRootNode = this._isRootNode( this.scrollParent[ 0 ] ),
6397			pageX = event.pageX,
6398			pageY = event.pageY;
6399
6400		// Cache the scroll
6401		if ( !scrollIsRootNode || !this.offset.scroll ) {
6402			this.offset.scroll = {
6403				top: this.scrollParent.scrollTop(),
6404				left: this.scrollParent.scrollLeft()
6405			};
6406		}
6407
6408		/*
6409		 * - Position constraining -
6410		 * Constrain the position to a mix of grid, containment.
6411		 */
6412
6413		// If we are not dragging yet, we won't check for options
6414		if ( constrainPosition ) {
6415			if ( this.containment ) {
6416				if ( this.relativeContainer ){
6417					co = this.relativeContainer.offset();
6418					containment = [
6419						this.containment[ 0 ] + co.left,
6420						this.containment[ 1 ] + co.top,
6421						this.containment[ 2 ] + co.left,
6422						this.containment[ 3 ] + co.top
6423					];
6424				} else {
6425					containment = this.containment;
6426				}
6427
6428				if (event.pageX - this.offset.click.left < containment[0]) {
6429					pageX = containment[0] + this.offset.click.left;
6430				}
6431				if (event.pageY - this.offset.click.top < containment[1]) {
6432					pageY = containment[1] + this.offset.click.top;
6433				}
6434				if (event.pageX - this.offset.click.left > containment[2]) {
6435					pageX = containment[2] + this.offset.click.left;
6436				}
6437				if (event.pageY - this.offset.click.top > containment[3]) {
6438					pageY = containment[3] + this.offset.click.top;
6439				}
6440			}
6441
6442			if (o.grid) {
6443				//Check for grid elements set to 0 to prevent divide by 0 error causing invalid argument errors in IE (see ticket #6950)
6444				top = o.grid[1] ? this.originalPageY + Math.round((pageY - this.originalPageY) / o.grid[1]) * o.grid[1] : this.originalPageY;
6445				pageY = containment ? ((top - this.offset.click.top >= containment[1] || top - this.offset.click.top > containment[3]) ? top : ((top - this.offset.click.top >= containment[1]) ? top - o.grid[1] : top + o.grid[1])) : top;
6446
6447				left = o.grid[0] ? this.originalPageX + Math.round((pageX - this.originalPageX) / o.grid[0]) * o.grid[0] : this.originalPageX;
6448				pageX = containment ? ((left - this.offset.click.left >= containment[0] || left - this.offset.click.left > containment[2]) ? left : ((left - this.offset.click.left >= containment[0]) ? left - o.grid[0] : left + o.grid[0])) : left;
6449			}
6450
6451			if ( o.axis === "y" ) {
6452				pageX = this.originalPageX;
6453			}
6454
6455			if ( o.axis === "x" ) {
6456				pageY = this.originalPageY;
6457			}
6458		}
6459
6460		return {
6461			top: (
6462				pageY -																	// The absolute mouse position
6463				this.offset.click.top	-												// Click offset (relative to the element)
6464				this.offset.relative.top -												// Only for relative positioned nodes: Relative offset from element to offset parent
6465				this.offset.parent.top +												// The offsetParent's offset without borders (offset + border)
6466				( this.cssPosition === "fixed" ? -this.offset.scroll.top : ( scrollIsRootNode ? 0 : this.offset.scroll.top ) )
6467			),
6468			left: (
6469				pageX -																	// The absolute mouse position
6470				this.offset.click.left -												// Click offset (relative to the element)
6471				this.offset.relative.left -												// Only for relative positioned nodes: Relative offset from element to offset parent
6472				this.offset.parent.left +												// The offsetParent's offset without borders (offset + border)
6473				( this.cssPosition === "fixed" ? -this.offset.scroll.left : ( scrollIsRootNode ? 0 : this.offset.scroll.left ) )
6474			)
6475		};
6476
6477	},
6478
6479	_clear: function() {
6480		this.helper.removeClass("ui-draggable-dragging");
6481		if (this.helper[0] !== this.element[0] && !this.cancelHelperRemoval) {
6482			this.helper.remove();
6483		}
6484		this.helper = null;
6485		this.cancelHelperRemoval = false;
6486		if ( this.destroyOnClear ) {
6487			this.destroy();
6488		}
6489	},
6490
6491	_normalizeRightBottom: function() {
6492		if ( this.options.axis !== "y" && this.helper.css( "right" ) !== "auto" ) {
6493			this.helper.width( this.helper.width() );
6494			this.helper.css( "right", "auto" );
6495		}
6496		if ( this.options.axis !== "x" && this.helper.css( "bottom" ) !== "auto" ) {
6497			this.helper.height( this.helper.height() );
6498			this.helper.css( "bottom", "auto" );
6499		}
6500	},
6501
6502	// From now on bulk stuff - mainly helpers
6503
6504	_trigger: function( type, event, ui ) {
6505		ui = ui || this._uiHash();
6506		$.ui.plugin.call( this, type, [ event, ui, this ], true );
6507
6508		// Absolute position and offset (see #6884 ) have to be recalculated after plugins
6509		if ( /^(drag|start|stop)/.test( type ) ) {
6510			this.positionAbs = this._convertPositionTo( "absolute" );
6511			ui.offset = this.positionAbs;
6512		}
6513		return $.Widget.prototype._trigger.call( this, type, event, ui );
6514	},
6515
6516	plugins: {},
6517
6518	_uiHash: function() {
6519		return {
6520			helper: this.helper,
6521			position: this.position,
6522			originalPosition: this.originalPosition,
6523			offset: this.positionAbs
6524		};
6525	}
6526
6527});
6528
6529$.ui.plugin.add( "draggable", "connectToSortable", {
6530	start: function( event, ui, draggable ) {
6531		var uiSortable = $.extend( {}, ui, {
6532			item: draggable.element
6533		});
6534
6535		draggable.sortables = [];
6536		$( draggable.options.connectToSortable ).each(function() {
6537			var sortable = $( this ).sortable( "instance" );
6538
6539			if ( sortable && !sortable.options.disabled ) {
6540				draggable.sortables.push( sortable );
6541
6542				// refreshPositions is called at drag start to refresh the containerCache
6543				// which is used in drag. This ensures it's initialized and synchronized
6544				// with any changes that might have happened on the page since initialization.
6545				sortable.refreshPositions();
6546				sortable._trigger("activate", event, uiSortable);
6547			}
6548		});
6549	},
6550	stop: function( event, ui, draggable ) {
6551		var uiSortable = $.extend( {}, ui, {
6552			item: draggable.element
6553		});
6554
6555		draggable.cancelHelperRemoval = false;
6556
6557		$.each( draggable.sortables, function() {
6558			var sortable = this;
6559
6560			if ( sortable.isOver ) {
6561				sortable.isOver = 0;
6562
6563				// Allow this sortable to handle removing the helper
6564				draggable.cancelHelperRemoval = true;
6565				sortable.cancelHelperRemoval = false;
6566
6567				// Use _storedCSS To restore properties in the sortable,
6568				// as this also handles revert (#9675) since the draggable
6569				// may have modified them in unexpected ways (#8809)
6570				sortable._storedCSS = {
6571					position: sortable.placeholder.css( "position" ),
6572					top: sortable.placeholder.css( "top" ),
6573					left: sortable.placeholder.css( "left" )
6574				};
6575
6576				sortable._mouseStop(event);
6577
6578				// Once drag has ended, the sortable should return to using
6579				// its original helper, not the shared helper from draggable
6580				sortable.options.helper = sortable.options._helper;
6581			} else {
6582				// Prevent this Sortable from removing the helper.
6583				// However, don't set the draggable to remove the helper
6584				// either as another connected Sortable may yet handle the removal.
6585				sortable.cancelHelperRemoval = true;
6586
6587				sortable._trigger( "deactivate", event, uiSortable );
6588			}
6589		});
6590	},
6591	drag: function( event, ui, draggable ) {
6592		$.each( draggable.sortables, function() {
6593			var innermostIntersecting = false,
6594				sortable = this;
6595
6596			// Copy over variables that sortable's _intersectsWith uses
6597			sortable.positionAbs = draggable.positionAbs;
6598			sortable.helperProportions = draggable.helperProportions;
6599			sortable.offset.click = draggable.offset.click;
6600
6601			if ( sortable._intersectsWith( sortable.containerCache ) ) {
6602				innermostIntersecting = true;
6603
6604				$.each( draggable.sortables, function() {
6605					// Copy over variables that sortable's _intersectsWith uses
6606					this.positionAbs = draggable.positionAbs;
6607					this.helperProportions = draggable.helperProportions;
6608					this.offset.click = draggable.offset.click;
6609
6610					if ( this !== sortable &&
6611							this._intersectsWith( this.containerCache ) &&
6612							$.contains( sortable.element[ 0 ], this.element[ 0 ] ) ) {
6613						innermostIntersecting = false;
6614					}
6615
6616					return innermostIntersecting;
6617				});
6618			}
6619
6620			if ( innermostIntersecting ) {
6621				// If it intersects, we use a little isOver variable and set it once,
6622				// so that the move-in stuff gets fired only once.
6623				if ( !sortable.isOver ) {
6624					sortable.isOver = 1;
6625
6626					// Store draggable's parent in case we need to reappend to it later.
6627					draggable._parent = ui.helper.parent();
6628
6629					sortable.currentItem = ui.helper
6630						.appendTo( sortable.element )
6631						.data( "ui-sortable-item", true );
6632
6633					// Store helper option to later restore it
6634					sortable.options._helper = sortable.options.helper;
6635
6636					sortable.options.helper = function() {
6637						return ui.helper[ 0 ];
6638					};
6639
6640					// Fire the start events of the sortable with our passed browser event,
6641					// and our own helper (so it doesn't create a new one)
6642					event.target = sortable.currentItem[ 0 ];
6643					sortable._mouseCapture( event, true );
6644					sortable._mouseStart( event, true, true );
6645
6646					// Because the browser event is way off the new appended portlet,
6647					// modify necessary variables to reflect the changes
6648					sortable.offset.click.top = draggable.offset.click.top;
6649					sortable.offset.click.left = draggable.offset.click.left;
6650					sortable.offset.parent.left -= draggable.offset.parent.left -
6651						sortable.offset.parent.left;
6652					sortable.offset.parent.top -= draggable.offset.parent.top -
6653						sortable.offset.parent.top;
6654
6655					draggable._trigger( "toSortable", event );
6656
6657					// Inform draggable that the helper is in a valid drop zone,
6658					// used solely in the revert option to handle "valid/invalid".
6659					draggable.dropped = sortable.element;
6660
6661					// Need to refreshPositions of all sortables in the case that
6662					// adding to one sortable changes the location of the other sortables (#9675)
6663					$.each( draggable.sortables, function() {
6664						this.refreshPositions();
6665					});
6666
6667					// hack so receive/update callbacks work (mostly)
6668					draggable.currentItem = draggable.element;
6669					sortable.fromOutside = draggable;
6670				}
6671
6672				if ( sortable.currentItem ) {
6673					sortable._mouseDrag( event );
6674					// Copy the sortable's position because the draggable's can potentially reflect
6675					// a relative position, while sortable is always absolute, which the dragged
6676					// element has now become. (#8809)
6677					ui.position = sortable.position;
6678				}
6679			} else {
6680				// If it doesn't intersect with the sortable, and it intersected before,
6681				// we fake the drag stop of the sortable, but make sure it doesn't remove
6682				// the helper by using cancelHelperRemoval.
6683				if ( sortable.isOver ) {
6684
6685					sortable.isOver = 0;
6686					sortable.cancelHelperRemoval = true;
6687
6688					// Calling sortable's mouseStop would trigger a revert,
6689					// so revert must be temporarily false until after mouseStop is called.
6690					sortable.options._revert = sortable.options.revert;
6691					sortable.options.revert = false;
6692
6693					sortable._trigger( "out", event, sortable._uiHash( sortable ) );
6694					sortable._mouseStop( event, true );
6695
6696					// restore sortable behaviors that were modfied
6697					// when the draggable entered the sortable area (#9481)
6698					sortable.options.revert = sortable.options._revert;
6699					sortable.options.helper = sortable.options._helper;
6700
6701					if ( sortable.placeholder ) {
6702						sortable.placeholder.remove();
6703					}
6704
6705					// Restore and recalculate the draggable's offset considering the sortable
6706					// may have modified them in unexpected ways. (#8809, #10669)
6707					ui.helper.appendTo( draggable._parent );
6708					draggable._refreshOffsets( event );
6709					ui.position = draggable._generatePosition( event, true );
6710
6711					draggable._trigger( "fromSortable", event );
6712
6713					// Inform draggable that the helper is no longer in a valid drop zone
6714					draggable.dropped = false;
6715
6716					// Need to refreshPositions of all sortables just in case removing
6717					// from one sortable changes the location of other sortables (#9675)
6718					$.each( draggable.sortables, function() {
6719						this.refreshPositions();
6720					});
6721				}
6722			}
6723		});
6724	}
6725});
6726
6727$.ui.plugin.add("draggable", "cursor", {
6728	start: function( event, ui, instance ) {
6729		var t = $( "body" ),
6730			o = instance.options;
6731
6732		if (t.css("cursor")) {
6733			o._cursor = t.css("cursor");
6734		}
6735		t.css("cursor", o.cursor);
6736	},
6737	stop: function( event, ui, instance ) {
6738		var o = instance.options;
6739		if (o._cursor) {
6740			$("body").css("cursor", o._cursor);
6741		}
6742	}
6743});
6744
6745$.ui.plugin.add("draggable", "opacity", {
6746	start: function( event, ui, instance ) {
6747		var t = $( ui.helper ),
6748			o = instance.options;
6749		if (t.css("opacity")) {
6750			o._opacity = t.css("opacity");
6751		}
6752		t.css("opacity", o.opacity);
6753	},
6754	stop: function( event, ui, instance ) {
6755		var o = instance.options;
6756		if (o._opacity) {
6757			$(ui.helper).css("opacity", o._opacity);
6758		}
6759	}
6760});
6761
6762$.ui.plugin.add("draggable", "scroll", {
6763	start: function( event, ui, i ) {
6764		if ( !i.scrollParentNotHidden ) {
6765			i.scrollParentNotHidden = i.helper.scrollParent( false );
6766		}
6767
6768		if ( i.scrollParentNotHidden[ 0 ] !== i.document[ 0 ] && i.scrollParentNotHidden[ 0 ].tagName !== "HTML" ) {
6769			i.overflowOffset = i.scrollParentNotHidden.offset();
6770		}
6771	},
6772	drag: function( event, ui, i  ) {
6773
6774		var o = i.options,
6775			scrolled = false,
6776			scrollParent = i.scrollParentNotHidden[ 0 ],
6777			document = i.document[ 0 ];
6778
6779		if ( scrollParent !== document && scrollParent.tagName !== "HTML" ) {
6780			if ( !o.axis || o.axis !== "x" ) {
6781				if ( ( i.overflowOffset.top + scrollParent.offsetHeight ) - event.pageY < o.scrollSensitivity ) {
6782					scrollParent.scrollTop = scrolled = scrollParent.scrollTop + o.scrollSpeed;
6783				} else if ( event.pageY - i.overflowOffset.top < o.scrollSensitivity ) {
6784					scrollParent.scrollTop = scrolled = scrollParent.scrollTop - o.scrollSpeed;
6785				}
6786			}
6787
6788			if ( !o.axis || o.axis !== "y" ) {
6789				if ( ( i.overflowOffset.left + scrollParent.offsetWidth ) - event.pageX < o.scrollSensitivity ) {
6790					scrollParent.scrollLeft = scrolled = scrollParent.scrollLeft + o.scrollSpeed;
6791				} else if ( event.pageX - i.overflowOffset.left < o.scrollSensitivity ) {
6792					scrollParent.scrollLeft = scrolled = scrollParent.scrollLeft - o.scrollSpeed;
6793				}
6794			}
6795
6796		} else {
6797
6798			if (!o.axis || o.axis !== "x") {
6799				if (event.pageY - $(document).scrollTop() < o.scrollSensitivity) {
6800					scrolled = $(document).scrollTop($(document).scrollTop() - o.scrollSpeed);
6801				} else if ($(window).height() - (event.pageY - $(document).scrollTop()) < o.scrollSensitivity) {
6802					scrolled = $(document).scrollTop($(document).scrollTop() + o.scrollSpeed);
6803				}
6804			}
6805
6806			if (!o.axis || o.axis !== "y") {
6807				if (event.pageX - $(document).scrollLeft() < o.scrollSensitivity) {
6808					scrolled = $(document).scrollLeft($(document).scrollLeft() - o.scrollSpeed);
6809				} else if ($(window).width() - (event.pageX - $(document).scrollLeft()) < o.scrollSensitivity) {
6810					scrolled = $(document).scrollLeft($(document).scrollLeft() + o.scrollSpeed);
6811				}
6812			}
6813
6814		}
6815
6816		if (scrolled !== false && $.ui.ddmanager && !o.dropBehaviour) {
6817			$.ui.ddmanager.prepareOffsets(i, event);
6818		}
6819
6820	}
6821});
6822
6823$.ui.plugin.add("draggable", "snap", {
6824	start: function( event, ui, i ) {
6825
6826		var o = i.options;
6827
6828		i.snapElements = [];
6829
6830		$(o.snap.constructor !== String ? ( o.snap.items || ":data(ui-draggable)" ) : o.snap).each(function() {
6831			var $t = $(this),
6832				$o = $t.offset();
6833			if (this !== i.element[0]) {
6834				i.snapElements.push({
6835					item: this,
6836					width: $t.outerWidth(), height: $t.outerHeight(),
6837					top: $o.top, left: $o.left
6838				});
6839			}
6840		});
6841
6842	},
6843	drag: function( event, ui, inst ) {
6844
6845		var ts, bs, ls, rs, l, r, t, b, i, first,
6846			o = inst.options,
6847			d = o.snapTolerance,
6848			x1 = ui.offset.left, x2 = x1 + inst.helperProportions.width,
6849			y1 = ui.offset.top, y2 = y1 + inst.helperProportions.height;
6850
6851		for (i = inst.snapElements.length - 1; i >= 0; i--){
6852
6853			l = inst.snapElements[i].left - inst.margins.left;
6854			r = l + inst.snapElements[i].width;
6855			t = inst.snapElements[i].top - inst.margins.top;
6856			b = t + inst.snapElements[i].height;
6857
6858			if ( x2 < l - d || x1 > r + d || y2 < t - d || y1 > b + d || !$.contains( inst.snapElements[ i ].item.ownerDocument, inst.snapElements[ i ].item ) ) {
6859				if (inst.snapElements[i].snapping) {
6860					(inst.options.snap.release && inst.options.snap.release.call(inst.element, event, $.extend(inst._uiHash(), { snapItem: inst.snapElements[i].item })));
6861				}
6862				inst.snapElements[i].snapping = false;
6863				continue;
6864			}
6865
6866			if (o.snapMode !== "inner") {
6867				ts = Math.abs(t - y2) <= d;
6868				bs = Math.abs(b - y1) <= d;
6869				ls = Math.abs(l - x2) <= d;
6870				rs = Math.abs(r - x1) <= d;
6871				if (ts) {
6872					ui.position.top = inst._convertPositionTo("relative", { top: t - inst.helperProportions.height, left: 0 }).top;
6873				}
6874				if (bs) {
6875					ui.position.top = inst._convertPositionTo("relative", { top: b, left: 0 }).top;
6876				}
6877				if (ls) {
6878					ui.position.left = inst._convertPositionTo("relative", { top: 0, left: l - inst.helperProportions.width }).left;
6879				}
6880				if (rs) {
6881					ui.position.left = inst._convertPositionTo("relative", { top: 0, left: r }).left;
6882				}
6883			}
6884
6885			first = (ts || bs || ls || rs);
6886
6887			if (o.snapMode !== "outer") {
6888				ts = Math.abs(t - y1) <= d;
6889				bs = Math.abs(b - y2) <= d;
6890				ls = Math.abs(l - x1) <= d;
6891				rs = Math.abs(r - x2) <= d;
6892				if (ts) {
6893					ui.position.top = inst._convertPositionTo("relative", { top: t, left: 0 }).top;
6894				}
6895				if (bs) {
6896					ui.position.top = inst._convertPositionTo("relative", { top: b - inst.helperProportions.height, left: 0 }).top;
6897				}
6898				if (ls) {
6899					ui.position.left = inst._convertPositionTo("relative", { top: 0, left: l }).left;
6900				}
6901				if (rs) {
6902					ui.position.left = inst._convertPositionTo("relative", { top: 0, left: r - inst.helperProportions.width }).left;
6903				}
6904			}
6905
6906			if (!inst.snapElements[i].snapping && (ts || bs || ls || rs || first)) {
6907				(inst.options.snap.snap && inst.options.snap.snap.call(inst.element, event, $.extend(inst._uiHash(), { snapItem: inst.snapElements[i].item })));
6908			}
6909			inst.snapElements[i].snapping = (ts || bs || ls || rs || first);
6910
6911		}
6912
6913	}
6914});
6915
6916$.ui.plugin.add("draggable", "stack", {
6917	start: function( event, ui, instance ) {
6918		var min,
6919			o = instance.options,
6920			group = $.makeArray($(o.stack)).sort(function(a, b) {
6921				return (parseInt($(a).css("zIndex"), 10) || 0) - (parseInt($(b).css("zIndex"), 10) || 0);
6922			});
6923
6924		if (!group.length) { return; }
6925
6926		min = parseInt($(group[0]).css("zIndex"), 10) || 0;
6927		$(group).each(function(i) {
6928			$(this).css("zIndex", min + i);
6929		});
6930		this.css("zIndex", (min + group.length));
6931	}
6932});
6933
6934$.ui.plugin.add("draggable", "zIndex", {
6935	start: function( event, ui, instance ) {
6936		var t = $( ui.helper ),
6937			o = instance.options;
6938
6939		if (t.css("zIndex")) {
6940			o._zIndex = t.css("zIndex");
6941		}
6942		t.css("zIndex", o.zIndex);
6943	},
6944	stop: function( event, ui, instance ) {
6945		var o = instance.options;
6946
6947		if (o._zIndex) {
6948			$(ui.helper).css("zIndex", o._zIndex);
6949		}
6950	}
6951});
6952
6953var draggable = $.ui.draggable;
6954
6955
6956/*!
6957 * jQuery UI Resizable 1.11.4
6958 * http://jqueryui.com
6959 *
6960 * Copyright jQuery Foundation and other contributors
6961 * Released under the MIT license.
6962 * http://jquery.org/license
6963 *
6964 * http://api.jqueryui.com/resizable/
6965 */
6966
6967
6968$.widget("ui.resizable", $.ui.mouse, {
6969	version: "1.11.4",
6970	widgetEventPrefix: "resize",
6971	options: {
6972		alsoResize: false,
6973		animate: false,
6974		animateDuration: "slow",
6975		animateEasing: "swing",
6976		aspectRatio: false,
6977		autoHide: false,
6978		containment: false,
6979		ghost: false,
6980		grid: false,
6981		handles: "e,s,se",
6982		helper: false,
6983		maxHeight: null,
6984		maxWidth: null,
6985		minHeight: 10,
6986		minWidth: 10,
6987		// See #7960
6988		zIndex: 90,
6989
6990		// callbacks
6991		resize: null,
6992		start: null,
6993		stop: null
6994	},
6995
6996	_num: function( value ) {
6997		return parseInt( value, 10 ) || 0;
6998	},
6999
7000	_isNumber: function( value ) {
7001		return !isNaN( parseInt( value, 10 ) );
7002	},
7003
7004	_hasScroll: function( el, a ) {
7005
7006		if ( $( el ).css( "overflow" ) === "hidden") {
7007			return false;
7008		}
7009
7010		var scroll = ( a && a === "left" ) ? "scrollLeft" : "scrollTop",
7011			has = false;
7012
7013		if ( el[ scroll ] > 0 ) {
7014			return true;
7015		}
7016
7017		// TODO: determine which cases actually cause this to happen
7018		// if the element doesn't have the scroll set, see if it's possible to
7019		// set the scroll
7020		el[ scroll ] = 1;
7021		has = ( el[ scroll ] > 0 );
7022		el[ scroll ] = 0;
7023		return has;
7024	},
7025
7026	_create: function() {
7027
7028		var n, i, handle, axis, hname,
7029			that = this,
7030			o = this.options;
7031		this.element.addClass("ui-resizable");
7032
7033		$.extend(this, {
7034			_aspectRatio: !!(o.aspectRatio),
7035			aspectRatio: o.aspectRatio,
7036			originalElement: this.element,
7037			_proportionallyResizeElements: [],
7038			_helper: o.helper || o.ghost || o.animate ? o.helper || "ui-resizable-helper" : null
7039		});
7040
7041		// Wrap the element if it cannot hold child nodes
7042		if (this.element[0].nodeName.match(/^(canvas|textarea|input|select|button|img)$/i)) {
7043
7044			this.element.wrap(
7045				$("<div class='ui-wrapper' style='overflow: hidden;'></div>").css({
7046					position: this.element.css("position"),
7047					width: this.element.outerWidth(),
7048					height: this.element.outerHeight(),
7049					top: this.element.css("top"),
7050					left: this.element.css("left")
7051				})
7052			);
7053
7054			this.element = this.element.parent().data(
7055				"ui-resizable", this.element.resizable( "instance" )
7056			);
7057
7058			this.elementIsWrapper = true;
7059
7060			this.element.css({
7061				marginLeft: this.originalElement.css("marginLeft"),
7062				marginTop: this.originalElement.css("marginTop"),
7063				marginRight: this.originalElement.css("marginRight"),
7064				marginBottom: this.originalElement.css("marginBottom")
7065			});
7066			this.originalElement.css({
7067				marginLeft: 0,
7068				marginTop: 0,
7069				marginRight: 0,
7070				marginBottom: 0
7071			});
7072			// support: Safari
7073			// Prevent Safari textarea resize
7074			this.originalResizeStyle = this.originalElement.css("resize");
7075			this.originalElement.css("resize", "none");
7076
7077			this._proportionallyResizeElements.push( this.originalElement.css({
7078				position: "static",
7079				zoom: 1,
7080				display: "block"
7081			}) );
7082
7083			// support: IE9
7084			// avoid IE jump (hard set the margin)
7085			this.originalElement.css({ margin: this.originalElement.css("margin") });
7086
7087			this._proportionallyResize();
7088		}
7089
7090		this.handles = o.handles ||
7091			( !$(".ui-resizable-handle", this.element).length ?
7092				"e,s,se" : {
7093					n: ".ui-resizable-n",
7094					e: ".ui-resizable-e",
7095					s: ".ui-resizable-s",
7096					w: ".ui-resizable-w",
7097					se: ".ui-resizable-se",
7098					sw: ".ui-resizable-sw",
7099					ne: ".ui-resizable-ne",
7100					nw: ".ui-resizable-nw"
7101				} );
7102
7103		this._handles = $();
7104		if ( this.handles.constructor === String ) {
7105
7106			if ( this.handles === "all") {
7107				this.handles = "n,e,s,w,se,sw,ne,nw";
7108			}
7109
7110			n = this.handles.split(",");
7111			this.handles = {};
7112
7113			for (i = 0; i < n.length; i++) {
7114
7115				handle = $.trim(n[i]);
7116				hname = "ui-resizable-" + handle;
7117				axis = $("<div class='ui-resizable-handle " + hname + "'></div>");
7118
7119				axis.css({ zIndex: o.zIndex });
7120
7121				// TODO : What's going on here?
7122				if ("se" === handle) {
7123					axis.addClass("ui-icon ui-icon-gripsmall-diagonal-se");
7124				}
7125
7126				this.handles[handle] = ".ui-resizable-" + handle;
7127				this.element.append(axis);
7128			}
7129
7130		}
7131
7132		this._renderAxis = function(target) {
7133
7134			var i, axis, padPos, padWrapper;
7135
7136			target = target || this.element;
7137
7138			for (i in this.handles) {
7139
7140				if (this.handles[i].constructor === String) {
7141					this.handles[i] = this.element.children( this.handles[ i ] ).first().show();
7142				} else if ( this.handles[ i ].jquery || this.handles[ i ].nodeType ) {
7143					this.handles[ i ] = $( this.handles[ i ] );
7144					this._on( this.handles[ i ], { "mousedown": that._mouseDown });
7145				}
7146
7147				if (this.elementIsWrapper && this.originalElement[0].nodeName.match(/^(textarea|input|select|button)$/i)) {
7148
7149					axis = $(this.handles[i], this.element);
7150
7151					padWrapper = /sw|ne|nw|se|n|s/.test(i) ? axis.outerHeight() : axis.outerWidth();
7152
7153					padPos = [ "padding",
7154						/ne|nw|n/.test(i) ? "Top" :
7155						/se|sw|s/.test(i) ? "Bottom" :
7156						/^e$/.test(i) ? "Right" : "Left" ].join("");
7157
7158					target.css(padPos, padWrapper);
7159
7160					this._proportionallyResize();
7161				}
7162
7163				this._handles = this._handles.add( this.handles[ i ] );
7164			}
7165		};
7166
7167		// TODO: make renderAxis a prototype function
7168		this._renderAxis(this.element);
7169
7170		this._handles = this._handles.add( this.element.find( ".ui-resizable-handle" ) );
7171		this._handles.disableSelection();
7172
7173		this._handles.mouseover(function() {
7174			if (!that.resizing) {
7175				if (this.className) {
7176					axis = this.className.match(/ui-resizable-(se|sw|ne|nw|n|e|s|w)/i);
7177				}
7178				that.axis = axis && axis[1] ? axis[1] : "se";
7179			}
7180		});
7181
7182		if (o.autoHide) {
7183			this._handles.hide();
7184			$(this.element)
7185				.addClass("ui-resizable-autohide")
7186				.mouseenter(function() {
7187					if (o.disabled) {
7188						return;
7189					}
7190					$(this).removeClass("ui-resizable-autohide");
7191					that._handles.show();
7192				})
7193				.mouseleave(function() {
7194					if (o.disabled) {
7195						return;
7196					}
7197					if (!that.resizing) {
7198						$(this).addClass("ui-resizable-autohide");
7199						that._handles.hide();
7200					}
7201				});
7202		}
7203
7204		this._mouseInit();
7205	},
7206
7207	_destroy: function() {
7208
7209		this._mouseDestroy();
7210
7211		var wrapper,
7212			_destroy = function(exp) {
7213				$(exp)
7214					.removeClass("ui-resizable ui-resizable-disabled ui-resizable-resizing")
7215					.removeData("resizable")
7216					.removeData("ui-resizable")
7217					.unbind(".resizable")
7218					.find(".ui-resizable-handle")
7219						.remove();
7220			};
7221
7222		// TODO: Unwrap at same DOM position
7223		if (this.elementIsWrapper) {
7224			_destroy(this.element);
7225			wrapper = this.element;
7226			this.originalElement.css({
7227				position: wrapper.css("position"),
7228				width: wrapper.outerWidth(),
7229				height: wrapper.outerHeight(),
7230				top: wrapper.css("top"),
7231				left: wrapper.css("left")
7232			}).insertAfter( wrapper );
7233			wrapper.remove();
7234		}
7235
7236		this.originalElement.css("resize", this.originalResizeStyle);
7237		_destroy(this.originalElement);
7238
7239		return this;
7240	},
7241
7242	_mouseCapture: function(event) {
7243		var i, handle,
7244			capture = false;
7245
7246		for (i in this.handles) {
7247			handle = $(this.handles[i])[0];
7248			if (handle === event.target || $.contains(handle, event.target)) {
7249				capture = true;
7250			}
7251		}
7252
7253		return !this.options.disabled && capture;
7254	},
7255
7256	_mouseStart: function(event) {
7257
7258		var curleft, curtop, cursor,
7259			o = this.options,
7260			el = this.element;
7261
7262		this.resizing = true;
7263
7264		this._renderProxy();
7265
7266		curleft = this._num(this.helper.css("left"));
7267		curtop = this._num(this.helper.css("top"));
7268
7269		if (o.containment) {
7270			curleft += $(o.containment).scrollLeft() || 0;
7271			curtop += $(o.containment).scrollTop() || 0;
7272		}
7273
7274		this.offset = this.helper.offset();
7275		this.position = { left: curleft, top: curtop };
7276
7277		this.size = this._helper ? {
7278				width: this.helper.width(),
7279				height: this.helper.height()
7280			} : {
7281				width: el.width(),
7282				height: el.height()
7283			};
7284
7285		this.originalSize = this._helper ? {
7286				width: el.outerWidth(),
7287				height: el.outerHeight()
7288			} : {
7289				width: el.width(),
7290				height: el.height()
7291			};
7292
7293		this.sizeDiff = {
7294			width: el.outerWidth() - el.width(),
7295			height: el.outerHeight() - el.height()
7296		};
7297
7298		this.originalPosition = { left: curleft, top: curtop };
7299		this.originalMousePosition = { left: event.pageX, top: event.pageY };
7300
7301		this.aspectRatio = (typeof o.aspectRatio === "number") ?
7302			o.aspectRatio :
7303			((this.originalSize.width / this.originalSize.height) || 1);
7304
7305		cursor = $(".ui-resizable-" + this.axis).css("cursor");
7306		$("body").css("cursor", cursor === "auto" ? this.axis + "-resize" : cursor);
7307
7308		el.addClass("ui-resizable-resizing");
7309		this._propagate("start", event);
7310		return true;
7311	},
7312
7313	_mouseDrag: function(event) {
7314
7315		var data, props,
7316			smp = this.originalMousePosition,
7317			a = this.axis,
7318			dx = (event.pageX - smp.left) || 0,
7319			dy = (event.pageY - smp.top) || 0,
7320			trigger = this._change[a];
7321
7322		this._updatePrevProperties();
7323
7324		if (!trigger) {
7325			return false;
7326		}
7327
7328		data = trigger.apply(this, [ event, dx, dy ]);
7329
7330		this._updateVirtualBoundaries(event.shiftKey);
7331		if (this._aspectRatio || event.shiftKey) {
7332			data = this._updateRatio(data, event);
7333		}
7334
7335		data = this._respectSize(data, event);
7336
7337		this._updateCache(data);
7338
7339		this._propagate("resize", event);
7340
7341		props = this._applyChanges();
7342
7343		if ( !this._helper && this._proportionallyResizeElements.length ) {
7344			this._proportionallyResize();
7345		}
7346
7347		if ( !$.isEmptyObject( props ) ) {
7348			this._updatePrevProperties();
7349			this._trigger( "resize", event, this.ui() );
7350			this._applyChanges();
7351		}
7352
7353		return false;
vendor: 10,889 bytes, lines 7354-7783
7354	},
7355
7356	_mouseStop: function(event) {
7357
7358		this.resizing = false;
7359		var pr, ista, soffseth, soffsetw, s, left, top,
7360			o = this.options, that = this;
7361
7362		if (this._helper) {
7363
7364			pr = this._proportionallyResizeElements;
7365			ista = pr.length && (/textarea/i).test(pr[0].nodeName);
7366			soffseth = ista && this._hasScroll(pr[0], "left") ? 0 : that.sizeDiff.height;
7367			soffsetw = ista ? 0 : that.sizeDiff.width;
7368
7369			s = {
7370				width: (that.helper.width()  - soffsetw),
7371				height: (that.helper.height() - soffseth)
7372			};
7373			left = (parseInt(that.element.css("left"), 10) +
7374				(that.position.left - that.originalPosition.left)) || null;
7375			top = (parseInt(that.element.css("top"), 10) +
7376				(that.position.top - that.originalPosition.top)) || null;
7377
7378			if (!o.animate) {
7379				this.element.css($.extend(s, { top: top, left: left }));
7380			}
7381
7382			that.helper.height(that.size.height);
7383			that.helper.width(that.size.width);
7384
7385			if (this._helper && !o.animate) {
7386				this._proportionallyResize();
7387			}
7388		}
7389
7390		$("body").css("cursor", "auto");
7391
7392		this.element.removeClass("ui-resizable-resizing");
7393
7394		this._propagate("stop", event);
7395
7396		if (this._helper) {
7397			this.helper.remove();
7398		}
7399
7400		return false;
7401
7402	},
7403
7404	_updatePrevProperties: function() {
7405		this.prevPosition = {
7406			top: this.position.top,
7407			left: this.position.left
7408		};
7409		this.prevSize = {
7410			width: this.size.width,
7411			height: this.size.height
7412		};
7413	},
7414
7415	_applyChanges: function() {
7416		var props = {};
7417
7418		if ( this.position.top !== this.prevPosition.top ) {
7419			props.top = this.position.top + "px";
7420		}
7421		if ( this.position.left !== this.prevPosition.left ) {
7422			props.left = this.position.left + "px";
7423		}
7424		if ( this.size.width !== this.prevSize.width ) {
7425			props.width = this.size.width + "px";
7426		}
7427		if ( this.size.height !== this.prevSize.height ) {
7428			props.height = this.size.height + "px";
7429		}
7430
7431		this.helper.css( props );
7432
7433		return props;
7434	},
7435
7436	_updateVirtualBoundaries: function(forceAspectRatio) {
7437		var pMinWidth, pMaxWidth, pMinHeight, pMaxHeight, b,
7438			o = this.options;
7439
7440		b = {
7441			minWidth: this._isNumber(o.minWidth) ? o.minWidth : 0,
7442			maxWidth: this._isNumber(o.maxWidth) ? o.maxWidth : Infinity,
7443			minHeight: this._isNumber(o.minHeight) ? o.minHeight : 0,
7444			maxHeight: this._isNumber(o.maxHeight) ? o.maxHeight : Infinity
7445		};
7446
7447		if (this._aspectRatio || forceAspectRatio) {
7448			pMinWidth = b.minHeight * this.aspectRatio;
7449			pMinHeight = b.minWidth / this.aspectRatio;
7450			pMaxWidth = b.maxHeight * this.aspectRatio;
7451			pMaxHeight = b.maxWidth / this.aspectRatio;
7452
7453			if (pMinWidth > b.minWidth) {
7454				b.minWidth = pMinWidth;
7455			}
7456			if (pMinHeight > b.minHeight) {
7457				b.minHeight = pMinHeight;
7458			}
7459			if (pMaxWidth < b.maxWidth) {
7460				b.maxWidth = pMaxWidth;
7461			}
7462			if (pMaxHeight < b.maxHeight) {
7463				b.maxHeight = pMaxHeight;
7464			}
7465		}
7466		this._vBoundaries = b;
7467	},
7468
7469	_updateCache: function(data) {
7470		this.offset = this.helper.offset();
7471		if (this._isNumber(data.left)) {
7472			this.position.left = data.left;
7473		}
7474		if (this._isNumber(data.top)) {
7475			this.position.top = data.top;
7476		}
7477		if (this._isNumber(data.height)) {
7478			this.size.height = data.height;
7479		}
7480		if (this._isNumber(data.width)) {
7481			this.size.width = data.width;
7482		}
7483	},
7484
7485	_updateRatio: function( data ) {
7486
7487		var cpos = this.position,
7488			csize = this.size,
7489			a = this.axis;
7490
7491		if (this._isNumber(data.height)) {
7492			data.width = (data.height * this.aspectRatio);
7493		} else if (this._isNumber(data.width)) {
7494			data.height = (data.width / this.aspectRatio);
7495		}
7496
7497		if (a === "sw") {
7498			data.left = cpos.left + (csize.width - data.width);
7499			data.top = null;
7500		}
7501		if (a === "nw") {
7502			data.top = cpos.top + (csize.height - data.height);
7503			data.left = cpos.left + (csize.width - data.width);
7504		}
7505
7506		return data;
7507	},
7508
7509	_respectSize: function( data ) {
7510
7511		var o = this._vBoundaries,
7512			a = this.axis,
7513			ismaxw = this._isNumber(data.width) && o.maxWidth && (o.maxWidth < data.width),
7514			ismaxh = this._isNumber(data.height) && o.maxHeight && (o.maxHeight < data.height),
7515			isminw = this._isNumber(data.width) && o.minWidth && (o.minWidth > data.width),
7516			isminh = this._isNumber(data.height) && o.minHeight && (o.minHeight > data.height),
7517			dw = this.originalPosition.left + this.originalSize.width,
7518			dh = this.position.top + this.size.height,
7519			cw = /sw|nw|w/.test(a), ch = /nw|ne|n/.test(a);
7520		if (isminw) {
7521			data.width = o.minWidth;
7522		}
7523		if (isminh) {
7524			data.height = o.minHeight;
7525		}
7526		if (ismaxw) {
7527			data.width = o.maxWidth;
7528		}
7529		if (ismaxh) {
7530			data.height = o.maxHeight;
7531		}
7532
7533		if (isminw && cw) {
7534			data.left = dw - o.minWidth;
7535		}
7536		if (ismaxw && cw) {
7537			data.left = dw - o.maxWidth;
7538		}
7539		if (isminh && ch) {
7540			data.top = dh - o.minHeight;
7541		}
7542		if (ismaxh && ch) {
7543			data.top = dh - o.maxHeight;
7544		}
7545
7546		// Fixing jump error on top/left - bug #2330
7547		if (!data.width && !data.height && !data.left && data.top) {
7548			data.top = null;
7549		} else if (!data.width && !data.height && !data.top && data.left) {
7550			data.left = null;
7551		}
7552
7553		return data;
7554	},
7555
7556	_getPaddingPlusBorderDimensions: function( element ) {
7557		var i = 0,
7558			widths = [],
7559			borders = [
7560				element.css( "borderTopWidth" ),
7561				element.css( "borderRightWidth" ),
7562				element.css( "borderBottomWidth" ),
7563				element.css( "borderLeftWidth" )
7564			],
7565			paddings = [
7566				element.css( "paddingTop" ),
7567				element.css( "paddingRight" ),
7568				element.css( "paddingBottom" ),
7569				element.css( "paddingLeft" )
7570			];
7571
7572		for ( ; i < 4; i++ ) {
7573			widths[ i ] = ( parseInt( borders[ i ], 10 ) || 0 );
7574			widths[ i ] += ( parseInt( paddings[ i ], 10 ) || 0 );
7575		}
7576
7577		return {
7578			height: widths[ 0 ] + widths[ 2 ],
7579			width: widths[ 1 ] + widths[ 3 ]
7580		};
7581	},
7582
7583	_proportionallyResize: function() {
7584
7585		if (!this._proportionallyResizeElements.length) {
7586			return;
7587		}
7588
7589		var prel,
7590			i = 0,
7591			element = this.helper || this.element;
7592
7593		for ( ; i < this._proportionallyResizeElements.length; i++) {
7594
7595			prel = this._proportionallyResizeElements[i];
7596
7597			// TODO: Seems like a bug to cache this.outerDimensions
7598			// considering that we are in a loop.
7599			if (!this.outerDimensions) {
7600				this.outerDimensions = this._getPaddingPlusBorderDimensions( prel );
7601			}
7602
7603			prel.css({
7604				height: (element.height() - this.outerDimensions.height) || 0,
7605				width: (element.width() - this.outerDimensions.width) || 0
7606			});
7607
7608		}
7609
7610	},
7611
7612	_renderProxy: function() {
7613
7614		var el = this.element, o = this.options;
7615		this.elementOffset = el.offset();
7616
7617		if (this._helper) {
7618
7619			this.helper = this.helper || $("<div style='overflow:hidden;'></div>");
7620
7621			this.helper.addClass(this._helper).css({
7622				width: this.element.outerWidth() - 1,
7623				height: this.element.outerHeight() - 1,
7624				position: "absolute",
7625				left: this.elementOffset.left + "px",
7626				top: this.elementOffset.top + "px",
7627				zIndex: ++o.zIndex //TODO: Don't modify option
7628			});
7629
7630			this.helper
7631				.appendTo("body")
7632				.disableSelection();
7633
7634		} else {
7635			this.helper = this.element;
7636		}
7637
7638	},
7639
7640	_change: {
7641		e: function(event, dx) {
7642			return { width: this.originalSize.width + dx };
7643		},
7644		w: function(event, dx) {
7645			var cs = this.originalSize, sp = this.originalPosition;
7646			return { left: sp.left + dx, width: cs.width - dx };
7647		},
7648		n: function(event, dx, dy) {
7649			var cs = this.originalSize, sp = this.originalPosition;
7650			return { top: sp.top + dy, height: cs.height - dy };
7651		},
7652		s: function(event, dx, dy) {
7653			return { height: this.originalSize.height + dy };
7654		},
7655		se: function(event, dx, dy) {
7656			return $.extend(this._change.s.apply(this, arguments),
7657				this._change.e.apply(this, [ event, dx, dy ]));
7658		},
7659		sw: function(event, dx, dy) {
7660			return $.extend(this._change.s.apply(this, arguments),
7661				this._change.w.apply(this, [ event, dx, dy ]));
7662		},
7663		ne: function(event, dx, dy) {
7664			return $.extend(this._change.n.apply(this, arguments),
7665				this._change.e.apply(this, [ event, dx, dy ]));
7666		},
7667		nw: function(event, dx, dy) {
7668			return $.extend(this._change.n.apply(this, arguments),
7669				this._change.w.apply(this, [ event, dx, dy ]));
7670		}
7671	},
7672
7673	_propagate: function(n, event) {
7674		$.ui.plugin.call(this, n, [ event, this.ui() ]);
7675		(n !== "resize" && this._trigger(n, event, this.ui()));
7676	},
7677
7678	plugins: {},
7679
7680	ui: function() {
7681		return {
7682			originalElement: this.originalElement,
7683			element: this.element,
7684			helper: this.helper,
7685			position: this.position,
7686			size: this.size,
7687			originalSize: this.originalSize,
7688			originalPosition: this.originalPosition
7689		};
7690	}
7691
7692});
7693
7694/*
7695 * Resizable Extensions
7696 */
7697
7698$.ui.plugin.add("resizable", "animate", {
7699
7700	stop: function( event ) {
7701		var that = $(this).resizable( "instance" ),
7702			o = that.options,
7703			pr = that._proportionallyResizeElements,
7704			ista = pr.length && (/textarea/i).test(pr[0].nodeName),
7705			soffseth = ista && that._hasScroll(pr[0], "left") ? 0 : that.sizeDiff.height,
7706			soffsetw = ista ? 0 : that.sizeDiff.width,
7707			style = { width: (that.size.width - soffsetw), height: (that.size.height - soffseth) },
7708			left = (parseInt(that.element.css("left"), 10) +
7709				(that.position.left - that.originalPosition.left)) || null,
7710			top = (parseInt(that.element.css("top"), 10) +
7711				(that.position.top - that.originalPosition.top)) || null;
7712
7713		that.element.animate(
7714			$.extend(style, top && left ? { top: top, left: left } : {}), {
7715				duration: o.animateDuration,
7716				easing: o.animateEasing,
7717				step: function() {
7718
7719					var data = {
7720						width: parseInt(that.element.css("width"), 10),
7721						height: parseInt(that.element.css("height"), 10),
7722						top: parseInt(that.element.css("top"), 10),
7723						left: parseInt(that.element.css("left"), 10)
7724					};
7725
7726					if (pr && pr.length) {
7727						$(pr[0]).css({ width: data.width, height: data.height });
7728					}
7729
7730					// propagating resize, and updating values for each animation step
7731					that._updateCache(data);
7732					that._propagate("resize", event);
7733
7734				}
7735			}
7736		);
7737	}
7738
7739});
7740
7741$.ui.plugin.add( "resizable", "containment", {
7742
7743	start: function() {
7744		var element, p, co, ch, cw, width, height,
7745			that = $( this ).resizable( "instance" ),
7746			o = that.options,
7747			el = that.element,
7748			oc = o.containment,
7749			ce = ( oc instanceof $ ) ? oc.get( 0 ) : ( /parent/.test( oc ) ) ? el.parent().get( 0 ) : oc;
7750
7751		if ( !ce ) {
7752			return;
7753		}
7754
7755		that.containerElement = $( ce );
7756
7757		if ( /document/.test( oc ) || oc === document ) {
7758			that.containerOffset = {
7759				left: 0,
7760				top: 0
7761			};
7762			that.containerPosition = {
7763				left: 0,
7764				top: 0
7765			};
7766
7767			that.parentData = {
7768				element: $( document ),
7769				left: 0,
7770				top: 0,
7771				width: $( document ).width(),
7772				height: $( document ).height() || document.body.parentNode.scrollHeight
7773			};
7774		} else {
7775			element = $( ce );
7776			p = [];
7777			$([ "Top", "Right", "Left", "Bottom" ]).each(function( i, name ) {
7778				p[ i ] = that._num( element.css( "padding" + name ) );
7779			});
7780
7781			that.containerOffset = element.offset();
7782			that.containerPosition = element.position();
7783			that.containerSize = {
vendor: 8,405 bytes, lines 7784-8118
7784				height: ( element.innerHeight() - p[ 3 ] ),
7785				width: ( element.innerWidth() - p[ 1 ] )
7786			};
7787
7788			co = that.containerOffset;
7789			ch = that.containerSize.height;
7790			cw = that.containerSize.width;
7791			width = ( that._hasScroll ( ce, "left" ) ? ce.scrollWidth : cw );
7792			height = ( that._hasScroll ( ce ) ? ce.scrollHeight : ch ) ;
7793
7794			that.parentData = {
7795				element: ce,
7796				left: co.left,
7797				top: co.top,
7798				width: width,
7799				height: height
7800			};
7801		}
7802	},
7803
7804	resize: function( event ) {
7805		var woset, hoset, isParent, isOffsetRelative,
7806			that = $( this ).resizable( "instance" ),
7807			o = that.options,
7808			co = that.containerOffset,
7809			cp = that.position,
7810			pRatio = that._aspectRatio || event.shiftKey,
7811			cop = {
7812				top: 0,
7813				left: 0
7814			},
7815			ce = that.containerElement,
7816			continueResize = true;
7817
7818		if ( ce[ 0 ] !== document && ( /static/ ).test( ce.css( "position" ) ) ) {
7819			cop = co;
7820		}
7821
7822		if ( cp.left < ( that._helper ? co.left : 0 ) ) {
7823			that.size.width = that.size.width +
7824				( that._helper ?
7825					( that.position.left - co.left ) :
7826					( that.position.left - cop.left ) );
7827
7828			if ( pRatio ) {
7829				that.size.height = that.size.width / that.aspectRatio;
7830				continueResize = false;
7831			}
7832			that.position.left = o.helper ? co.left : 0;
7833		}
7834
7835		if ( cp.top < ( that._helper ? co.top : 0 ) ) {
7836			that.size.height = that.size.height +
7837				( that._helper ?
7838					( that.position.top - co.top ) :
7839					that.position.top );
7840
7841			if ( pRatio ) {
7842				that.size.width = that.size.height * that.aspectRatio;
7843				continueResize = false;
7844			}
7845			that.position.top = that._helper ? co.top : 0;
7846		}
7847
7848		isParent = that.containerElement.get( 0 ) === that.element.parent().get( 0 );
7849		isOffsetRelative = /relative|absolute/.test( that.containerElement.css( "position" ) );
7850
7851		if ( isParent && isOffsetRelative ) {
7852			that.offset.left = that.parentData.left + that.position.left;
7853			that.offset.top = that.parentData.top + that.position.top;
7854		} else {
7855			that.offset.left = that.element.offset().left;
7856			that.offset.top = that.element.offset().top;
7857		}
7858
7859		woset = Math.abs( that.sizeDiff.width +
7860			(that._helper ?
7861				that.offset.left - cop.left :
7862				(that.offset.left - co.left)) );
7863
7864		hoset = Math.abs( that.sizeDiff.height +
7865			(that._helper ?
7866				that.offset.top - cop.top :
7867				(that.offset.top - co.top)) );
7868
7869		if ( woset + that.size.width >= that.parentData.width ) {
7870			that.size.width = that.parentData.width - woset;
7871			if ( pRatio ) {
7872				that.size.height = that.size.width / that.aspectRatio;
7873				continueResize = false;
7874			}
7875		}
7876
7877		if ( hoset + that.size.height >= that.parentData.height ) {
7878			that.size.height = that.parentData.height - hoset;
7879			if ( pRatio ) {
7880				that.size.width = that.size.height * that.aspectRatio;
7881				continueResize = false;
7882			}
7883		}
7884
7885		if ( !continueResize ) {
7886			that.position.left = that.prevPosition.left;
7887			that.position.top = that.prevPosition.top;
7888			that.size.width = that.prevSize.width;
7889			that.size.height = that.prevSize.height;
7890		}
7891	},
7892
7893	stop: function() {
7894		var that = $( this ).resizable( "instance" ),
7895			o = that.options,
7896			co = that.containerOffset,
7897			cop = that.containerPosition,
7898			ce = that.containerElement,
7899			helper = $( that.helper ),
7900			ho = helper.offset(),
7901			w = helper.outerWidth() - that.sizeDiff.width,
7902			h = helper.outerHeight() - that.sizeDiff.height;
7903
7904		if ( that._helper && !o.animate && ( /relative/ ).test( ce.css( "position" ) ) ) {
7905			$( this ).css({
7906				left: ho.left - cop.left - co.left,
7907				width: w,
7908				height: h
7909			});
7910		}
7911
7912		if ( that._helper && !o.animate && ( /static/ ).test( ce.css( "position" ) ) ) {
7913			$( this ).css({
7914				left: ho.left - cop.left - co.left,
7915				width: w,
7916				height: h
7917			});
7918		}
7919	}
7920});
7921
7922$.ui.plugin.add("resizable", "alsoResize", {
7923
7924	start: function() {
7925		var that = $(this).resizable( "instance" ),
7926			o = that.options;
7927
7928		$(o.alsoResize).each(function() {
7929			var el = $(this);
7930			el.data("ui-resizable-alsoresize", {
7931				width: parseInt(el.width(), 10), height: parseInt(el.height(), 10),
7932				left: parseInt(el.css("left"), 10), top: parseInt(el.css("top"), 10)
7933			});
7934		});
7935	},
7936
7937	resize: function(event, ui) {
7938		var that = $(this).resizable( "instance" ),
7939			o = that.options,
7940			os = that.originalSize,
7941			op = that.originalPosition,
7942			delta = {
7943				height: (that.size.height - os.height) || 0,
7944				width: (that.size.width - os.width) || 0,
7945				top: (that.position.top - op.top) || 0,
7946				left: (that.position.left - op.left) || 0
7947			};
7948
7949			$(o.alsoResize).each(function() {
7950				var el = $(this), start = $(this).data("ui-resizable-alsoresize"), style = {},
7951					css = el.parents(ui.originalElement[0]).length ?
7952							[ "width", "height" ] :
7953							[ "width", "height", "top", "left" ];
7954
7955				$.each(css, function(i, prop) {
7956					var sum = (start[prop] || 0) + (delta[prop] || 0);
7957					if (sum && sum >= 0) {
7958						style[prop] = sum || null;
7959					}
7960				});
7961
7962				el.css(style);
7963			});
7964	},
7965
7966	stop: function() {
7967		$(this).removeData("resizable-alsoresize");
7968	}
7969});
7970
7971$.ui.plugin.add("resizable", "ghost", {
7972
7973	start: function() {
7974
7975		var that = $(this).resizable( "instance" ), o = that.options, cs = that.size;
7976
7977		that.ghost = that.originalElement.clone();
7978		that.ghost
7979			.css({
7980				opacity: 0.25,
7981				display: "block",
7982				position: "relative",
7983				height: cs.height,
7984				width: cs.width,
7985				margin: 0,
7986				left: 0,
7987				top: 0
7988			})
7989			.addClass("ui-resizable-ghost")
7990			.addClass(typeof o.ghost === "string" ? o.ghost : "");
7991
7992		that.ghost.appendTo(that.helper);
7993
7994	},
7995
7996	resize: function() {
7997		var that = $(this).resizable( "instance" );
7998		if (that.ghost) {
7999			that.ghost.css({
8000				position: "relative",
8001				height: that.size.height,
8002				width: that.size.width
8003			});
8004		}
8005	},
8006
8007	stop: function() {
8008		var that = $(this).resizable( "instance" );
8009		if (that.ghost && that.helper) {
8010			that.helper.get(0).removeChild(that.ghost.get(0));
8011		}
8012	}
8013
8014});
8015
8016$.ui.plugin.add("resizable", "grid", {
8017
8018	resize: function() {
8019		var outerDimensions,
8020			that = $(this).resizable( "instance" ),
8021			o = that.options,
8022			cs = that.size,
8023			os = that.originalSize,
8024			op = that.originalPosition,
8025			a = that.axis,
8026			grid = typeof o.grid === "number" ? [ o.grid, o.grid ] : o.grid,
8027			gridX = (grid[0] || 1),
8028			gridY = (grid[1] || 1),
8029			ox = Math.round((cs.width - os.width) / gridX) * gridX,
8030			oy = Math.round((cs.height - os.height) / gridY) * gridY,
8031			newWidth = os.width + ox,
8032			newHeight = os.height + oy,
8033			isMaxWidth = o.maxWidth && (o.maxWidth < newWidth),
8034			isMaxHeight = o.maxHeight && (o.maxHeight < newHeight),
8035			isMinWidth = o.minWidth && (o.minWidth > newWidth),
8036			isMinHeight = o.minHeight && (o.minHeight > newHeight);
8037
8038		o.grid = grid;
8039
8040		if (isMinWidth) {
8041			newWidth += gridX;
8042		}
8043		if (isMinHeight) {
8044			newHeight += gridY;
8045		}
8046		if (isMaxWidth) {
8047			newWidth -= gridX;
8048		}
8049		if (isMaxHeight) {
8050			newHeight -= gridY;
8051		}
8052
8053		if (/^(se|s|e)$/.test(a)) {
8054			that.size.width = newWidth;
8055			that.size.height = newHeight;
8056		} else if (/^(ne)$/.test(a)) {
8057			that.size.width = newWidth;
8058			that.size.height = newHeight;
8059			that.position.top = op.top - oy;
8060		} else if (/^(sw)$/.test(a)) {
8061			that.size.width = newWidth;
8062			that.size.height = newHeight;
8063			that.position.left = op.left - ox;
8064		} else {
8065			if ( newHeight - gridY <= 0 || newWidth - gridX <= 0) {
8066				outerDimensions = that._getPaddingPlusBorderDimensions( this );
8067			}
8068
8069			if ( newHeight - gridY > 0 ) {
8070				that.size.height = newHeight;
8071				that.position.top = op.top - oy;
8072			} else {
8073				newHeight = gridY - outerDimensions.height;
8074				that.size.height = newHeight;
8075				that.position.top = op.top + os.height - newHeight;
8076			}
8077			if ( newWidth - gridX > 0 ) {
8078				that.size.width = newWidth;
8079				that.position.left = op.left - ox;
8080			} else {
8081				newWidth = gridX - outerDimensions.width;
8082				that.size.width = newWidth;
8083				that.position.left = op.left + os.width - newWidth;
8084			}
8085		}
8086	}
8087
8088});
8089
8090var resizable = $.ui.resizable;
8091
8092
8093/*!
8094 * jQuery UI Dialog 1.11.4
8095 * http://jqueryui.com
8096 *
8097 * Copyright jQuery Foundation and other contributors
8098 * Released under the MIT license.
8099 * http://jquery.org/license
8100 *
8101 * http://api.jqueryui.com/dialog/
8102 */
8103
8104
8105var dialog = $.widget( "ui.dialog", {
8106	version: "1.11.4",
8107	options: {
8108		appendTo: "body",
8109		autoOpen: true,
8110		buttons: [],
8111		closeOnEscape: true,
8112		closeText: "Close",
8113		dialogClass: "",
8114		draggable: true,
8115		hide: null,
8116		height: "auto",
8117		maxHeight: null,
8118		maxWidth: 
8118function() {
8119			$( this ).css( "max-width", "400" );
8120		},
8121		minHeight: 150,
8122		minWidth: 150,
8123		modal: false,
8124		position: {
8125			my: "center",
8126			at: "center",
8127			of: window,
8128			collision: "fit",
8129			// Ensure the titlebar is always visible
8130			using: function( pos ) {
8131				var topOffset = $( this ).css( pos ).offset().top;
8132				if ( topOffset < 0 ) {
8133					$( this ).css( "top", pos.top - topOffset );
8134				}
8135			}
8136		},
8137		resizable: false,
8138		show: null,
8139		title: false
vendor: 35,087 bytes, lines 8139-9479
8139,
8140		width: 300,
8141
8142		// callbacks
8143		beforeClose: null,
8144		close: null,
8145		drag: null,
8146		dragStart: null,
8147		dragStop: null,
8148		focus: null,
8149		open: null,
8150		resize: null,
8151		resizeStart: null,
8152		resizeStop: null
8153	},
8154
8155	sizeRelatedOptions: {
8156		buttons: true,
8157		height: true,
8158		maxHeight: true,
8159		maxWidth: true,
8160		minHeight: true,
8161		minWidth: true,
8162		width: true
8163	},
8164
8165	resizableRelatedOptions: {
8166		maxHeight: true,
8167		maxWidth: true,
8168		minHeight: true,
8169		minWidth: true
8170	},
8171
8172	_create: function() {
8173		this.originalCss = {
8174			display: this.element[ 0 ].style.display,
8175			width: this.element[ 0 ].style.width,
8176			minHeight: this.element[ 0 ].style.minHeight,
8177			maxHeight: this.element[ 0 ].style.maxHeight,
8178			height: this.element[ 0 ].style.height
8179		};
8180		this.originalPosition = {
8181			parent: this.element.parent(),
8182			index: this.element.parent().children().index( this.element )
8183		};
8184		this.originalTitle = this.element.attr( "title" );
8185		this.options.title = this.options.title || this.originalTitle;
8186
8187		this._createWrapper();
8188
8189		this.element
8190			.show()
8191			.removeAttr( "title" )
8192			.addClass( "ui-dialog-content ui-widget-content" )
8193			.appendTo( this.uiDialog );
8194
8195		this._createTitlebar();
8196		this._createButtonPane();
8197
8198		if ( this.options.draggable && $.fn.draggable ) {
8199			this._makeDraggable();
8200		}
8201		if ( this.options.resizable && $.fn.resizable ) {
8202			this._makeResizable();
8203		}
8204
8205		this._isOpen = false;
8206
8207		this._trackFocus();
8208	},
8209
8210	_init: function() {
8211		if ( this.options.autoOpen ) {
8212			this.open();
8213		}
8214	},
8215
8216	_appendTo: function() {
8217		var element = this.options.appendTo;
8218		if ( element && (element.jquery || element.nodeType) ) {
8219			return $( element );
8220		}
8221		return this.document.find( element || "body" ).eq( 0 );
8222	},
8223
8224	_destroy: function() {
8225		var next,
8226			originalPosition = this.originalPosition;
8227
8228		this._untrackInstance();
8229		this._destroyOverlay();
8230
8231		this.element
8232			.removeUniqueId()
8233			.removeClass( "ui-dialog-content ui-widget-content" )
8234			.css( this.originalCss )
8235			// Without detaching first, the following becomes really slow
8236			.detach();
8237
8238		this.uiDialog.stop( true, true ).remove();
8239
8240		if ( this.originalTitle ) {
8241			this.element.attr( "title", this.originalTitle );
8242		}
8243
8244		next = originalPosition.parent.children().eq( originalPosition.index );
8245		// Don't try to place the dialog next to itself (#8613)
8246		if ( next.length && next[ 0 ] !== this.element[ 0 ] ) {
8247			next.before( this.element );
8248		} else {
8249			originalPosition.parent.append( this.element );
8250		}
8251	},
8252
8253	widget: function() {
8254		return this.uiDialog;
8255	},
8256
8257	disable: $.noop,
8258	enable: $.noop,
8259
8260	close: function( event ) {
8261		var activeElement,
8262			that = this;
8263
8264		if ( !this._isOpen || this._trigger( "beforeClose", event ) === false ) {
8265			return;
8266		}
8267
8268		this._isOpen = false;
8269		this._focusedElement = null;
8270		this._destroyOverlay();
8271		this._untrackInstance();
8272
8273		if ( !this.opener.filter( ":focusable" ).focus().length ) {
8274
8275			// support: IE9
8276			// IE9 throws an "Unspecified error" accessing document.activeElement from an <iframe>
8277			try {
8278				activeElement = this.document[ 0 ].activeElement;
8279
8280				// Support: IE9, IE10
8281				// If the <body> is blurred, IE will switch windows, see #4520
8282				if ( activeElement && activeElement.nodeName.toLowerCase() !== "body" ) {
8283
8284					// Hiding a focused element doesn't trigger blur in WebKit
8285					// so in case we have nothing to focus on, explicitly blur the active element
8286					// https://bugs.webkit.org/show_bug.cgi?id=47182
8287					$( activeElement ).blur();
8288				}
8289			} catch ( error ) {}
8290		}
8291
8292		this._hide( this.uiDialog, this.options.hide, function() {
8293			that._trigger( "close", event );
8294		});
8295	},
8296
8297	isOpen: function() {
8298		return this._isOpen;
8299	},
8300
8301	moveToTop: function() {
8302		this._moveToTop();
8303	},
8304
8305	_moveToTop: function( event, silent ) {
8306		var moved = false,
8307			zIndices = this.uiDialog.siblings( ".ui-front:visible" ).map(function() {
8308				return +$( this ).css( "z-index" );
8309			}).get(),
8310			zIndexMax = Math.max.apply( null, zIndices );
8311
8312		if ( zIndexMax >= +this.uiDialog.css( "z-index" ) ) {
8313			this.uiDialog.css( "z-index", zIndexMax + 1 );
8314			moved = true;
8315		}
8316
8317		if ( moved && !silent ) {
8318			this._trigger( "focus", event );
8319		}
8320		return moved;
8321	},
8322
8323	open: function() {
8324		var that = this;
8325		if ( this._isOpen ) {
8326			if ( this._moveToTop() ) {
8327				this._focusTabbable();
8328			}
8329			return;
8330		}
8331
8332		this._isOpen = true;
8333		this.opener = $( this.document[ 0 ].activeElement );
8334
8335		this._size();
8336		this._position();
8337		this._createOverlay();
8338		this._moveToTop( null, true );
8339
8340		// Ensure the overlay is moved to the top with the dialog, but only when
8341		// opening. The overlay shouldn't move after the dialog is open so that
8342		// modeless dialogs opened after the modal dialog stack properly.
8343		if ( this.overlay ) {
8344			this.overlay.css( "z-index", this.uiDialog.css( "z-index" ) - 1 );
8345		}
8346
8347		this._show( this.uiDialog, this.options.show, function() {
8348			that._focusTabbable();
8349			that._trigger( "focus" );
8350		});
8351
8352		// Track the dialog immediately upon openening in case a focus event
8353		// somehow occurs outside of the dialog before an element inside the
8354		// dialog is focused (#10152)
8355		this._makeFocusTarget();
8356
8357		this._trigger( "open" );
8358	},
8359
8360	_focusTabbable: function() {
8361		// Set focus to the first match:
8362		// 1. An element that was focused previously
8363		// 2. First element inside the dialog matching [autofocus]
8364		// 3. Tabbable element inside the content element
8365		// 4. Tabbable element inside the buttonpane
8366		// 5. The close button
8367		// 6. The dialog itself
8368		var hasFocus = this._focusedElement;
8369		if ( !hasFocus ) {
8370			hasFocus = this.element.find( "[autofocus]" );
8371		}
8372		if ( !hasFocus.length ) {
8373			hasFocus = this.element.find( ":tabbable" );
8374		}
8375		if ( !hasFocus.length ) {
8376			hasFocus = this.uiDialogButtonPane.find( ":tabbable" );
8377		}
8378		if ( !hasFocus.length ) {
8379			hasFocus = this.uiDialogTitlebarClose.filter( ":tabbable" );
8380		}
8381		if ( !hasFocus.length ) {
8382			hasFocus = this.uiDialog;
8383		}
8384		hasFocus.eq( 0 ).focus();
8385	},
8386
8387	_keepFocus: function( event ) {
8388		function checkFocus() {
8389			var activeElement = this.document[0].activeElement,
8390				isActive = this.uiDialog[0] === activeElement ||
8391					$.contains( this.uiDialog[0], activeElement );
8392			if ( !isActive ) {
8393				this._focusTabbable();
8394			}
8395		}
8396		event.preventDefault();
8397		checkFocus.call( this );
8398		// support: IE
8399		// IE <= 8 doesn't prevent moving focus even with event.preventDefault()
8400		// so we check again later
8401		this._delay( checkFocus );
8402	},
8403
8404	_createWrapper: function() {
8405		this.uiDialog = $("<div>")
8406			.addClass( "ui-dialog ui-widget ui-widget-content ui-corner-all ui-front " +
8407				this.options.dialogClass )
8408			.hide()
8409			.attr({
8410				// Setting tabIndex makes the div focusable
8411				tabIndex: -1,
8412				role: "dialog"
8413			})
8414			.appendTo( this._appendTo() );
8415
8416		this._on( this.uiDialog, {
8417			keydown: function( event ) {
8418				if ( this.options.closeOnEscape && !event.isDefaultPrevented() && event.keyCode &&
8419						event.keyCode === $.ui.keyCode.ESCAPE ) {
8420					event.preventDefault();
8421					this.close( event );
8422					return;
8423				}
8424
8425				// prevent tabbing out of dialogs
8426				if ( event.keyCode !== $.ui.keyCode.TAB || event.isDefaultPrevented() ) {
8427					return;
8428				}
8429				var tabbables = this.uiDialog.find( ":tabbable" ),
8430					first = tabbables.filter( ":first" ),
8431					last = tabbables.filter( ":last" );
8432
8433				if ( ( event.target === last[0] || event.target === this.uiDialog[0] ) && !event.shiftKey ) {
8434					this._delay(function() {
8435						first.focus();
8436					});
8437					event.preventDefault();
8438				} else if ( ( event.target === first[0] || event.target === this.uiDialog[0] ) && event.shiftKey ) {
8439					this._delay(function() {
8440						last.focus();
8441					});
8442					event.preventDefault();
8443				}
8444			},
8445			mousedown: function( event ) {
8446				if ( this._moveToTop( event ) ) {
8447					this._focusTabbable();
8448				}
8449			}
8450		});
8451
8452		// We assume that any existing aria-describedby attribute means
8453		// that the dialog content is marked up properly
8454		// otherwise we brute force the content as the description
8455		if ( !this.element.find( "[aria-describedby]" ).length ) {
8456			this.uiDialog.attr({
8457				"aria-describedby": this.element.uniqueId().attr( "id" )
8458			});
8459		}
8460	},
8461
8462	_createTitlebar: function() {
8463		var uiDialogTitle;
8464
8465		this.uiDialogTitlebar = $( "<div>" )
8466			.addClass( "ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix" )
8467			.prependTo( this.uiDialog );
8468		this._on( this.uiDialogTitlebar, {
8469			mousedown: function( event ) {
8470				// Don't prevent click on close button (#8838)
8471				// Focusing a dialog that is partially scrolled out of view
8472				// causes the browser to scroll it into view, preventing the click event
8473				if ( !$( event.target ).closest( ".ui-dialog-titlebar-close" ) ) {
8474					// Dialog isn't getting focus when dragging (#8063)
8475					this.uiDialog.focus();
8476				}
8477			}
8478		});
8479
8480		// support: IE
8481		// Use type="button" to prevent enter keypresses in textboxes from closing the
8482		// dialog in IE (#9312)
8483		this.uiDialogTitlebarClose = $( "<button type='button'></button>" )
8484			.button({
8485				label: this.options.closeText,
8486				icons: {
8487					primary: "ui-icon-closethick"
8488				},
8489				text: false
8490			})
8491			.addClass( "ui-dialog-titlebar-close" )
8492			.appendTo( this.uiDialogTitlebar );
8493		this._on( this.uiDialogTitlebarClose, {
8494			click: function( event ) {
8495				event.preventDefault();
8496				this.close( event );
8497			}
8498		});
8499
8500		uiDialogTitle = $( "<span>" )
8501			.uniqueId()
8502			.addClass( "ui-dialog-title" )
8503			.prependTo( this.uiDialogTitlebar );
8504		this._title( uiDialogTitle );
8505
8506		this.uiDialog.attr({
8507			"aria-labelledby": uiDialogTitle.attr( "id" )
8508		});
8509	},
8510
8511	_title: function( title ) {
8512		if ( !this.options.title ) {
8513			title.html( "&#160;" );
8514		}
8515		title.text( this.options.title );
8516	},
8517
8518	_createButtonPane: function() {
8519		this.uiDialogButtonPane = $( "<div>" )
8520			.addClass( "ui-dialog-buttonpane ui-widget-content ui-helper-clearfix" );
8521
8522		this.uiButtonSet = $( "<div>" )
8523			.addClass( "ui-dialog-buttonset" )
8524			.appendTo( this.uiDialogButtonPane );
8525
8526		this._createButtons();
8527	},
8528
8529	_createButtons: function() {
8530		var that = this,
8531			buttons = this.options.buttons;
8532
8533		// if we already have a button pane, remove it
8534		this.uiDialogButtonPane.remove();
8535		this.uiButtonSet.empty();
8536
8537		if ( $.isEmptyObject( buttons ) || ($.isArray( buttons ) && !buttons.length) ) {
8538			this.uiDialog.removeClass( "ui-dialog-buttons" );
8539			return;
8540		}
8541
8542		$.each( buttons, function( name, props ) {
8543			var click, buttonOptions;
8544			props = $.isFunction( props ) ?
8545				{ click: props, text: name } :
8546				props;
8547			// Default to a non-submitting button
8548			props = $.extend( { type: "button" }, props );
8549			// Change the context for the click callback to be the main element
8550			click = props.click;
8551			props.click = function() {
8552				click.apply( that.element[ 0 ], arguments );
8553			};
8554			buttonOptions = {
8555				icons: props.icons,
8556				text: props.showText
8557			};
8558			delete props.icons;
8559			delete props.showText;
8560			$( "<button></button>", props )
8561				.button( buttonOptions )
8562				.appendTo( that.uiButtonSet );
8563		});
8564		this.uiDialog.addClass( "ui-dialog-buttons" );
8565		this.uiDialogButtonPane.appendTo( this.uiDialog );
8566	},
8567
8568	_makeDraggable: function() {
8569		var that = this,
8570			options = this.options;
8571
8572		function filteredUi( ui ) {
8573			return {
8574				position: ui.position,
8575				offset: ui.offset
8576			};
8577		}
8578
8579		this.uiDialog.draggable({
8580			cancel: ".ui-dialog-content, .ui-dialog-titlebar-close",
8581			handle: ".ui-dialog-titlebar",
8582			containment: "document",
8583			start: function( event, ui ) {
8584				$( this ).addClass( "ui-dialog-dragging" );
8585				that._blockFrames();
8586				that._trigger( "dragStart", event, filteredUi( ui ) );
8587			},
8588			drag: function( event, ui ) {
8589				that._trigger( "drag", event, filteredUi( ui ) );
8590			},
8591			stop: function( event, ui ) {
8592				var left = ui.offset.left - that.document.scrollLeft(),
8593					top = ui.offset.top - that.document.scrollTop();
8594
8595				options.position = {
8596					my: "left top",
8597					at: "left" + (left >= 0 ? "+" : "") + left + " " +
8598						"top" + (top >= 0 ? "+" : "") + top,
8599					of: that.window
8600				};
8601				$( this ).removeClass( "ui-dialog-dragging" );
8602				that._unblockFrames();
8603				that._trigger( "dragStop", event, filteredUi( ui ) );
8604			}
8605		});
8606	},
8607
8608	_makeResizable: function() {
8609		var that = this,
8610			options = this.options,
8611			handles = options.resizable,
8612			// .ui-resizable has position: relative defined in the stylesheet
8613			// but dialogs have to use absolute or fixed positioning
8614			position = this.uiDialog.css("position"),
8615			resizeHandles = typeof handles === "string" ?
8616				handles	:
8617				"n,e,s,w,se,sw,ne,nw";
8618
8619		function filteredUi( ui ) {
8620			return {
8621				originalPosition: ui.originalPosition,
8622				originalSize: ui.originalSize,
8623				position: ui.position,
8624				size: ui.size
8625			};
8626		}
8627
8628		this.uiDialog.resizable({
8629			cancel: ".ui-dialog-content",
8630			containment: "document",
8631			alsoResize: this.element,
8632			maxWidth: options.maxWidth,
8633			maxHeight: options.maxHeight,
8634			minWidth: options.minWidth,
8635			minHeight: this._minHeight(),
8636			handles: resizeHandles,
8637			start: function( event, ui ) {
8638				$( this ).addClass( "ui-dialog-resizing" );
8639				that._blockFrames();
8640				that._trigger( "resizeStart", event, filteredUi( ui ) );
8641			},
8642			resize: function( event, ui ) {
8643				that._trigger( "resize", event, filteredUi( ui ) );
8644			},
8645			stop: function( event, ui ) {
8646				var offset = that.uiDialog.offset(),
8647					left = offset.left - that.document.scrollLeft(),
8648					top = offset.top - that.document.scrollTop();
8649
8650				options.height = that.uiDialog.height();
8651				options.width = that.uiDialog.width();
8652				options.position = {
8653					my: "left top",
8654					at: "left" + (left >= 0 ? "+" : "") + left + " " +
8655						"top" + (top >= 0 ? "+" : "") + top,
8656					of: that.window
8657				};
8658				$( this ).removeClass( "ui-dialog-resizing" );
8659				that._unblockFrames();
8660				that._trigger( "resizeStop", event, filteredUi( ui ) );
8661			}
8662		})
8663		.css( "position", position );
8664	},
8665
8666	_trackFocus: function() {
8667		this._on( this.widget(), {
8668			focusin: function( event ) {
8669				this._makeFocusTarget();
8670				this._focusedElement = $( event.target );
8671			}
8672		});
8673	},
8674
8675	_makeFocusTarget: function() {
8676		this._untrackInstance();
8677		this._trackingInstances().unshift( this );
8678	},
8679
8680	_untrackInstance: function() {
8681		var instances = this._trackingInstances(),
8682			exists = $.inArray( this, instances );
8683		if ( exists !== -1 ) {
8684			instances.splice( exists, 1 );
8685		}
8686	},
8687
8688	_trackingInstances: function() {
8689		var instances = this.document.data( "ui-dialog-instances" );
8690		if ( !instances ) {
8691			instances = [];
8692			this.document.data( "ui-dialog-instances", instances );
8693		}
8694		return instances;
8695	},
8696
8697	_minHeight: function() {
8698		var options = this.options;
8699
8700		return options.height === "auto" ?
8701			options.minHeight :
8702			Math.min( options.minHeight, options.height );
8703	},
8704
8705	_position: function() {
8706		// Need to show the dialog to get the actual offset in the position plugin
8707		var isVisible = this.uiDialog.is( ":visible" );
8708		if ( !isVisible ) {
8709			this.uiDialog.show();
8710		}
8711		this.uiDialog.position( this.options.position );
8712		if ( !isVisible ) {
8713			this.uiDialog.hide();
8714		}
8715	},
8716
8717	_setOptions: function( options ) {
8718		var that = this,
8719			resize = false,
8720			resizableOptions = {};
8721
8722		$.each( options, function( key, value ) {
8723			that._setOption( key, value );
8724
8725			if ( key in that.sizeRelatedOptions ) {
8726				resize = true;
8727			}
8728			if ( key in that.resizableRelatedOptions ) {
8729				resizableOptions[ key ] = value;
8730			}
8731		});
8732
8733		if ( resize ) {
8734			this._size();
8735			this._position();
8736		}
8737		if ( this.uiDialog.is( ":data(ui-resizable)" ) ) {
8738			this.uiDialog.resizable( "option", resizableOptions );
8739		}
8740	},
8741
8742	_setOption: function( key, value ) {
8743		var isDraggable, isResizable,
8744			uiDialog = this.uiDialog;
8745
8746		if ( key === "dialogClass" ) {
8747			uiDialog
8748				.removeClass( this.options.dialogClass )
8749				.addClass( value );
8750		}
8751
8752		if ( key === "disabled" ) {
8753			return;
8754		}
8755
8756		this._super( key, value );
8757
8758		if ( key === "appendTo" ) {
8759			this.uiDialog.appendTo( this._appendTo() );
8760		}
8761
8762		if ( key === "buttons" ) {
8763			this._createButtons();
8764		}
8765
8766		if ( key === "closeText" ) {
8767			this.uiDialogTitlebarClose.button({
8768				// Ensure that we always pass a string
8769				label: "" + value
8770			});
8771		}
8772
8773		if ( key === "draggable" ) {
8774			isDraggable = uiDialog.is( ":data(ui-draggable)" );
8775			if ( isDraggable && !value ) {
8776				uiDialog.draggable( "destroy" );
8777			}
8778
8779			if ( !isDraggable && value ) {
8780				this._makeDraggable();
8781			}
8782		}
8783
8784		if ( key === "position" ) {
8785			this._position();
8786		}
8787
8788		if ( key === "resizable" ) {
8789			// currently resizable, becoming non-resizable
8790			isResizable = uiDialog.is( ":data(ui-resizable)" );
8791			if ( isResizable && !value ) {
8792				uiDialog.resizable( "destroy" );
8793			}
8794
8795			// currently resizable, changing handles
8796			if ( isResizable && typeof value === "string" ) {
8797				uiDialog.resizable( "option", "handles", value );
8798			}
8799
8800			// currently non-resizable, becoming resizable
8801			if ( !isResizable && value !== false ) {
8802				this._makeResizable();
8803			}
8804		}
8805
8806		if ( key === "title" ) {
8807			this._title( this.uiDialogTitlebar.find( ".ui-dialog-title" ) );
8808		}
8809	},
8810
8811	_size: function() {
8812		// If the user has resized the dialog, the .ui-dialog and .ui-dialog-content
8813		// divs will both have width and height set, so we need to reset them
8814		var nonContentHeight, minContentHeight, maxContentHeight,
8815			options = this.options;
8816
8817		// Reset content sizing
8818		this.element.show().css({
8819			width: "auto",
8820			minHeight: 0,
8821			maxHeight: "none",
8822			height: 0
8823		});
8824
8825		if ( options.minWidth > options.width ) {
8826			options.width = options.minWidth;
8827		}
8828
8829		// reset wrapper sizing
8830		// determine the height of all the non-content elements
8831		nonContentHeight = this.uiDialog.css({
8832				height: "auto",
8833				width: options.width
8834			})
8835			.outerHeight();
8836		minContentHeight = Math.max( 0, options.minHeight - nonContentHeight );
8837		maxContentHeight = typeof options.maxHeight === "number" ?
8838			Math.max( 0, options.maxHeight - nonContentHeight ) :
8839			"none";
8840
8841		if ( options.height === "auto" ) {
8842			this.element.css({
8843				minHeight: minContentHeight,
8844				maxHeight: maxContentHeight,
8845				height: "auto"
8846			});
8847		} else {
8848			this.element.height( Math.max( 0, options.height - nonContentHeight ) );
8849		}
8850
8851		if ( this.uiDialog.is( ":data(ui-resizable)" ) ) {
8852			this.uiDialog.resizable( "option", "minHeight", this._minHeight() );
8853		}
8854	},
8855
8856	_blockFrames: function() {
8857		this.iframeBlocks = this.document.find( "iframe" ).map(function() {
8858			var iframe = $( this );
8859
8860			return $( "<div>" )
8861				.css({
8862					position: "absolute",
8863					width: iframe.outerWidth(),
8864					height: iframe.outerHeight()
8865				})
8866				.appendTo( iframe.parent() )
8867				.offset( iframe.offset() )[0];
8868		});
8869	},
8870
8871	_unblockFrames: function() {
8872		if ( this.iframeBlocks ) {
8873			this.iframeBlocks.remove();
8874			delete this.iframeBlocks;
8875		}
8876	},
8877
8878	_allowInteraction: function( event ) {
8879		if ( $( event.target ).closest( ".ui-dialog" ).length ) {
8880			return true;
8881		}
8882
8883		// TODO: Remove hack when datepicker implements
8884		// the .ui-front logic (#8989)
8885		return !!$( event.target ).closest( ".ui-datepicker" ).length;
8886	},
8887
8888	_createOverlay: function() {
8889		if ( !this.options.modal ) {
8890			return;
8891		}
8892
8893		// We use a delay in case the overlay is created from an
8894		// event that we're going to be cancelling (#2804)
8895		var isOpening = true;
8896		this._delay(function() {
8897			isOpening = false;
8898		});
8899
8900		if ( !this.document.data( "ui-dialog-overlays" ) ) {
8901
8902			// Prevent use of anchors and inputs
8903			// Using _on() for an event handler shared across many instances is
8904			// safe because the dialogs stack and must be closed in reverse order
8905			this._on( this.document, {
8906				focusin: function( event ) {
8907					if ( isOpening ) {
8908						return;
8909					}
8910
8911					if ( !this._allowInteraction( event ) ) {
8912						event.preventDefault();
8913						this._trackingInstances()[ 0 ]._focusTabbable();
8914					}
8915				}
8916			});
8917		}
8918
8919		this.overlay = $( "<div>" )
8920			.addClass( "ui-widget-overlay ui-front" )
8921			.appendTo( this._appendTo() );
8922		this._on( this.overlay, {
8923			mousedown: "_keepFocus"
8924		});
8925		this.document.data( "ui-dialog-overlays",
8926			(this.document.data( "ui-dialog-overlays" ) || 0) + 1 );
8927	},
8928
8929	_destroyOverlay: function() {
8930		if ( !this.options.modal ) {
8931			return;
8932		}
8933
8934		if ( this.overlay ) {
8935			var overlays = this.document.data( "ui-dialog-overlays" ) - 1;
8936
8937			if ( !overlays ) {
8938				this.document
8939					.unbind( "focusin" )
8940					.removeData( "ui-dialog-overlays" );
8941			} else {
8942				this.document.data( "ui-dialog-overlays", overlays );
8943			}
8944
8945			this.overlay.remove();
8946			this.overlay = null;
8947		}
8948	}
8949});
8950
8951
8952/*!
8953 * jQuery UI Droppable 1.11.4
8954 * http://jqueryui.com
8955 *
8956 * Copyright jQuery Foundation and other contributors
8957 * Released under the MIT license.
8958 * http://jquery.org/license
8959 *
8960 * http://api.jqueryui.com/droppable/
8961 */
8962
8963
8964$.widget( "ui.droppable", {
8965	version: "1.11.4",
8966	widgetEventPrefix: "drop",
8967	options: {
8968		accept: "*",
8969		activeClass: false,
8970		addClasses: true,
8971		greedy: false,
8972		hoverClass: false,
8973		scope: "default",
8974		tolerance: "intersect",
8975
8976		// callbacks
8977		activate: null,
8978		deactivate: null,
8979		drop: null,
8980		out: null,
8981		over: null
8982	},
8983	_create: function() {
8984
8985		var proportions,
8986			o = this.options,
8987			accept = o.accept;
8988
8989		this.isover = false;
8990		this.isout = true;
8991
8992		this.accept = $.isFunction( accept ) ? accept : function( d ) {
8993			return d.is( accept );
8994		};
8995
8996		this.proportions = function( /* valueToWrite */ ) {
8997			if ( arguments.length ) {
8998				// Store the droppable's proportions
8999				proportions = arguments[ 0 ];
9000			} else {
9001				// Retrieve or derive the droppable's proportions
9002				return proportions ?
9003					proportions :
9004					proportions = {
9005						width: this.element[ 0 ].offsetWidth,
9006						height: this.element[ 0 ].offsetHeight
9007					};
9008			}
9009		};
9010
9011		this._addToManager( o.scope );
9012
9013		o.addClasses && this.element.addClass( "ui-droppable" );
9014
9015	},
9016
9017	_addToManager: function( scope ) {
9018		// Add the reference and positions to the manager
9019		$.ui.ddmanager.droppables[ scope ] = $.ui.ddmanager.droppables[ scope ] || [];
9020		$.ui.ddmanager.droppables[ scope ].push( this );
9021	},
9022
9023	_splice: function( drop ) {
9024		var i = 0;
9025		for ( ; i < drop.length; i++ ) {
9026			if ( drop[ i ] === this ) {
9027				drop.splice( i, 1 );
9028			}
9029		}
9030	},
9031
9032	_destroy: function() {
9033		var drop = $.ui.ddmanager.droppables[ this.options.scope ];
9034
9035		this._splice( drop );
9036
9037		this.element.removeClass( "ui-droppable ui-droppable-disabled" );
9038	},
9039
9040	_setOption: function( key, value ) {
9041
9042		if ( key === "accept" ) {
9043			this.accept = $.isFunction( value ) ? value : function( d ) {
9044				return d.is( value );
9045			};
9046		} else if ( key === "scope" ) {
9047			var drop = $.ui.ddmanager.droppables[ this.options.scope ];
9048
9049			this._splice( drop );
9050			this._addToManager( value );
9051		}
9052
9053		this._super( key, value );
9054	},
9055
9056	_activate: function( event ) {
9057		var draggable = $.ui.ddmanager.current;
9058		if ( this.options.activeClass ) {
9059			this.element.addClass( this.options.activeClass );
9060		}
9061		if ( draggable ){
9062			this._trigger( "activate", event, this.ui( draggable ) );
9063		}
9064	},
9065
9066	_deactivate: function( event ) {
9067		var draggable = $.ui.ddmanager.current;
9068		if ( this.options.activeClass ) {
9069			this.element.removeClass( this.options.activeClass );
9070		}
9071		if ( draggable ){
9072			this._trigger( "deactivate", event, this.ui( draggable ) );
9073		}
9074	},
9075
9076	_over: function( event ) {
9077
9078		var draggable = $.ui.ddmanager.current;
9079
9080		// Bail if draggable and droppable are same element
9081		if ( !draggable || ( draggable.currentItem || draggable.element )[ 0 ] === this.element[ 0 ] ) {
9082			return;
9083		}
9084
9085		if ( this.accept.call( this.element[ 0 ], ( draggable.currentItem || draggable.element ) ) ) {
9086			if ( this.options.hoverClass ) {
9087				this.element.addClass( this.options.hoverClass );
9088			}
9089			this._trigger( "over", event, this.ui( draggable ) );
9090		}
9091
9092	},
9093
9094	_out: function( event ) {
9095
9096		var draggable = $.ui.ddmanager.current;
9097
9098		// Bail if draggable and droppable are same element
9099		if ( !draggable || ( draggable.currentItem || draggable.element )[ 0 ] === this.element[ 0 ] ) {
9100			return;
9101		}
9102
9103		if ( this.accept.call( this.element[ 0 ], ( draggable.currentItem || draggable.element ) ) ) {
9104			if ( this.options.hoverClass ) {
9105				this.element.removeClass( this.options.hoverClass );
9106			}
9107			this._trigger( "out", event, this.ui( draggable ) );
9108		}
9109
9110	},
9111
9112	_drop: function( event, custom ) {
9113
9114		var draggable = custom || $.ui.ddmanager.current,
9115			childrenIntersection = false;
9116
9117		// Bail if draggable and droppable are same element
9118		if ( !draggable || ( draggable.currentItem || draggable.element )[ 0 ] === this.element[ 0 ] ) {
9119			return false;
9120		}
9121
9122		this.element.find( ":data(ui-droppable)" ).not( ".ui-draggable-dragging" ).each(function() {
9123			var inst = $( this ).droppable( "instance" );
9124			if (
9125				inst.options.greedy &&
9126				!inst.options.disabled &&
9127				inst.options.scope === draggable.options.scope &&
9128				inst.accept.call( inst.element[ 0 ], ( draggable.currentItem || draggable.element ) ) &&
9129				$.ui.intersect( draggable, $.extend( inst, { offset: inst.element.offset() } ), inst.options.tolerance, event )
9130			) { childrenIntersection = true; return false; }
9131		});
9132		if ( childrenIntersection ) {
9133			return false;
9134		}
9135
9136		if ( this.accept.call( this.element[ 0 ], ( draggable.currentItem || draggable.element ) ) ) {
9137			if ( this.options.activeClass ) {
9138				this.element.removeClass( this.options.activeClass );
9139			}
9140			if ( this.options.hoverClass ) {
9141				this.element.removeClass( this.options.hoverClass );
9142			}
9143			this._trigger( "drop", event, this.ui( draggable ) );
9144			return this.element;
9145		}
9146
9147		return false;
9148
9149	},
9150
9151	ui: function( c ) {
9152		return {
9153			draggable: ( c.currentItem || c.element ),
9154			helper: c.helper,
9155			position: c.position,
9156			offset: c.positionAbs
9157		};
9158	}
9159
9160});
9161
9162$.ui.intersect = (function() {
9163	function isOverAxis( x, reference, size ) {
9164		return ( x >= reference ) && ( x < ( reference + size ) );
9165	}
9166
9167	return function( draggable, droppable, toleranceMode, event ) {
9168
9169		if ( !droppable.offset ) {
9170			return false;
9171		}
9172
9173		var x1 = ( draggable.positionAbs || draggable.position.absolute ).left + draggable.margins.left,
9174			y1 = ( draggable.positionAbs || draggable.position.absolute ).top + draggable.margins.top,
9175			x2 = x1 + draggable.helperProportions.width,
9176			y2 = y1 + draggable.helperProportions.height,
9177			l = droppable.offset.left,
9178			t = droppable.offset.top,
9179			r = l + droppable.proportions().width,
9180			b = t + droppable.proportions().height;
9181
9182		switch ( toleranceMode ) {
9183		case "fit":
9184			return ( l <= x1 && x2 <= r && t <= y1 && y2 <= b );
9185		case "intersect":
9186			return ( l < x1 + ( draggable.helperProportions.width / 2 ) && // Right Half
9187				x2 - ( draggable.helperProportions.width / 2 ) < r && // Left Half
9188				t < y1 + ( draggable.helperProportions.height / 2 ) && // Bottom Half
9189				y2 - ( draggable.helperProportions.height / 2 ) < b ); // Top Half
9190		case "pointer":
9191			return isOverAxis( event.pageY, t, droppable.proportions().height ) && isOverAxis( event.pageX, l, droppable.proportions().width );
9192		case "touch":
9193			return (
9194				( y1 >= t && y1 <= b ) || // Top edge touching
9195				( y2 >= t && y2 <= b ) || // Bottom edge touching
9196				( y1 < t && y2 > b ) // Surrounded vertically
9197			) && (
9198				( x1 >= l && x1 <= r ) || // Left edge touching
9199				( x2 >= l && x2 <= r ) || // Right edge touching
9200				( x1 < l && x2 > r ) // Surrounded horizontally
9201			);
9202		default:
9203			return false;
9204		}
9205	};
9206})();
9207
9208/*
9209	This manager tracks offsets of draggables and droppables
9210*/
9211$.ui.ddmanager = {
9212	current: null,
9213	droppables: { "default": [] },
9214	prepareOffsets: function( t, event ) {
9215
9216		var i, j,
9217			m = $.ui.ddmanager.droppables[ t.options.scope ] || [],
9218			type = event ? event.type : null, // workaround for #2317
9219			list = ( t.currentItem || t.element ).find( ":data(ui-droppable)" ).addBack();
9220
9221		droppablesLoop: for ( i = 0; i < m.length; i++ ) {
9222
9223			// No disabled and non-accepted
9224			if ( m[ i ].options.disabled || ( t && !m[ i ].accept.call( m[ i ].element[ 0 ], ( t.currentItem || t.element ) ) ) ) {
9225				continue;
9226			}
9227
9228			// Filter out elements in the current dragged item
9229			for ( j = 0; j < list.length; j++ ) {
9230				if ( list[ j ] === m[ i ].element[ 0 ] ) {
9231					m[ i ].proportions().height = 0;
9232					continue droppablesLoop;
9233				}
9234			}
9235
9236			m[ i ].visible = m[ i ].element.css( "display" ) !== "none";
9237			if ( !m[ i ].visible ) {
9238				continue;
9239			}
9240
9241			// Activate the droppable if used directly from draggables
9242			if ( type === "mousedown" ) {
9243				m[ i ]._activate.call( m[ i ], event );
9244			}
9245
9246			m[ i ].offset = m[ i ].element.offset();
9247			m[ i ].proportions({ width: m[ i ].element[ 0 ].offsetWidth, height: m[ i ].element[ 0 ].offsetHeight });
9248
9249		}
9250
9251	},
9252	drop: function( draggable, event ) {
9253
9254		var dropped = false;
9255		// Create a copy of the droppables in case the list changes during the drop (#9116)
9256		$.each( ( $.ui.ddmanager.droppables[ draggable.options.scope ] || [] ).slice(), function() {
9257
9258			if ( !this.options ) {
9259				return;
9260			}
9261			if ( !this.options.disabled && this.visible && $.ui.intersect( draggable, this, this.options.tolerance, event ) ) {
9262				dropped = this._drop.call( this, event ) || dropped;
9263			}
9264
9265			if ( !this.options.disabled && this.visible && this.accept.call( this.element[ 0 ], ( draggable.currentItem || draggable.element ) ) ) {
9266				this.isout = true;
9267				this.isover = false;
9268				this._deactivate.call( this, event );
9269			}
9270
9271		});
9272		return dropped;
9273
9274	},
9275	dragStart: function( draggable, event ) {
9276		// Listen for scrolling so that if the dragging causes scrolling the position of the droppables can be recalculated (see #5003)
9277		draggable.element.parentsUntil( "body" ).bind( "scroll.droppable", function() {
9278			if ( !draggable.options.refreshPositions ) {
9279				$.ui.ddmanager.prepareOffsets( draggable, event );
9280			}
9281		});
9282	},
9283	drag: function( draggable, event ) {
9284
9285		// If you have a highly dynamic page, you might try this option. It renders positions every time you move the mouse.
9286		if ( draggable.options.refreshPositions ) {
9287			$.ui.ddmanager.prepareOffsets( draggable, event );
9288		}
9289
9290		// Run through all droppables and check their positions based on specific tolerance options
9291		$.each( $.ui.ddmanager.droppables[ draggable.options.scope ] || [], function() {
9292
9293			if ( this.options.disabled || this.greedyChild || !this.visible ) {
9294				return;
9295			}
9296
9297			var parentInstance, scope, parent,
9298				intersects = $.ui.intersect( draggable, this, this.options.tolerance, event ),
9299				c = !intersects && this.isover ? "isout" : ( intersects && !this.isover ? "isover" : null );
9300			if ( !c ) {
9301				return;
9302			}
9303
9304			if ( this.options.greedy ) {
9305				// find droppable parents with same scope
9306				scope = this.options.scope;
9307				parent = this.element.parents( ":data(ui-droppable)" ).filter(function() {
9308					return $( this ).droppable( "instance" ).options.scope === scope;
9309				});
9310
9311				if ( parent.length ) {
9312					parentInstance = $( parent[ 0 ] ).droppable( "instance" );
9313					parentInstance.greedyChild = ( c === "isover" );
9314				}
9315			}
9316
9317			// we just moved into a greedy child
9318			if ( parentInstance && c === "isover" ) {
9319				parentInstance.isover = false;
9320				parentInstance.isout = true;
9321				parentInstance._out.call( parentInstance, event );
9322			}
9323
9324			this[ c ] = true;
9325			this[c === "isout" ? "isover" : "isout"] = false;
9326			this[c === "isover" ? "_over" : "_out"].call( this, event );
9327
9328			// we just moved out of a greedy child
9329			if ( parentInstance && c === "isout" ) {
9330				parentInstance.isout = false;
9331				parentInstance.isover = true;
9332				parentInstance._over.call( parentInstance, event );
9333			}
9334		});
9335
9336	},
9337	dragStop: function( draggable, event ) {
9338		draggable.element.parentsUntil( "body" ).unbind( "scroll.droppable" );
9339		// Call prepareOffsets one final time since IE does not fire return scroll events when overflow was caused by drag (see #5003)
9340		if ( !draggable.options.refreshPositions ) {
9341			$.ui.ddmanager.prepareOffsets( draggable, event );
9342		}
9343	}
9344};
9345
9346var droppable = $.ui.droppable;
9347
9348
9349/*!
9350 * jQuery UI Effects 1.11.4
9351 * http://jqueryui.com
9352 *
9353 * Copyright jQuery Foundation and other contributors
9354 * Released under the MIT license.
9355 * http://jquery.org/license
9356 *
9357 * http://api.jqueryui.com/category/effects-core/
9358 */
9359
9360
9361var dataSpace = "ui-effects-",
9362
9363	// Create a local jQuery because jQuery Color relies on it and the
9364	// global may not exist with AMD and a custom build (#10199)
9365	jQuery = $;
9366
9367$.effects = {
9368	effect: {}
9369};
9370
9371/*!
9372 * jQuery Color Animations v2.1.2
9373 * https://github.com/jquery/jquery-color
9374 *
9375 * Copyright 2014 jQuery Foundation and other contributors
9376 * Released under the MIT license.
9377 * http://jquery.org/license
9378 *
9379 * Date: Wed Jan 16 08:47:09 2013 -0600
9380 */
9381(function( jQuery, undefined ) {
9382
9383	var stepHooks = "backgroundColor borderBottomColor borderLeftColor borderRightColor borderTopColor color columnRuleColor outlineColor textDecorationColor textEmphasisColor",
9384
9385	// plusequals test for += 100 -= 100
9386	rplusequals = /^([\-+])=\s*(\d+\.?\d*)/,
9387	// a set of RE's that can match strings and generate color tuples.
9388	stringParsers = [ {
9389			re: /rgba?\(\s*(\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(\d{1,3})\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/,
9390			parse: function( execResult ) {
9391				return [
9392					execResult[ 1 ],
9393					execResult[ 2 ],
9394					execResult[ 3 ],
9395					execResult[ 4 ]
9396				];
9397			}
9398		}, {
9399			re: /rgba?\(\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/,
9400			parse: function( execResult ) {
9401				return [
9402					execResult[ 1 ] * 2.55,
9403					execResult[ 2 ] * 2.55,
9404					execResult[ 3 ] * 2.55,
9405					execResult[ 4 ]
9406				];
9407			}
9408		}, {
9409			// this regex ignores A-F because it's compared against an already lowercased string
9410			re: /#([a-f0-9]{2})([a-f0-9]{2})([a-f0-9]{2})/,
9411			parse: function( execResult ) {
9412				return [
9413					parseInt( execResult[ 1 ], 16 ),
9414					parseInt( execResult[ 2 ], 16 ),
9415					parseInt( execResult[ 3 ], 16 )
9416				];
9417			}
9418		}, {
9419			// this regex ignores A-F because it's compared against an already lowercased string
9420			re: /#([a-f0-9])([a-f0-9])([a-f0-9])/,
9421			parse: function( execResult ) {
9422				return [
9423					parseInt( execResult[ 1 ] + execResult[ 1 ], 16 ),
9424					parseInt( execResult[ 2 ] + execResult[ 2 ], 16 ),
9425					parseInt( execResult[ 3 ] + execResult[ 3 ], 16 )
9426				];
9427			}
9428		}, {
9429			re: /hsla?\(\s*(\d+(?:\.\d+)?)\s*,\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/,
9430			space: "hsla",
9431			parse: function( execResult ) {
9432				return [
9433					execResult[ 1 ],
9434					execResult[ 2 ] / 100,
9435					execResult[ 3 ] / 100,
9436					execResult[ 4 ]
9437				];
9438			}
9439		} ],
9440
9441	// jQuery.Color( )
9442	color = jQuery.Color = function( color, green, blue, alpha ) {
9443		return new jQuery.Color.fn.parse( color, green, blue, alpha );
9444	},
9445	spaces = {
9446		rgba: {
9447			props: {
9448				red: {
9449					idx: 0,
9450					type: "byte"
9451				},
9452				green: {
9453					idx: 1,
9454					type: "byte"
9455				},
9456				blue: {
9457					idx: 2,
9458					type: "byte"
9459				}
9460			}
9461		},
9462
9463		hsla: {
9464			props: {
9465				hue: {
9466					idx: 0,
9467					type: "degrees"
9468				},
9469				saturation: {
9470					idx: 1,
9471					type: "percent"
9472				},
9473				lightness: {
9474					idx: 2,
9475					type: "percent"
9476				}
9477			}
9478		}
9479	},
vendor: 9,998 bytes, lines 9480-9887
9480	propTypes = {
9481		"byte": {
9482			floor: true,
9483			max: 255
9484		},
9485		"percent": {
9486			max: 1
9487		},
9488		"degrees": {
9489			mod: 360,
9490			floor: true
9491		}
9492	},
9493	support = color.support = {},
9494
9495	// element for support tests
9496	supportElem = jQuery( "<p>" )[ 0 ],
9497
9498	// colors = jQuery.Color.names
9499	colors,
9500
9501	// local aliases of functions called often
9502	each = jQuery.each;
9503
9504// determine rgba support immediately
9505supportElem.style.cssText = "background-color:rgba(1,1,1,.5)";
9506support.rgba = supportElem.style.backgroundColor.indexOf( "rgba" ) > -1;
9507
9508// define cache name and alpha properties
9509// for rgba and hsla spaces
9510each( spaces, function( spaceName, space ) {
9511	space.cache = "_" + spaceName;
9512	space.props.alpha = {
9513		idx: 3,
9514		type: "percent",
9515		def: 1
9516	};
9517});
9518
9519function clamp( value, prop, allowEmpty ) {
9520	var type = propTypes[ prop.type ] || {};
9521
9522	if ( value == null ) {
9523		return (allowEmpty || !prop.def) ? null : prop.def;
9524	}
9525
9526	// ~~ is an short way of doing floor for positive numbers
9527	value = type.floor ? ~~value : parseFloat( value );
9528
9529	// IE will pass in empty strings as value for alpha,
9530	// which will hit this case
9531	if ( isNaN( value ) ) {
9532		return prop.def;
9533	}
9534
9535	if ( type.mod ) {
9536		// we add mod before modding to make sure that negatives values
9537		// get converted properly: -10 -> 350
9538		return (value + type.mod) % type.mod;
9539	}
9540
9541	// for now all property types without mod have min and max
9542	return 0 > value ? 0 : type.max < value ? type.max : value;
9543}
9544
9545function stringParse( string ) {
9546	var inst = color(),
9547		rgba = inst._rgba = [];
9548
9549	string = string.toLowerCase();
9550
9551	each( stringParsers, function( i, parser ) {
9552		var parsed,
9553			match = parser.re.exec( string ),
9554			values = match && parser.parse( match ),
9555			spaceName = parser.space || "rgba";
9556
9557		if ( values ) {
9558			parsed = inst[ spaceName ]( values );
9559
9560			// if this was an rgba parse the assignment might happen twice
9561			// oh well....
9562			inst[ spaces[ spaceName ].cache ] = parsed[ spaces[ spaceName ].cache ];
9563			rgba = inst._rgba = parsed._rgba;
9564
9565			// exit each( stringParsers ) here because we matched
9566			return false;
9567		}
9568	});
9569
9570	// Found a stringParser that handled it
9571	if ( rgba.length ) {
9572
9573		// if this came from a parsed string, force "transparent" when alpha is 0
9574		// chrome, (and maybe others) return "transparent" as rgba(0,0,0,0)
9575		if ( rgba.join() === "0,0,0,0" ) {
9576			jQuery.extend( rgba, colors.transparent );
9577		}
9578		return inst;
9579	}
9580
9581	// named colors
9582	return colors[ string ];
9583}
9584
9585color.fn = jQuery.extend( color.prototype, {
9586	parse: function( red, green, blue, alpha ) {
9587		if ( red === undefined ) {
9588			this._rgba = [ null, null, null, null ];
9589			return this;
9590		}
9591		if ( red.jquery || red.nodeType ) {
9592			red = jQuery( red ).css( green );
9593			green = undefined;
9594		}
9595
9596		var inst = this,
9597			type = jQuery.type( red ),
9598			rgba = this._rgba = [];
9599
9600		// more than 1 argument specified - assume ( red, green, blue, alpha )
9601		if ( green !== undefined ) {
9602			red = [ red, green, blue, alpha ];
9603			type = "array";
9604		}
9605
9606		if ( type === "string" ) {
9607			return this.parse( stringParse( red ) || colors._default );
9608		}
9609
9610		if ( type === "array" ) {
9611			each( spaces.rgba.props, function( key, prop ) {
9612				rgba[ prop.idx ] = clamp( red[ prop.idx ], prop );
9613			});
9614			return this;
9615		}
9616
9617		if ( type === "object" ) {
9618			if ( red instanceof color ) {
9619				each( spaces, function( spaceName, space ) {
9620					if ( red[ space.cache ] ) {
9621						inst[ space.cache ] = red[ space.cache ].slice();
9622					}
9623				});
9624			} else {
9625				each( spaces, function( spaceName, space ) {
9626					var cache = space.cache;
9627					each( space.props, function( key, prop ) {
9628
9629						// if the cache doesn't exist, and we know how to convert
9630						if ( !inst[ cache ] && space.to ) {
9631
9632							// if the value was null, we don't need to copy it
9633							// if the key was alpha, we don't need to copy it either
9634							if ( key === "alpha" || red[ key ] == null ) {
9635								return;
9636							}
9637							inst[ cache ] = space.to( inst._rgba );
9638						}
9639
9640						// this is the only case where we allow nulls for ALL properties.
9641						// call clamp with alwaysAllowEmpty
9642						inst[ cache ][ prop.idx ] = clamp( red[ key ], prop, true );
9643					});
9644
9645					// everything defined but alpha?
9646					if ( inst[ cache ] && jQuery.inArray( null, inst[ cache ].slice( 0, 3 ) ) < 0 ) {
9647						// use the default of 1
9648						inst[ cache ][ 3 ] = 1;
9649						if ( space.from ) {
9650							inst._rgba = space.from( inst[ cache ] );
9651						}
9652					}
9653				});
9654			}
9655			return this;
9656		}
9657	},
9658	is: function( compare ) {
9659		var is = color( compare ),
9660			same = true,
9661			inst = this;
9662
9663		each( spaces, function( _, space ) {
9664			var localCache,
9665				isCache = is[ space.cache ];
9666			if (isCache) {
9667				localCache = inst[ space.cache ] || space.to && space.to( inst._rgba ) || [];
9668				each( space.props, function( _, prop ) {
9669					if ( isCache[ prop.idx ] != null ) {
9670						same = ( isCache[ prop.idx ] === localCache[ prop.idx ] );
9671						return same;
9672					}
9673				});
9674			}
9675			return same;
9676		});
9677		return same;
9678	},
9679	_space: function() {
9680		var used = [],
9681			inst = this;
9682		each( spaces, function( spaceName, space ) {
9683			if ( inst[ space.cache ] ) {
9684				used.push( spaceName );
9685			}
9686		});
9687		return used.pop();
9688	},
9689	transition: function( other, distance ) {
9690		var end = color( other ),
9691			spaceName = end._space(),
9692			space = spaces[ spaceName ],
9693			startColor = this.alpha() === 0 ? color( "transparent" ) : this,
9694			start = startColor[ space.cache ] || space.to( startColor._rgba ),
9695			result = start.slice();
9696
9697		end = end[ space.cache ];
9698		each( space.props, function( key, prop ) {
9699			var index = prop.idx,
9700				startValue = start[ index ],
9701				endValue = end[ index ],
9702				type = propTypes[ prop.type ] || {};
9703
9704			// if null, don't override start value
9705			if ( endValue === null ) {
9706				return;
9707			}
9708			// if null - use end
9709			if ( startValue === null ) {
9710				result[ index ] = endValue;
9711			} else {
9712				if ( type.mod ) {
9713					if ( endValue - startValue > type.mod / 2 ) {
9714						startValue += type.mod;
9715					} else if ( startValue - endValue > type.mod / 2 ) {
9716						startValue -= type.mod;
9717					}
9718				}
9719				result[ index ] = clamp( ( endValue - startValue ) * distance + startValue, prop );
9720			}
9721		});
9722		return this[ spaceName ]( result );
9723	},
9724	blend: function( opaque ) {
9725		// if we are already opaque - return ourself
9726		if ( this._rgba[ 3 ] === 1 ) {
9727			return this;
9728		}
9729
9730		var rgb = this._rgba.slice(),
9731			a = rgb.pop(),
9732			blend = color( opaque )._rgba;
9733
9734		return color( jQuery.map( rgb, function( v, i ) {
9735			return ( 1 - a ) * blend[ i ] + a * v;
9736		}));
9737	},
9738	toRgbaString: function() {
9739		var prefix = "rgba(",
9740			rgba = jQuery.map( this._rgba, function( v, i ) {
9741				return v == null ? ( i > 2 ? 1 : 0 ) : v;
9742			});
9743
9744		if ( rgba[ 3 ] === 1 ) {
9745			rgba.pop();
9746			prefix = "rgb(";
9747		}
9748
9749		return prefix + rgba.join() + ")";
9750	},
9751	toHslaString: function() {
9752		var prefix = "hsla(",
9753			hsla = jQuery.map( this.hsla(), function( v, i ) {
9754				if ( v == null ) {
9755					v = i > 2 ? 1 : 0;
9756				}
9757
9758				// catch 1 and 2
9759				if ( i && i < 3 ) {
9760					v = Math.round( v * 100 ) + "%";
9761				}
9762				return v;
9763			});
9764
9765		if ( hsla[ 3 ] === 1 ) {
9766			hsla.pop();
9767			prefix = "hsl(";
9768		}
9769		return prefix + hsla.join() + ")";
9770	},
9771	toHexString: function( includeAlpha ) {
9772		var rgba = this._rgba.slice(),
9773			alpha = rgba.pop();
9774
9775		if ( includeAlpha ) {
9776			rgba.push( ~~( alpha * 255 ) );
9777		}
9778
9779		return "#" + jQuery.map( rgba, function( v ) {
9780
9781			// default to 0 when nulls exist
9782			v = ( v || 0 ).toString( 16 );
9783			return v.length === 1 ? "0" + v : v;
9784		}).join("");
9785	},
9786	toString: function() {
9787		return this._rgba[ 3 ] === 0 ? "transparent" : this.toRgbaString();
9788	}
9789});
9790color.fn.parse.prototype = color.fn;
9791
9792// hsla conversions adapted from:
9793// https://code.google.com/p/maashaack/source/browse/packages/graphics/trunk/src/graphics/colors/HUE2RGB.as?r=5021
9794
9795function hue2rgb( p, q, h ) {
9796	h = ( h + 1 ) % 1;
9797	if ( h * 6 < 1 ) {
9798		return p + ( q - p ) * h * 6;
9799	}
9800	if ( h * 2 < 1) {
9801		return q;
9802	}
9803	if ( h * 3 < 2 ) {
9804		return p + ( q - p ) * ( ( 2 / 3 ) - h ) * 6;
9805	}
9806	return p;
9807}
9808
9809spaces.hsla.to = function( rgba ) {
9810	if ( rgba[ 0 ] == null || rgba[ 1 ] == null || rgba[ 2 ] == null ) {
9811		return [ null, null, null, rgba[ 3 ] ];
9812	}
9813	var r = rgba[ 0 ] / 255,
9814		g = rgba[ 1 ] / 255,
9815		b = rgba[ 2 ] / 255,
9816		a = rgba[ 3 ],
9817		max = Math.max( r, g, b ),
9818		min = Math.min( r, g, b ),
9819		diff = max - min,
9820		add = max + min,
9821		l = add * 0.5,
9822		h, s;
9823
9824	if ( min === max ) {
9825		h = 0;
9826	} else if ( r === max ) {
9827		h = ( 60 * ( g - b ) / diff ) + 360;
9828	} else if ( g === max ) {
9829		h = ( 60 * ( b - r ) / diff ) + 120;
9830	} else {
9831		h = ( 60 * ( r - g ) / diff ) + 240;
9832	}
9833
9834	// chroma (diff) == 0 means greyscale which, by definition, saturation = 0%
9835	// otherwise, saturation is based on the ratio of chroma (diff) to lightness (add)
9836	if ( diff === 0 ) {
9837		s = 0;
9838	} else if ( l <= 0.5 ) {
9839		s = diff / add;
9840	} else {
9841		s = diff / ( 2 - add );
9842	}
9843	return [ Math.round(h) % 360, s, l, a == null ? 1 : a ];
9844};
9845
9846spaces.hsla.from = function( hsla ) {
9847	if ( hsla[ 0 ] == null || hsla[ 1 ] == null || hsla[ 2 ] == null ) {
9848		return [ null, null, null, hsla[ 3 ] ];
9849	}
9850	var h = hsla[ 0 ] / 360,
9851		s = hsla[ 1 ],
9852		l = hsla[ 2 ],
9853		a = hsla[ 3 ],
9854		q = l <= 0.5 ? l * ( 1 + s ) : l + s - l * s,
9855		p = 2 * l - q;
9856
9857	return [
9858		Math.round( hue2rgb( p, q, h + ( 1 / 3 ) ) * 255 ),
9859		Math.round( hue2rgb( p, q, h ) * 255 ),
9860		Math.round( hue2rgb( p, q, h - ( 1 / 3 ) ) * 255 ),
9861		a
9862	];
9863};
9864
9865each( spaces, function( spaceName, space ) {
9866	var props = space.props,
9867		cache = space.cache,
9868		to = space.to,
9869		from = space.from;
9870
9871	// makes rgba() and hsla()
9872	color.fn[ spaceName ] = function( value ) {
9873
9874		// generate a cache for this space if it doesn't exist
9875		if ( to && !this[ cache ] ) {
9876			this[ cache ] = to( this._rgba );
9877		}
9878		if ( value === undefined ) {
9879			return this[ cache ].slice();
9880		}
9881
9882		var ret,
9883			type = jQuery.type( value ),
9884			arr = ( type === "array" || type === "object" ) ? value : arguments,
9885			local = this[ cache ].slice();
9886
9887		each( props, function( key, prop ) {
vendor: 50,293 bytes, lines 9888-11951
9888			var val = arr[ type === "object" ? key : prop.idx ];
9889			if ( val == null ) {
9890				val = local[ prop.idx ];
9891			}
9892			local[ prop.idx ] = clamp( val, prop );
9893		});
9894
9895		if ( from ) {
9896			ret = color( from( local ) );
9897			ret[ cache ] = local;
9898			return ret;
9899		} else {
9900			return color( local );
9901		}
9902	};
9903
9904	// makes red() green() blue() alpha() hue() saturation() lightness()
9905	each( props, function( key, prop ) {
9906		// alpha is included in more than one space
9907		if ( color.fn[ key ] ) {
9908			return;
9909		}
9910		color.fn[ key ] = function( value ) {
9911			var vtype = jQuery.type( value ),
9912				fn = ( key === "alpha" ? ( this._hsla ? "hsla" : "rgba" ) : spaceName ),
9913				local = this[ fn ](),
9914				cur = local[ prop.idx ],
9915				match;
9916
9917			if ( vtype === "undefined" ) {
9918				return cur;
9919			}
9920
9921			if ( vtype === "function" ) {
9922				value = value.call( this, cur );
9923				vtype = jQuery.type( value );
9924			}
9925			if ( value == null && prop.empty ) {
9926				return this;
9927			}
9928			if ( vtype === "string" ) {
9929				match = rplusequals.exec( value );
9930				if ( match ) {
9931					value = cur + parseFloat( match[ 2 ] ) * ( match[ 1 ] === "+" ? 1 : -1 );
9932				}
9933			}
9934			local[ prop.idx ] = value;
9935			return this[ fn ]( local );
9936		};
9937	});
9938});
9939
9940// add cssHook and .fx.step function for each named hook.
9941// accept a space separated string of properties
9942color.hook = function( hook ) {
9943	var hooks = hook.split( " " );
9944	each( hooks, function( i, hook ) {
9945		jQuery.cssHooks[ hook ] = {
9946			set: function( elem, value ) {
9947				var parsed, curElem,
9948					backgroundColor = "";
9949
9950				if ( value !== "transparent" && ( jQuery.type( value ) !== "string" || ( parsed = stringParse( value ) ) ) ) {
9951					value = color( parsed || value );
9952					if ( !support.rgba && value._rgba[ 3 ] !== 1 ) {
9953						curElem = hook === "backgroundColor" ? elem.parentNode : elem;
9954						while (
9955							(backgroundColor === "" || backgroundColor === "transparent") &&
9956							curElem && curElem.style
9957						) {
9958							try {
9959								backgroundColor = jQuery.css( curElem, "backgroundColor" );
9960								curElem = curElem.parentNode;
9961							} catch ( e ) {
9962							}
9963						}
9964
9965						value = value.blend( backgroundColor && backgroundColor !== "transparent" ?
9966							backgroundColor :
9967							"_default" );
9968					}
9969
9970					value = value.toRgbaString();
9971				}
9972				try {
9973					elem.style[ hook ] = value;
9974				} catch ( e ) {
9975					// wrapped to prevent IE from throwing errors on "invalid" values like 'auto' or 'inherit'
9976				}
9977			}
9978		};
9979		jQuery.fx.step[ hook ] = function( fx ) {
9980			if ( !fx.colorInit ) {
9981				fx.start = color( fx.elem, hook );
9982				fx.end = color( fx.end );
9983				fx.colorInit = true;
9984			}
9985			jQuery.cssHooks[ hook ].set( fx.elem, fx.start.transition( fx.end, fx.pos ) );
9986		};
9987	});
9988
9989};
9990
9991color.hook( stepHooks );
9992
9993jQuery.cssHooks.borderColor = {
9994	expand: function( value ) {
9995		var expanded = {};
9996
9997		each( [ "Top", "Right", "Bottom", "Left" ], function( i, part ) {
9998			expanded[ "border" + part + "Color" ] = value;
9999		});
10000		return expanded;
10001	}
10002};
10003
10004// Basic color names only.
10005// Usage of any of the other color names requires adding yourself or including
10006// jquery.color.svg-names.js.
10007colors = jQuery.Color.names = {
10008	// 4.1. Basic color keywords
10009	aqua: "#00ffff",
10010	black: "#000000",
10011	blue: "#0000ff",
10012	fuchsia: "#ff00ff",
10013	gray: "#808080",
10014	green: "#008000",
10015	lime: "#00ff00",
10016	maroon: "#800000",
10017	navy: "#000080",
10018	olive: "#808000",
10019	purple: "#800080",
10020	red: "#ff0000",
10021	silver: "#c0c0c0",
10022	teal: "#008080",
10023	white: "#ffffff",
10024	yellow: "#ffff00",
10025
10026	// 4.2.3. "transparent" color keyword
10027	transparent: [ null, null, null, 0 ],
10028
10029	_default: "#ffffff"
10030};
10031
10032})( jQuery );
10033
10034/******************************************************************************/
10035/****************************** CLASS ANIMATIONS ******************************/
10036/******************************************************************************/
10037(function() {
10038
10039var classAnimationActions = [ "add", "remove", "toggle" ],
10040	shorthandStyles = {
10041		border: 1,
10042		borderBottom: 1,
10043		borderColor: 1,
10044		borderLeft: 1,
10045		borderRight: 1,
10046		borderTop: 1,
10047		borderWidth: 1,
10048		margin: 1,
10049		padding: 1
10050	};
10051
10052$.each([ "borderLeftStyle", "borderRightStyle", "borderBottomStyle", "borderTopStyle" ], function( _, prop ) {
10053	$.fx.step[ prop ] = function( fx ) {
10054		if ( fx.end !== "none" && !fx.setAttr || fx.pos === 1 && !fx.setAttr ) {
10055			jQuery.style( fx.elem, prop, fx.end );
10056			fx.setAttr = true;
10057		}
10058	};
10059});
10060
10061function getElementStyles( elem ) {
10062	var key, len,
10063		style = elem.ownerDocument.defaultView ?
10064			elem.ownerDocument.defaultView.getComputedStyle( elem, null ) :
10065			elem.currentStyle,
10066		styles = {};
10067
10068	if ( style && style.length && style[ 0 ] && style[ style[ 0 ] ] ) {
10069		len = style.length;
10070		while ( len-- ) {
10071			key = style[ len ];
10072			if ( typeof style[ key ] === "string" ) {
10073				styles[ $.camelCase( key ) ] = style[ key ];
10074			}
10075		}
10076	// support: Opera, IE <9
10077	} else {
10078		for ( key in style ) {
10079			if ( typeof style[ key ] === "string" ) {
10080				styles[ key ] = style[ key ];
10081			}
10082		}
10083	}
10084
10085	return styles;
10086}
10087
10088function styleDifference( oldStyle, newStyle ) {
10089	var diff = {},
10090		name, value;
10091
10092	for ( name in newStyle ) {
10093		value = newStyle[ name ];
10094		if ( oldStyle[ name ] !== value ) {
10095			if ( !shorthandStyles[ name ] ) {
10096				if ( $.fx.step[ name ] || !isNaN( parseFloat( value ) ) ) {
10097					diff[ name ] = value;
10098				}
10099			}
10100		}
10101	}
10102
10103	return diff;
10104}
10105
10106// support: jQuery <1.8
10107if ( !$.fn.addBack ) {
10108	$.fn.addBack = function( selector ) {
10109		return this.add( selector == null ?
10110			this.prevObject : this.prevObject.filter( selector )
10111		);
10112	};
10113}
10114
10115$.effects.animateClass = function( value, duration, easing, callback ) {
10116	var o = $.speed( duration, easing, callback );
10117
10118	return this.queue( function() {
10119		var animated = $( this ),
10120			baseClass = animated.attr( "class" ) || "",
10121			applyClassChange,
10122			allAnimations = o.children ? animated.find( "*" ).addBack() : animated;
10123
10124		// map the animated objects to store the original styles.
10125		allAnimations = allAnimations.map(function() {
10126			var el = $( this );
10127			return {
10128				el: el,
10129				start: getElementStyles( this )
10130			};
10131		});
10132
10133		// apply class change
10134		applyClassChange = function() {
10135			$.each( classAnimationActions, function(i, action) {
10136				if ( value[ action ] ) {
10137					animated[ action + "Class" ]( value[ action ] );
10138				}
10139			});
10140		};
10141		applyClassChange();
10142
10143		// map all animated objects again - calculate new styles and diff
10144		allAnimations = allAnimations.map(function() {
10145			this.end = getElementStyles( this.el[ 0 ] );
10146			this.diff = styleDifference( this.start, this.end );
10147			return this;
10148		});
10149
10150		// apply original class
10151		animated.attr( "class", baseClass );
10152
10153		// map all animated objects again - this time collecting a promise
10154		allAnimations = allAnimations.map(function() {
10155			var styleInfo = this,
10156				dfd = $.Deferred(),
10157				opts = $.extend({}, o, {
10158					queue: false,
10159					complete: function() {
10160						dfd.resolve( styleInfo );
10161					}
10162				});
10163
10164			this.el.animate( this.diff, opts );
10165			return dfd.promise();
10166		});
10167
10168		// once all animations have completed:
10169		$.when.apply( $, allAnimations.get() ).done(function() {
10170
10171			// set the final class
10172			applyClassChange();
10173
10174			// for each animated element,
10175			// clear all css properties that were animated
10176			$.each( arguments, function() {
10177				var el = this.el;
10178				$.each( this.diff, function(key) {
10179					el.css( key, "" );
10180				});
10181			});
10182
10183			// this is guarnteed to be there if you use jQuery.speed()
10184			// it also handles dequeuing the next anim...
10185			o.complete.call( animated[ 0 ] );
10186		});
10187	});
10188};
10189
10190$.fn.extend({
10191	addClass: (function( orig ) {
10192		return function( classNames, speed, easing, callback ) {
10193			return speed ?
10194				$.effects.animateClass.call( this,
10195					{ add: classNames }, speed, easing, callback ) :
10196				orig.apply( this, arguments );
10197		};
10198	})( $.fn.addClass ),
10199
10200	removeClass: (function( orig ) {
10201		return function( classNames, speed, easing, callback ) {
10202			return arguments.length > 1 ?
10203				$.effects.animateClass.call( this,
10204					{ remove: classNames }, speed, easing, callback ) :
10205				orig.apply( this, arguments );
10206		};
10207	})( $.fn.removeClass ),
10208
10209	toggleClass: (function( orig ) {
10210		return function( classNames, force, speed, easing, callback ) {
10211			if ( typeof force === "boolean" || force === undefined ) {
10212				if ( !speed ) {
10213					// without speed parameter
10214					return orig.apply( this, arguments );
10215				} else {
10216					return $.effects.animateClass.call( this,
10217						(force ? { add: classNames } : { remove: classNames }),
10218						speed, easing, callback );
10219				}
10220			} else {
10221				// without force parameter
10222				return $.effects.animateClass.call( this,
10223					{ toggle: classNames }, force, speed, easing );
10224			}
10225		};
10226	})( $.fn.toggleClass ),
10227
10228	switchClass: function( remove, add, speed, easing, callback) {
10229		return $.effects.animateClass.call( this, {
10230			add: add,
10231			remove: remove
10232		}, speed, easing, callback );
10233	}
10234});
10235
10236})();
10237
10238/******************************************************************************/
10239/*********************************** EFFECTS **********************************/
10240/******************************************************************************/
10241
10242(function() {
10243
10244$.extend( $.effects, {
10245	version: "1.11.4",
10246
10247	// Saves a set of properties in a data storage
10248	save: function( element, set ) {
10249		for ( var i = 0; i < set.length; i++ ) {
10250			if ( set[ i ] !== null ) {
10251				element.data( dataSpace + set[ i ], element[ 0 ].style[ set[ i ] ] );
10252			}
10253		}
10254	},
10255
10256	// Restores a set of previously saved properties from a data storage
10257	restore: function( element, set ) {
10258		var val, i;
10259		for ( i = 0; i < set.length; i++ ) {
10260			if ( set[ i ] !== null ) {
10261				val = element.data( dataSpace + set[ i ] );
10262				// support: jQuery 1.6.2
10263				// http://bugs.jquery.com/ticket/9917
10264				// jQuery 1.6.2 incorrectly returns undefined for any falsy value.
10265				// We can't differentiate between "" and 0 here, so we just assume
10266				// empty string since it's likely to be a more common value...
10267				if ( val === undefined ) {
10268					val = "";
10269				}
10270				element.css( set[ i ], val );
10271			}
10272		}
10273	},
10274
10275	setMode: function( el, mode ) {
10276		if (mode === "toggle") {
10277			mode = el.is( ":hidden" ) ? "show" : "hide";
10278		}
10279		return mode;
10280	},
10281
10282	// Translates a [top,left] array into a baseline value
10283	// this should be a little more flexible in the future to handle a string & hash
10284	getBaseline: function( origin, original ) {
10285		var y, x;
10286		switch ( origin[ 0 ] ) {
10287			case "top": y = 0; break;
10288			case "middle": y = 0.5; break;
10289			case "bottom": y = 1; break;
10290			default: y = origin[ 0 ] / original.height;
10291		}
10292		switch ( origin[ 1 ] ) {
10293			case "left": x = 0; break;
10294			case "center": x = 0.5; break;
10295			case "right": x = 1; break;
10296			default: x = origin[ 1 ] / original.width;
10297		}
10298		return {
10299			x: x,
10300			y: y
10301		};
10302	},
10303
10304	// Wraps the element around a wrapper that copies position properties
10305	createWrapper: function( element ) {
10306
10307		// if the element is already wrapped, return it
10308		if ( element.parent().is( ".ui-effects-wrapper" )) {
10309			return element.parent();
10310		}
10311
10312		// wrap the element
10313		var props = {
10314				width: element.outerWidth(true),
10315				height: element.outerHeight(true),
10316				"float": element.css( "float" )
10317			},
10318			wrapper = $( "<div></div>" )
10319				.addClass( "ui-effects-wrapper" )
10320				.css({
10321					fontSize: "100%",
10322					background: "transparent",
10323					border: "none",
10324					margin: 0,
10325					padding: 0
10326				}),
10327			// Store the size in case width/height are defined in % - Fixes #5245
10328			size = {
10329				width: element.width(),
10330				height: element.height()
10331			},
10332			active = document.activeElement;
10333
10334		// support: Firefox
10335		// Firefox incorrectly exposes anonymous content
10336		// https://bugzilla.mozilla.org/show_bug.cgi?id=561664
10337		try {
10338			active.id;
10339		} catch ( e ) {
10340			active = document.body;
10341		}
10342
10343		element.wrap( wrapper );
10344
10345		// Fixes #7595 - Elements lose focus when wrapped.
10346		if ( element[ 0 ] === active || $.contains( element[ 0 ], active ) ) {
10347			$( active ).focus();
10348		}
10349
10350		wrapper = element.parent(); //Hotfix for jQuery 1.4 since some change in wrap() seems to actually lose the reference to the wrapped element
10351
10352		// transfer positioning properties to the wrapper
10353		if ( element.css( "position" ) === "static" ) {
10354			wrapper.css({ position: "relative" });
10355			element.css({ position: "relative" });
10356		} else {
10357			$.extend( props, {
10358				position: element.css( "position" ),
10359				zIndex: element.css( "z-index" )
10360			});
10361			$.each([ "top", "left", "bottom", "right" ], function(i, pos) {
10362				props[ pos ] = element.css( pos );
10363				if ( isNaN( parseInt( props[ pos ], 10 ) ) ) {
10364					props[ pos ] = "auto";
10365				}
10366			});
10367			element.css({
10368				position: "relative",
10369				top: 0,
10370				left: 0,
10371				right: "auto",
10372				bottom: "auto"
10373			});
10374		}
10375		element.css(size);
10376
10377		return wrapper.css( props ).show();
10378	},
10379
10380	removeWrapper: function( element ) {
10381		var active = document.activeElement;
10382
10383		if ( element.parent().is( ".ui-effects-wrapper" ) ) {
10384			element.parent().replaceWith( element );
10385
10386			// Fixes #7595 - Elements lose focus when wrapped.
10387			if ( element[ 0 ] === active || $.contains( element[ 0 ], active ) ) {
10388				$( active ).focus();
10389			}
10390		}
10391
10392		return element;
10393	},
10394
10395	setTransition: function( element, list, factor, value ) {
10396		value = value || {};
10397		$.each( list, function( i, x ) {
10398			var unit = element.cssUnit( x );
10399			if ( unit[ 0 ] > 0 ) {
10400				value[ x ] = unit[ 0 ] * factor + unit[ 1 ];
10401			}
10402		});
10403		return value;
10404	}
10405});
10406
10407// return an effect options object for the given parameters:
10408function _normalizeArguments( effect, options, speed, callback ) {
10409
10410	// allow passing all options as the first parameter
10411	if ( $.isPlainObject( effect ) ) {
10412		options = effect;
10413		effect = effect.effect;
10414	}
10415
10416	// convert to an object
10417	effect = { effect: effect };
10418
10419	// catch (effect, null, ...)
10420	if ( options == null ) {
10421		options = {};
10422	}
10423
10424	// catch (effect, callback)
10425	if ( $.isFunction( options ) ) {
10426		callback = options;
10427		speed = null;
10428		options = {};
10429	}
10430
10431	// catch (effect, speed, ?)
10432	if ( typeof options === "number" || $.fx.speeds[ options ] ) {
10433		callback = speed;
10434		speed = options;
10435		options = {};
10436	}
10437
10438	// catch (effect, options, callback)
10439	if ( $.isFunction( speed ) ) {
10440		callback = speed;
10441		speed = null;
10442	}
10443
10444	// add options to effect
10445	if ( options ) {
10446		$.extend( effect, options );
10447	}
10448
10449	speed = speed || options.duration;
10450	effect.duration = $.fx.off ? 0 :
10451		typeof speed === "number" ? speed :
10452		speed in $.fx.speeds ? $.fx.speeds[ speed ] :
10453		$.fx.speeds._default;
10454
10455	effect.complete = callback || options.complete;
10456
10457	return effect;
10458}
10459
10460function standardAnimationOption( option ) {
10461	// Valid standard speeds (nothing, number, named speed)
10462	if ( !option || typeof option === "number" || $.fx.speeds[ option ] ) {
10463		return true;
10464	}
10465
10466	// Invalid strings - treat as "normal" speed
10467	if ( typeof option === "string" && !$.effects.effect[ option ] ) {
10468		return true;
10469	}
10470
10471	// Complete callback
10472	if ( $.isFunction( option ) ) {
10473		return true;
10474	}
10475
10476	// Options hash (but not naming an effect)
10477	if ( typeof option === "object" && !option.effect ) {
10478		return true;
10479	}
10480
10481	// Didn't match any standard API
10482	return false;
10483}
10484
10485$.fn.extend({
10486	effect: function( /* effect, options, speed, callback */ ) {
10487		var args = _normalizeArguments.apply( this, arguments ),
10488			mode = args.mode,
10489			queue = args.queue,
10490			effectMethod = $.effects.effect[ args.effect ];
10491
10492		if ( $.fx.off || !effectMethod ) {
10493			// delegate to the original method (e.g., .show()) if possible
10494			if ( mode ) {
10495				return this[ mode ]( args.duration, args.complete );
10496			} else {
10497				return this.each( function() {
10498					if ( args.complete ) {
10499						args.complete.call( this );
10500					}
10501				});
10502			}
10503		}
10504
10505		function run( next ) {
10506			var elem = $( this ),
10507				complete = args.complete,
10508				mode = args.mode;
10509
10510			function done() {
10511				if ( $.isFunction( complete ) ) {
10512					complete.call( elem[0] );
10513				}
10514				if ( $.isFunction( next ) ) {
10515					next();
10516				}
10517			}
10518
10519			// If the element already has the correct final state, delegate to
10520			// the core methods so the internal tracking of "olddisplay" works.
10521			if ( elem.is( ":hidden" ) ? mode === "hide" : mode === "show" ) {
10522				elem[ mode ]();
10523				done();
10524			} else {
10525				effectMethod.call( elem[0], args, done );
10526			}
10527		}
10528
10529		return queue === false ? this.each( run ) : this.queue( queue || "fx", run );
10530	},
10531
10532	show: (function( orig ) {
10533		return function( option ) {
10534			if ( standardAnimationOption( option ) ) {
10535				return orig.apply( this, arguments );
10536			} else {
10537				var args = _normalizeArguments.apply( this, arguments );
10538				args.mode = "show";
10539				return this.effect.call( this, args );
10540			}
10541		};
10542	})( $.fn.show ),
10543
10544	hide: (function( orig ) {
10545		return function( option ) {
10546			if ( standardAnimationOption( option ) ) {
10547				return orig.apply( this, arguments );
10548			} else {
10549				var args = _normalizeArguments.apply( this, arguments );
10550				args.mode = "hide";
10551				return this.effect.call( this, args );
10552			}
10553		};
10554	})( $.fn.hide ),
10555
10556	toggle: (function( orig ) {
10557		return function( option ) {
10558			if ( standardAnimationOption( option ) || typeof option === "boolean" ) {
10559				return orig.apply( this, arguments );
10560			} else {
10561				var args = _normalizeArguments.apply( this, arguments );
10562				args.mode = "toggle";
10563				return this.effect.call( this, args );
10564			}
10565		};
10566	})( $.fn.toggle ),
10567
10568	// helper functions
10569	cssUnit: function(key) {
10570		var style = this.css( key ),
10571			val = [];
10572
10573		$.each( [ "em", "px", "%", "pt" ], function( i, unit ) {
10574			if ( style.indexOf( unit ) > 0 ) {
10575				val = [ parseFloat( style ), unit ];
10576			}
10577		});
10578		return val;
10579	}
10580});
10581
10582})();
10583
10584/******************************************************************************/
10585/*********************************** EASING ***********************************/
10586/******************************************************************************/
10587
10588(function() {
10589
10590// based on easing equations from Robert Penner (http://www.robertpenner.com/easing)
10591
10592var baseEasings = {};
10593
10594$.each( [ "Quad", "Cubic", "Quart", "Quint", "Expo" ], function( i, name ) {
10595	baseEasings[ name ] = function( p ) {
10596		return Math.pow( p, i + 2 );
10597	};
10598});
10599
10600$.extend( baseEasings, {
10601	Sine: function( p ) {
10602		return 1 - Math.cos( p * Math.PI / 2 );
10603	},
10604	Circ: function( p ) {
10605		return 1 - Math.sqrt( 1 - p * p );
10606	},
10607	Elastic: function( p ) {
10608		return p === 0 || p === 1 ? p :
10609			-Math.pow( 2, 8 * (p - 1) ) * Math.sin( ( (p - 1) * 80 - 7.5 ) * Math.PI / 15 );
10610	},
10611	Back: function( p ) {
10612		return p * p * ( 3 * p - 2 );
10613	},
10614	Bounce: function( p ) {
10615		var pow2,
10616			bounce = 4;
10617
10618		while ( p < ( ( pow2 = Math.pow( 2, --bounce ) ) - 1 ) / 11 ) {}
10619		return 1 / Math.pow( 4, 3 - bounce ) - 7.5625 * Math.pow( ( pow2 * 3 - 2 ) / 22 - p, 2 );
10620	}
10621});
10622
10623$.each( baseEasings, function( name, easeIn ) {
10624	$.easing[ "easeIn" + name ] = easeIn;
10625	$.easing[ "easeOut" + name ] = function( p ) {
10626		return 1 - easeIn( 1 - p );
10627	};
10628	$.easing[ "easeInOut" + name ] = function( p ) {
10629		return p < 0.5 ?
10630			easeIn( p * 2 ) / 2 :
10631			1 - easeIn( p * -2 + 2 ) / 2;
10632	};
10633});
10634
10635})();
10636
10637var effect = $.effects;
10638
10639
10640/*!
10641 * jQuery UI Effects Blind 1.11.4
10642 * http://jqueryui.com
10643 *
10644 * Copyright jQuery Foundation and other contributors
10645 * Released under the MIT license.
10646 * http://jquery.org/license
10647 *
10648 * http://api.jqueryui.com/blind-effect/
10649 */
10650
10651
10652var effectBlind = $.effects.effect.blind = function( o, done ) {
10653	// Create element
10654	var el = $( this ),
10655		rvertical = /up|down|vertical/,
10656		rpositivemotion = /up|left|vertical|horizontal/,
10657		props = [ "position", "top", "bottom", "left", "right", "height", "width" ],
10658		mode = $.effects.setMode( el, o.mode || "hide" ),
10659		direction = o.direction || "up",
10660		vertical = rvertical.test( direction ),
10661		ref = vertical ? "height" : "width",
10662		ref2 = vertical ? "top" : "left",
10663		motion = rpositivemotion.test( direction ),
10664		animation = {},
10665		show = mode === "show",
10666		wrapper, distance, margin;
10667
10668	// if already wrapped, the wrapper's properties are my property. #6245
10669	if ( el.parent().is( ".ui-effects-wrapper" ) ) {
10670		$.effects.save( el.parent(), props );
10671	} else {
10672		$.effects.save( el, props );
10673	}
10674	el.show();
10675	wrapper = $.effects.createWrapper( el ).css({
10676		overflow: "hidden"
10677	});
10678
10679	distance = wrapper[ ref ]();
10680	margin = parseFloat( wrapper.css( ref2 ) ) || 0;
10681
10682	animation[ ref ] = show ? distance : 0;
10683	if ( !motion ) {
10684		el
10685			.css( vertical ? "bottom" : "right", 0 )
10686			.css( vertical ? "top" : "left", "auto" )
10687			.css({ position: "absolute" });
10688
10689		animation[ ref2 ] = show ? margin : distance + margin;
10690	}
10691
10692	// start at 0 if we are showing
10693	if ( show ) {
10694		wrapper.css( ref, 0 );
10695		if ( !motion ) {
10696			wrapper.css( ref2, margin + distance );
10697		}
10698	}
10699
10700	// Animate
10701	wrapper.animate( animation, {
10702		duration: o.duration,
10703		easing: o.easing,
10704		queue: false,
10705		complete: function() {
10706			if ( mode === "hide" ) {
10707				el.hide();
10708			}
10709			$.effects.restore( el, props );
10710			$.effects.removeWrapper( el );
10711			done();
10712		}
10713	});
10714};
10715
10716
10717/*!
10718 * jQuery UI Effects Bounce 1.11.4
10719 * http://jqueryui.com
10720 *
10721 * Copyright jQuery Foundation and other contributors
10722 * Released under the MIT license.
10723 * http://jquery.org/license
10724 *
10725 * http://api.jqueryui.com/bounce-effect/
10726 */
10727
10728
10729var effectBounce = $.effects.effect.bounce = function( o, done ) {
10730	var el = $( this ),
10731		props = [ "position", "top", "bottom", "left", "right", "height", "width" ],
10732
10733		// defaults:
10734		mode = $.effects.setMode( el, o.mode || "effect" ),
10735		hide = mode === "hide",
10736		show = mode === "show",
10737		direction = o.direction || "up",
10738		distance = o.distance,
10739		times = o.times || 5,
10740
10741		// number of internal animations
10742		anims = times * 2 + ( show || hide ? 1 : 0 ),
10743		speed = o.duration / anims,
10744		easing = o.easing,
10745
10746		// utility:
10747		ref = ( direction === "up" || direction === "down" ) ? "top" : "left",
10748		motion = ( direction === "up" || direction === "left" ),
10749		i,
10750		upAnim,
10751		downAnim,
10752
10753		// we will need to re-assemble the queue to stack our animations in place
10754		queue = el.queue(),
10755		queuelen = queue.length;
10756
10757	// Avoid touching opacity to prevent clearType and PNG issues in IE
10758	if ( show || hide ) {
10759		props.push( "opacity" );
10760	}
10761
10762	$.effects.save( el, props );
10763	el.show();
10764	$.effects.createWrapper( el ); // Create Wrapper
10765
10766	// default distance for the BIGGEST bounce is the outer Distance / 3
10767	if ( !distance ) {
10768		distance = el[ ref === "top" ? "outerHeight" : "outerWidth" ]() / 3;
10769	}
10770
10771	if ( show ) {
10772		downAnim = { opacity: 1 };
10773		downAnim[ ref ] = 0;
10774
10775		// if we are showing, force opacity 0 and set the initial position
10776		// then do the "first" animation
10777		el.css( "opacity", 0 )
10778			.css( ref, motion ? -distance * 2 : distance * 2 )
10779			.animate( downAnim, speed, easing );
10780	}
10781
10782	// start at the smallest distance if we are hiding
10783	if ( hide ) {
10784		distance = distance / Math.pow( 2, times - 1 );
10785	}
10786
10787	downAnim = {};
10788	downAnim[ ref ] = 0;
10789	// Bounces up/down/left/right then back to 0 -- times * 2 animations happen here
10790	for ( i = 0; i < times; i++ ) {
10791		upAnim = {};
10792		upAnim[ ref ] = ( motion ? "-=" : "+=" ) + distance;
10793
10794		el.animate( upAnim, speed, easing )
10795			.animate( downAnim, speed, easing );
10796
10797		distance = hide ? distance * 2 : distance / 2;
10798	}
10799
10800	// Last Bounce when Hiding
10801	if ( hide ) {
10802		upAnim = { opacity: 0 };
10803		upAnim[ ref ] = ( motion ? "-=" : "+=" ) + distance;
10804
10805		el.animate( upAnim, speed, easing );
10806	}
10807
10808	el.queue(function() {
10809		if ( hide ) {
10810			el.hide();
10811		}
10812		$.effects.restore( el, props );
10813		$.effects.removeWrapper( el );
10814		done();
10815	});
10816
10817	// inject all the animations we just queued to be first in line (after "inprogress")
10818	if ( queuelen > 1) {
10819		queue.splice.apply( queue,
10820			[ 1, 0 ].concat( queue.splice( queuelen, anims + 1 ) ) );
10821	}
10822	el.dequeue();
10823
10824};
10825
10826
10827/*!
10828 * jQuery UI Effects Clip 1.11.4
10829 * http://jqueryui.com
10830 *
10831 * Copyright jQuery Foundation and other contributors
10832 * Released under the MIT license.
10833 * http://jquery.org/license
10834 *
10835 * http://api.jqueryui.com/clip-effect/
10836 */
10837
10838
10839var effectClip = $.effects.effect.clip = function( o, done ) {
10840	// Create element
10841	var el = $( this ),
10842		props = [ "position", "top", "bottom", "left", "right", "height", "width" ],
10843		mode = $.effects.setMode( el, o.mode || "hide" ),
10844		show = mode === "show",
10845		direction = o.direction || "vertical",
10846		vert = direction === "vertical",
10847		size = vert ? "height" : "width",
10848		position = vert ? "top" : "left",
10849		animation = {},
10850		wrapper, animate, distance;
10851
10852	// Save & Show
10853	$.effects.save( el, props );
10854	el.show();
10855
10856	// Create Wrapper
10857	wrapper = $.effects.createWrapper( el ).css({
10858		overflow: "hidden"
10859	});
10860	animate = ( el[0].tagName === "IMG" ) ? wrapper : el;
10861	distance = animate[ size ]();
10862
10863	// Shift
10864	if ( show ) {
10865		animate.css( size, 0 );
10866		animate.css( position, distance / 2 );
10867	}
10868
10869	// Create Animation Object:
10870	animation[ size ] = show ? distance : 0;
10871	animation[ position ] = show ? 0 : distance / 2;
10872
10873	// Animate
10874	animate.animate( animation, {
10875		queue: false,
10876		duration: o.duration,
10877		easing: o.easing,
10878		complete: function() {
10879			if ( !show ) {
10880				el.hide();
10881			}
10882			$.effects.restore( el, props );
10883			$.effects.removeWrapper( el );
10884			done();
10885		}
10886	});
10887
10888};
10889
10890
10891/*!
10892 * jQuery UI Effects Drop 1.11.4
10893 * http://jqueryui.com
10894 *
10895 * Copyright jQuery Foundation and other contributors
10896 * Released under the MIT license.
10897 * http://jquery.org/license
10898 *
10899 * http://api.jqueryui.com/drop-effect/
10900 */
10901
10902
10903var effectDrop = $.effects.effect.drop = function( o, done ) {
10904
10905	var el = $( this ),
10906		props = [ "position", "top", "bottom", "left", "right", "opacity", "height", "width" ],
10907		mode = $.effects.setMode( el, o.mode || "hide" ),
10908		show = mode === "show",
10909		direction = o.direction || "left",
10910		ref = ( direction === "up" || direction === "down" ) ? "top" : "left",
10911		motion = ( direction === "up" || direction === "left" ) ? "pos" : "neg",
10912		animation = {
10913			opacity: show ? 1 : 0
10914		},
10915		distance;
10916
10917	// Adjust
10918	$.effects.save( el, props );
10919	el.show();
10920	$.effects.createWrapper( el );
10921
10922	distance = o.distance || el[ ref === "top" ? "outerHeight" : "outerWidth" ]( true ) / 2;
10923
10924	if ( show ) {
10925		el
10926			.css( "opacity", 0 )
10927			.css( ref, motion === "pos" ? -distance : distance );
10928	}
10929
10930	// Animation
10931	animation[ ref ] = ( show ?
10932		( motion === "pos" ? "+=" : "-=" ) :
10933		( motion === "pos" ? "-=" : "+=" ) ) +
10934		distance;
10935
10936	// Animate
10937	el.animate( animation, {
10938		queue: false,
10939		duration: o.duration,
10940		easing: o.easing,
10941		complete: function() {
10942			if ( mode === "hide" ) {
10943				el.hide();
10944			}
10945			$.effects.restore( el, props );
10946			$.effects.removeWrapper( el );
10947			done();
10948		}
10949	});
10950};
10951
10952
10953/*!
10954 * jQuery UI Effects Explode 1.11.4
10955 * http://jqueryui.com
10956 *
10957 * Copyright jQuery Foundation and other contributors
10958 * Released under the MIT license.
10959 * http://jquery.org/license
10960 *
10961 * http://api.jqueryui.com/explode-effect/
10962 */
10963
10964
10965var effectExplode = $.effects.effect.explode = function( o, done ) {
10966
10967	var rows = o.pieces ? Math.round( Math.sqrt( o.pieces ) ) : 3,
10968		cells = rows,
10969		el = $( this ),
10970		mode = $.effects.setMode( el, o.mode || "hide" ),
10971		show = mode === "show",
10972
10973		// show and then visibility:hidden the element before calculating offset
10974		offset = el.show().css( "visibility", "hidden" ).offset(),
10975
10976		// width and height of a piece
10977		width = Math.ceil( el.outerWidth() / cells ),
10978		height = Math.ceil( el.outerHeight() / rows ),
10979		pieces = [],
10980
10981		// loop
10982		i, j, left, top, mx, my;
10983
10984	// children animate complete:
10985	function childComplete() {
10986		pieces.push( this );
10987		if ( pieces.length === rows * cells ) {
10988			animComplete();
10989		}
10990	}
10991
10992	// clone the element for each row and cell.
10993	for ( i = 0; i < rows ; i++ ) { // ===>
10994		top = offset.top + i * height;
10995		my = i - ( rows - 1 ) / 2 ;
10996
10997		for ( j = 0; j < cells ; j++ ) { // |||
10998			left = offset.left + j * width;
10999			mx = j - ( cells - 1 ) / 2 ;
11000
11001			// Create a clone of the now hidden main element that will be absolute positioned
11002			// within a wrapper div off the -left and -top equal to size of our pieces
11003			el
11004				.clone()
11005				.appendTo( "body" )
11006				.wrap( "<div></div>" )
11007				.css({
11008					position: "absolute",
11009					visibility: "visible",
11010					left: -j * width,
11011					top: -i * height
11012				})
11013
11014			// select the wrapper - make it overflow: hidden and absolute positioned based on
11015			// where the original was located +left and +top equal to the size of pieces
11016				.parent()
11017				.addClass( "ui-effects-explode" )
11018				.css({
11019					position: "absolute",
11020					overflow: "hidden",
11021					width: width,
11022					height: height,
11023					left: left + ( show ? mx * width : 0 ),
11024					top: top + ( show ? my * height : 0 ),
11025					opacity: show ? 0 : 1
11026				}).animate({
11027					left: left + ( show ? 0 : mx * width ),
11028					top: top + ( show ? 0 : my * height ),
11029					opacity: show ? 1 : 0
11030				}, o.duration || 500, o.easing, childComplete );
11031		}
11032	}
11033
11034	function animComplete() {
11035		el.css({
11036			visibility: "visible"
11037		});
11038		$( pieces ).remove();
11039		if ( !show ) {
11040			el.hide();
11041		}
11042		done();
11043	}
11044};
11045
11046
11047/*!
11048 * jQuery UI Effects Fade 1.11.4
11049 * http://jqueryui.com
11050 *
11051 * Copyright jQuery Foundation and other contributors
11052 * Released under the MIT license.
11053 * http://jquery.org/license
11054 *
11055 * http://api.jqueryui.com/fade-effect/
11056 */
11057
11058
11059var effectFade = $.effects.effect.fade = function( o, done ) {
11060	var el = $( this ),
11061		mode = $.effects.setMode( el, o.mode || "toggle" );
11062
11063	el.animate({
11064		opacity: mode
11065	}, {
11066		queue: false,
11067		duration: o.duration,
11068		easing: o.easing,
11069		complete: done
11070	});
11071};
11072
11073
11074/*!
11075 * jQuery UI Effects Fold 1.11.4
11076 * http://jqueryui.com
11077 *
11078 * Copyright jQuery Foundation and other contributors
11079 * Released under the MIT license.
11080 * http://jquery.org/license
11081 *
11082 * http://api.jqueryui.com/fold-effect/
11083 */
11084
11085
11086var effectFold = $.effects.effect.fold = function( o, done ) {
11087
11088	// Create element
11089	var el = $( this ),
11090		props = [ "position", "top", "bottom", "left", "right", "height", "width" ],
11091		mode = $.effects.setMode( el, o.mode || "hide" ),
11092		show = mode === "show",
11093		hide = mode === "hide",
11094		size = o.size || 15,
11095		percent = /([0-9]+)%/.exec( size ),
11096		horizFirst = !!o.horizFirst,
11097		widthFirst = show !== horizFirst,
11098		ref = widthFirst ? [ "width", "height" ] : [ "height", "width" ],
11099		duration = o.duration / 2,
11100		wrapper, distance,
11101		animation1 = {},
11102		animation2 = {};
11103
11104	$.effects.save( el, props );
11105	el.show();
11106
11107	// Create Wrapper
11108	wrapper = $.effects.createWrapper( el ).css({
11109		overflow: "hidden"
11110	});
11111	distance = widthFirst ?
11112		[ wrapper.width(), wrapper.height() ] :
11113		[ wrapper.height(), wrapper.width() ];
11114
11115	if ( percent ) {
11116		size = parseInt( percent[ 1 ], 10 ) / 100 * distance[ hide ? 0 : 1 ];
11117	}
11118	if ( show ) {
11119		wrapper.css( horizFirst ? {
11120			height: 0,
11121			width: size
11122		} : {
11123			height: size,
11124			width: 0
11125		});
11126	}
11127
11128	// Animation
11129	animation1[ ref[ 0 ] ] = show ? distance[ 0 ] : size;
11130	animation2[ ref[ 1 ] ] = show ? distance[ 1 ] : 0;
11131
11132	// Animate
11133	wrapper
11134		.animate( animation1, duration, o.easing )
11135		.animate( animation2, duration, o.easing, function() {
11136			if ( hide ) {
11137				el.hide();
11138			}
11139			$.effects.restore( el, props );
11140			$.effects.removeWrapper( el );
11141			done();
11142		});
11143
11144};
11145
11146
11147/*!
11148 * jQuery UI Effects Highlight 1.11.4
11149 * http://jqueryui.com
11150 *
11151 * Copyright jQuery Foundation and other contributors
11152 * Released under the MIT license.
11153 * http://jquery.org/license
11154 *
11155 * http://api.jqueryui.com/highlight-effect/
11156 */
11157
11158
11159var effectHighlight = $.effects.effect.highlight = function( o, done ) {
11160	var elem = $( this ),
11161		props = [ "backgroundImage", "backgroundColor", "opacity" ],
11162		mode = $.effects.setMode( elem, o.mode || "show" ),
11163		animation = {
11164			backgroundColor: elem.css( "backgroundColor" )
11165		};
11166
11167	if (mode === "hide") {
11168		animation.opacity = 0;
11169	}
11170
11171	$.effects.save( elem, props );
11172
11173	elem
11174		.show()
11175		.css({
11176			backgroundImage: "none",
11177			backgroundColor: o.color || "#ffff99"
11178		})
11179		.animate( animation, {
11180			queue: false,
11181			duration: o.duration,
11182			easing: o.easing,
11183			complete: function() {
11184				if ( mode === "hide" ) {
11185					elem.hide();
11186				}
11187				$.effects.restore( elem, props );
11188				done();
11189			}
11190		});
11191};
11192
11193
11194/*!
11195 * jQuery UI Effects Size 1.11.4
11196 * http://jqueryui.com
11197 *
11198 * Copyright jQuery Foundation and other contributors
11199 * Released under the MIT license.
11200 * http://jquery.org/license
11201 *
11202 * http://api.jqueryui.com/size-effect/
11203 */
11204
11205
11206var effectSize = $.effects.effect.size = function( o, done ) {
11207
11208	// Create element
11209	var original, baseline, factor,
11210		el = $( this ),
11211		props0 = [ "position", "top", "bottom", "left", "right", "width", "height", "overflow", "opacity" ],
11212
11213		// Always restore
11214		props1 = [ "position", "top", "bottom", "left", "right", "overflow", "opacity" ],
11215
11216		// Copy for children
11217		props2 = [ "width", "height", "overflow" ],
11218		cProps = [ "fontSize" ],
11219		vProps = [ "borderTopWidth", "borderBottomWidth", "paddingTop", "paddingBottom" ],
11220		hProps = [ "borderLeftWidth", "borderRightWidth", "paddingLeft", "paddingRight" ],
11221
11222		// Set options
11223		mode = $.effects.setMode( el, o.mode || "effect" ),
11224		restore = o.restore || mode !== "effect",
11225		scale = o.scale || "both",
11226		origin = o.origin || [ "middle", "center" ],
11227		position = el.css( "position" ),
11228		props = restore ? props0 : props1,
11229		zero = {
11230			height: 0,
11231			width: 0,
11232			outerHeight: 0,
11233			outerWidth: 0
11234		};
11235
11236	if ( mode === "show" ) {
11237		el.show();
11238	}
11239	original = {
11240		height: el.height(),
11241		width: el.width(),
11242		outerHeight: el.outerHeight(),
11243		outerWidth: el.outerWidth()
11244	};
11245
11246	if ( o.mode === "toggle" && mode === "show" ) {
11247		el.from = o.to || zero;
11248		el.to = o.from || original;
11249	} else {
11250		el.from = o.from || ( mode === "show" ? zero : original );
11251		el.to = o.to || ( mode === "hide" ? zero : original );
11252	}
11253
11254	// Set scaling factor
11255	factor = {
11256		from: {
11257			y: el.from.height / original.height,
11258			x: el.from.width / original.width
11259		},
11260		to: {
11261			y: el.to.height / original.height,
11262			x: el.to.width / original.width
11263		}
11264	};
11265
11266	// Scale the css box
11267	if ( scale === "box" || scale === "both" ) {
11268
11269		// Vertical props scaling
11270		if ( factor.from.y !== factor.to.y ) {
11271			props = props.concat( vProps );
11272			el.from = $.effects.setTransition( el, vProps, factor.from.y, el.from );
11273			el.to = $.effects.setTransition( el, vProps, factor.to.y, el.to );
11274		}
11275
11276		// Horizontal props scaling
11277		if ( factor.from.x !== factor.to.x ) {
11278			props = props.concat( hProps );
11279			el.from = $.effects.setTransition( el, hProps, factor.from.x, el.from );
11280			el.to = $.effects.setTransition( el, hProps, factor.to.x, el.to );
11281		}
11282	}
11283
11284	// Scale the content
11285	if ( scale === "content" || scale === "both" ) {
11286
11287		// Vertical props scaling
11288		if ( factor.from.y !== factor.to.y ) {
11289			props = props.concat( cProps ).concat( props2 );
11290			el.from = $.effects.setTransition( el, cProps, factor.from.y, el.from );
11291			el.to = $.effects.setTransition( el, cProps, factor.to.y, el.to );
11292		}
11293	}
11294
11295	$.effects.save( el, props );
11296	el.show();
11297	$.effects.createWrapper( el );
11298	el.css( "overflow", "hidden" ).css( el.from );
11299
11300	// Adjust
11301	if (origin) { // Calculate baseline shifts
11302		baseline = $.effects.getBaseline( origin, original );
11303		el.from.top = ( original.outerHeight - el.outerHeight() ) * baseline.y;
11304		el.from.left = ( original.outerWidth - el.outerWidth() ) * baseline.x;
11305		el.to.top = ( original.outerHeight - el.to.outerHeight ) * baseline.y;
11306		el.to.left = ( original.outerWidth - el.to.outerWidth ) * baseline.x;
11307	}
11308	el.css( el.from ); // set top & left
11309
11310	// Animate
11311	if ( scale === "content" || scale === "both" ) { // Scale the children
11312
11313		// Add margins/font-size
11314		vProps = vProps.concat([ "marginTop", "marginBottom" ]).concat(cProps);
11315		hProps = hProps.concat([ "marginLeft", "marginRight" ]);
11316		props2 = props0.concat(vProps).concat(hProps);
11317
11318		el.find( "*[width]" ).each( function() {
11319			var child = $( this ),
11320				c_original = {
11321					height: child.height(),
11322					width: child.width(),
11323					outerHeight: child.outerHeight(),
11324					outerWidth: child.outerWidth()
11325				};
11326			if (restore) {
11327				$.effects.save(child, props2);
11328			}
11329
11330			child.from = {
11331				height: c_original.height * factor.from.y,
11332				width: c_original.width * factor.from.x,
11333				outerHeight: c_original.outerHeight * factor.from.y,
11334				outerWidth: c_original.outerWidth * factor.from.x
11335			};
11336			child.to = {
11337				height: c_original.height * factor.to.y,
11338				width: c_original.width * factor.to.x,
11339				outerHeight: c_original.height * factor.to.y,
11340				outerWidth: c_original.width * factor.to.x
11341			};
11342
11343			// Vertical props scaling
11344			if ( factor.from.y !== factor.to.y ) {
11345				child.from = $.effects.setTransition( child, vProps, factor.from.y, child.from );
11346				child.to = $.effects.setTransition( child, vProps, factor.to.y, child.to );
11347			}
11348
11349			// Horizontal props scaling
11350			if ( factor.from.x !== factor.to.x ) {
11351				child.from = $.effects.setTransition( child, hProps, factor.from.x, child.from );
11352				child.to = $.effects.setTransition( child, hProps, factor.to.x, child.to );
11353			}
11354
11355			// Animate children
11356			child.css( child.from );
11357			child.animate( child.to, o.duration, o.easing, function() {
11358
11359				// Restore children
11360				if ( restore ) {
11361					$.effects.restore( child, props2 );
11362				}
11363			});
11364		});
11365	}
11366
11367	// Animate
11368	el.animate( el.to, {
11369		queue: false,
11370		duration: o.duration,
11371		easing: o.easing,
11372		complete: function() {
11373			if ( el.to.opacity === 0 ) {
11374				el.css( "opacity", el.from.opacity );
11375			}
11376			if ( mode === "hide" ) {
11377				el.hide();
11378			}
11379			$.effects.restore( el, props );
11380			if ( !restore ) {
11381
11382				// we need to calculate our new positioning based on the scaling
11383				if ( position === "static" ) {
11384					el.css({
11385						position: "relative",
11386						top: el.to.top,
11387						left: el.to.left
11388					});
11389				} else {
11390					$.each([ "top", "left" ], function( idx, pos ) {
11391						el.css( pos, function( _, str ) {
11392							var val = parseInt( str, 10 ),
11393								toRef = idx ? el.to.left : el.to.top;
11394
11395							// if original was "auto", recalculate the new value from wrapper
11396							if ( str === "auto" ) {
11397								return toRef + "px";
11398							}
11399
11400							return val + toRef + "px";
11401						});
11402					});
11403				}
11404			}
11405
11406			$.effects.removeWrapper( el );
11407			done();
11408		}
11409	});
11410
11411};
11412
11413
11414/*!
11415 * jQuery UI Effects Scale 1.11.4
11416 * http://jqueryui.com
11417 *
11418 * Copyright jQuery Foundation and other contributors
11419 * Released under the MIT license.
11420 * http://jquery.org/license
11421 *
11422 * http://api.jqueryui.com/scale-effect/
11423 */
11424
11425
11426var effectScale = $.effects.effect.scale = function( o, done ) {
11427
11428	// Create element
11429	var el = $( this ),
11430		options = $.extend( true, {}, o ),
11431		mode = $.effects.setMode( el, o.mode || "effect" ),
11432		percent = parseInt( o.percent, 10 ) ||
11433			( parseInt( o.percent, 10 ) === 0 ? 0 : ( mode === "hide" ? 0 : 100 ) ),
11434		direction = o.direction || "both",
11435		origin = o.origin,
11436		original = {
11437			height: el.height(),
11438			width: el.width(),
11439			outerHeight: el.outerHeight(),
11440			outerWidth: el.outerWidth()
11441		},
11442		factor = {
11443			y: direction !== "horizontal" ? (percent / 100) : 1,
11444			x: direction !== "vertical" ? (percent / 100) : 1
11445		};
11446
11447	// We are going to pass this effect to the size effect:
11448	options.effect = "size";
11449	options.queue = false;
11450	options.complete = done;
11451
11452	// Set default origin and restore for show/hide
11453	if ( mode !== "effect" ) {
11454		options.origin = origin || [ "middle", "center" ];
11455		options.restore = true;
11456	}
11457
11458	options.from = o.from || ( mode === "show" ? {
11459		height: 0,
11460		width: 0,
11461		outerHeight: 0,
11462		outerWidth: 0
11463	} : original );
11464	options.to = {
11465		height: original.height * factor.y,
11466		width: original.width * factor.x,
11467		outerHeight: original.outerHeight * factor.y,
11468		outerWidth: original.outerWidth * factor.x
11469	};
11470
11471	// Fade option to support puff
11472	if ( options.fade ) {
11473		if ( mode === "show" ) {
11474			options.from.opacity = 0;
11475			options.to.opacity = 1;
11476		}
11477		if ( mode === "hide" ) {
11478			options.from.opacity = 1;
11479			options.to.opacity = 0;
11480		}
11481	}
11482
11483	// Animate
11484	el.effect( options );
11485
11486};
11487
11488
11489/*!
11490 * jQuery UI Effects Puff 1.11.4
11491 * http://jqueryui.com
11492 *
11493 * Copyright jQuery Foundation and other contributors
11494 * Released under the MIT license.
11495 * http://jquery.org/license
11496 *
11497 * http://api.jqueryui.com/puff-effect/
11498 */
11499
11500
11501var effectPuff = $.effects.effect.puff = function( o, done ) {
11502	var elem = $( this ),
11503		mode = $.effects.setMode( elem, o.mode || "hide" ),
11504		hide = mode === "hide",
11505		percent = parseInt( o.percent, 10 ) || 150,
11506		factor = percent / 100,
11507		original = {
11508			height: elem.height(),
11509			width: elem.width(),
11510			outerHeight: elem.outerHeight(),
11511			outerWidth: elem.outerWidth()
11512		};
11513
11514	$.extend( o, {
11515		effect: "scale",
11516		queue: false,
11517		fade: true,
11518		mode: mode,
11519		complete: done,
11520		percent: hide ? percent : 100,
11521		from: hide ?
11522			original :
11523			{
11524				height: original.height * factor,
11525				width: original.width * factor,
11526				outerHeight: original.outerHeight * factor,
11527				outerWidth: original.outerWidth * factor
11528			}
11529	});
11530
11531	elem.effect( o );
11532};
11533
11534
11535/*!
11536 * jQuery UI Effects Pulsate 1.11.4
11537 * http://jqueryui.com
11538 *
11539 * Copyright jQuery Foundation and other contributors
11540 * Released under the MIT license.
11541 * http://jquery.org/license
11542 *
11543 * http://api.jqueryui.com/pulsate-effect/
11544 */
11545
11546
11547var effectPulsate = $.effects.effect.pulsate = function( o, done ) {
11548	var elem = $( this ),
11549		mode = $.effects.setMode( elem, o.mode || "show" ),
11550		show = mode === "show",
11551		hide = mode === "hide",
11552		showhide = ( show || mode === "hide" ),
11553
11554		// showing or hiding leaves of the "last" animation
11555		anims = ( ( o.times || 5 ) * 2 ) + ( showhide ? 1 : 0 ),
11556		duration = o.duration / anims,
11557		animateTo = 0,
11558		queue = elem.queue(),
11559		queuelen = queue.length,
11560		i;
11561
11562	if ( show || !elem.is(":visible")) {
11563		elem.css( "opacity", 0 ).show();
11564		animateTo = 1;
11565	}
11566
11567	// anims - 1 opacity "toggles"
11568	for ( i = 1; i < anims; i++ ) {
11569		elem.animate({
11570			opacity: animateTo
11571		}, duration, o.easing );
11572		animateTo = 1 - animateTo;
11573	}
11574
11575	elem.animate({
11576		opacity: animateTo
11577	}, duration, o.easing);
11578
11579	elem.queue(function() {
11580		if ( hide ) {
11581			elem.hide();
11582		}
11583		done();
11584	});
11585
11586	// We just queued up "anims" animations, we need to put them next in the queue
11587	if ( queuelen > 1 ) {
11588		queue.splice.apply( queue,
11589			[ 1, 0 ].concat( queue.splice( queuelen, anims + 1 ) ) );
11590	}
11591	elem.dequeue();
11592};
11593
11594
11595/*!
11596 * jQuery UI Effects Shake 1.11.4
11597 * http://jqueryui.com
11598 *
11599 * Copyright jQuery Foundation and other contributors
11600 * Released under the MIT license.
11601 * http://jquery.org/license
11602 *
11603 * http://api.jqueryui.com/shake-effect/
11604 */
11605
11606
11607var effectShake = $.effects.effect.shake = function( o, done ) {
11608
11609	var el = $( this ),
11610		props = [ "position", "top", "bottom", "left", "right", "height", "width" ],
11611		mode = $.effects.setMode( el, o.mode || "effect" ),
11612		direction = o.direction || "left",
11613		distance = o.distance || 20,
11614		times = o.times || 3,
11615		anims = times * 2 + 1,
11616		speed = Math.round( o.duration / anims ),
11617		ref = (direction === "up" || direction === "down") ? "top" : "left",
11618		positiveMotion = (direction === "up" || direction === "left"),
11619		animation = {},
11620		animation1 = {},
11621		animation2 = {},
11622		i,
11623
11624		// we will need to re-assemble the queue to stack our animations in place
11625		queue = el.queue(),
11626		queuelen = queue.length;
11627
11628	$.effects.save( el, props );
11629	el.show();
11630	$.effects.createWrapper( el );
11631
11632	// Animation
11633	animation[ ref ] = ( positiveMotion ? "-=" : "+=" ) + distance;
11634	animation1[ ref ] = ( positiveMotion ? "+=" : "-=" ) + distance * 2;
11635	animation2[ ref ] = ( positiveMotion ? "-=" : "+=" ) + distance * 2;
11636
11637	// Animate
11638	el.animate( animation, speed, o.easing );
11639
11640	// Shakes
11641	for ( i = 1; i < times; i++ ) {
11642		el.animate( animation1, speed, o.easing ).animate( animation2, speed, o.easing );
11643	}
11644	el
11645		.animate( animation1, speed, o.easing )
11646		.animate( animation, speed / 2, o.easing )
11647		.queue(function() {
11648			if ( mode === "hide" ) {
11649				el.hide();
11650			}
11651			$.effects.restore( el, props );
11652			$.effects.removeWrapper( el );
11653			done();
11654		});
11655
11656	// inject all the animations we just queued to be first in line (after "inprogress")
11657	if ( queuelen > 1) {
11658		queue.splice.apply( queue,
11659			[ 1, 0 ].concat( queue.splice( queuelen, anims + 1 ) ) );
11660	}
11661	el.dequeue();
11662
11663};
11664
11665
11666/*!
11667 * jQuery UI Effects Slide 1.11.4
11668 * http://jqueryui.com
11669 *
11670 * Copyright jQuery Foundation and other contributors
11671 * Released under the MIT license.
11672 * http://jquery.org/license
11673 *
11674 * http://api.jqueryui.com/slide-effect/
11675 */
11676
11677
11678var effectSlide = $.effects.effect.slide = function( o, done ) {
11679
11680	// Create element
11681	var el = $( this ),
11682		props = [ "position", "top", "bottom", "left", "right", "width", "height" ],
11683		mode = $.effects.setMode( el, o.mode || "show" ),
11684		show = mode === "show",
11685		direction = o.direction || "left",
11686		ref = (direction === "up" || direction === "down") ? "top" : "left",
11687		positiveMotion = (direction === "up" || direction === "left"),
11688		distance,
11689		animation = {};
11690
11691	// Adjust
11692	$.effects.save( el, props );
11693	el.show();
11694	distance = o.distance || el[ ref === "top" ? "outerHeight" : "outerWidth" ]( true );
11695
11696	$.effects.createWrapper( el ).css({
11697		overflow: "hidden"
11698	});
11699
11700	if ( show ) {
11701		el.css( ref, positiveMotion ? (isNaN(distance) ? "-" + distance : -distance) : distance );
11702	}
11703
11704	// Animation
11705	animation[ ref ] = ( show ?
11706		( positiveMotion ? "+=" : "-=") :
11707		( positiveMotion ? "-=" : "+=")) +
11708		distance;
11709
11710	// Animate
11711	el.animate( animation, {
11712		queue: false,
11713		duration: o.duration,
11714		easing: o.easing,
11715		complete: function() {
11716			if ( mode === "hide" ) {
11717				el.hide();
11718			}
11719			$.effects.restore( el, props );
11720			$.effects.removeWrapper( el );
11721			done();
11722		}
11723	});
11724};
11725
11726
11727/*!
11728 * jQuery UI Effects Transfer 1.11.4
11729 * http://jqueryui.com
11730 *
11731 * Copyright jQuery Foundation and other contributors
11732 * Released under the MIT license.
11733 * http://jquery.org/license
11734 *
11735 * http://api.jqueryui.com/transfer-effect/
11736 */
11737
11738
11739var effectTransfer = $.effects.effect.transfer = function( o, done ) {
11740	var elem = $( this ),
11741		target = $( o.to ),
11742		targetFixed = target.css( "position" ) === "fixed",
11743		body = $("body"),
11744		fixTop = targetFixed ? body.scrollTop() : 0,
11745		fixLeft = targetFixed ? body.scrollLeft() : 0,
11746		endPosition = target.offset(),
11747		animation = {
11748			top: endPosition.top - fixTop,
11749			left: endPosition.left - fixLeft,
11750			height: target.innerHeight(),
11751			width: target.innerWidth()
11752		},
11753		startPosition = elem.offset(),
11754		transfer = $( "<div class='ui-effects-transfer'></div>" )
11755			.appendTo( document.body )
11756			.addClass( o.className )
11757			.css({
11758				top: startPosition.top - fixTop,
11759				left: startPosition.left - fixLeft,
11760				height: elem.innerHeight(),
11761				width: elem.innerWidth(),
11762				position: targetFixed ? "fixed" : "absolute"
11763			})
11764			.animate( animation, o.duration, o.easing, function() {
11765				transfer.remove();
11766				done();
11767			});
11768};
11769
11770
11771/*!
11772 * jQuery UI Progressbar 1.11.4
11773 * http://jqueryui.com
11774 *
11775 * Copyright jQuery Foundation and other contributors
11776 * Released under the MIT license.
11777 * http://jquery.org/license
11778 *
11779 * http://api.jqueryui.com/progressbar/
11780 */
11781
11782
11783var progressbar = $.widget( "ui.progressbar", {
11784	version: "1.11.4",
11785	options: {
11786		max: 100,
11787		value: 0,
11788
11789		change: null,
11790		complete: null
11791	},
11792
11793	min: 0,
11794
11795	_create: function() {
11796		// Constrain initial value
11797		this.oldValue = this.options.value = this._constrainedValue();
11798
11799		this.element
11800			.addClass( "ui-progressbar ui-widget ui-widget-content ui-corner-all" )
11801			.attr({
11802				// Only set static values, aria-valuenow and aria-valuemax are
11803				// set inside _refreshValue()
11804				role: "progressbar",
11805				"aria-valuemin": this.min
11806			});
11807
11808		this.valueDiv = $( "<div class='ui-progressbar-value ui-widget-header ui-corner-left'></div>" )
11809			.appendTo( this.element );
11810
11811		this._refreshValue();
11812	},
11813
11814	_destroy: function() {
11815		this.element
11816			.removeClass( "ui-progressbar ui-widget ui-widget-content ui-corner-all" )
11817			.removeAttr( "role" )
11818			.removeAttr( "aria-valuemin" )
11819			.removeAttr( "aria-valuemax" )
11820			.removeAttr( "aria-valuenow" );
11821
11822		this.valueDiv.remove();
11823	},
11824
11825	value: function( newValue ) {
11826		if ( newValue === undefined ) {
11827			return this.options.value;
11828		}
11829
11830		this.options.value = this._constrainedValue( newValue );
11831		this._refreshValue();
11832	},
11833
11834	_constrainedValue: function( newValue ) {
11835		if ( newValue === undefined ) {
11836			newValue = this.options.value;
11837		}
11838
11839		this.indeterminate = newValue === false;
11840
11841		// sanitize value
11842		if ( typeof newValue !== "number" ) {
11843			newValue = 0;
11844		}
11845
11846		return this.indeterminate ? false :
11847			Math.min( this.options.max, Math.max( this.min, newValue ) );
11848	},
11849
11850	_setOptions: function( options ) {
11851		// Ensure "value" option is set after other values (like max)
11852		var value = options.value;
11853		delete options.value;
11854
11855		this._super( options );
11856
11857		this.options.value = this._constrainedValue( value );
11858		this._refreshValue();
11859	},
11860
11861	_setOption: function( key, value ) {
11862		if ( key === "max" ) {
11863			// Don't allow a max less than min
11864			value = Math.max( this.min, value );
11865		}
11866		if ( key === "disabled" ) {
11867			this.element
11868				.toggleClass( "ui-state-disabled", !!value )
11869				.attr( "aria-disabled", value );
11870		}
11871		this._super( key, value );
11872	},
11873
11874	_percentage: function() {
11875		return this.indeterminate ? 100 : 100 * ( this.options.value - this.min ) / ( this.options.max - this.min );
11876	},
11877
11878	_refreshValue: function() {
11879		var value = this.options.value,
11880			percentage = this._percentage();
11881
11882		this.valueDiv
11883			.toggle( this.indeterminate || value > this.min )
11884			.toggleClass( "ui-corner-right", value === this.options.max )
11885			.width( percentage.toFixed(0) + "%" );
11886
11887		this.element.toggleClass( "ui-progressbar-indeterminate", this.indeterminate );
11888
11889		if ( this.indeterminate ) {
11890			this.element.removeAttr( "aria-valuenow" );
11891			if ( !this.overlayDiv ) {
11892				this.overlayDiv = $( "<div class='ui-progressbar-overlay'></div>" ).appendTo( this.valueDiv );
11893			}
11894		} else {
11895			this.element.attr({
11896				"aria-valuemax": this.options.max,
11897				"aria-valuenow": value
11898			});
11899			if ( this.overlayDiv ) {
11900				this.overlayDiv.remove();
11901				this.overlayDiv = null;
11902			}
11903		}
11904
11905		if ( this.oldValue !== value ) {
11906			this.oldValue = value;
11907			this._trigger( "change" );
11908		}
11909		if ( value === this.options.max ) {
11910			this._trigger( "complete" );
11911		}
11912	}
11913});
11914
11915
11916/*!
11917 * jQuery UI Selectable 1.11.4
11918 * http://jqueryui.com
11919 *
11920 * Copyright jQuery Foundation and other contributors
11921 * Released under the MIT license.
11922 * http://jquery.org/license
11923 *
11924 * http://api.jqueryui.com/selectable/
11925 */
11926
11927
11928var selectable = $.widget("ui.selectable", $.ui.mouse, {
11929	version: "1.11.4",
11930	options: {
11931		appendTo: "body",
11932		autoRefresh: true,
11933		distance: 0,
11934		filter: "*",
11935		tolerance: "touch",
11936
11937		// callbacks
11938		selected: null,
11939		selecting: null,
11940		start: null,
11941		stop: null,
11942		unselected: null,
11943		unselecting: null
11944	},
11945	_create: function() {
11946		var selectees,
11947			that = this;
11948
11949		this.element.addClass("ui-selectable");
11950
11951		this.dragged = false;
vendor: 4,465 bytes, lines 11952-12119
11952
11953		// cache selectee children based on filter
11954		this.refresh = function() {
11955			selectees = $(that.options.filter, that.element[0]);
11956			selectees.addClass("ui-selectee");
11957			selectees.each(function() {
11958				var $this = $(this),
11959					pos = $this.offset();
11960				$.data(this, "selectable-item", {
11961					element: this,
11962					$element: $this,
11963					left: pos.left,
11964					top: pos.top,
11965					right: pos.left + $this.outerWidth(),
11966					bottom: pos.top + $this.outerHeight(),
11967					startselected: false,
11968					selected: $this.hasClass("ui-selected"),
11969					selecting: $this.hasClass("ui-selecting"),
11970					unselecting: $this.hasClass("ui-unselecting")
11971				});
11972			});
11973		};
11974		this.refresh();
11975
11976		this.selectees = selectees.addClass("ui-selectee");
11977
11978		this._mouseInit();
11979
11980		this.helper = $("<div class='ui-selectable-helper'></div>");
11981	},
11982
11983	_destroy: function() {
11984		this.selectees
11985			.removeClass("ui-selectee")
11986			.removeData("selectable-item");
11987		this.element
11988			.removeClass("ui-selectable ui-selectable-disabled");
11989		this._mouseDestroy();
11990	},
11991
11992	_mouseStart: function(event) {
11993		var that = this,
11994			options = this.options;
11995
11996		this.opos = [ event.pageX, event.pageY ];
11997
11998		if (this.options.disabled) {
11999			return;
12000		}
12001
12002		this.selectees = $(options.filter, this.element[0]);
12003
12004		this._trigger("start", event);
12005
12006		$(options.appendTo).append(this.helper);
12007		// position helper (lasso)
12008		this.helper.css({
12009			"left": event.pageX,
12010			"top": event.pageY,
12011			"width": 0,
12012			"height": 0
12013		});
12014
12015		if (options.autoRefresh) {
12016			this.refresh();
12017		}
12018
12019		this.selectees.filter(".ui-selected").each(function() {
12020			var selectee = $.data(this, "selectable-item");
12021			selectee.startselected = true;
12022			if (!event.metaKey && !event.ctrlKey) {
12023				selectee.$element.removeClass("ui-selected");
12024				selectee.selected = false;
12025				selectee.$element.addClass("ui-unselecting");
12026				selectee.unselecting = true;
12027				// selectable UNSELECTING callback
12028				that._trigger("unselecting", event, {
12029					unselecting: selectee.element
12030				});
12031			}
12032		});
12033
12034		$(event.target).parents().addBack().each(function() {
12035			var doSelect,
12036				selectee = $.data(this, "selectable-item");
12037			if (selectee) {
12038				doSelect = (!event.metaKey && !event.ctrlKey) || !selectee.$element.hasClass("ui-selected");
12039				selectee.$element
12040					.removeClass(doSelect ? "ui-unselecting" : "ui-selected")
12041					.addClass(doSelect ? "ui-selecting" : "ui-unselecting");
12042				selectee.unselecting = !doSelect;
12043				selectee.selecting = doSelect;
12044				selectee.selected = doSelect;
12045				// selectable (UN)SELECTING callback
12046				if (doSelect) {
12047					that._trigger("selecting", event, {
12048						selecting: selectee.element
12049					});
12050				} else {
12051					that._trigger("unselecting", event, {
12052						unselecting: selectee.element
12053					});
12054				}
12055				return false;
12056			}
12057		});
12058
12059	},
12060
12061	_mouseDrag: function(event) {
12062
12063		this.dragged = true;
12064
12065		if (this.options.disabled) {
12066			return;
12067		}
12068
12069		var tmp,
12070			that = this,
12071			options = this.options,
12072			x1 = this.opos[0],
12073			y1 = this.opos[1],
12074			x2 = event.pageX,
12075			y2 = event.pageY;
12076
12077		if (x1 > x2) { tmp = x2; x2 = x1; x1 = tmp; }
12078		if (y1 > y2) { tmp = y2; y2 = y1; y1 = tmp; }
12079		this.helper.css({ left: x1, top: y1, width: x2 - x1, height: y2 - y1 });
12080
12081		this.selectees.each(function() {
12082			var selectee = $.data(this, "selectable-item"),
12083				hit = false;
12084
12085			//prevent helper from being selected if appendTo: selectable
12086			if (!selectee || selectee.element === that.element[0]) {
12087				return;
12088			}
12089
12090			if (options.tolerance === "touch") {
12091				hit = ( !(selectee.left > x2 || selectee.right < x1 || selectee.top > y2 || selectee.bottom < y1) );
12092			} else if (options.tolerance === "fit") {
12093				hit = (selectee.left > x1 && selectee.right < x2 && selectee.top > y1 && selectee.bottom < y2);
12094			}
12095
12096			if (hit) {
12097				// SELECT
12098				if (selectee.selected) {
12099					selectee.$element.removeClass("ui-selected");
12100					selectee.selected = false;
12101				}
12102				if (selectee.unselecting) {
12103					selectee.$element.removeClass("ui-unselecting");
12104					selectee.unselecting = false;
12105				}
12106				if (!selectee.selecting) {
12107					selectee.$element.addClass("ui-selecting");
12108					selectee.selecting = true;
12109					// selectable SELECTING callback
12110					that._trigger("selecting", event, {
12111						selecting: selectee.element
12112					});
12113				}
12114			} else {
12115				// UNSELECT
12116				if (selectee.selecting) {
12117					if ((event.metaKey || event.ctrlKey) && selectee.startselected) {
12118						selectee.$element.removeClass("ui-selecting");
12119						selectee.selecting = false;
vendor: 20,164 bytes, lines 12120-12988
12120						selectee.$element.addClass("ui-selected");
12121						selectee.selected = true;
12122					} else {
12123						selectee.$element.removeClass("ui-selecting");
12124						selectee.selecting = false;
12125						if (selectee.startselected) {
12126							selectee.$element.addClass("ui-unselecting");
12127							selectee.unselecting = true;
12128						}
12129						// selectable UNSELECTING callback
12130						that._trigger("unselecting", event, {
12131							unselecting: selectee.element
12132						});
12133					}
12134				}
12135				if (selectee.selected) {
12136					if (!event.metaKey && !event.ctrlKey && !selectee.startselected) {
12137						selectee.$element.removeClass("ui-selected");
12138						selectee.selected = false;
12139
12140						selectee.$element.addClass("ui-unselecting");
12141						selectee.unselecting = true;
12142						// selectable UNSELECTING callback
12143						that._trigger("unselecting", event, {
12144							unselecting: selectee.element
12145						});
12146					}
12147				}
12148			}
12149		});
12150
12151		return false;
12152	},
12153
12154	_mouseStop: function(event) {
12155		var that = this;
12156
12157		this.dragged = false;
12158
12159		$(".ui-unselecting", this.element[0]).each(function() {
12160			var selectee = $.data(this, "selectable-item");
12161			selectee.$element.removeClass("ui-unselecting");
12162			selectee.unselecting = false;
12163			selectee.startselected = false;
12164			that._trigger("unselected", event, {
12165				unselected: selectee.element
12166			});
12167		});
12168		$(".ui-selecting", this.element[0]).each(function() {
12169			var selectee = $.data(this, "selectable-item");
12170			selectee.$element.removeClass("ui-selecting").addClass("ui-selected");
12171			selectee.selecting = false;
12172			selectee.selected = true;
12173			selectee.startselected = true;
12174			that._trigger("selected", event, {
12175				selected: selectee.element
12176			});
12177		});
12178		this._trigger("stop", event);
12179
12180		this.helper.remove();
12181
12182		return false;
12183	}
12184
12185});
12186
12187
12188/*!
12189 * jQuery UI Selectmenu 1.11.4
12190 * http://jqueryui.com
12191 *
12192 * Copyright jQuery Foundation and other contributors
12193 * Released under the MIT license.
12194 * http://jquery.org/license
12195 *
12196 * http://api.jqueryui.com/selectmenu
12197 */
12198
12199
12200var selectmenu = $.widget( "ui.selectmenu", {
12201	version: "1.11.4",
12202	defaultElement: "<select>",
12203	options: {
12204		appendTo: null,
12205		disabled: null,
12206		icons: {
12207			button: "ui-icon-triangle-1-s"
12208		},
12209		position: {
12210			my: "left top",
12211			at: "left bottom",
12212			collision: "none"
12213		},
12214		width: null,
12215
12216		// callbacks
12217		change: null,
12218		close: null,
12219		focus: null,
12220		open: null,
12221		select: null
12222	},
12223
12224	_create: function() {
12225		var selectmenuId = this.element.uniqueId().attr( "id" );
12226		this.ids = {
12227			element: selectmenuId,
12228			button: selectmenuId + "-button",
12229			menu: selectmenuId + "-menu"
12230		};
12231
12232		this._drawButton();
12233		this._drawMenu();
12234
12235		if ( this.options.disabled ) {
12236			this.disable();
12237		}
12238	},
12239
12240	_drawButton: function() {
12241		var that = this;
12242
12243		// Associate existing label with the new button
12244		this.label = $( "label[for='" + this.ids.element + "']" ).attr( "for", this.ids.button );
12245		this._on( this.label, {
12246			click: function( event ) {
12247				this.button.focus();
12248				event.preventDefault();
12249			}
12250		});
12251
12252		// Hide original select element
12253		this.element.hide();
12254
12255		// Create button
12256		this.button = $( "<span>", {
12257			"class": "ui-selectmenu-button ui-widget ui-state-default ui-corner-all",
12258			tabindex: this.options.disabled ? -1 : 0,
12259			id: this.ids.button,
12260			role: "combobox",
12261			"aria-expanded": "false",
12262			"aria-autocomplete": "list",
12263			"aria-owns": this.ids.menu,
12264			"aria-haspopup": "true"
12265		})
12266			.insertAfter( this.element );
12267
12268		$( "<span>", {
12269			"class": "ui-icon " + this.options.icons.button
12270		})
12271			.prependTo( this.button );
12272
12273		this.buttonText = $( "<span>", {
12274			"class": "ui-selectmenu-text"
12275		})
12276			.appendTo( this.button );
12277
12278		this._setText( this.buttonText, this.element.find( "option:selected" ).text() );
12279		this._resizeButton();
12280
12281		this._on( this.button, this._buttonEvents );
12282		this.button.one( "focusin", function() {
12283
12284			// Delay rendering the menu items until the button receives focus.
12285			// The menu may have already been rendered via a programmatic open.
12286			if ( !that.menuItems ) {
12287				that._refreshMenu();
12288			}
12289		});
12290		this._hoverable( this.button );
12291		this._focusable( this.button );
12292	},
12293
12294	_drawMenu: function() {
12295		var that = this;
12296
12297		// Create menu
12298		this.menu = $( "<ul>", {
12299			"aria-hidden": "true",
12300			"aria-labelledby": this.ids.button,
12301			id: this.ids.menu
12302		});
12303
12304		// Wrap menu
12305		this.menuWrap = $( "<div>", {
12306			"class": "ui-selectmenu-menu ui-front"
12307		})
12308			.append( this.menu )
12309			.appendTo( this._appendTo() );
12310
12311		// Initialize menu widget
12312		this.menuInstance = this.menu
12313			.menu({
12314				role: "listbox",
12315				select: function( event, ui ) {
12316					event.preventDefault();
12317
12318					// support: IE8
12319					// If the item was selected via a click, the text selection
12320					// will be destroyed in IE
12321					that._setSelection();
12322
12323					that._select( ui.item.data( "ui-selectmenu-item" ), event );
12324				},
12325				focus: function( event, ui ) {
12326					var item = ui.item.data( "ui-selectmenu-item" );
12327
12328					// Prevent inital focus from firing and check if its a newly focused item
12329					if ( that.focusIndex != null && item.index !== that.focusIndex ) {
12330						that._trigger( "focus", event, { item: item } );
12331						if ( !that.isOpen ) {
12332							that._select( item, event );
12333						}
12334					}
12335					that.focusIndex = item.index;
12336
12337					that.button.attr( "aria-activedescendant",
12338						that.menuItems.eq( item.index ).attr( "id" ) );
12339				}
12340			})
12341			.menu( "instance" );
12342
12343		// Adjust menu styles to dropdown
12344		this.menu
12345			.addClass( "ui-corner-bottom" )
12346			.removeClass( "ui-corner-all" );
12347
12348		// Don't close the menu on mouseleave
12349		this.menuInstance._off( this.menu, "mouseleave" );
12350
12351		// Cancel the menu's collapseAll on document click
12352		this.menuInstance._closeOnDocumentClick = function() {
12353			return false;
12354		};
12355
12356		// Selects often contain empty items, but never contain dividers
12357		this.menuInstance._isDivider = function() {
12358			return false;
12359		};
12360	},
12361
12362	refresh: function() {
12363		this._refreshMenu();
12364		this._setText( this.buttonText, this._getSelectedItem().text() );
12365		if ( !this.options.width ) {
12366			this._resizeButton();
12367		}
12368	},
12369
12370	_refreshMenu: function() {
12371		this.menu.empty();
12372
12373		var item,
12374			options = this.element.find( "option" );
12375
12376		if ( !options.length ) {
12377			return;
12378		}
12379
12380		this._parseOptions( options );
12381		this._renderMenu( this.menu, this.items );
12382
12383		this.menuInstance.refresh();
12384		this.menuItems = this.menu.find( "li" ).not( ".ui-selectmenu-optgroup" );
12385
12386		item = this._getSelectedItem();
12387
12388		// Update the menu to have the correct item focused
12389		this.menuInstance.focus( null, item );
12390		this._setAria( item.data( "ui-selectmenu-item" ) );
12391
12392		// Set disabled state
12393		this._setOption( "disabled", this.element.prop( "disabled" ) );
12394	},
12395
12396	open: function( event ) {
12397		if ( this.options.disabled ) {
12398			return;
12399		}
12400
12401		// If this is the first time the menu is being opened, render the items
12402		if ( !this.menuItems ) {
12403			this._refreshMenu();
12404		} else {
12405
12406			// Menu clears focus on close, reset focus to selected item
12407			this.menu.find( ".ui-state-focus" ).removeClass( "ui-state-focus" );
12408			this.menuInstance.focus( null, this._getSelectedItem() );
12409		}
12410
12411		this.isOpen = true;
12412		this._toggleAttr();
12413		this._resizeMenu();
12414		this._position();
12415
12416		this._on( this.document, this._documentClick );
12417
12418		this._trigger( "open", event );
12419	},
12420
12421	_position: function() {
12422		this.menuWrap.position( $.extend( { of: this.button }, this.options.position ) );
12423	},
12424
12425	close: function( event ) {
12426		if ( !this.isOpen ) {
12427			return;
12428		}
12429
12430		this.isOpen = false;
12431		this._toggleAttr();
12432
12433		this.range = null;
12434		this._off( this.document );
12435
12436		this._trigger( "close", event );
12437	},
12438
12439	widget: function() {
12440		return this.button;
12441	},
12442
12443	menuWidget: function() {
12444		return this.menu;
12445	},
12446
12447	_renderMenu: function( ul, items ) {
12448		var that = this,
12449			currentOptgroup = "";
12450
12451		$.each( items, function( index, item ) {
12452			if ( item.optgroup !== currentOptgroup ) {
12453				$( "<li>", {
12454					"class": "ui-selectmenu-optgroup ui-menu-divider" +
12455						( item.element.parent( "optgroup" ).prop( "disabled" ) ?
12456							" ui-state-disabled" :
12457							"" ),
12458					text: item.optgroup
12459				})
12460					.appendTo( ul );
12461
12462				currentOptgroup = item.optgroup;
12463			}
12464
12465			that._renderItemData( ul, item );
12466		});
12467	},
12468
12469	_renderItemData: function( ul, item ) {
12470		return this._renderItem( ul, item ).data( "ui-selectmenu-item", item );
12471	},
12472
12473	_renderItem: function( ul, item ) {
12474		var li = $( "<li>" );
12475
12476		if ( item.disabled ) {
12477			li.addClass( "ui-state-disabled" );
12478		}
12479		this._setText( li, item.label );
12480
12481		return li.appendTo( ul );
12482	},
12483
12484	_setText: function( element, value ) {
12485		if ( value ) {
12486			element.text( value );
12487		} else {
12488			element.html( "&#160;" );
12489		}
12490	},
12491
12492	_move: function( direction, event ) {
12493		var item, next,
12494			filter = ".ui-menu-item";
12495
12496		if ( this.isOpen ) {
12497			item = this.menuItems.eq( this.focusIndex );
12498		} else {
12499			item = this.menuItems.eq( this.element[ 0 ].selectedIndex );
12500			filter += ":not(.ui-state-disabled)";
12501		}
12502
12503		if ( direction === "first" || direction === "last" ) {
12504			next = item[ direction === "first" ? "prevAll" : "nextAll" ]( filter ).eq( -1 );
12505		} else {
12506			next = item[ direction + "All" ]( filter ).eq( 0 );
12507		}
12508
12509		if ( next.length ) {
12510			this.menuInstance.focus( event, next );
12511		}
12512	},
12513
12514	_getSelectedItem: function() {
12515		return this.menuItems.eq( this.element[ 0 ].selectedIndex );
12516	},
12517
12518	_toggle: function( event ) {
12519		this[ this.isOpen ? "close" : "open" ]( event );
12520	},
12521
12522	_setSelection: function() {
12523		var selection;
12524
12525		if ( !this.range ) {
12526			return;
12527		}
12528
12529		if ( window.getSelection ) {
12530			selection = window.getSelection();
12531			selection.removeAllRanges();
12532			selection.addRange( this.range );
12533
12534		// support: IE8
12535		} else {
12536			this.range.select();
12537		}
12538
12539		// support: IE
12540		// Setting the text selection kills the button focus in IE, but
12541		// restoring the focus doesn't kill the selection.
12542		this.button.focus();
12543	},
12544
12545	_documentClick: {
12546		mousedown: function( event ) {
12547			if ( !this.isOpen ) {
12548				return;
12549			}
12550
12551			if ( !$( event.target ).closest( ".ui-selectmenu-menu, #" + this.ids.button ).length ) {
12552				this.close( event );
12553			}
12554		}
12555	},
12556
12557	_buttonEvents: {
12558
12559		// Prevent text selection from being reset when interacting with the selectmenu (#10144)
12560		mousedown: function() {
12561			var selection;
12562
12563			if ( window.getSelection ) {
12564				selection = window.getSelection();
12565				if ( selection.rangeCount ) {
12566					this.range = selection.getRangeAt( 0 );
12567				}
12568
12569			// support: IE8
12570			} else {
12571				this.range = document.selection.createRange();
12572			}
12573		},
12574
12575		click: function( event ) {
12576			this._setSelection();
12577			this._toggle( event );
12578		},
12579
12580		keydown: function( event ) {
12581			var preventDefault = true;
12582			switch ( event.keyCode ) {
12583				case $.ui.keyCode.TAB:
12584				case $.ui.keyCode.ESCAPE:
12585					this.close( event );
12586					preventDefault = false;
12587					break;
12588				case $.ui.keyCode.ENTER:
12589					if ( this.isOpen ) {
12590						this._selectFocusedItem( event );
12591					}
12592					break;
12593				case $.ui.keyCode.UP:
12594					if ( event.altKey ) {
12595						this._toggle( event );
12596					} else {
12597						this._move( "prev", event );
12598					}
12599					break;
12600				case $.ui.keyCode.DOWN:
12601					if ( event.altKey ) {
12602						this._toggle( event );
12603					} else {
12604						this._move( "next", event );
12605					}
12606					break;
12607				case $.ui.keyCode.SPACE:
12608					if ( this.isOpen ) {
12609						this._selectFocusedItem( event );
12610					} else {
12611						this._toggle( event );
12612					}
12613					break;
12614				case $.ui.keyCode.LEFT:
12615					this._move( "prev", event );
12616					break;
12617				case $.ui.keyCode.RIGHT:
12618					this._move( "next", event );
12619					break;
12620				case $.ui.keyCode.HOME:
12621				case $.ui.keyCode.PAGE_UP:
12622					this._move( "first", event );
12623					break;
12624				case $.ui.keyCode.END:
12625				case $.ui.keyCode.PAGE_DOWN:
12626					this._move( "last", event );
12627					break;
12628				default:
12629					this.menu.trigger( event );
12630					preventDefault = false;
12631			}
12632
12633			if ( preventDefault ) {
12634				event.preventDefault();
12635			}
12636		}
12637	},
12638
12639	_selectFocusedItem: function( event ) {
12640		var item = this.menuItems.eq( this.focusIndex );
12641		if ( !item.hasClass( "ui-state-disabled" ) ) {
12642			this._select( item.data( "ui-selectmenu-item" ), event );
12643		}
12644	},
12645
12646	_select: function( item, event ) {
12647		var oldIndex = this.element[ 0 ].selectedIndex;
12648
12649		// Change native select element
12650		this.element[ 0 ].selectedIndex = item.index;
12651		this._setText( this.buttonText, item.label );
12652		this._setAria( item );
12653		this._trigger( "select", event, { item: item } );
12654
12655		if ( item.index !== oldIndex ) {
12656			this._trigger( "change", event, { item: item } );
12657		}
12658
12659		this.close( event );
12660	},
12661
12662	_setAria: function( item ) {
12663		var id = this.menuItems.eq( item.index ).attr( "id" );
12664
12665		this.button.attr({
12666			"aria-labelledby": id,
12667			"aria-activedescendant": id
12668		});
12669		this.menu.attr( "aria-activedescendant", id );
12670	},
12671
12672	_setOption: function( key, value ) {
12673		if ( key === "icons" ) {
12674			this.button.find( "span.ui-icon" )
12675				.removeClass( this.options.icons.button )
12676				.addClass( value.button );
12677		}
12678
12679		this._super( key, value );
12680
12681		if ( key === "appendTo" ) {
12682			this.menuWrap.appendTo( this._appendTo() );
12683		}
12684
12685		if ( key === "disabled" ) {
12686			this.menuInstance.option( "disabled", value );
12687			this.button
12688				.toggleClass( "ui-state-disabled", value )
12689				.attr( "aria-disabled", value );
12690
12691			this.element.prop( "disabled", value );
12692			if ( value ) {
12693				this.button.attr( "tabindex", -1 );
12694				this.close();
12695			} else {
12696				this.button.attr( "tabindex", 0 );
12697			}
12698		}
12699
12700		if ( key === "width" ) {
12701			this._resizeButton();
12702		}
12703	},
12704
12705	_appendTo: function() {
12706		var element = this.options.appendTo;
12707
12708		if ( element ) {
12709			element = element.jquery || element.nodeType ?
12710				$( element ) :
12711				this.document.find( element ).eq( 0 );
12712		}
12713
12714		if ( !element || !element[ 0 ] ) {
12715			element = this.element.closest( ".ui-front" );
12716		}
12717
12718		if ( !element.length ) {
12719			element = this.document[ 0 ].body;
12720		}
12721
12722		return element;
12723	},
12724
12725	_toggleAttr: function() {
12726		this.button
12727			.toggleClass( "ui-corner-top", this.isOpen )
12728			.toggleClass( "ui-corner-all", !this.isOpen )
12729			.attr( "aria-expanded", this.isOpen );
12730		this.menuWrap.toggleClass( "ui-selectmenu-open", this.isOpen );
12731		this.menu.attr( "aria-hidden", !this.isOpen );
12732	},
12733
12734	_resizeButton: function() {
12735		var width = this.options.width;
12736
12737		if ( !width ) {
12738			width = this.element.show().outerWidth();
12739			this.element.hide();
12740		}
12741
12742		this.button.outerWidth( width );
12743	},
12744
12745	_resizeMenu: function() {
12746		this.menu.outerWidth( Math.max(
12747			this.button.outerWidth(),
12748
12749			// support: IE10
12750			// IE10 wraps long text (possibly a rounding bug)
12751			// so we add 1px to avoid the wrapping
12752			this.menu.width( "" ).outerWidth() + 1
12753		) );
12754	},
12755
12756	_getCreateOptions: function() {
12757		return { disabled: this.element.prop( "disabled" ) };
12758	},
12759
12760	_parseOptions: function( options ) {
12761		var data = [];
12762		options.each(function( index, item ) {
12763			var option = $( item ),
12764				optgroup = option.parent( "optgroup" );
12765			data.push({
12766				element: option,
12767				index: index,
12768				value: option.val(),
12769				label: option.text(),
12770				optgroup: optgroup.attr( "label" ) || "",
12771				disabled: optgroup.prop( "disabled" ) || option.prop( "disabled" )
12772			});
12773		});
12774		this.items = data;
12775	},
12776
12777	_destroy: function() {
12778		this.menuWrap.remove();
12779		this.button.remove();
12780		this.element.show();
12781		this.element.removeUniqueId();
12782		this.label.attr( "for", this.ids.element );
12783	}
12784});
12785
12786
12787/*!
12788 * jQuery UI Slider 1.11.4
12789 * http://jqueryui.com
12790 *
12791 * Copyright jQuery Foundation and other contributors
12792 * Released under the MIT license.
12793 * http://jquery.org/license
12794 *
12795 * http://api.jqueryui.com/slider/
12796 */
12797
12798
12799var slider = $.widget( "ui.slider", $.ui.mouse, {
12800	version: "1.11.4",
12801	widgetEventPrefix: "slide",
12802
12803	options: {
12804		animate: false,
12805		distance: 0,
12806		max: 100,
12807		min: 0,
12808		orientation: "horizontal",
12809		range: false,
12810		step: 1,
12811		value: 0,
12812		values: null,
12813
12814		// callbacks
12815		change: null,
12816		slide: null,
12817		start: null,
12818		stop: null
12819	},
12820
12821	// number of pages in a slider
12822	// (how many times can you page up/down to go through the whole range)
12823	numPages: 5,
12824
12825	_create: function() {
12826		this._keySliding = false;
12827		this._mouseSliding = false;
12828		this._animateOff = true;
12829		this._handleIndex = null;
12830		this._detectOrientation();
12831		this._mouseInit();
12832		this._calculateNewMax();
12833
12834		this.element
12835			.addClass( "ui-slider" +
12836				" ui-slider-" + this.orientation +
12837				" ui-widget" +
12838				" ui-widget-content" +
12839				" ui-corner-all");
12840
12841		this._refresh();
12842		this._setOption( "disabled", this.options.disabled );
12843
12844		this._animateOff = false;
12845	},
12846
12847	_refresh: function() {
12848		this._createRange();
12849		this._createHandles();
12850		this._setupEvents();
12851		this._refreshValue();
12852	},
12853
12854	_createHandles: function() {
12855		var i, handleCount,
12856			options = this.options,
12857			existingHandles = this.element.find( ".ui-slider-handle" ).addClass( "ui-state-default ui-corner-all" ),
12858			handle = "<span class='ui-slider-handle ui-state-default ui-corner-all' tabindex='0'></span>",
12859			handles = [];
12860
12861		handleCount = ( options.values && options.values.length ) || 1;
12862
12863		if ( existingHandles.length > handleCount ) {
12864			existingHandles.slice( handleCount ).remove();
12865			existingHandles = existingHandles.slice( 0, handleCount );
12866		}
12867
12868		for ( i = existingHandles.length; i < handleCount; i++ ) {
12869			handles.push( handle );
12870		}
12871
12872		this.handles = existingHandles.add( $( handles.join( "" ) ).appendTo( this.element ) );
12873
12874		this.handle = this.handles.eq( 0 );
12875
12876		this.handles.each(function( i ) {
12877			$( this ).data( "ui-slider-handle-index", i );
12878		});
12879	},
12880
12881	_createRange: function() {
12882		var options = this.options,
12883			classes = "";
12884
12885		if ( options.range ) {
12886			if ( options.range === true ) {
12887				if ( !options.values ) {
12888					options.values = [ this._valueMin(), this._valueMin() ];
12889				} else if ( options.values.length && options.values.length !== 2 ) {
12890					options.values = [ options.values[0], options.values[0] ];
12891				} else if ( $.isArray( options.values ) ) {
12892					options.values = options.values.slice(0);
12893				}
12894			}
12895
12896			if ( !this.range || !this.range.length ) {
12897				this.range = $( "<div></div>" )
12898					.appendTo( this.element );
12899
12900				classes = "ui-slider-range" +
12901				// note: this isn't the most fittingly semantic framework class for this element,
12902				// but worked best visually with a variety of themes
12903				" ui-widget-header ui-corner-all";
12904			} else {
12905				this.range.removeClass( "ui-slider-range-min ui-slider-range-max" )
12906					// Handle range switching from true to min/max
12907					.css({
12908						"left": "",
12909						"bottom": ""
12910					});
12911			}
12912
12913			this.range.addClass( classes +
12914				( ( options.range === "min" || options.range === "max" ) ? " ui-slider-range-" + options.range : "" ) );
12915		} else {
12916			if ( this.range ) {
12917				this.range.remove();
12918			}
12919			this.range = null;
12920		}
12921	},
12922
12923	_setupEvents: function() {
12924		this._off( this.handles );
12925		this._on( this.handles, this._handleEvents );
12926		this._hoverable( this.handles );
12927		this._focusable( this.handles );
12928	},
12929
12930	_destroy: function() {
12931		this.handles.remove();
12932		if ( this.range ) {
12933			this.range.remove();
12934		}
12935
12936		this.element
12937			.removeClass( "ui-slider" +
12938				" ui-slider-horizontal" +
12939				" ui-slider-vertical" +
12940				" ui-widget" +
12941				" ui-widget-content" +
12942				" ui-corner-all" );
12943
12944		this._mouseDestroy();
12945	},
12946
12947	_mouseCapture: function( event ) {
12948		var position, normValue, distance, closestHandle, index, allowed, offset, mouseOverHandle,
12949			that = this,
12950			o = this.options;
12951
12952		if ( o.disabled ) {
12953			return false;
12954		}
12955
12956		this.elementSize = {
12957			width: this.element.outerWidth(),
12958			height: this.element.outerHeight()
12959		};
12960		this.elementOffset = this.element.offset();
12961
12962		position = { x: event.pageX, y: event.pageY };
12963		normValue = this._normValueFromMouse( position );
12964		distance = this._valueMax() - this._valueMin() + 1;
12965		this.handles.each(function( i ) {
12966			var thisDistance = Math.abs( normValue - that.values(i) );
12967			if (( distance > thisDistance ) ||
12968				( distance === thisDistance &&
12969					(i === that._lastChangedValue || that.values(i) === o.min ))) {
12970				distance = thisDistance;
12971				closestHandle = $( this );
12972				index = i;
12973			}
12974		});
12975
12976		allowed = this._start( event, index );
12977		if ( allowed === false ) {
12978			return false;
12979		}
12980		this._mouseSliding = true;
12981
12982		this._handleIndex = index;
12983
12984		closestHandle
12985			.addClass( "ui-state-active" )
12986			.focus();
12987
12988		offset = closestHandle.offset();
vendor: 4,641 bytes, lines 12989-13161
12989		mouseOverHandle = !$( event.target ).parents().addBack().is( ".ui-slider-handle" );
12990		this._clickOffset = mouseOverHandle ? { left: 0, top: 0 } : {
12991			left: event.pageX - offset.left - ( closestHandle.width() / 2 ),
12992			top: event.pageY - offset.top -
12993				( closestHandle.height() / 2 ) -
12994				( parseInt( closestHandle.css("borderTopWidth"), 10 ) || 0 ) -
12995				( parseInt( closestHandle.css("borderBottomWidth"), 10 ) || 0) +
12996				( parseInt( closestHandle.css("marginTop"), 10 ) || 0)
12997		};
12998
12999		if ( !this.handles.hasClass( "ui-state-hover" ) ) {
13000			this._slide( event, index, normValue );
13001		}
13002		this._animateOff = true;
13003		return true;
13004	},
13005
13006	_mouseStart: function() {
13007		return true;
13008	},
13009
13010	_mouseDrag: function( event ) {
13011		var position = { x: event.pageX, y: event.pageY },
13012			normValue = this._normValueFromMouse( position );
13013
13014		this._slide( event, this._handleIndex, normValue );
13015
13016		return false;
13017	},
13018
13019	_mouseStop: function( event ) {
13020		this.handles.removeClass( "ui-state-active" );
13021		this._mouseSliding = false;
13022
13023		this._stop( event, this._handleIndex );
13024		this._change( event, this._handleIndex );
13025
13026		this._handleIndex = null;
13027		this._clickOffset = null;
13028		this._animateOff = false;
13029
13030		return false;
13031	},
13032
13033	_detectOrientation: function() {
13034		this.orientation = ( this.options.orientation === "vertical" ) ? "vertical" : "horizontal";
13035	},
13036
13037	_normValueFromMouse: function( position ) {
13038		var pixelTotal,
13039			pixelMouse,
13040			percentMouse,
13041			valueTotal,
13042			valueMouse;
13043
13044		if ( this.orientation === "horizontal" ) {
13045			pixelTotal = this.elementSize.width;
13046			pixelMouse = position.x - this.elementOffset.left - ( this._clickOffset ? this._clickOffset.left : 0 );
13047		} else {
13048			pixelTotal = this.elementSize.height;
13049			pixelMouse = position.y - this.elementOffset.top - ( this._clickOffset ? this._clickOffset.top : 0 );
13050		}
13051
13052		percentMouse = ( pixelMouse / pixelTotal );
13053		if ( percentMouse > 1 ) {
13054			percentMouse = 1;
13055		}
13056		if ( percentMouse < 0 ) {
13057			percentMouse = 0;
13058		}
13059		if ( this.orientation === "vertical" ) {
13060			percentMouse = 1 - percentMouse;
13061		}
13062
13063		valueTotal = this._valueMax() - this._valueMin();
13064		valueMouse = this._valueMin() + percentMouse * valueTotal;
13065
13066		return this._trimAlignValue( valueMouse );
13067	},
13068
13069	_start: function( event, index ) {
13070		var uiHash = {
13071			handle: this.handles[ index ],
13072			value: this.value()
13073		};
13074		if ( this.options.values && this.options.values.length ) {
13075			uiHash.value = this.values( index );
13076			uiHash.values = this.values();
13077		}
13078		return this._trigger( "start", event, uiHash );
13079	},
13080
13081	_slide: function( event, index, newVal ) {
13082		var otherVal,
13083			newValues,
13084			allowed;
13085
13086		if ( this.options.values && this.options.values.length ) {
13087			otherVal = this.values( index ? 0 : 1 );
13088
13089			if ( ( this.options.values.length === 2 && this.options.range === true ) &&
13090					( ( index === 0 && newVal > otherVal) || ( index === 1 && newVal < otherVal ) )
13091				) {
13092				newVal = otherVal;
13093			}
13094
13095			if ( newVal !== this.values( index ) ) {
13096				newValues = this.values();
13097				newValues[ index ] = newVal;
13098				// A slide can be canceled by returning false from the slide callback
13099				allowed = this._trigger( "slide", event, {
13100					handle: this.handles[ index ],
13101					value: newVal,
13102					values: newValues
13103				} );
13104				otherVal = this.values( index ? 0 : 1 );
13105				if ( allowed !== false ) {
13106					this.values( index, newVal );
13107				}
13108			}
13109		} else {
13110			if ( newVal !== this.value() ) {
13111				// A slide can be canceled by returning false from the slide callback
13112				allowed = this._trigger( "slide", event, {
13113					handle: this.handles[ index ],
13114					value: newVal
13115				} );
13116				if ( allowed !== false ) {
13117					this.value( newVal );
13118				}
13119			}
13120		}
13121	},
13122
13123	_stop: function( event, index ) {
13124		var uiHash = {
13125			handle: this.handles[ index ],
13126			value: this.value()
13127		};
13128		if ( this.options.values && this.options.values.length ) {
13129			uiHash.value = this.values( index );
13130			uiHash.values = this.values();
13131		}
13132
13133		this._trigger( "stop", event, uiHash );
13134	},
13135
13136	_change: function( event, index ) {
13137		if ( !this._keySliding && !this._mouseSliding ) {
13138			var uiHash = {
13139				handle: this.handles[ index ],
13140				value: this.value()
13141			};
13142			if ( this.options.values && this.options.values.length ) {
13143				uiHash.value = this.values( index );
13144				uiHash.values = this.values();
13145			}
13146
13147			//store the last changed value index for reference when handles overlap
13148			this._lastChangedValue = index;
13149
13150			this._trigger( "change", event, uiHash );
13151		}
13152	},
13153
13154	value: function( newValue ) {
13155		if ( arguments.length ) {
13156			this.options.value = this._trimAlignValue( newValue );
13157			this._refreshValue();
13158			this._change( null, 0 );
13159			return;
13160		}
13161
vendor: 56,341 bytes, lines 13162-14940
13162		return this._value();
13163	},
13164
13165	values: function( index, newValue ) {
13166		var vals,
13167			newValues,
13168			i;
13169
13170		if ( arguments.length > 1 ) {
13171			this.options.values[ index ] = this._trimAlignValue( newValue );
13172			this._refreshValue();
13173			this._change( null, index );
13174			return;
13175		}
13176
13177		if ( arguments.length ) {
13178			if ( $.isArray( arguments[ 0 ] ) ) {
13179				vals = this.options.values;
13180				newValues = arguments[ 0 ];
13181				for ( i = 0; i < vals.length; i += 1 ) {
13182					vals[ i ] = this._trimAlignValue( newValues[ i ] );
13183					this._change( null, i );
13184				}
13185				this._refreshValue();
13186			} else {
13187				if ( this.options.values && this.options.values.length ) {
13188					return this._values( index );
13189				} else {
13190					return this.value();
13191				}
13192			}
13193		} else {
13194			return this._values();
13195		}
13196	},
13197
13198	_setOption: function( key, value ) {
13199		var i,
13200			valsLength = 0;
13201
13202		if ( key === "range" && this.options.range === true ) {
13203			if ( value === "min" ) {
13204				this.options.value = this._values( 0 );
13205				this.options.values = null;
13206			} else if ( value === "max" ) {
13207				this.options.value = this._values( this.options.values.length - 1 );
13208				this.options.values = null;
13209			}
13210		}
13211
13212		if ( $.isArray( this.options.values ) ) {
13213			valsLength = this.options.values.length;
13214		}
13215
13216		if ( key === "disabled" ) {
13217			this.element.toggleClass( "ui-state-disabled", !!value );
13218		}
13219
13220		this._super( key, value );
13221
13222		switch ( key ) {
13223			case "orientation":
13224				this._detectOrientation();
13225				this.element
13226					.removeClass( "ui-slider-horizontal ui-slider-vertical" )
13227					.addClass( "ui-slider-" + this.orientation );
13228				this._refreshValue();
13229
13230				// Reset positioning from previous orientation
13231				this.handles.css( value === "horizontal" ? "bottom" : "left", "" );
13232				break;
13233			case "value":
13234				this._animateOff = true;
13235				this._refreshValue();
13236				this._change( null, 0 );
13237				this._animateOff = false;
13238				break;
13239			case "values":
13240				this._animateOff = true;
13241				this._refreshValue();
13242				for ( i = 0; i < valsLength; i += 1 ) {
13243					this._change( null, i );
13244				}
13245				this._animateOff = false;
13246				break;
13247			case "step":
13248			case "min":
13249			case "max":
13250				this._animateOff = true;
13251				this._calculateNewMax();
13252				this._refreshValue();
13253				this._animateOff = false;
13254				break;
13255			case "range":
13256				this._animateOff = true;
13257				this._refresh();
13258				this._animateOff = false;
13259				break;
13260		}
13261	},
13262
13263	//internal value getter
13264	// _value() returns value trimmed by min and max, aligned by step
13265	_value: function() {
13266		var val = this.options.value;
13267		val = this._trimAlignValue( val );
13268
13269		return val;
13270	},
13271
13272	//internal values getter
13273	// _values() returns array of values trimmed by min and max, aligned by step
13274	// _values( index ) returns single value trimmed by min and max, aligned by step
13275	_values: function( index ) {
13276		var val,
13277			vals,
13278			i;
13279
13280		if ( arguments.length ) {
13281			val = this.options.values[ index ];
13282			val = this._trimAlignValue( val );
13283
13284			return val;
13285		} else if ( this.options.values && this.options.values.length ) {
13286			// .slice() creates a copy of the array
13287			// this copy gets trimmed by min and max and then returned
13288			vals = this.options.values.slice();
13289			for ( i = 0; i < vals.length; i += 1) {
13290				vals[ i ] = this._trimAlignValue( vals[ i ] );
13291			}
13292
13293			return vals;
13294		} else {
13295			return [];
13296		}
13297	},
13298
13299	// returns the step-aligned value that val is closest to, between (inclusive) min and max
13300	_trimAlignValue: function( val ) {
13301		if ( val <= this._valueMin() ) {
13302			return this._valueMin();
13303		}
13304		if ( val >= this._valueMax() ) {
13305			return this._valueMax();
13306		}
13307		var step = ( this.options.step > 0 ) ? this.options.step : 1,
13308			valModStep = (val - this._valueMin()) % step,
13309			alignValue = val - valModStep;
13310
13311		if ( Math.abs(valModStep) * 2 >= step ) {
13312			alignValue += ( valModStep > 0 ) ? step : ( -step );
13313		}
13314
13315		// Since JavaScript has problems with large floats, round
13316		// the final value to 5 digits after the decimal point (see #4124)
13317		return parseFloat( alignValue.toFixed(5) );
13318	},
13319
13320	_calculateNewMax: function() {
13321		var max = this.options.max,
13322			min = this._valueMin(),
13323			step = this.options.step,
13324			aboveMin = Math.floor( ( +( max - min ).toFixed( this._precision() ) ) / step ) * step;
13325		max = aboveMin + min;
13326		this.max = parseFloat( max.toFixed( this._precision() ) );
13327	},
13328
13329	_precision: function() {
13330		var precision = this._precisionOf( this.options.step );
13331		if ( this.options.min !== null ) {
13332			precision = Math.max( precision, this._precisionOf( this.options.min ) );
13333		}
13334		return precision;
13335	},
13336
13337	_precisionOf: function( num ) {
13338		var str = num.toString(),
13339			decimal = str.indexOf( "." );
13340		return decimal === -1 ? 0 : str.length - decimal - 1;
13341	},
13342
13343	_valueMin: function() {
13344		return this.options.min;
13345	},
13346
13347	_valueMax: function() {
13348		return this.max;
13349	},
13350
13351	_refreshValue: function() {
13352		var lastValPercent, valPercent, value, valueMin, valueMax,
13353			oRange = this.options.range,
13354			o = this.options,
13355			that = this,
13356			animate = ( !this._animateOff ) ? o.animate : false,
13357			_set = {};
13358
13359		if ( this.options.values && this.options.values.length ) {
13360			this.handles.each(function( i ) {
13361				valPercent = ( that.values(i) - that._valueMin() ) / ( that._valueMax() - that._valueMin() ) * 100;
13362				_set[ that.orientation === "horizontal" ? "left" : "bottom" ] = valPercent + "%";
13363				$( this ).stop( 1, 1 )[ animate ? "animate" : "css" ]( _set, o.animate );
13364				if ( that.options.range === true ) {
13365					if ( that.orientation === "horizontal" ) {
13366						if ( i === 0 ) {
13367							that.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { left: valPercent + "%" }, o.animate );
13368						}
13369						if ( i === 1 ) {
13370							that.range[ animate ? "animate" : "css" ]( { width: ( valPercent - lastValPercent ) + "%" }, { queue: false, duration: o.animate } );
13371						}
13372					} else {
13373						if ( i === 0 ) {
13374							that.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { bottom: ( valPercent ) + "%" }, o.animate );
13375						}
13376						if ( i === 1 ) {
13377							that.range[ animate ? "animate" : "css" ]( { height: ( valPercent - lastValPercent ) + "%" }, { queue: false, duration: o.animate } );
13378						}
13379					}
13380				}
13381				lastValPercent = valPercent;
13382			});
13383		} else {
13384			value = this.value();
13385			valueMin = this._valueMin();
13386			valueMax = this._valueMax();
13387			valPercent = ( valueMax !== valueMin ) ?
13388					( value - valueMin ) / ( valueMax - valueMin ) * 100 :
13389					0;
13390			_set[ this.orientation === "horizontal" ? "left" : "bottom" ] = valPercent + "%";
13391			this.handle.stop( 1, 1 )[ animate ? "animate" : "css" ]( _set, o.animate );
13392
13393			if ( oRange === "min" && this.orientation === "horizontal" ) {
13394				this.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { width: valPercent + "%" }, o.animate );
13395			}
13396			if ( oRange === "max" && this.orientation === "horizontal" ) {
13397				this.range[ animate ? "animate" : "css" ]( { width: ( 100 - valPercent ) + "%" }, { queue: false, duration: o.animate } );
13398			}
13399			if ( oRange === "min" && this.orientation === "vertical" ) {
13400				this.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { height: valPercent + "%" }, o.animate );
13401			}
13402			if ( oRange === "max" && this.orientation === "vertical" ) {
13403				this.range[ animate ? "animate" : "css" ]( { height: ( 100 - valPercent ) + "%" }, { queue: false, duration: o.animate } );
13404			}
13405		}
13406	},
13407
13408	_handleEvents: {
13409		keydown: function( event ) {
13410			var allowed, curVal, newVal, step,
13411				index = $( event.target ).data( "ui-slider-handle-index" );
13412
13413			switch ( event.keyCode ) {
13414				case $.ui.keyCode.HOME:
13415				case $.ui.keyCode.END:
13416				case $.ui.keyCode.PAGE_UP:
13417				case $.ui.keyCode.PAGE_DOWN:
13418				case $.ui.keyCode.UP:
13419				case $.ui.keyCode.RIGHT:
13420				case $.ui.keyCode.DOWN:
13421				case $.ui.keyCode.LEFT:
13422					event.preventDefault();
13423					if ( !this._keySliding ) {
13424						this._keySliding = true;
13425						$( event.target ).addClass( "ui-state-active" );
13426						allowed = this._start( event, index );
13427						if ( allowed === false ) {
13428							return;
13429						}
13430					}
13431					break;
13432			}
13433
13434			step = this.options.step;
13435			if ( this.options.values && this.options.values.length ) {
13436				curVal = newVal = this.values( index );
13437			} else {
13438				curVal = newVal = this.value();
13439			}
13440
13441			switch ( event.keyCode ) {
13442				case $.ui.keyCode.HOME:
13443					newVal = this._valueMin();
13444					break;
13445				case $.ui.keyCode.END:
13446					newVal = this._valueMax();
13447					break;
13448				case $.ui.keyCode.PAGE_UP:
13449					newVal = this._trimAlignValue(
13450						curVal + ( ( this._valueMax() - this._valueMin() ) / this.numPages )
13451					);
13452					break;
13453				case $.ui.keyCode.PAGE_DOWN:
13454					newVal = this._trimAlignValue(
13455						curVal - ( (this._valueMax() - this._valueMin()) / this.numPages ) );
13456					break;
13457				case $.ui.keyCode.UP:
13458				case $.ui.keyCode.RIGHT:
13459					if ( curVal === this._valueMax() ) {
13460						return;
13461					}
13462					newVal = this._trimAlignValue( curVal + step );
13463					break;
13464				case $.ui.keyCode.DOWN:
13465				case $.ui.keyCode.LEFT:
13466					if ( curVal === this._valueMin() ) {
13467						return;
13468					}
13469					newVal = this._trimAlignValue( curVal - step );
13470					break;
13471			}
13472
13473			this._slide( event, index, newVal );
13474		},
13475		keyup: function( event ) {
13476			var index = $( event.target ).data( "ui-slider-handle-index" );
13477
13478			if ( this._keySliding ) {
13479				this._keySliding = false;
13480				this._stop( event, index );
13481				this._change( event, index );
13482				$( event.target ).removeClass( "ui-state-active" );
13483			}
13484		}
13485	}
13486});
13487
13488
13489/*!
13490 * jQuery UI Sortable 1.11.4
13491 * http://jqueryui.com
13492 *
13493 * Copyright jQuery Foundation and other contributors
13494 * Released under the MIT license.
13495 * http://jquery.org/license
13496 *
13497 * http://api.jqueryui.com/sortable/
13498 */
13499
13500
13501var sortable = $.widget("ui.sortable", $.ui.mouse, {
13502	version: "1.11.4",
13503	widgetEventPrefix: "sort",
13504	ready: false,
13505	options: {
13506		appendTo: "parent",
13507		axis: false,
13508		connectWith: false,
13509		containment: false,
13510		cursor: "auto",
13511		cursorAt: false,
13512		dropOnEmpty: true,
13513		forcePlaceholderSize: false,
13514		forceHelperSize: false,
13515		grid: false,
13516		handle: false,
13517		helper: "original",
13518		items: "> *",
13519		opacity: false,
13520		placeholder: false,
13521		revert: false,
13522		scroll: true,
13523		scrollSensitivity: 20,
13524		scrollSpeed: 20,
13525		scope: "default",
13526		tolerance: "intersect",
13527		zIndex: 1000,
13528
13529		// callbacks
13530		activate: null,
13531		beforeStop: null,
13532		change: null,
13533		deactivate: null,
13534		out: null,
13535		over: null,
13536		receive: null,
13537		remove: null,
13538		sort: null,
13539		start: null,
13540		stop: null,
13541		update: null
13542	},
13543
13544	_isOverAxis: function( x, reference, size ) {
13545		return ( x >= reference ) && ( x < ( reference + size ) );
13546	},
13547
13548	_isFloating: function( item ) {
13549		return (/left|right/).test(item.css("float")) || (/inline|table-cell/).test(item.css("display"));
13550	},
13551
13552	_create: function() {
13553		this.containerCache = {};
13554		this.element.addClass("ui-sortable");
13555
13556		//Get the items
13557		this.refresh();
13558
13559		//Let's determine the parent's offset
13560		this.offset = this.element.offset();
13561
13562		//Initialize mouse events for interaction
13563		this._mouseInit();
13564
13565		this._setHandleClassName();
13566
13567		//We're ready to go
13568		this.ready = true;
13569
13570	},
13571
13572	_setOption: function( key, value ) {
13573		this._super( key, value );
13574
13575		if ( key === "handle" ) {
13576			this._setHandleClassName();
13577		}
13578	},
13579
13580	_setHandleClassName: function() {
13581		this.element.find( ".ui-sortable-handle" ).removeClass( "ui-sortable-handle" );
13582		$.each( this.items, function() {
13583			( this.instance.options.handle ?
13584				this.item.find( this.instance.options.handle ) : this.item )
13585				.addClass( "ui-sortable-handle" );
13586		});
13587	},
13588
13589	_destroy: function() {
13590		this.element
13591			.removeClass( "ui-sortable ui-sortable-disabled" )
13592			.find( ".ui-sortable-handle" )
13593				.removeClass( "ui-sortable-handle" );
13594		this._mouseDestroy();
13595
13596		for ( var i = this.items.length - 1; i >= 0; i-- ) {
13597			this.items[i].item.removeData(this.widgetName + "-item");
13598		}
13599
13600		return this;
13601	},
13602
13603	_mouseCapture: function(event, overrideHandle) {
13604		var currentItem = null,
13605			validHandle = false,
13606			that = this;
13607
13608		if (this.reverting) {
13609			return false;
13610		}
13611
13612		if(this.options.disabled || this.options.type === "static") {
13613			return false;
13614		}
13615
13616		//We have to refresh the items data once first
13617		this._refreshItems(event);
13618
13619		//Find out if the clicked node (or one of its parents) is a actual item in this.items
13620		$(event.target).parents().each(function() {
13621			if($.data(this, that.widgetName + "-item") === that) {
13622				currentItem = $(this);
13623				return false;
13624			}
13625		});
13626		if($.data(event.target, that.widgetName + "-item") === that) {
13627			currentItem = $(event.target);
13628		}
13629
13630		if(!currentItem) {
13631			return false;
13632		}
13633		if(this.options.handle && !overrideHandle) {
13634			$(this.options.handle, currentItem).find("*").addBack().each(function() {
13635				if(this === event.target) {
13636					validHandle = true;
13637				}
13638			});
13639			if(!validHandle) {
13640				return false;
13641			}
13642		}
13643
13644		this.currentItem = currentItem;
13645		this._removeCurrentsFromItems();
13646		return true;
13647
13648	},
13649
13650	_mouseStart: function(event, overrideHandle, noActivation) {
13651
13652		var i, body,
13653			o = this.options;
13654
13655		this.currentContainer = this;
13656
13657		//We only need to call refreshPositions, because the refreshItems call has been moved to mouseCapture
13658		this.refreshPositions();
13659
13660		//Create and append the visible helper
13661		this.helper = this._createHelper(event);
13662
13663		//Cache the helper size
13664		this._cacheHelperProportions();
13665
13666		/*
13667		 * - Position generation -
13668		 * This block generates everything position related - it's the core of draggables.
13669		 */
13670
13671		//Cache the margins of the original element
13672		this._cacheMargins();
13673
13674		//Get the next scrolling parent
13675		this.scrollParent = this.helper.scrollParent();
13676
13677		//The element's absolute position on the page minus margins
13678		this.offset = this.currentItem.offset();
13679		this.offset = {
13680			top: this.offset.top - this.margins.top,
13681			left: this.offset.left - this.margins.left
13682		};
13683
13684		$.extend(this.offset, {
13685			click: { //Where the click happened, relative to the element
13686				left: event.pageX - this.offset.left,
13687				top: event.pageY - this.offset.top
13688			},
13689			parent: this._getParentOffset(),
13690			relative: this._getRelativeOffset() //This is a relative to absolute position minus the actual position calculation - only used for relative positioned helper
13691		});
13692
13693		// Only after we got the offset, we can change the helper's position to absolute
13694		// TODO: Still need to figure out a way to make relative sorting possible
13695		this.helper.css("position", "absolute");
13696		this.cssPosition = this.helper.css("position");
13697
13698		//Generate the original position
13699		this.originalPosition = this._generatePosition(event);
13700		this.originalPageX = event.pageX;
13701		this.originalPageY = event.pageY;
13702
13703		//Adjust the mouse offset relative to the helper if "cursorAt" is supplied
13704		(o.cursorAt && this._adjustOffsetFromHelper(o.cursorAt));
13705
13706		//Cache the former DOM position
13707		this.domPosition = { prev: this.currentItem.prev()[0], parent: this.currentItem.parent()[0] };
13708
13709		//If the helper is not the original, hide the original so it's not playing any role during the drag, won't cause anything bad this way
13710		if(this.helper[0] !== this.currentItem[0]) {
13711			this.currentItem.hide();
13712		}
13713
13714		//Create the placeholder
13715		this._createPlaceholder();
13716
13717		//Set a containment if given in the options
13718		if(o.containment) {
13719			this._setContainment();
13720		}
13721
13722		if( o.cursor && o.cursor !== "auto" ) { // cursor option
13723			body = this.document.find( "body" );
13724
13725			// support: IE
13726			this.storedCursor = body.css( "cursor" );
13727			body.css( "cursor", o.cursor );
13728
13729			this.storedStylesheet = $( "<style>*{ cursor: "+o.cursor+" !important; }</style>" ).appendTo( body );
13730		}
13731
13732		if(o.opacity) { // opacity option
13733			if (this.helper.css("opacity")) {
13734				this._storedOpacity = this.helper.css("opacity");
13735			}
13736			this.helper.css("opacity", o.opacity);
13737		}
13738
13739		if(o.zIndex) { // zIndex option
13740			if (this.helper.css("zIndex")) {
13741				this._storedZIndex = this.helper.css("zIndex");
13742			}
13743			this.helper.css("zIndex", o.zIndex);
13744		}
13745
13746		//Prepare scrolling
13747		if(this.scrollParent[0] !== this.document[0] && this.scrollParent[0].tagName !== "HTML") {
13748			this.overflowOffset = this.scrollParent.offset();
13749		}
13750
13751		//Call callbacks
13752		this._trigger("start", event, this._uiHash());
13753
13754		//Recache the helper size
13755		if(!this._preserveHelperProportions) {
13756			this._cacheHelperProportions();
13757		}
13758
13759
13760		//Post "activate" events to possible containers
13761		if( !noActivation ) {
13762			for ( i = this.containers.length - 1; i >= 0; i-- ) {
13763				this.containers[ i ]._trigger( "activate", event, this._uiHash( this ) );
13764			}
13765		}
13766
13767		//Prepare possible droppables
13768		if($.ui.ddmanager) {
13769			$.ui.ddmanager.current = this;
13770		}
13771
13772		if ($.ui.ddmanager && !o.dropBehaviour) {
13773			$.ui.ddmanager.prepareOffsets(this, event);
13774		}
13775
13776		this.dragging = true;
13777
13778		this.helper.addClass("ui-sortable-helper");
13779		this._mouseDrag(event); //Execute the drag once - this causes the helper not to be visible before getting its correct position
13780		return true;
13781
13782	},
13783
13784	_mouseDrag: function(event) {
13785		var i, item, itemElement, intersection,
13786			o = this.options,
13787			scrolled = false;
13788
13789		//Compute the helpers position
13790		this.position = this._generatePosition(event);
13791		this.positionAbs = this._convertPositionTo("absolute");
13792
13793		if (!this.lastPositionAbs) {
13794			this.lastPositionAbs = this.positionAbs;
13795		}
13796
13797		//Do scrolling
13798		if(this.options.scroll) {
13799			if(this.scrollParent[0] !== this.document[0] && this.scrollParent[0].tagName !== "HTML") {
13800
13801				if((this.overflowOffset.top + this.scrollParent[0].offsetHeight) - event.pageY < o.scrollSensitivity) {
13802					this.scrollParent[0].scrollTop = scrolled = this.scrollParent[0].scrollTop + o.scrollSpeed;
13803				} else if(event.pageY - this.overflowOffset.top < o.scrollSensitivity) {
13804					this.scrollParent[0].scrollTop = scrolled = this.scrollParent[0].scrollTop - o.scrollSpeed;
13805				}
13806
13807				if((this.overflowOffset.left + this.scrollParent[0].offsetWidth) - event.pageX < o.scrollSensitivity) {
13808					this.scrollParent[0].scrollLeft = scrolled = this.scrollParent[0].scrollLeft + o.scrollSpeed;
13809				} else if(event.pageX - this.overflowOffset.left < o.scrollSensitivity) {
13810					this.scrollParent[0].scrollLeft = scrolled = this.scrollParent[0].scrollLeft - o.scrollSpeed;
13811				}
13812
13813			} else {
13814
13815				if(event.pageY - this.document.scrollTop() < o.scrollSensitivity) {
13816					scrolled = this.document.scrollTop(this.document.scrollTop() - o.scrollSpeed);
13817				} else if(this.window.height() - (event.pageY - this.document.scrollTop()) < o.scrollSensitivity) {
13818					scrolled = this.document.scrollTop(this.document.scrollTop() + o.scrollSpeed);
13819				}
13820
13821				if(event.pageX - this.document.scrollLeft() < o.scrollSensitivity) {
13822					scrolled = this.document.scrollLeft(this.document.scrollLeft() - o.scrollSpeed);
13823				} else if(this.window.width() - (event.pageX - this.document.scrollLeft()) < o.scrollSensitivity) {
13824					scrolled = this.document.scrollLeft(this.document.scrollLeft() + o.scrollSpeed);
13825				}
13826
13827			}
13828
13829			if(scrolled !== false && $.ui.ddmanager && !o.dropBehaviour) {
13830				$.ui.ddmanager.prepareOffsets(this, event);
13831			}
13832		}
13833
13834		//Regenerate the absolute position used for position checks
13835		this.positionAbs = this._convertPositionTo("absolute");
13836
13837		//Set the helper position
13838		if(!this.options.axis || this.options.axis !== "y") {
13839			this.helper[0].style.left = this.position.left+"px";
13840		}
13841		if(!this.options.axis || this.options.axis !== "x") {
13842			this.helper[0].style.top = this.position.top+"px";
13843		}
13844
13845		//Rearrange
13846		for (i = this.items.length - 1; i >= 0; i--) {
13847
13848			//Cache variables and intersection, continue if no intersection
13849			item = this.items[i];
13850			itemElement = item.item[0];
13851			intersection = this._intersectsWithPointer(item);
13852			if (!intersection) {
13853				continue;
13854			}
13855
13856			// Only put the placeholder inside the current Container, skip all
13857			// items from other containers. This works because when moving
13858			// an item from one container to another the
13859			// currentContainer is switched before the placeholder is moved.
13860			//
13861			// Without this, moving items in "sub-sortables" can cause
13862			// the placeholder to jitter between the outer and inner container.
13863			if (item.instance !== this.currentContainer) {
13864				continue;
13865			}
13866
13867			// cannot intersect with itself
13868			// no useless actions that have been done before
13869			// no action if the item moved is the parent of the item checked
13870			if (itemElement !== this.currentItem[0] &&
13871				this.placeholder[intersection === 1 ? "next" : "prev"]()[0] !== itemElement &&
13872				!$.contains(this.placeholder[0], itemElement) &&
13873				(this.options.type === "semi-dynamic" ? !$.contains(this.element[0], itemElement) : true)
13874			) {
13875
13876				this.direction = intersection === 1 ? "down" : "up";
13877
13878				if (this.options.tolerance === "pointer" || this._intersectsWithSides(item)) {
13879					this._rearrange(event, item);
13880				} else {
13881					break;
13882				}
13883
13884				this._trigger("change", event, this._uiHash());
13885				break;
13886			}
13887		}
13888
13889		//Post events to containers
13890		this._contactContainers(event);
13891
13892		//Interconnect with droppables
13893		if($.ui.ddmanager) {
13894			$.ui.ddmanager.drag(this, event);
13895		}
13896
13897		//Call callbacks
13898		this._trigger("sort", event, this._uiHash());
13899
13900		this.lastPositionAbs = this.positionAbs;
13901		return false;
13902
13903	},
13904
13905	_mouseStop: function(event, noPropagation) {
13906
13907		if(!event) {
13908			return;
13909		}
13910
13911		//If we are using droppables, inform the manager about the drop
13912		if ($.ui.ddmanager && !this.options.dropBehaviour) {
13913			$.ui.ddmanager.drop(this, event);
13914		}
13915
13916		if(this.options.revert) {
13917			var that = this,
13918				cur = this.placeholder.offset(),
13919				axis = this.options.axis,
13920				animation = {};
13921
13922			if ( !axis || axis === "x" ) {
13923				animation.left = cur.left - this.offset.parent.left - this.margins.left + (this.offsetParent[0] === this.document[0].body ? 0 : this.offsetParent[0].scrollLeft);
13924			}
13925			if ( !axis || axis === "y" ) {
13926				animation.top = cur.top - this.offset.parent.top - this.margins.top + (this.offsetParent[0] === this.document[0].body ? 0 : this.offsetParent[0].scrollTop);
13927			}
13928			this.reverting = true;
13929			$(this.helper).animate( animation, parseInt(this.options.revert, 10) || 500, function() {
13930				that._clear(event);
13931			});
13932		} else {
13933			this._clear(event, noPropagation);
13934		}
13935
13936		return false;
13937
13938	},
13939
13940	cancel: function() {
13941
13942		if(this.dragging) {
13943
13944			this._mouseUp({ target: null });
13945
13946			if(this.options.helper === "original") {
13947				this.currentItem.css(this._storedCSS).removeClass("ui-sortable-helper");
13948			} else {
13949				this.currentItem.show();
13950			}
13951
13952			//Post deactivating events to containers
13953			for (var i = this.containers.length - 1; i >= 0; i--){
13954				this.containers[i]._trigger("deactivate", null, this._uiHash(this));
13955				if(this.containers[i].containerCache.over) {
13956					this.containers[i]._trigger("out", null, this._uiHash(this));
13957					this.containers[i].containerCache.over = 0;
13958				}
13959			}
13960
13961		}
13962
13963		if (this.placeholder) {
13964			//$(this.placeholder[0]).remove(); would have been the jQuery way - unfortunately, it unbinds ALL events from the original node!
13965			if(this.placeholder[0].parentNode) {
13966				this.placeholder[0].parentNode.removeChild(this.placeholder[0]);
13967			}
13968			if(this.options.helper !== "original" && this.helper && this.helper[0].parentNode) {
13969				this.helper.remove();
13970			}
13971
13972			$.extend(this, {
13973				helper: null,
13974				dragging: false,
13975				reverting: false,
13976				_noFinalSort: null
13977			});
13978
13979			if(this.domPosition.prev) {
13980				$(this.domPosition.prev).after(this.currentItem);
13981			} else {
13982				$(this.domPosition.parent).prepend(this.currentItem);
13983			}
13984		}
13985
13986		return this;
13987
13988	},
13989
13990	serialize: function(o) {
13991
13992		var items = this._getItemsAsjQuery(o && o.connected),
13993			str = [];
13994		o = o || {};
13995
13996		$(items).each(function() {
13997			var res = ($(o.item || this).attr(o.attribute || "id") || "").match(o.expression || (/(.+)[\-=_](.+)/));
13998			if (res) {
13999				str.push((o.key || res[1]+"[]")+"="+(o.key && o.expression ? res[1] : res[2]));
14000			}
14001		});
14002
14003		if(!str.length && o.key) {
14004			str.push(o.key + "=");
14005		}
14006
14007		return str.join("&");
14008
14009	},
14010
14011	toArray: function(o) {
14012
14013		var items = this._getItemsAsjQuery(o && o.connected),
14014			ret = [];
14015
14016		o = o || {};
14017
14018		items.each(function() { ret.push($(o.item || this).attr(o.attribute || "id") || ""); });
14019		return ret;
14020
14021	},
14022
14023	/* Be careful with the following core functions */
14024	_intersectsWith: function(item) {
14025
14026		var x1 = this.positionAbs.left,
14027			x2 = x1 + this.helperProportions.width,
14028			y1 = this.positionAbs.top,
14029			y2 = y1 + this.helperProportions.height,
14030			l = item.left,
14031			r = l + item.width,
14032			t = item.top,
14033			b = t + item.height,
14034			dyClick = this.offset.click.top,
14035			dxClick = this.offset.click.left,
14036			isOverElementHeight = ( this.options.axis === "x" ) || ( ( y1 + dyClick ) > t && ( y1 + dyClick ) < b ),
14037			isOverElementWidth = ( this.options.axis === "y" ) || ( ( x1 + dxClick ) > l && ( x1 + dxClick ) < r ),
14038			isOverElement = isOverElementHeight && isOverElementWidth;
14039
14040		if ( this.options.tolerance === "pointer" ||
14041			this.options.forcePointerForContainers ||
14042			(this.options.tolerance !== "pointer" && this.helperProportions[this.floating ? "width" : "height"] > item[this.floating ? "width" : "height"])
14043		) {
14044			return isOverElement;
14045		} else {
14046
14047			return (l < x1 + (this.helperProportions.width / 2) && // Right Half
14048				x2 - (this.helperProportions.width / 2) < r && // Left Half
14049				t < y1 + (this.helperProportions.height / 2) && // Bottom Half
14050				y2 - (this.helperProportions.height / 2) < b ); // Top Half
14051
14052		}
14053	},
14054
14055	_intersectsWithPointer: function(item) {
14056
14057		var isOverElementHeight = (this.options.axis === "x") || this._isOverAxis(this.positionAbs.top + this.offset.click.top, item.top, item.height),
14058			isOverElementWidth = (this.options.axis === "y") || this._isOverAxis(this.positionAbs.left + this.offset.click.left, item.left, item.width),
14059			isOverElement = isOverElementHeight && isOverElementWidth,
14060			verticalDirection = this._getDragVerticalDirection(),
14061			horizontalDirection = this._getDragHorizontalDirection();
14062
14063		if (!isOverElement) {
14064			return false;
14065		}
14066
14067		return this.floating ?
14068			( ((horizontalDirection && horizontalDirection === "right") || verticalDirection === "down") ? 2 : 1 )
14069			: ( verticalDirection && (verticalDirection === "down" ? 2 : 1) );
14070
14071	},
14072
14073	_intersectsWithSides: function(item) {
14074
14075		var isOverBottomHalf = this._isOverAxis(this.positionAbs.top + this.offset.click.top, item.top + (item.height/2), item.height),
14076			isOverRightHalf = this._isOverAxis(this.positionAbs.left + this.offset.click.left, item.left + (item.width/2), item.width),
14077			verticalDirection = this._getDragVerticalDirection(),
14078			horizontalDirection = this._getDragHorizontalDirection();
14079
14080		if (this.floating && horizontalDirection) {
14081			return ((horizontalDirection === "right" && isOverRightHalf) || (horizontalDirection === "left" && !isOverRightHalf));
14082		} else {
14083			return verticalDirection && ((verticalDirection === "down" && isOverBottomHalf) || (verticalDirection === "up" && !isOverBottomHalf));
14084		}
14085
14086	},
14087
14088	_getDragVerticalDirection: function() {
14089		var delta = this.positionAbs.top - this.lastPositionAbs.top;
14090		return delta !== 0 && (delta > 0 ? "down" : "up");
14091	},
14092
14093	_getDragHorizontalDirection: function() {
14094		var delta = this.positionAbs.left - this.lastPositionAbs.left;
14095		return delta !== 0 && (delta > 0 ? "right" : "left");
14096	},
14097
14098	refresh: function(event) {
14099		this._refreshItems(event);
14100		this._setHandleClassName();
14101		this.refreshPositions();
14102		return this;
14103	},
14104
14105	_connectWith: function() {
14106		var options = this.options;
14107		return options.connectWith.constructor === String ? [options.connectWith] : options.connectWith;
14108	},
14109
14110	_getItemsAsjQuery: function(connected) {
14111
14112		var i, j, cur, inst,
14113			items = [],
14114			queries = [],
14115			connectWith = this._connectWith();
14116
14117		if(connectWith && connected) {
14118			for (i = connectWith.length - 1; i >= 0; i--){
14119				cur = $(connectWith[i], this.document[0]);
14120				for ( j = cur.length - 1; j >= 0; j--){
14121					inst = $.data(cur[j], this.widgetFullName);
14122					if(inst && inst !== this && !inst.options.disabled) {
14123						queries.push([$.isFunction(inst.options.items) ? inst.options.items.call(inst.element) : $(inst.options.items, inst.element).not(".ui-sortable-helper").not(".ui-sortable-placeholder"), inst]);
14124					}
14125				}
14126			}
14127		}
14128
14129		queries.push([$.isFunction(this.options.items) ? this.options.items.call(this.element, null, { options: this.options, item: this.currentItem }) : $(this.options.items, this.element).not(".ui-sortable-helper").not(".ui-sortable-placeholder"), this]);
14130
14131		function addItems() {
14132			items.push( this );
14133		}
14134		for (i = queries.length - 1; i >= 0; i--){
14135			queries[i][0].each( addItems );
14136		}
14137
14138		return $(items);
14139
14140	},
14141
14142	_removeCurrentsFromItems: function() {
14143
14144		var list = this.currentItem.find(":data(" + this.widgetName + "-item)");
14145
14146		this.items = $.grep(this.items, function (item) {
14147			for (var j=0; j < list.length; j++) {
14148				if(list[j] === item.item[0]) {
14149					return false;
14150				}
14151			}
14152			return true;
14153		});
14154
14155	},
14156
14157	_refreshItems: function(event) {
14158
14159		this.items = [];
14160		this.containers = [this];
14161
14162		var i, j, cur, inst, targetData, _queries, item, queriesLength,
14163			items = this.items,
14164			queries = [[$.isFunction(this.options.items) ? this.options.items.call(this.element[0], event, { item: this.currentItem }) : $(this.options.items, this.element), this]],
14165			connectWith = this._connectWith();
14166
14167		if(connectWith && this.ready) { //Shouldn't be run the first time through due to massive slow-down
14168			for (i = connectWith.length - 1; i >= 0; i--){
14169				cur = $(connectWith[i], this.document[0]);
14170				for (j = cur.length - 1; j >= 0; j--){
14171					inst = $.data(cur[j], this.widgetFullName);
14172					if(inst && inst !== this && !inst.options.disabled) {
14173						queries.push([$.isFunction(inst.options.items) ? inst.options.items.call(inst.element[0], event, { item: this.currentItem }) : $(inst.options.items, inst.element), inst]);
14174						this.containers.push(inst);
14175					}
14176				}
14177			}
14178		}
14179
14180		for (i = queries.length - 1; i >= 0; i--) {
14181			targetData = queries[i][1];
14182			_queries = queries[i][0];
14183
14184			for (j=0, queriesLength = _queries.length; j < queriesLength; j++) {
14185				item = $(_queries[j]);
14186
14187				item.data(this.widgetName + "-item", targetData); // Data for target checking (mouse manager)
14188
14189				items.push({
14190					item: item,
14191					instance: targetData,
14192					width: 0, height: 0,
14193					left: 0, top: 0
14194				});
14195			}
14196		}
14197
14198	},
14199
14200	refreshPositions: function(fast) {
14201
14202		// Determine whether items are being displayed horizontally
14203		this.floating = this.items.length ?
14204			this.options.axis === "x" || this._isFloating( this.items[ 0 ].item ) :
14205			false;
14206
14207		//This has to be redone because due to the item being moved out/into the offsetParent, the offsetParent's position will change
14208		if(this.offsetParent && this.helper) {
14209			this.offset.parent = this._getParentOffset();
14210		}
14211
14212		var i, item, t, p;
14213
14214		for (i = this.items.length - 1; i >= 0; i--){
14215			item = this.items[i];
14216
14217			//We ignore calculating positions of all connected containers when we're not over them
14218			if(item.instance !== this.currentContainer && this.currentContainer && item.item[0] !== this.currentItem[0]) {
14219				continue;
14220			}
14221
14222			t = this.options.toleranceElement ? $(this.options.toleranceElement, item.item) : item.item;
14223
14224			if (!fast) {
14225				item.width = t.outerWidth();
14226				item.height = t.outerHeight();
14227			}
14228
14229			p = t.offset();
14230			item.left = p.left;
14231			item.top = p.top;
14232		}
14233
14234		if(this.options.custom && this.options.custom.refreshContainers) {
14235			this.options.custom.refreshContainers.call(this);
14236		} else {
14237			for (i = this.containers.length - 1; i >= 0; i--){
14238				p = this.containers[i].element.offset();
14239				this.containers[i].containerCache.left = p.left;
14240				this.containers[i].containerCache.top = p.top;
14241				this.containers[i].containerCache.width = this.containers[i].element.outerWidth();
14242				this.containers[i].containerCache.height = this.containers[i].element.outerHeight();
14243			}
14244		}
14245
14246		return this;
14247	},
14248
14249	_createPlaceholder: function(that) {
14250		that = that || this;
14251		var className,
14252			o = that.options;
14253
14254		if(!o.placeholder || o.placeholder.constructor === String) {
14255			className = o.placeholder;
14256			o.placeholder = {
14257				element: function() {
14258
14259					var nodeName = that.currentItem[0].nodeName.toLowerCase(),
14260						element = $( "<" + nodeName + ">", that.document[0] )
14261							.addClass(className || that.currentItem[0].className+" ui-sortable-placeholder")
14262							.removeClass("ui-sortable-helper");
14263
14264					if ( nodeName === "tbody" ) {
14265						that._createTrPlaceholder(
14266							that.currentItem.find( "tr" ).eq( 0 ),
14267							$( "<tr>", that.document[ 0 ] ).appendTo( element )
14268						);
14269					} else if ( nodeName === "tr" ) {
14270						that._createTrPlaceholder( that.currentItem, element );
14271					} else if ( nodeName === "img" ) {
14272						element.attr( "src", that.currentItem.attr( "src" ) );
14273					}
14274
14275					if ( !className ) {
14276						element.css( "visibility", "hidden" );
14277					}
14278
14279					return element;
14280				},
14281				update: function(container, p) {
14282
14283					// 1. If a className is set as 'placeholder option, we don't force sizes - the class is responsible for that
14284					// 2. The option 'forcePlaceholderSize can be enabled to force it even if a class name is specified
14285					if(className && !o.forcePlaceholderSize) {
14286						return;
14287					}
14288
14289					//If the element doesn't have a actual height by itself (without styles coming from a stylesheet), it receives the inline height from the dragged item
14290					if(!p.height()) { p.height(that.currentItem.innerHeight() - parseInt(that.currentItem.css("paddingTop")||0, 10) - parseInt(that.currentItem.css("paddingBottom")||0, 10)); }
14291					if(!p.width()) { p.width(that.currentItem.innerWidth() - parseInt(that.currentItem.css("paddingLeft")||0, 10) - parseInt(that.currentItem.css("paddingRight")||0, 10)); }
14292				}
14293			};
14294		}
14295
14296		//Create the placeholder
14297		that.placeholder = $(o.placeholder.element.call(that.element, that.currentItem));
14298
14299		//Append it after the actual current item
14300		that.currentItem.after(that.placeholder);
14301
14302		//Update the size of the placeholder (TODO: Logic to fuzzy, see line 316/317)
14303		o.placeholder.update(that, that.placeholder);
14304
14305	},
14306
14307	_createTrPlaceholder: function( sourceTr, targetTr ) {
14308		var that = this;
14309
14310		sourceTr.children().each(function() {
14311			$( "<td>&#160;</td>", that.document[ 0 ] )
14312				.attr( "colspan", $( this ).attr( "colspan" ) || 1 )
14313				.appendTo( targetTr );
14314		});
14315	},
14316
14317	_contactContainers: function(event) {
14318		var i, j, dist, itemWithLeastDistance, posProperty, sizeProperty, cur, nearBottom, floating, axis,
14319			innermostContainer = null,
14320			innermostIndex = null;
14321
14322		// get innermost container that intersects with item
14323		for (i = this.containers.length - 1; i >= 0; i--) {
14324
14325			// never consider a container that's located within the item itself
14326			if($.contains(this.currentItem[0], this.containers[i].element[0])) {
14327				continue;
14328			}
14329
14330			if(this._intersectsWith(this.containers[i].containerCache)) {
14331
14332				// if we've already found a container and it's more "inner" than this, then continue
14333				if(innermostContainer && $.contains(this.containers[i].element[0], innermostContainer.element[0])) {
14334					continue;
14335				}
14336
14337				innermostContainer = this.containers[i];
14338				innermostIndex = i;
14339
14340			} else {
14341				// container doesn't intersect. trigger "out" event if necessary
14342				if(this.containers[i].containerCache.over) {
14343					this.containers[i]._trigger("out", event, this._uiHash(this));
14344					this.containers[i].containerCache.over = 0;
14345				}
14346			}
14347
14348		}
14349
14350		// if no intersecting containers found, return
14351		if(!innermostContainer) {
14352			return;
14353		}
14354
14355		// move the item into the container if it's not there already
14356		if(this.containers.length === 1) {
14357			if (!this.containers[innermostIndex].containerCache.over) {
14358				this.containers[innermostIndex]._trigger("over", event, this._uiHash(this));
14359				this.containers[innermostIndex].containerCache.over = 1;
14360			}
14361		} else {
14362
14363			//When entering a new container, we will find the item with the least distance and append our item near it
14364			dist = 10000;
14365			itemWithLeastDistance = null;
14366			floating = innermostContainer.floating || this._isFloating(this.currentItem);
14367			posProperty = floating ? "left" : "top";
14368			sizeProperty = floating ? "width" : "height";
14369			axis = floating ? "clientX" : "clientY";
14370
14371			for (j = this.items.length - 1; j >= 0; j--) {
14372				if(!$.contains(this.containers[innermostIndex].element[0], this.items[j].item[0])) {
14373					continue;
14374				}
14375				if(this.items[j].item[0] === this.currentItem[0]) {
14376					continue;
14377				}
14378
14379				cur = this.items[j].item.offset()[posProperty];
14380				nearBottom = false;
14381				if ( event[ axis ] - cur > this.items[ j ][ sizeProperty ] / 2 ) {
14382					nearBottom = true;
14383				}
14384
14385				if ( Math.abs( event[ axis ] - cur ) < dist ) {
14386					dist = Math.abs( event[ axis ] - cur );
14387					itemWithLeastDistance = this.items[ j ];
14388					this.direction = nearBottom ? "up": "down";
14389				}
14390			}
14391
14392			//Check if dropOnEmpty is enabled
14393			if(!itemWithLeastDistance && !this.options.dropOnEmpty) {
14394				return;
14395			}
14396
14397			if(this.currentContainer === this.containers[innermostIndex]) {
14398				if ( !this.currentContainer.containerCache.over ) {
14399					this.containers[ innermostIndex ]._trigger( "over", event, this._uiHash() );
14400					this.currentContainer.containerCache.over = 1;
14401				}
14402				return;
14403			}
14404
14405			itemWithLeastDistance ? this._rearrange(event, itemWithLeastDistance, null, true) : this._rearrange(event, null, this.containers[innermostIndex].element, true);
14406			this._trigger("change", event, this._uiHash());
14407			this.containers[innermostIndex]._trigger("change", event, this._uiHash(this));
14408			this.currentContainer = this.containers[innermostIndex];
14409
14410			//Update the placeholder
14411			this.options.placeholder.update(this.currentContainer, this.placeholder);
14412
14413			this.containers[innermostIndex]._trigger("over", event, this._uiHash(this));
14414			this.containers[innermostIndex].containerCache.over = 1;
14415		}
14416
14417
14418	},
14419
14420	_createHelper: function(event) {
14421
14422		var o = this.options,
14423			helper = $.isFunction(o.helper) ? $(o.helper.apply(this.element[0], [event, this.currentItem])) : (o.helper === "clone" ? this.currentItem.clone() : this.currentItem);
14424
14425		//Add the helper to the DOM if that didn't happen already
14426		if(!helper.parents("body").length) {
14427			$(o.appendTo !== "parent" ? o.appendTo : this.currentItem[0].parentNode)[0].appendChild(helper[0]);
14428		}
14429
14430		if(helper[0] === this.currentItem[0]) {
14431			this._storedCSS = { width: this.currentItem[0].style.width, height: this.currentItem[0].style.height, position: this.currentItem.css("position"), top: this.currentItem.css("top"), left: this.currentItem.css("left") };
14432		}
14433
14434		if(!helper[0].style.width || o.forceHelperSize) {
14435			helper.width(this.currentItem.width());
14436		}
14437		if(!helper[0].style.height || o.forceHelperSize) {
14438			helper.height(this.currentItem.height());
14439		}
14440
14441		return helper;
14442
14443	},
14444
14445	_adjustOffsetFromHelper: function(obj) {
14446		if (typeof obj === "string") {
14447			obj = obj.split(" ");
14448		}
14449		if ($.isArray(obj)) {
14450			obj = {left: +obj[0], top: +obj[1] || 0};
14451		}
14452		if ("left" in obj) {
14453			this.offset.click.left = obj.left + this.margins.left;
14454		}
14455		if ("right" in obj) {
14456			this.offset.click.left = this.helperProportions.width - obj.right + this.margins.left;
14457		}
14458		if ("top" in obj) {
14459			this.offset.click.top = obj.top + this.margins.top;
14460		}
14461		if ("bottom" in obj) {
14462			this.offset.click.top = this.helperProportions.height - obj.bottom + this.margins.top;
14463		}
14464	},
14465
14466	_getParentOffset: function() {
14467
14468
14469		//Get the offsetParent and cache its position
14470		this.offsetParent = this.helper.offsetParent();
14471		var po = this.offsetParent.offset();
14472
14473		// This is a special case where we need to modify a offset calculated on start, since the following happened:
14474		// 1. The position of the helper is absolute, so it's position is calculated based on the next positioned parent
14475		// 2. The actual offset parent is a child of the scroll parent, and the scroll parent isn't the document, which means that
14476		//    the scroll is included in the initial calculation of the offset of the parent, and never recalculated upon drag
14477		if(this.cssPosition === "absolute" && this.scrollParent[0] !== this.document[0] && $.contains(this.scrollParent[0], this.offsetParent[0])) {
14478			po.left += this.scrollParent.scrollLeft();
14479			po.top += this.scrollParent.scrollTop();
14480		}
14481
14482		// This needs to be actually done for all browsers, since pageX/pageY includes this information
14483		// with an ugly IE fix
14484		if( this.offsetParent[0] === this.document[0].body || (this.offsetParent[0].tagName && this.offsetParent[0].tagName.toLowerCase() === "html" && $.ui.ie)) {
14485			po = { top: 0, left: 0 };
14486		}
14487
14488		return {
14489			top: po.top + (parseInt(this.offsetParent.css("borderTopWidth"),10) || 0),
14490			left: po.left + (parseInt(this.offsetParent.css("borderLeftWidth"),10) || 0)
14491		};
14492
14493	},
14494
14495	_getRelativeOffset: function() {
14496
14497		if(this.cssPosition === "relative") {
14498			var p = this.currentItem.position();
14499			return {
14500				top: p.top - (parseInt(this.helper.css("top"),10) || 0) + this.scrollParent.scrollTop(),
14501				left: p.left - (parseInt(this.helper.css("left"),10) || 0) + this.scrollParent.scrollLeft()
14502			};
14503		} else {
14504			return { top: 0, left: 0 };
14505		}
14506
14507	},
14508
14509	_cacheMargins: function() {
14510		this.margins = {
14511			left: (parseInt(this.currentItem.css("marginLeft"),10) || 0),
14512			top: (parseInt(this.currentItem.css("marginTop"),10) || 0)
14513		};
14514	},
14515
14516	_cacheHelperProportions: function() {
14517		this.helperProportions = {
14518			width: this.helper.outerWidth(),
14519			height: this.helper.outerHeight()
14520		};
14521	},
14522
14523	_setContainment: function() {
14524
14525		var ce, co, over,
14526			o = this.options;
14527		if(o.containment === "parent") {
14528			o.containment = this.helper[0].parentNode;
14529		}
14530		if(o.containment === "document" || o.containment === "window") {
14531			this.containment = [
14532				0 - this.offset.relative.left - this.offset.parent.left,
14533				0 - this.offset.relative.top - this.offset.parent.top,
14534				o.containment === "document" ? this.document.width() : this.window.width() - this.helperProportions.width - this.margins.left,
14535				(o.containment === "document" ? this.document.width() : this.window.height() || this.document[0].body.parentNode.scrollHeight) - this.helperProportions.height - this.margins.top
14536			];
14537		}
14538
14539		if(!(/^(document|window|parent)$/).test(o.containment)) {
14540			ce = $(o.containment)[0];
14541			co = $(o.containment).offset();
14542			over = ($(ce).css("overflow") !== "hidden");
14543
14544			this.containment = [
14545				co.left + (parseInt($(ce).css("borderLeftWidth"),10) || 0) + (parseInt($(ce).css("paddingLeft"),10) || 0) - this.margins.left,
14546				co.top + (parseInt($(ce).css("borderTopWidth"),10) || 0) + (parseInt($(ce).css("paddingTop"),10) || 0) - this.margins.top,
14547				co.left+(over ? Math.max(ce.scrollWidth,ce.offsetWidth) : ce.offsetWidth) - (parseInt($(ce).css("borderLeftWidth"),10) || 0) - (parseInt($(ce).css("paddingRight"),10) || 0) - this.helperProportions.width - this.margins.left,
14548				co.top+(over ? Math.max(ce.scrollHeight,ce.offsetHeight) : ce.offsetHeight) - (parseInt($(ce).css("borderTopWidth"),10) || 0) - (parseInt($(ce).css("paddingBottom"),10) || 0) - this.helperProportions.height - this.margins.top
14549			];
14550		}
14551
14552	},
14553
14554	_convertPositionTo: function(d, pos) {
14555
14556		if(!pos) {
14557			pos = this.position;
14558		}
14559		var mod = d === "absolute" ? 1 : -1,
14560			scroll = this.cssPosition === "absolute" && !(this.scrollParent[0] !== this.document[0] && $.contains(this.scrollParent[0], this.offsetParent[0])) ? this.offsetParent : this.scrollParent,
14561			scrollIsRootNode = (/(html|body)/i).test(scroll[0].tagName);
14562
14563		return {
14564			top: (
14565				pos.top	+																// The absolute mouse position
14566				this.offset.relative.top * mod +										// Only for relative positioned nodes: Relative offset from element to offset parent
14567				this.offset.parent.top * mod -											// The offsetParent's offset without borders (offset + border)
14568				( ( this.cssPosition === "fixed" ? -this.scrollParent.scrollTop() : ( scrollIsRootNode ? 0 : scroll.scrollTop() ) ) * mod)
14569			),
14570			left: (
14571				pos.left +																// The absolute mouse position
14572				this.offset.relative.left * mod +										// Only for relative positioned nodes: Relative offset from element to offset parent
14573				this.offset.parent.left * mod	-										// The offsetParent's offset without borders (offset + border)
14574				( ( this.cssPosition === "fixed" ? -this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 : scroll.scrollLeft() ) * mod)
14575			)
14576		};
14577
14578	},
14579
14580	_generatePosition: function(event) {
14581
14582		var top, left,
14583			o = this.options,
14584			pageX = event.pageX,
14585			pageY = event.pageY,
14586			scroll = this.cssPosition === "absolute" && !(this.scrollParent[0] !== this.document[0] && $.contains(this.scrollParent[0], this.offsetParent[0])) ? this.offsetParent : this.scrollParent, scrollIsRootNode = (/(html|body)/i).test(scroll[0].tagName);
14587
14588		// This is another very weird special case that only happens for relative elements:
14589		// 1. If the css position is relative
14590		// 2. and the scroll parent is the document or similar to the offset parent
14591		// we have to refresh the relative offset during the scroll so there are no jumps
14592		if(this.cssPosition === "relative" && !(this.scrollParent[0] !== this.document[0] && this.scrollParent[0] !== this.offsetParent[0])) {
14593			this.offset.relative = this._getRelativeOffset();
14594		}
14595
14596		/*
14597		 * - Position constraining -
14598		 * Constrain the position to a mix of grid, containment.
14599		 */
14600
14601		if(this.originalPosition) { //If we are not dragging yet, we won't check for options
14602
14603			if(this.containment) {
14604				if(event.pageX - this.offset.click.left < this.containment[0]) {
14605					pageX = this.containment[0] + this.offset.click.left;
14606				}
14607				if(event.pageY - this.offset.click.top < this.containment[1]) {
14608					pageY = this.containment[1] + this.offset.click.top;
14609				}
14610				if(event.pageX - this.offset.click.left > this.containment[2]) {
14611					pageX = this.containment[2] + this.offset.click.left;
14612				}
14613				if(event.pageY - this.offset.click.top > this.containment[3]) {
14614					pageY = this.containment[3] + this.offset.click.top;
14615				}
14616			}
14617
14618			if(o.grid) {
14619				top = this.originalPageY + Math.round((pageY - this.originalPageY) / o.grid[1]) * o.grid[1];
14620				pageY = this.containment ? ( (top - this.offset.click.top >= this.containment[1] && top - this.offset.click.top <= this.containment[3]) ? top : ((top - this.offset.click.top >= this.containment[1]) ? top - o.grid[1] : top + o.grid[1])) : top;
14621
14622				left = this.originalPageX + Math.round((pageX - this.originalPageX) / o.grid[0]) * o.grid[0];
14623				pageX = this.containment ? ( (left - this.offset.click.left >= this.containment[0] && left - this.offset.click.left <= this.containment[2]) ? left : ((left - this.offset.click.left >= this.containment[0]) ? left - o.grid[0] : left + o.grid[0])) : left;
14624			}
14625
14626		}
14627
14628		return {
14629			top: (
14630				pageY -																// The absolute mouse position
14631				this.offset.click.top -													// Click offset (relative to the element)
14632				this.offset.relative.top	-											// Only for relative positioned nodes: Relative offset from element to offset parent
14633				this.offset.parent.top +												// The offsetParent's offset without borders (offset + border)
14634				( ( this.cssPosition === "fixed" ? -this.scrollParent.scrollTop() : ( scrollIsRootNode ? 0 : scroll.scrollTop() ) ))
14635			),
14636			left: (
14637				pageX -																// The absolute mouse position
14638				this.offset.click.left -												// Click offset (relative to the element)
14639				this.offset.relative.left	-											// Only for relative positioned nodes: Relative offset from element to offset parent
14640				this.offset.parent.left +												// The offsetParent's offset without borders (offset + border)
14641				( ( this.cssPosition === "fixed" ? -this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 : scroll.scrollLeft() ))
14642			)
14643		};
14644
14645	},
14646
14647	_rearrange: function(event, i, a, hardRefresh) {
14648
14649		a ? a[0].appendChild(this.placeholder[0]) : i.item[0].parentNode.insertBefore(this.placeholder[0], (this.direction === "down" ? i.item[0] : i.item[0].nextSibling));
14650
14651		//Various things done here to improve the performance:
14652		// 1. we create a setTimeout, that calls refreshPositions
14653		// 2. on the instance, we have a counter variable, that get's higher after every append
14654		// 3. on the local scope, we copy the counter variable, and check in the timeout, if it's still the same
14655		// 4. this lets only the last addition to the timeout stack through
14656		this.counter = this.counter ? ++this.counter : 1;
14657		var counter = this.counter;
14658
14659		this._delay(function() {
14660			if(counter === this.counter) {
14661				this.refreshPositions(!hardRefresh); //Precompute after each DOM insertion, NOT on mousemove
14662			}
14663		});
14664
14665	},
14666
14667	_clear: function(event, noPropagation) {
14668
14669		this.reverting = false;
14670		// We delay all events that have to be triggered to after the point where the placeholder has been removed and
14671		// everything else normalized again
14672		var i,
14673			delayedTriggers = [];
14674
14675		// We first have to update the dom position of the actual currentItem
14676		// Note: don't do it if the current item is already removed (by a user), or it gets reappended (see #4088)
14677		if(!this._noFinalSort && this.currentItem.parent().length) {
14678			this.placeholder.before(this.currentItem);
14679		}
14680		this._noFinalSort = null;
14681
14682		if(this.helper[0] === this.currentItem[0]) {
14683			for(i in this._storedCSS) {
14684				if(this._storedCSS[i] === "auto" || this._storedCSS[i] === "static") {
14685					this._storedCSS[i] = "";
14686				}
14687			}
14688			this.currentItem.css(this._storedCSS).removeClass("ui-sortable-helper");
14689		} else {
14690			this.currentItem.show();
14691		}
14692
14693		if(this.fromOutside && !noPropagation) {
14694			delayedTriggers.push(function(event) { this._trigger("receive", event, this._uiHash(this.fromOutside)); });
14695		}
14696		if((this.fromOutside || this.domPosition.prev !== this.currentItem.prev().not(".ui-sortable-helper")[0] || this.domPosition.parent !== this.currentItem.parent()[0]) && !noPropagation) {
14697			delayedTriggers.push(function(event) { this._trigger("update", event, this._uiHash()); }); //Trigger update callback if the DOM position has changed
14698		}
14699
14700		// Check if the items Container has Changed and trigger appropriate
14701		// events.
14702		if (this !== this.currentContainer) {
14703			if(!noPropagation) {
14704				delayedTriggers.push(function(event) { this._trigger("remove", event, this._uiHash()); });
14705				delayedTriggers.push((function(c) { return function(event) { c._trigger("receive", event, this._uiHash(this)); };  }).call(this, this.currentContainer));
14706				delayedTriggers.push((function(c) { return function(event) { c._trigger("update", event, this._uiHash(this));  }; }).call(this, this.currentContainer));
14707			}
14708		}
14709
14710
14711		//Post events to containers
14712		function delayEvent( type, instance, container ) {
14713			return function( event ) {
14714				container._trigger( type, event, instance._uiHash( instance ) );
14715			};
14716		}
14717		for (i = this.containers.length - 1; i >= 0; i--){
14718			if (!noPropagation) {
14719				delayedTriggers.push( delayEvent( "deactivate", this, this.containers[ i ] ) );
14720			}
14721			if(this.containers[i].containerCache.over) {
14722				delayedTriggers.push( delayEvent( "out", this, this.containers[ i ] ) );
14723				this.containers[i].containerCache.over = 0;
14724			}
14725		}
14726
14727		//Do what was originally in plugins
14728		if ( this.storedCursor ) {
14729			this.document.find( "body" ).css( "cursor", this.storedCursor );
14730			this.storedStylesheet.remove();
14731		}
14732		if(this._storedOpacity) {
14733			this.helper.css("opacity", this._storedOpacity);
14734		}
14735		if(this._storedZIndex) {
14736			this.helper.css("zIndex", this._storedZIndex === "auto" ? "" : this._storedZIndex);
14737		}
14738
14739		this.dragging = false;
14740
14741		if(!noPropagation) {
14742			this._trigger("beforeStop", event, this._uiHash());
14743		}
14744
14745		//$(this.placeholder[0]).remove(); would have been the jQuery way - unfortunately, it unbinds ALL events from the original node!
14746		this.placeholder[0].parentNode.removeChild(this.placeholder[0]);
14747
14748		if ( !this.cancelHelperRemoval ) {
14749			if ( this.helper[ 0 ] !== this.currentItem[ 0 ] ) {
14750				this.helper.remove();
14751			}
14752			this.helper = null;
14753		}
14754
14755		if(!noPropagation) {
14756			for (i=0; i < delayedTriggers.length; i++) {
14757				delayedTriggers[i].call(this, event);
14758			} //Trigger all delayed events
14759			this._trigger("stop", event, this._uiHash());
14760		}
14761
14762		this.fromOutside = false;
14763		return !this.cancelHelperRemoval;
14764
14765	},
14766
14767	_trigger: function() {
14768		if ($.Widget.prototype._trigger.apply(this, arguments) === false) {
14769			this.cancel();
14770		}
14771	},
14772
14773	_uiHash: function(_inst) {
14774		var inst = _inst || this;
14775		return {
14776			helper: inst.helper,
14777			placeholder: inst.placeholder || $([]),
14778			position: inst.position,
14779			originalPosition: inst.originalPosition,
14780			offset: inst.positionAbs,
14781			item: inst.currentItem,
14782			sender: _inst ? _inst.element : null
14783		};
14784	}
14785
14786});
14787
14788
14789/*!
14790 * jQuery UI Spinner 1.11.4
14791 * http://jqueryui.com
14792 *
14793 * Copyright jQuery Foundation and other contributors
14794 * Released under the MIT license.
14795 * http://jquery.org/license
14796 *
14797 * http://api.jqueryui.com/spinner/
14798 */
14799
14800
14801function spinner_modifier( fn ) {
14802	return function() {
14803		var previous = this.element.val();
14804		fn.apply( this, arguments );
14805		this._refresh();
14806		if ( previous !== this.element.val() ) {
14807			this._trigger( "change" );
14808		}
14809	};
14810}
14811
14812var spinner = $.widget( "ui.spinner", {
14813	version: "1.11.4",
14814	defaultElement: "<input>",
14815	widgetEventPrefix: "spin",
14816	options: {
14817		culture: null,
14818		icons: {
14819			down: "ui-icon-triangle-1-s",
14820			up: "ui-icon-triangle-1-n"
14821		},
14822		incremental: true,
14823		max: null,
14824		min: null,
14825		numberFormat: null,
14826		page: 10,
14827		step: 1,
14828
14829		change: null,
14830		spin: null,
14831		start: null,
14832		stop: null
14833	},
14834
14835	_create: function() {
14836		// handle string values that need to be parsed
14837		this._setOption( "max", this.options.max );
14838		this._setOption( "min", this.options.min );
14839		this._setOption( "step", this.options.step );
14840
14841		// Only format if there is a value, prevents the field from being marked
14842		// as invalid in Firefox, see #9573.
14843		if ( this.value() !== "" ) {
14844			// Format the value, but don't constrain.
14845			this._value( this.element.val(), true );
14846		}
14847
14848		this._draw();
14849		this._on( this._events );
14850		this._refresh();
14851
14852		// turning off autocomplete prevents the browser from remembering the
14853		// value when navigating through history, so we re-enable autocomplete
14854		// if the page is unloaded before the widget is destroyed. #7790
14855		this._on( this.window, {
14856			beforeunload: function() {
14857				this.element.removeAttr( "autocomplete" );
14858			}
14859		});
14860	},
14861
14862	_getCreateOptions: function() {
14863		var options = {},
14864			element = this.element;
14865
14866		$.each( [ "min", "max", "step" ], function( i, option ) {
14867			var value = element.attr( option );
14868			if ( value !== undefined && value.length ) {
14869				options[ option ] = value;
14870			}
14871		});
14872
14873		return options;
14874	},
14875
14876	_events: {
14877		keydown: function( event ) {
14878			if ( this._start( event ) && this._keydown( event ) ) {
14879				event.preventDefault();
14880			}
14881		},
14882		keyup: "_stop",
14883		focus: function() {
14884			this.previous = this.element.val();
14885		},
14886		blur: function( event ) {
14887			if ( this.cancelBlur ) {
14888				delete this.cancelBlur;
14889				return;
14890			}
14891
14892			this._stop();
14893			this._refresh();
14894			if ( this.previous !== this.element.val() ) {
14895				this._trigger( "change", event );
14896			}
14897		},
14898		mousewheel: function( event, delta ) {
14899			if ( !delta ) {
14900				return;
14901			}
14902			if ( !this.spinning && !this._start( event ) ) {
14903				return false;
14904			}
14905
14906			this._spin( (delta > 0 ? 1 : -1) * this.options.step, event );
14907			clearTimeout( this.mousewheelTimer );
14908			this.mousewheelTimer = this._delay(function() {
14909				if ( this.spinning ) {
14910					this._stop( event );
14911				}
14912			}, 100 );
14913			event.preventDefault();
14914		},
14915		"mousedown .ui-spinner-button": function( event ) {
14916			var previous;
14917
14918			// We never want the buttons to have focus; whenever the user is
14919			// interacting with the spinner, the focus should be on the input.
14920			// If the input is focused then this.previous is properly set from
14921			// when the input first received focus. If the input is not focused
14922			// then we need to set this.previous based on the value before spinning.
14923			previous = this.element[0] === this.document[0].activeElement ?
14924				this.previous : this.element.val();
14925			function checkFocus() {
14926				var isActive = this.element[0] === this.document[0].activeElement;
14927				if ( !isActive ) {
14928					this.element.focus();
14929					this.previous = previous;
14930					// support: IE
14931					// IE sets focus asynchronously, so we need to check if focus
14932					// moved off of the input because the user clicked on the button.
14933					this._delay(function() {
14934						this.previous = previous;
14935					});
14936				}
14937			}
14938
14939			// ensure focus is on (or stays on) the text field
14940			event.preventDefault();
vendor: 5,275 bytes, lines 14941-15142
14941			checkFocus.call( this );
14942
14943			// support: IE
14944			// IE doesn't prevent moving focus even with event.preventDefault()
14945			// so we set a flag to know when we should ignore the blur event
14946			// and check (again) if focus moved off of the input.
14947			this.cancelBlur = true;
14948			this._delay(function() {
14949				delete this.cancelBlur;
14950				checkFocus.call( this );
14951			});
14952
14953			if ( this._start( event ) === false ) {
14954				return;
14955			}
14956
14957			this._repeat( null, $( event.currentTarget ).hasClass( "ui-spinner-up" ) ? 1 : -1, event );
14958		},
14959		"mouseup .ui-spinner-button": "_stop",
14960		"mouseenter .ui-spinner-button": function( event ) {
14961			// button will add ui-state-active if mouse was down while mouseleave and kept down
14962			if ( !$( event.currentTarget ).hasClass( "ui-state-active" ) ) {
14963				return;
14964			}
14965
14966			if ( this._start( event ) === false ) {
14967				return false;
14968			}
14969			this._repeat( null, $( event.currentTarget ).hasClass( "ui-spinner-up" ) ? 1 : -1, event );
14970		},
14971		// TODO: do we really want to consider this a stop?
14972		// shouldn't we just stop the repeater and wait until mouseup before
14973		// we trigger the stop event?
14974		"mouseleave .ui-spinner-button": "_stop"
14975	},
14976
14977	_draw: function() {
14978		var uiSpinner = this.uiSpinner = this.element
14979			.addClass( "ui-spinner-input" )
14980			.attr( "autocomplete", "off" )
14981			.wrap( this._uiSpinnerHtml() )
14982			.parent()
14983				// add buttons
14984				.append( this._buttonHtml() );
14985
14986		this.element.attr( "role", "spinbutton" );
14987
14988		// button bindings
14989		this.buttons = uiSpinner.find( ".ui-spinner-button" )
14990			.attr( "tabIndex", -1 )
14991			.button()
14992			.removeClass( "ui-corner-all" );
14993
14994		// IE 6 doesn't understand height: 50% for the buttons
14995		// unless the wrapper has an explicit height
14996		if ( this.buttons.height() > Math.ceil( uiSpinner.height() * 0.5 ) &&
14997				uiSpinner.height() > 0 ) {
14998			uiSpinner.height( uiSpinner.height() );
14999		}
15000
15001		// disable spinner if element was already disabled
15002		if ( this.options.disabled ) {
15003			this.disable();
15004		}
15005	},
15006
15007	_keydown: function( event ) {
15008		var options = this.options,
15009			keyCode = $.ui.keyCode;
15010
15011		switch ( event.keyCode ) {
15012		case keyCode.UP:
15013			this._repeat( null, 1, event );
15014			return true;
15015		case keyCode.DOWN:
15016			this._repeat( null, -1, event );
15017			return true;
15018		case keyCode.PAGE_UP:
15019			this._repeat( null, options.page, event );
15020			return true;
15021		case keyCode.PAGE_DOWN:
15022			this._repeat( null, -options.page, event );
15023			return true;
15024		}
15025
15026		return false;
15027	},
15028
15029	_uiSpinnerHtml: function() {
15030		return "<span class='ui-spinner ui-widget ui-widget-content ui-corner-all'></span>";
15031	},
15032
15033	_buttonHtml: function() {
15034		return "" +
15035			"<a class='ui-spinner-button ui-spinner-up ui-corner-tr'>" +
15036				"<span class='ui-icon " + this.options.icons.up + "'>&#9650;</span>" +
15037			"</a>" +
15038			"<a class='ui-spinner-button ui-spinner-down ui-corner-br'>" +
15039				"<span class='ui-icon " + this.options.icons.down + "'>&#9660;</span>" +
15040			"</a>";
15041	},
15042
15043	_start: function( event ) {
15044		if ( !this.spinning && this._trigger( "start", event ) === false ) {
15045			return false;
15046		}
15047
15048		if ( !this.counter ) {
15049			this.counter = 1;
15050		}
15051		this.spinning = true;
15052		return true;
15053	},
15054
15055	_repeat: function( i, steps, event ) {
15056		i = i || 500;
15057
15058		clearTimeout( this.timer );
15059		this.timer = this._delay(function() {
15060			this._repeat( 40, steps, event );
15061		}, i );
15062
15063		this._spin( steps * this.options.step, event );
15064	},
15065
15066	_spin: function( step, event ) {
15067		var value = this.value() || 0;
15068
15069		if ( !this.counter ) {
15070			this.counter = 1;
15071		}
15072
15073		value = this._adjustValue( value + step * this._increment( this.counter ) );
15074
15075		if ( !this.spinning || this._trigger( "spin", event, { value: value } ) !== false) {
15076			this._value( value );
15077			this.counter++;
15078		}
15079	},
15080
15081	_increment: function( i ) {
15082		var incremental = this.options.incremental;
15083
15084		if ( incremental ) {
15085			return $.isFunction( incremental ) ?
15086				incremental( i ) :
15087				Math.floor( i * i * i / 50000 - i * i / 500 + 17 * i / 200 + 1 );
15088		}
15089
15090		return 1;
15091	},
15092
15093	_precision: function() {
15094		var precision = this._precisionOf( this.options.step );
15095		if ( this.options.min !== null ) {
15096			precision = Math.max( precision, this._precisionOf( this.options.min ) );
15097		}
15098		return precision;
15099	},
15100
15101	_precisionOf: function( num ) {
15102		var str = num.toString(),
15103			decimal = str.indexOf( "." );
15104		return decimal === -1 ? 0 : str.length - decimal - 1;
15105	},
15106
15107	_adjustValue: function( value ) {
15108		var base, aboveMin,
15109			options = this.options;
15110
15111		// make sure we're at a valid step
15112		// - find out where we are relative to the base (min or 0)
15113		base = options.min !== null ? options.min : 0;
15114		aboveMin = value - base;
15115		// - round to the nearest step
15116		aboveMin = Math.round(aboveMin / options.step) * options.step;
15117		// - rounding is based on 0, so adjust back to our base
15118		value = base + aboveMin;
15119
15120		// fix precision from bad JS floating point math
15121		value = parseFloat( value.toFixed( this._precision() ) );
15122
15123		// clamp the value
15124		if ( options.max !== null && value > options.max) {
15125			return options.max;
15126		}
15127		if ( options.min !== null && value < options.min ) {
15128			return options.min;
15129		}
15130
15131		return value;
15132	},
15133
15134	_stop: function( event ) {
15135		if ( !this.spinning ) {
15136			return;
15137		}
15138
15139		clearTimeout( this.timer );
15140		clearTimeout( this.mousewheelTimer );
15141		this.counter = 0;
15142		this.spinning = false;
vendor: 16,063 bytes, lines 15143-15760
15143		this._trigger( "stop", event );
15144	},
15145
15146	_setOption: function( key, value ) {
15147		if ( key === "culture" || key === "numberFormat" ) {
15148			var prevValue = this._parse( this.element.val() );
15149			this.options[ key ] = value;
15150			this.element.val( this._format( prevValue ) );
15151			return;
15152		}
15153
15154		if ( key === "max" || key === "min" || key === "step" ) {
15155			if ( typeof value === "string" ) {
15156				value = this._parse( value );
15157			}
15158		}
15159		if ( key === "icons" ) {
15160			this.buttons.first().find( ".ui-icon" )
15161				.removeClass( this.options.icons.up )
15162				.addClass( value.up );
15163			this.buttons.last().find( ".ui-icon" )
15164				.removeClass( this.options.icons.down )
15165				.addClass( value.down );
15166		}
15167
15168		this._super( key, value );
15169
15170		if ( key === "disabled" ) {
15171			this.widget().toggleClass( "ui-state-disabled", !!value );
15172			this.element.prop( "disabled", !!value );
15173			this.buttons.button( value ? "disable" : "enable" );
15174		}
15175	},
15176
15177	_setOptions: spinner_modifier(function( options ) {
15178		this._super( options );
15179	}),
15180
15181	_parse: function( val ) {
15182		if ( typeof val === "string" && val !== "" ) {
15183			val = window.Globalize && this.options.numberFormat ?
15184				Globalize.parseFloat( val, 10, this.options.culture ) : +val;
15185		}
15186		return val === "" || isNaN( val ) ? null : val;
15187	},
15188
15189	_format: function( value ) {
15190		if ( value === "" ) {
15191			return "";
15192		}
15193		return window.Globalize && this.options.numberFormat ?
15194			Globalize.format( value, this.options.numberFormat, this.options.culture ) :
15195			value;
15196	},
15197
15198	_refresh: function() {
15199		this.element.attr({
15200			"aria-valuemin": this.options.min,
15201			"aria-valuemax": this.options.max,
15202			// TODO: what should we do with values that can't be parsed?
15203			"aria-valuenow": this._parse( this.element.val() )
15204		});
15205	},
15206
15207	isValid: function() {
15208		var value = this.value();
15209
15210		// null is invalid
15211		if ( value === null ) {
15212			return false;
15213		}
15214
15215		// if value gets adjusted, it's invalid
15216		return value === this._adjustValue( value );
15217	},
15218
15219	// update the value without triggering change
15220	_value: function( value, allowAny ) {
15221		var parsed;
15222		if ( value !== "" ) {
15223			parsed = this._parse( value );
15224			if ( parsed !== null ) {
15225				if ( !allowAny ) {
15226					parsed = this._adjustValue( parsed );
15227				}
15228				value = this._format( parsed );
15229			}
15230		}
15231		this.element.val( value );
15232		this._refresh();
15233	},
15234
15235	_destroy: function() {
15236		this.element
15237			.removeClass( "ui-spinner-input" )
15238			.prop( "disabled", false )
15239			.removeAttr( "autocomplete" )
15240			.removeAttr( "role" )
15241			.removeAttr( "aria-valuemin" )
15242			.removeAttr( "aria-valuemax" )
15243			.removeAttr( "aria-valuenow" );
15244		this.uiSpinner.replaceWith( this.element );
15245	},
15246
15247	stepUp: spinner_modifier(function( steps ) {
15248		this._stepUp( steps );
15249	}),
15250	_stepUp: function( steps ) {
15251		if ( this._start() ) {
15252			this._spin( (steps || 1) * this.options.step );
15253			this._stop();
15254		}
15255	},
15256
15257	stepDown: spinner_modifier(function( steps ) {
15258		this._stepDown( steps );
15259	}),
15260	_stepDown: function( steps ) {
15261		if ( this._start() ) {
15262			this._spin( (steps || 1) * -this.options.step );
15263			this._stop();
15264		}
15265	},
15266
15267	pageUp: spinner_modifier(function( pages ) {
15268		this._stepUp( (pages || 1) * this.options.page );
15269	}),
15270
15271	pageDown: spinner_modifier(function( pages ) {
15272		this._stepDown( (pages || 1) * this.options.page );
15273	}),
15274
15275	value: function( newVal ) {
15276		if ( !arguments.length ) {
15277			return this._parse( this.element.val() );
15278		}
15279		spinner_modifier( this._value ).call( this, newVal );
15280	},
15281
15282	widget: function() {
15283		return this.uiSpinner;
15284	}
15285});
15286
15287
15288/*!
15289 * jQuery UI Tabs 1.11.4
15290 * http://jqueryui.com
15291 *
15292 * Copyright jQuery Foundation and other contributors
15293 * Released under the MIT license.
15294 * http://jquery.org/license
15295 *
15296 * http://api.jqueryui.com/tabs/
15297 */
15298
15299
15300var tabs = $.widget( "ui.tabs", {
15301	version: "1.11.4",
15302	delay: 300,
15303	options: {
15304		active: null,
15305		collapsible: false,
15306		event: "click",
15307		heightStyle: "content",
15308		hide: null,
15309		show: null,
15310
15311		// callbacks
15312		activate: null,
15313		beforeActivate: null,
15314		beforeLoad: null,
15315		load: null
15316	},
15317
15318	_isLocal: (function() {
15319		var rhash = /#.*$/;
15320
15321		return function( anchor ) {
15322			var anchorUrl, locationUrl;
15323
15324			// support: IE7
15325			// IE7 doesn't normalize the href property when set via script (#9317)
15326			anchor = anchor.cloneNode( false );
15327
15328			anchorUrl = anchor.href.replace( rhash, "" );
15329			locationUrl = location.href.replace( rhash, "" );
15330
15331			// decoding may throw an error if the URL isn't UTF-8 (#9518)
15332			try {
15333				anchorUrl = decodeURIComponent( anchorUrl );
15334			} catch ( error ) {}
15335			try {
15336				locationUrl = decodeURIComponent( locationUrl );
15337			} catch ( error ) {}
15338
15339			return anchor.hash.length > 1 && anchorUrl === locationUrl;
15340		};
15341	})(),
15342
15343	_create: function() {
15344		var that = this,
15345			options = this.options;
15346
15347		this.running = false;
15348
15349		this.element
15350			.addClass( "ui-tabs ui-widget ui-widget-content ui-corner-all" )
15351			.toggleClass( "ui-tabs-collapsible", options.collapsible );
15352
15353		this._processTabs();
15354		options.active = this._initialActive();
15355
15356		// Take disabling tabs via class attribute from HTML
15357		// into account and update option properly.
15358		if ( $.isArray( options.disabled ) ) {
15359			options.disabled = $.unique( options.disabled.concat(
15360				$.map( this.tabs.filter( ".ui-state-disabled" ), function( li ) {
15361					return that.tabs.index( li );
15362				})
15363			) ).sort();
15364		}
15365
15366		// check for length avoids error when initializing empty list
15367		if ( this.options.active !== false && this.anchors.length ) {
15368			this.active = this._findActive( options.active );
15369		} else {
15370			this.active = $();
15371		}
15372
15373		this._refresh();
15374
15375		if ( this.active.length ) {
15376			this.load( options.active );
15377		}
15378	},
15379
15380	_initialActive: function() {
15381		var active = this.options.active,
15382			collapsible = this.options.collapsible,
15383			locationHash = location.hash.substring( 1 );
15384
15385		if ( active === null ) {
15386			// check the fragment identifier in the URL
15387			if ( locationHash ) {
15388				this.tabs.each(function( i, tab ) {
15389					if ( $( tab ).attr( "aria-controls" ) === locationHash ) {
15390						active = i;
15391						return false;
15392					}
15393				});
15394			}
15395
15396			// check for a tab marked active via a class
15397			if ( active === null ) {
15398				active = this.tabs.index( this.tabs.filter( ".ui-tabs-active" ) );
15399			}
15400
15401			// no active tab, set to false
15402			if ( active === null || active === -1 ) {
15403				active = this.tabs.length ? 0 : false;
15404			}
15405		}
15406
15407		// handle numbers: negative, out of range
15408		if ( active !== false ) {
15409			active = this.tabs.index( this.tabs.eq( active ) );
15410			if ( active === -1 ) {
15411				active = collapsible ? false : 0;
15412			}
15413		}
15414
15415		// don't allow collapsible: false and active: false
15416		if ( !collapsible && active === false && this.anchors.length ) {
15417			active = 0;
15418		}
15419
15420		return active;
15421	},
15422
15423	_getCreateEventData: function() {
15424		return {
15425			tab: this.active,
15426			panel: !this.active.length ? $() : this._getPanelForTab( this.active )
15427		};
15428	},
15429
15430	_tabKeydown: function( event ) {
15431		var focusedTab = $( this.document[0].activeElement ).closest( "li" ),
15432			selectedIndex = this.tabs.index( focusedTab ),
15433			goingForward = true;
15434
15435		if ( this._handlePageNav( event ) ) {
15436			return;
15437		}
15438
15439		switch ( event.keyCode ) {
15440			case $.ui.keyCode.RIGHT:
15441			case $.ui.keyCode.DOWN:
15442				selectedIndex++;
15443				break;
15444			case $.ui.keyCode.UP:
15445			case $.ui.keyCode.LEFT:
15446				goingForward = false;
15447				selectedIndex--;
15448				break;
15449			case $.ui.keyCode.END:
15450				selectedIndex = this.anchors.length - 1;
15451				break;
15452			case $.ui.keyCode.HOME:
15453				selectedIndex = 0;
15454				break;
15455			case $.ui.keyCode.SPACE:
15456				// Activate only, no collapsing
15457				event.preventDefault();
15458				clearTimeout( this.activating );
15459				this._activate( selectedIndex );
15460				return;
15461			case $.ui.keyCode.ENTER:
15462				// Toggle (cancel delayed activation, allow collapsing)
15463				event.preventDefault();
15464				clearTimeout( this.activating );
15465				// Determine if we should collapse or activate
15466				this._activate( selectedIndex === this.options.active ? false : selectedIndex );
15467				return;
15468			default:
15469				return;
15470		}
15471
15472		// Focus the appropriate tab, based on which key was pressed
15473		event.preventDefault();
15474		clearTimeout( this.activating );
15475		selectedIndex = this._focusNextTab( selectedIndex, goingForward );
15476
15477		// Navigating with control/command key will prevent automatic activation
15478		if ( !event.ctrlKey && !event.metaKey ) {
15479
15480			// Update aria-selected immediately so that AT think the tab is already selected.
15481			// Otherwise AT may confuse the user by stating that they need to activate the tab,
15482			// but the tab will already be activated by the time the announcement finishes.
15483			focusedTab.attr( "aria-selected", "false" );
15484			this.tabs.eq( selectedIndex ).attr( "aria-selected", "true" );
15485
15486			this.activating = this._delay(function() {
15487				this.option( "active", selectedIndex );
15488			}, this.delay );
15489		}
15490	},
15491
15492	_panelKeydown: function( event ) {
15493		if ( this._handlePageNav( event ) ) {
15494			return;
15495		}
15496
15497		// Ctrl+up moves focus to the current tab
15498		if ( event.ctrlKey && event.keyCode === $.ui.keyCode.UP ) {
15499			event.preventDefault();
15500			this.active.focus();
15501		}
15502	},
15503
15504	// Alt+page up/down moves focus to the previous/next tab (and activates)
15505	_handlePageNav: function( event ) {
15506		if ( event.altKey && event.keyCode === $.ui.keyCode.PAGE_UP ) {
15507			this._activate( this._focusNextTab( this.options.active - 1, false ) );
15508			return true;
15509		}
15510		if ( event.altKey && event.keyCode === $.ui.keyCode.PAGE_DOWN ) {
15511			this._activate( this._focusNextTab( this.options.active + 1, true ) );
15512			return true;
15513		}
15514	},
15515
15516	_findNextTab: function( index, goingForward ) {
15517		var lastTabIndex = this.tabs.length - 1;
15518
15519		function constrain() {
15520			if ( index > lastTabIndex ) {
15521				index = 0;
15522			}
15523			if ( index < 0 ) {
15524				index = lastTabIndex;
15525			}
15526			return index;
15527		}
15528
15529		while ( $.inArray( constrain(), this.options.disabled ) !== -1 ) {
15530			index = goingForward ? index + 1 : index - 1;
15531		}
15532
15533		return index;
15534	},
15535
15536	_focusNextTab: function( index, goingForward ) {
15537		index = this._findNextTab( index, goingForward );
15538		this.tabs.eq( index ).focus();
15539		return index;
15540	},
15541
15542	_setOption: function( key, value ) {
15543		if ( key === "active" ) {
15544			// _activate() will handle invalid values and update this.options
15545			this._activate( value );
15546			return;
15547		}
15548
15549		if ( key === "disabled" ) {
15550			// don't use the widget factory's disabled handling
15551			this._setupDisabled( value );
15552			return;
15553		}
15554
15555		this._super( key, value);
15556
15557		if ( key === "collapsible" ) {
15558			this.element.toggleClass( "ui-tabs-collapsible", value );
15559			// Setting collapsible: false while collapsed; open first panel
15560			if ( !value && this.options.active === false ) {
15561				this._activate( 0 );
15562			}
15563		}
15564
15565		if ( key === "event" ) {
15566			this._setupEvents( value );
15567		}
15568
15569		if ( key === "heightStyle" ) {
15570			this._setupHeightStyle( value );
15571		}
15572	},
15573
15574	_sanitizeSelector: function( hash ) {
15575		return hash ? hash.replace( /[!"$%&'()*+,.\/:;<=>?@\[\]\^`{|}~]/g, "\\$&" ) : "";
15576	},
15577
15578	refresh: function() {
15579		var options = this.options,
15580			lis = this.tablist.children( ":has(a[href])" );
15581
15582		// get disabled tabs from class attribute from HTML
15583		// this will get converted to a boolean if needed in _refresh()
15584		options.disabled = $.map( lis.filter( ".ui-state-disabled" ), function( tab ) {
15585			return lis.index( tab );
15586		});
15587
15588		this._processTabs();
15589
15590		// was collapsed or no tabs
15591		if ( options.active === false || !this.anchors.length ) {
15592			options.active = false;
15593			this.active = $();
15594		// was active, but active tab is gone
15595		} else if ( this.active.length && !$.contains( this.tablist[ 0 ], this.active[ 0 ] ) ) {
15596			// all remaining tabs are disabled
15597			if ( this.tabs.length === options.disabled.length ) {
15598				options.active = false;
15599				this.active = $();
15600			// activate previous tab
15601			} else {
15602				this._activate( this._findNextTab( Math.max( 0, options.active - 1 ), false ) );
15603			}
15604		// was active, active tab still exists
15605		} else {
15606			// make sure active index is correct
15607			options.active = this.tabs.index( this.active );
15608		}
15609
15610		this._refresh();
15611	},
15612
15613	_refresh: function() {
15614		this._setupDisabled( this.options.disabled );
15615		this._setupEvents( this.options.event );
15616		this._setupHeightStyle( this.options.heightStyle );
15617
15618		this.tabs.not( this.active ).attr({
15619			"aria-selected": "false",
15620			"aria-expanded": "false",
15621			tabIndex: -1
15622		});
15623		this.panels.not( this._getPanelForTab( this.active ) )
15624			.hide()
15625			.attr({
15626				"aria-hidden": "true"
15627			});
15628
15629		// Make sure one tab is in the tab order
15630		if ( !this.active.length ) {
15631			this.tabs.eq( 0 ).attr( "tabIndex", 0 );
15632		} else {
15633			this.active
15634				.addClass( "ui-tabs-active ui-state-active" )
15635				.attr({
15636					"aria-selected": "true",
15637					"aria-expanded": "true",
15638					tabIndex: 0
15639				});
15640			this._getPanelForTab( this.active )
15641				.show()
15642				.attr({
15643					"aria-hidden": "false"
15644				});
15645		}
15646	},
15647
15648	_processTabs: function() {
15649		var that = this,
15650			prevTabs = this.tabs,
15651			prevAnchors = this.anchors,
15652			prevPanels = this.panels;
15653
15654		this.tablist = this._getList()
15655			.addClass( "ui-tabs-nav ui-helper-reset ui-helper-clearfix ui-widget-header ui-corner-all" )
15656			.attr( "role", "tablist" )
15657
15658			// Prevent users from focusing disabled tabs via click
15659			.delegate( "> li", "mousedown" + this.eventNamespace, function( event ) {
15660				if ( $( this ).is( ".ui-state-disabled" ) ) {
15661					event.preventDefault();
15662				}
15663			})
15664
15665			// support: IE <9
15666			// Preventing the default action in mousedown doesn't prevent IE
15667			// from focusing the element, so if the anchor gets focused, blur.
15668			// We don't have to worry about focusing the previously focused
15669			// element since clicking on a non-focusable element should focus
15670			// the body anyway.
15671			.delegate( ".ui-tabs-anchor", "focus" + this.eventNamespace, function() {
15672				if ( $( this ).closest( "li" ).is( ".ui-state-disabled" ) ) {
15673					this.blur();
15674				}
15675			});
15676
15677		this.tabs = this.tablist.find( "> li:has(a[href])" )
15678			.addClass( "ui-state-default ui-corner-top" )
15679			.attr({
15680				role: "tab",
15681				tabIndex: -1
15682			});
15683
15684		this.anchors = this.tabs.map(function() {
15685				return $( "a", this )[ 0 ];
15686			})
15687			.addClass( "ui-tabs-anchor" )
15688			.attr({
15689				role: "presentation",
15690				tabIndex: -1
15691			});
15692
15693		this.panels = $();
15694
15695		this.anchors.each(function( i, anchor ) {
15696			var selector, panel, panelId,
15697				anchorId = $( anchor ).uniqueId().attr( "id" ),
15698				tab = $( anchor ).closest( "li" ),
15699				originalAriaControls = tab.attr( "aria-controls" );
15700
15701			// inline tab
15702			if ( that._isLocal( anchor ) ) {
15703				selector = anchor.hash;
15704				panelId = selector.substring( 1 );
15705				panel = that.element.find( that._sanitizeSelector( selector ) );
15706			// remote tab
15707			} else {
15708				// If the tab doesn't already have aria-controls,
15709				// generate an id by using a throw-away element
15710				panelId = tab.attr( "aria-controls" ) || $( {} ).uniqueId()[ 0 ].id;
15711				selector = "#" + panelId;
15712				panel = that.element.find( selector );
15713				if ( !panel.length ) {
15714					panel = that._createPanel( panelId );
15715					panel.insertAfter( that.panels[ i - 1 ] || that.tablist );
15716				}
15717				panel.attr( "aria-live", "polite" );
15718			}
15719
15720			if ( panel.length) {
15721				that.panels = that.panels.add( panel );
15722			}
15723			if ( originalAriaControls ) {
15724				tab.data( "ui-tabs-aria-controls", originalAriaControls );
15725			}
15726			tab.attr({
15727				"aria-controls": panelId,
15728				"aria-labelledby": anchorId
15729			});
15730			panel.attr( "aria-labelledby", anchorId );
15731		});
15732
15733		this.panels
15734			.addClass( "ui-tabs-panel ui-widget-content ui-corner-bottom" )
15735			.attr( "role", "tabpanel" );
15736
15737		// Avoid memory leaks (#10056)
15738		if ( prevTabs ) {
15739			this._off( prevTabs.not( this.tabs ) );
15740			this._off( prevAnchors.not( this.anchors ) );
15741			this._off( prevPanels.not( this.panels ) );
15742		}
15743	},
15744
15745	// allow overriding how to find the list for rare usage scenarios (#7715)
15746	_getList: function() {
15747		return this.tablist || this.element.find( "ol,ul" ).eq( 0 );
15748	},
15749
15750	_createPanel: function( id ) {
15751		return $( "<div>" )
15752			.attr( "id", id )
15753			.addClass( "ui-tabs-panel ui-widget-content ui-corner-bottom" )
15754			.data( "ui-tabs-destroy", true );
15755	},
15756
15757	_setupDisabled: function( disabled ) {
15758		if ( $.isArray( disabled ) ) {
15759			if ( !disabled.length ) {
15760				disabled = false;
vendor: 4,561 bytes, lines 15761-15928
15761			} else if ( disabled.length === this.anchors.length ) {
15762				disabled = true;
15763			}
15764		}
15765
15766		// disable tabs
15767		for ( var i = 0, li; ( li = this.tabs[ i ] ); i++ ) {
15768			if ( disabled === true || $.inArray( i, disabled ) !== -1 ) {
15769				$( li )
15770					.addClass( "ui-state-disabled" )
15771					.attr( "aria-disabled", "true" );
15772			} else {
15773				$( li )
15774					.removeClass( "ui-state-disabled" )
15775					.removeAttr( "aria-disabled" );
15776			}
15777		}
15778
15779		this.options.disabled = disabled;
15780	},
15781
15782	_setupEvents: function( event ) {
15783		var events = {};
15784		if ( event ) {
15785			$.each( event.split(" "), function( index, eventName ) {
15786				events[ eventName ] = "_eventHandler";
15787			});
15788		}
15789
15790		this._off( this.anchors.add( this.tabs ).add( this.panels ) );
15791		// Always prevent the default action, even when disabled
15792		this._on( true, this.anchors, {
15793			click: function( event ) {
15794				event.preventDefault();
15795			}
15796		});
15797		this._on( this.anchors, events );
15798		this._on( this.tabs, { keydown: "_tabKeydown" } );
15799		this._on( this.panels, { keydown: "_panelKeydown" } );
15800
15801		this._focusable( this.tabs );
15802		this._hoverable( this.tabs );
15803	},
15804
15805	_setupHeightStyle: function( heightStyle ) {
15806		var maxHeight,
15807			parent = this.element.parent();
15808
15809		if ( heightStyle === "fill" ) {
15810			maxHeight = parent.height();
15811			maxHeight -= this.element.outerHeight() - this.element.height();
15812
15813			this.element.siblings( ":visible" ).each(function() {
15814				var elem = $( this ),
15815					position = elem.css( "position" );
15816
15817				if ( position === "absolute" || position === "fixed" ) {
15818					return;
15819				}
15820				maxHeight -= elem.outerHeight( true );
15821			});
15822
15823			this.element.children().not( this.panels ).each(function() {
15824				maxHeight -= $( this ).outerHeight( true );
15825			});
15826
15827			this.panels.each(function() {
15828				$( this ).height( Math.max( 0, maxHeight -
15829					$( this ).innerHeight() + $( this ).height() ) );
15830			})
15831			.css( "overflow", "auto" );
15832		} else if ( heightStyle === "auto" ) {
15833			maxHeight = 0;
15834			this.panels.each(function() {
15835				maxHeight = Math.max( maxHeight, $( this ).height( "" ).height() );
15836			}).height( maxHeight );
15837		}
15838	},
15839
15840	_eventHandler: function( event ) {
15841		var options = this.options,
15842			active = this.active,
15843			anchor = $( event.currentTarget ),
15844			tab = anchor.closest( "li" ),
15845			clickedIsActive = tab[ 0 ] === active[ 0 ],
15846			collapsing = clickedIsActive && options.collapsible,
15847			toShow = collapsing ? $() : this._getPanelForTab( tab ),
15848			toHide = !active.length ? $() : this._getPanelForTab( active ),
15849			eventData = {
15850				oldTab: active,
15851				oldPanel: toHide,
15852				newTab: collapsing ? $() : tab,
15853				newPanel: toShow
15854			};
15855
15856		event.preventDefault();
15857
15858		if ( tab.hasClass( "ui-state-disabled" ) ||
15859				// tab is already loading
15860				tab.hasClass( "ui-tabs-loading" ) ||
15861				// can't switch durning an animation
15862				this.running ||
15863				// click on active header, but not collapsible
15864				( clickedIsActive && !options.collapsible ) ||
15865				// allow canceling activation
15866				( this._trigger( "beforeActivate", event, eventData ) === false ) ) {
15867			return;
15868		}
15869
15870		options.active = collapsing ? false : this.tabs.index( tab );
15871
15872		this.active = clickedIsActive ? $() : tab;
15873		if ( this.xhr ) {
15874			this.xhr.abort();
15875		}
15876
15877		if ( !toHide.length && !toShow.length ) {
15878			$.error( "jQuery UI Tabs: Mismatching fragment identifier." );
15879		}
15880
15881		if ( toShow.length ) {
15882			this.load( this.tabs.index( tab ), event );
15883		}
15884		this._toggle( event, eventData );
15885	},
15886
15887	// handles show/hide for selecting tabs
15888	_toggle: function( event, eventData ) {
15889		var that = this,
15890			toShow = eventData.newPanel,
15891			toHide = eventData.oldPanel;
15892
15893		this.running = true;
15894
15895		function complete() {
15896			that.running = false;
15897			that._trigger( "activate", event, eventData );
15898		}
15899
15900		function show() {
15901			eventData.newTab.closest( "li" ).addClass( "ui-tabs-active ui-state-active" );
15902
15903			if ( toShow.length && that.options.show ) {
15904				that._show( toShow, that.options.show, complete );
15905			} else {
15906				toShow.show();
15907				complete();
15908			}
15909		}
15910
15911		// start out by hiding, then showing, then completing
15912		if ( toHide.length && this.options.hide ) {
15913			this._hide( toHide, this.options.hide, function() {
15914				eventData.oldTab.closest( "li" ).removeClass( "ui-tabs-active ui-state-active" );
15915				show();
15916			});
15917		} else {
15918			eventData.oldTab.closest( "li" ).removeClass( "ui-tabs-active ui-state-active" );
15919			toHide.hide();
15920			show();
15921		}
15922
15923		toHide.attr( "aria-hidden", "true" );
15924		eventData.oldTab.attr({
15925			"aria-selected": "false",
15926			"aria-expanded": "false"
15927		});
15928		// If we're switching tabs, remove the old tab from the tab order.
vendor: 18,503 bytes, lines 15929-16619
15929		// If we're opening from collapsed state, remove the previous tab from the tab order.
15930		// If we're collapsing, then keep the collapsing tab in the tab order.
15931		if ( toShow.length && toHide.length ) {
15932			eventData.oldTab.attr( "tabIndex", -1 );
15933		} else if ( toShow.length ) {
15934			this.tabs.filter(function() {
15935				return $( this ).attr( "tabIndex" ) === 0;
15936			})
15937			.attr( "tabIndex", -1 );
15938		}
15939
15940		toShow.attr( "aria-hidden", "false" );
15941		eventData.newTab.attr({
15942			"aria-selected": "true",
15943			"aria-expanded": "true",
15944			tabIndex: 0
15945		});
15946	},
15947
15948	_activate: function( index ) {
15949		var anchor,
15950			active = this._findActive( index );
15951
15952		// trying to activate the already active panel
15953		if ( active[ 0 ] === this.active[ 0 ] ) {
15954			return;
15955		}
15956
15957		// trying to collapse, simulate a click on the current active header
15958		if ( !active.length ) {
15959			active = this.active;
15960		}
15961
15962		anchor = active.find( ".ui-tabs-anchor" )[ 0 ];
15963		this._eventHandler({
15964			target: anchor,
15965			currentTarget: anchor,
15966			preventDefault: $.noop
15967		});
15968	},
15969
15970	_findActive: function( index ) {
15971		return index === false ? $() : this.tabs.eq( index );
15972	},
15973
15974	_getIndex: function( index ) {
15975		// meta-function to give users option to provide a href string instead of a numerical index.
15976		if ( typeof index === "string" ) {
15977			index = this.anchors.index( this.anchors.filter( "[href$='" + index + "']" ) );
15978		}
15979
15980		return index;
15981	},
15982
15983	_destroy: function() {
15984		if ( this.xhr ) {
15985			this.xhr.abort();
15986		}
15987
15988		this.element.removeClass( "ui-tabs ui-widget ui-widget-content ui-corner-all ui-tabs-collapsible" );
15989
15990		this.tablist
15991			.removeClass( "ui-tabs-nav ui-helper-reset ui-helper-clearfix ui-widget-header ui-corner-all" )
15992			.removeAttr( "role" );
15993
15994		this.anchors
15995			.removeClass( "ui-tabs-anchor" )
15996			.removeAttr( "role" )
15997			.removeAttr( "tabIndex" )
15998			.removeUniqueId();
15999
16000		this.tablist.unbind( this.eventNamespace );
16001
16002		this.tabs.add( this.panels ).each(function() {
16003			if ( $.data( this, "ui-tabs-destroy" ) ) {
16004				$( this ).remove();
16005			} else {
16006				$( this )
16007					.removeClass( "ui-state-default ui-state-active ui-state-disabled " +
16008						"ui-corner-top ui-corner-bottom ui-widget-content ui-tabs-active ui-tabs-panel" )
16009					.removeAttr( "tabIndex" )
16010					.removeAttr( "aria-live" )
16011					.removeAttr( "aria-busy" )
16012					.removeAttr( "aria-selected" )
16013					.removeAttr( "aria-labelledby" )
16014					.removeAttr( "aria-hidden" )
16015					.removeAttr( "aria-expanded" )
16016					.removeAttr( "role" );
16017			}
16018		});
16019
16020		this.tabs.each(function() {
16021			var li = $( this ),
16022				prev = li.data( "ui-tabs-aria-controls" );
16023			if ( prev ) {
16024				li
16025					.attr( "aria-controls", prev )
16026					.removeData( "ui-tabs-aria-controls" );
16027			} else {
16028				li.removeAttr( "aria-controls" );
16029			}
16030		});
16031
16032		this.panels.show();
16033
16034		if ( this.options.heightStyle !== "content" ) {
16035			this.panels.css( "height", "" );
16036		}
16037	},
16038
16039	enable: function( index ) {
16040		var disabled = this.options.disabled;
16041		if ( disabled === false ) {
16042			return;
16043		}
16044
16045		if ( index === undefined ) {
16046			disabled = false;
16047		} else {
16048			index = this._getIndex( index );
16049			if ( $.isArray( disabled ) ) {
16050				disabled = $.map( disabled, function( num ) {
16051					return num !== index ? num : null;
16052				});
16053			} else {
16054				disabled = $.map( this.tabs, function( li, num ) {
16055					return num !== index ? num : null;
16056				});
16057			}
16058		}
16059		this._setupDisabled( disabled );
16060	},
16061
16062	disable: function( index ) {
16063		var disabled = this.options.disabled;
16064		if ( disabled === true ) {
16065			return;
16066		}
16067
16068		if ( index === undefined ) {
16069			disabled = true;
16070		} else {
16071			index = this._getIndex( index );
16072			if ( $.inArray( index, disabled ) !== -1 ) {
16073				return;
16074			}
16075			if ( $.isArray( disabled ) ) {
16076				disabled = $.merge( [ index ], disabled ).sort();
16077			} else {
16078				disabled = [ index ];
16079			}
16080		}
16081		this._setupDisabled( disabled );
16082	},
16083
16084	load: function( index, event ) {
16085		index = this._getIndex( index );
16086		var that = this,
16087			tab = this.tabs.eq( index ),
16088			anchor = tab.find( ".ui-tabs-anchor" ),
16089			panel = this._getPanelForTab( tab ),
16090			eventData = {
16091				tab: tab,
16092				panel: panel
16093			},
16094			complete = function( jqXHR, status ) {
16095				if ( status === "abort" ) {
16096					that.panels.stop( false, true );
16097				}
16098
16099				tab.removeClass( "ui-tabs-loading" );
16100				panel.removeAttr( "aria-busy" );
16101
16102				if ( jqXHR === that.xhr ) {
16103					delete that.xhr;
16104				}
16105			};
16106
16107		// not remote
16108		if ( this._isLocal( anchor[ 0 ] ) ) {
16109			return;
16110		}
16111
16112		this.xhr = $.ajax( this._ajaxSettings( anchor, event, eventData ) );
16113
16114		// support: jQuery <1.8
16115		// jQuery <1.8 returns false if the request is canceled in beforeSend,
16116		// but as of 1.8, $.ajax() always returns a jqXHR object.
16117		if ( this.xhr && this.xhr.statusText !== "canceled" ) {
16118			tab.addClass( "ui-tabs-loading" );
16119			panel.attr( "aria-busy", "true" );
16120
16121			this.xhr
16122				.done(function( response, status, jqXHR ) {
16123					// support: jQuery <1.8
16124					// http://bugs.jquery.com/ticket/11778
16125					setTimeout(function() {
16126						panel.html( response );
16127						that._trigger( "load", event, eventData );
16128
16129						complete( jqXHR, status );
16130					}, 1 );
16131				})
16132				.fail(function( jqXHR, status ) {
16133					// support: jQuery <1.8
16134					// http://bugs.jquery.com/ticket/11778
16135					setTimeout(function() {
16136						complete( jqXHR, status );
16137					}, 1 );
16138				});
16139		}
16140	},
16141
16142	_ajaxSettings: function( anchor, event, eventData ) {
16143		var that = this;
16144		return {
16145			url: anchor.attr( "href" ),
16146			beforeSend: function( jqXHR, settings ) {
16147				return that._trigger( "beforeLoad", event,
16148					$.extend( { jqXHR: jqXHR, ajaxSettings: settings }, eventData ) );
16149			}
16150		};
16151	},
16152
16153	_getPanelForTab: function( tab ) {
16154		var id = $( tab ).attr( "aria-controls" );
16155		return this.element.find( this._sanitizeSelector( "#" + id ) );
16156	}
16157});
16158
16159
16160/*!
16161 * jQuery UI Tooltip 1.11.4
16162 * http://jqueryui.com
16163 *
16164 * Copyright jQuery Foundation and other contributors
16165 * Released under the MIT license.
16166 * http://jquery.org/license
16167 *
16168 * http://api.jqueryui.com/tooltip/
16169 */
16170
16171
16172var tooltip = $.widget( "ui.tooltip", {
16173	version: "1.11.4",
16174	options: {
16175		content: function() {
16176			// support: IE<9, Opera in jQuery <1.7
16177			// .text() can't accept undefined, so coerce to a string
16178			var title = $( this ).attr( "title" ) || "";
16179			// Escape title, since we're going from an attribute to raw HTML
16180			return $( "<a>" ).text( title ).html();
16181		},
16182		hide: true,
16183		// Disabled elements have inconsistent behavior across browsers (#8661)
16184		items: "[title]:not([disabled])",
16185		position: {
16186			my: "left top+15",
16187			at: "left bottom",
16188			collision: "flipfit flip"
16189		},
16190		show: true,
16191		tooltipClass: null,
16192		track: false,
16193
16194		// callbacks
16195		close: null,
16196		open: null
16197	},
16198
16199	_addDescribedBy: function( elem, id ) {
16200		var describedby = (elem.attr( "aria-describedby" ) || "").split( /\s+/ );
16201		describedby.push( id );
16202		elem
16203			.data( "ui-tooltip-id", id )
16204			.attr( "aria-describedby", $.trim( describedby.join( " " ) ) );
16205	},
16206
16207	_removeDescribedBy: function( elem ) {
16208		var id = elem.data( "ui-tooltip-id" ),
16209			describedby = (elem.attr( "aria-describedby" ) || "").split( /\s+/ ),
16210			index = $.inArray( id, describedby );
16211
16212		if ( index !== -1 ) {
16213			describedby.splice( index, 1 );
16214		}
16215
16216		elem.removeData( "ui-tooltip-id" );
16217		describedby = $.trim( describedby.join( " " ) );
16218		if ( describedby ) {
16219			elem.attr( "aria-describedby", describedby );
16220		} else {
16221			elem.removeAttr( "aria-describedby" );
16222		}
16223	},
16224
16225	_create: function() {
16226		this._on({
16227			mouseover: "open",
16228			focusin: "open"
16229		});
16230
16231		// IDs of generated tooltips, needed for destroy
16232		this.tooltips = {};
16233
16234		// IDs of parent tooltips where we removed the title attribute
16235		this.parents = {};
16236
16237		if ( this.options.disabled ) {
16238			this._disable();
16239		}
16240
16241		// Append the aria-live region so tooltips announce correctly
16242		this.liveRegion = $( "<div>" )
16243			.attr({
16244				role: "log",
16245				"aria-live": "assertive",
16246				"aria-relevant": "additions"
16247			})
16248			.addClass( "ui-helper-hidden-accessible" )
16249			.appendTo( this.document[ 0 ].body );
16250	},
16251
16252	_setOption: function( key, value ) {
16253		var that = this;
16254
16255		if ( key === "disabled" ) {
16256			this[ value ? "_disable" : "_enable" ]();
16257			this.options[ key ] = value;
16258			// disable element style changes
16259			return;
16260		}
16261
16262		this._super( key, value );
16263
16264		if ( key === "content" ) {
16265			$.each( this.tooltips, function( id, tooltipData ) {
16266				that._updateContent( tooltipData.element );
16267			});
16268		}
16269	},
16270
16271	_disable: function() {
16272		var that = this;
16273
16274		// close open tooltips
16275		$.each( this.tooltips, function( id, tooltipData ) {
16276			var event = $.Event( "blur" );
16277			event.target = event.currentTarget = tooltipData.element[ 0 ];
16278			that.close( event, true );
16279		});
16280
16281		// remove title attributes to prevent native tooltips
16282		this.element.find( this.options.items ).addBack().each(function() {
16283			var element = $( this );
16284			if ( element.is( "[title]" ) ) {
16285				element
16286					.data( "ui-tooltip-title", element.attr( "title" ) )
16287					.removeAttr( "title" );
16288			}
16289		});
16290	},
16291
16292	_enable: function() {
16293		// restore title attributes
16294		this.element.find( this.options.items ).addBack().each(function() {
16295			var element = $( this );
16296			if ( element.data( "ui-tooltip-title" ) ) {
16297				element.attr( "title", element.data( "ui-tooltip-title" ) );
16298			}
16299		});
16300	},
16301
16302	open: function( event ) {
16303		var that = this,
16304			target = $( event ? event.target : this.element )
16305				// we need closest here due to mouseover bubbling,
16306				// but always pointing at the same event target
16307				.closest( this.options.items );
16308
16309		// No element to show a tooltip for or the tooltip is already open
16310		if ( !target.length || target.data( "ui-tooltip-id" ) ) {
16311			return;
16312		}
16313
16314		if ( target.attr( "title" ) ) {
16315			target.data( "ui-tooltip-title", target.attr( "title" ) );
16316		}
16317
16318		target.data( "ui-tooltip-open", true );
16319
16320		// kill parent tooltips, custom or native, for hover
16321		if ( event && event.type === "mouseover" ) {
16322			target.parents().each(function() {
16323				var parent = $( this ),
16324					blurEvent;
16325				if ( parent.data( "ui-tooltip-open" ) ) {
16326					blurEvent = $.Event( "blur" );
16327					blurEvent.target = blurEvent.currentTarget = this;
16328					that.close( blurEvent, true );
16329				}
16330				if ( parent.attr( "title" ) ) {
16331					parent.uniqueId();
16332					that.parents[ this.id ] = {
16333						element: this,
16334						title: parent.attr( "title" )
16335					};
16336					parent.attr( "title", "" );
16337				}
16338			});
16339		}
16340
16341		this._registerCloseHandlers( event, target );
16342		this._updateContent( target, event );
16343	},
16344
16345	_updateContent: function( target, event ) {
16346		var content,
16347			contentOption = this.options.content,
16348			that = this,
16349			eventType = event ? event.type : null;
16350
16351		if ( typeof contentOption === "string" ) {
16352			return this._open( event, target, contentOption );
16353		}
16354
16355		content = contentOption.call( target[0], function( response ) {
16356
16357			// IE may instantly serve a cached response for ajax requests
16358			// delay this call to _open so the other call to _open runs first
16359			that._delay(function() {
16360
16361				// Ignore async response if tooltip was closed already
16362				if ( !target.data( "ui-tooltip-open" ) ) {
16363					return;
16364				}
16365
16366				// jQuery creates a special event for focusin when it doesn't
16367				// exist natively. To improve performance, the native event
16368				// object is reused and the type is changed. Therefore, we can't
16369				// rely on the type being correct after the event finished
16370				// bubbling, so we set it back to the previous value. (#8740)
16371				if ( event ) {
16372					event.type = eventType;
16373				}
16374				this._open( event, target, response );
16375			});
16376		});
16377		if ( content ) {
16378			this._open( event, target, content );
16379		}
16380	},
16381
16382	_open: function( event, target, content ) {
16383		var tooltipData, tooltip, delayedShow, a11yContent,
16384			positionOption = $.extend( {}, this.options.position );
16385
16386		if ( !content ) {
16387			return;
16388		}
16389
16390		// Content can be updated multiple times. If the tooltip already
16391		// exists, then just update the content and bail.
16392		tooltipData = this._find( target );
16393		if ( tooltipData ) {
16394			tooltipData.tooltip.find( ".ui-tooltip-content" ).html( content );
16395			return;
16396		}
16397
16398		// if we have a title, clear it to prevent the native tooltip
16399		// we have to check first to avoid defining a title if none exists
16400		// (we don't want to cause an element to start matching [title])
16401		//
16402		// We use removeAttr only for key events, to allow IE to export the correct
16403		// accessible attributes. For mouse events, set to empty string to avoid
16404		// native tooltip showing up (happens only when removing inside mouseover).
16405		if ( target.is( "[title]" ) ) {
16406			if ( event && event.type === "mouseover" ) {
16407				target.attr( "title", "" );
16408			} else {
16409				target.removeAttr( "title" );
16410			}
16411		}
16412
16413		tooltipData = this._tooltip( target );
16414		tooltip = tooltipData.tooltip;
16415		this._addDescribedBy( target, tooltip.attr( "id" ) );
16416		tooltip.find( ".ui-tooltip-content" ).html( content );
16417
16418		// Support: Voiceover on OS X, JAWS on IE <= 9
16419		// JAWS announces deletions even when aria-relevant="additions"
16420		// Voiceover will sometimes re-read the entire log region's contents from the beginning
16421		this.liveRegion.children().hide();
16422		if ( content.clone ) {
16423			a11yContent = content.clone();
16424			a11yContent.removeAttr( "id" ).find( "[id]" ).removeAttr( "id" );
16425		} else {
16426			a11yContent = content;
16427		}
16428		$( "<div>" ).html( a11yContent ).appendTo( this.liveRegion );
16429
16430		function position( event ) {
16431			positionOption.of = event;
16432			if ( tooltip.is( ":hidden" ) ) {
16433				return;
16434			}
16435			tooltip.position( positionOption );
16436		}
16437		if ( this.options.track && event && /^mouse/.test( event.type ) ) {
16438			this._on( this.document, {
16439				mousemove: position
16440			});
16441			// trigger once to override element-relative positioning
16442			position( event );
16443		} else {
16444			tooltip.position( $.extend({
16445				of: target
16446			}, this.options.position ) );
16447		}
16448
16449		tooltip.hide();
16450
16451		this._show( tooltip, this.options.show );
16452		// Handle tracking tooltips that are shown with a delay (#8644). As soon
16453		// as the tooltip is visible, position the tooltip using the most recent
16454		// event.
16455		if ( this.options.show && this.options.show.delay ) {
16456			delayedShow = this.delayedShow = setInterval(function() {
16457				if ( tooltip.is( ":visible" ) ) {
16458					position( positionOption.of );
16459					clearInterval( delayedShow );
16460				}
16461			}, $.fx.interval );
16462		}
16463
16464		this._trigger( "open", event, { tooltip: tooltip } );
16465	},
16466
16467	_registerCloseHandlers: function( event, target ) {
16468		var events = {
16469			keyup: function( event ) {
16470				if ( event.keyCode === $.ui.keyCode.ESCAPE ) {
16471					var fakeEvent = $.Event(event);
16472					fakeEvent.currentTarget = target[0];
16473					this.close( fakeEvent, true );
16474				}
16475			}
16476		};
16477
16478		// Only bind remove handler for delegated targets. Non-delegated
16479		// tooltips will handle this in destroy.
16480		if ( target[ 0 ] !== this.element[ 0 ] ) {
16481			events.remove = function() {
16482				this._removeTooltip( this._find( target ).tooltip );
16483			};
16484		}
16485
16486		if ( !event || event.type === "mouseover" ) {
16487			events.mouseleave = "close";
16488		}
16489		if ( !event || event.type === "focusin" ) {
16490			events.focusout = "close";
16491		}
16492		this._on( true, target, events );
16493	},
16494
16495	close: function( event ) {
16496		var tooltip,
16497			that = this,
16498			target = $( event ? event.currentTarget : this.element ),
16499			tooltipData = this._find( target );
16500
16501		// The tooltip may already be closed
16502		if ( !tooltipData ) {
16503
16504			// We set ui-tooltip-open immediately upon open (in open()), but only set the
16505			// additional data once there's actually content to show (in _open()). So even if the
16506			// tooltip doesn't have full data, we always remove ui-tooltip-open in case we're in
16507			// the period between open() and _open().
16508			target.removeData( "ui-tooltip-open" );
16509			return;
16510		}
16511
16512		tooltip = tooltipData.tooltip;
16513
16514		// disabling closes the tooltip, so we need to track when we're closing
16515		// to avoid an infinite loop in case the tooltip becomes disabled on close
16516		if ( tooltipData.closing ) {
16517			return;
16518		}
16519
16520		// Clear the interval for delayed tracking tooltips
16521		clearInterval( this.delayedShow );
16522
16523		// only set title if we had one before (see comment in _open())
16524		// If the title attribute has changed since open(), don't restore
16525		if ( target.data( "ui-tooltip-title" ) && !target.attr( "title" ) ) {
16526			target.attr( "title", target.data( "ui-tooltip-title" ) );
16527		}
16528
16529		this._removeDescribedBy( target );
16530
16531		tooltipData.hiding = true;
16532		tooltip.stop( true );
16533		this._hide( tooltip, this.options.hide, function() {
16534			that._removeTooltip( $( this ) );
16535		});
16536
16537		target.removeData( "ui-tooltip-open" );
16538		this._off( target, "mouseleave focusout keyup" );
16539
16540		// Remove 'remove' binding only on delegated targets
16541		if ( target[ 0 ] !== this.element[ 0 ] ) {
16542			this._off( target, "remove" );
16543		}
16544		this._off( this.document, "mousemove" );
16545
16546		if ( event && event.type === "mouseleave" ) {
16547			$.each( this.parents, function( id, parent ) {
16548				$( parent.element ).attr( "title", parent.title );
16549				delete that.parents[ id ];
16550			});
16551		}
16552
16553		tooltipData.closing = true;
16554		this._trigger( "close", event, { tooltip: tooltip } );
16555		if ( !tooltipData.hiding ) {
16556			tooltipData.closing = false;
16557		}
16558	},
16559
16560	_tooltip: function( element ) {
16561		var tooltip = $( "<div>" )
16562				.attr( "role", "tooltip" )
16563				.addClass( "ui-tooltip ui-widget ui-corner-all ui-widget-content " +
16564					( this.options.tooltipClass || "" ) ),
16565			id = tooltip.uniqueId().attr( "id" );
16566
16567		$( "<div>" )
16568			.addClass( "ui-tooltip-content" )
16569			.appendTo( tooltip );
16570
16571		tooltip.appendTo( this.document[0].body );
16572
16573		return this.tooltips[ id ] = {
16574			element: element,
16575			tooltip: tooltip
16576		};
16577	},
16578
16579	_find: function( target ) {
16580		var id = target.data( "ui-tooltip-id" );
16581		return id ? this.tooltips[ id ] : null;
16582	},
16583
16584	_removeTooltip: function( tooltip ) {
16585		tooltip.remove();
16586		delete this.tooltips[ tooltip.attr( "id" ) ];
16587	},
16588
16589	_destroy: function() {
16590		var that = this;
16591
16592		// close open tooltips
16593		$.each( this.tooltips, function( id, tooltipData ) {
16594			// Delegate to close method to handle common cleanup
16595			var event = $.Event( "blur" ),
16596				element = tooltipData.element;
16597			event.target = event.currentTarget = element[ 0 ];
16598			that.close( event, true );
16599
16600			// Remove immediately; destroying an open tooltip doesn't use the
16601			// hide animation
16602			$( "#" + id ).remove();
16603
16604			// Restore the title
16605			if ( element.data( "ui-tooltip-title" ) ) {
16606				// If the title attribute has changed since open(), don't restore
16607				if ( !element.attr( "title" ) ) {
16608					element.attr( "title", element.data( "ui-tooltip-title" ) );
16609				}
16610				element.removeData( "ui-tooltip-title" );
16611			}
16612		});
16613		this.liveRegion.remove();
16614	}
16615});
16616
16617
16618
16619}));

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.