PageSourceSearch

https://www.firecomms.com/dccom/components/GDForm/assets/jquery-ui-1.10.4.js

js firecomms.com collected 2026-10-04 02:47:46 UTC 436,715 bytes, 15,008 lines download raw bytes

vendor: 8,544 bytes, lines 1-295
1/*! jQuery UI - v1.10.4 - 2014-03-30
2* http://jqueryui.com
3* Includes: jquery.ui.core.js, jquery.ui.widget.js, jquery.ui.mouse.js, jquery.ui.position.js, jquery.ui.draggable.js, jquery.ui.droppable.js, jquery.ui.resizable.js, jquery.ui.selectable.js, jquery.ui.sortable.js, jquery.ui.accordion.js, jquery.ui.autocomplete.js, jquery.ui.button.js, jquery.ui.datepicker.js, jquery.ui.dialog.js, jquery.ui.menu.js, jquery.ui.progressbar.js, jquery.ui.slider.js, jquery.ui.spinner.js, jquery.ui.tabs.js, jquery.ui.tooltip.js, jquery.ui.effect.js, jquery.ui.effect-blind.js, jquery.ui.effect-bounce.js, jquery.ui.effect-clip.js, jquery.ui.effect-drop.js, jquery.ui.effect-explode.js, jquery.ui.effect-fade.js, jquery.ui.effect-fold.js, jquery.ui.effect-highlight.js, jquery.ui.effect-pulsate.js, jquery.ui.effect-scale.js, jquery.ui.effect-shake.js, jquery.ui.effect-slide.js, jquery.ui.effect-transfer.js
4* Copyright 2014 jQuery Foundation and other contributors; Licensed MIT */
5
6(function( $, undefined ) {
7
8var uuid = 0,
9	runiqueId = /^ui-id-\d+$/;
10
11// $.ui might exist from components with no dependencies, e.g., $.ui.position
12$.ui = $.ui || {};
13
14$.extend( $.ui, {
15	version: "1.10.4",
16
17	keyCode: {
18		BACKSPACE: 8,
19		COMMA: 188,
20		DELETE: 46,
21		DOWN: 40,
22		END: 35,
23		ENTER: 13,
24		ESCAPE: 27,
25		HOME: 36,
26		LEFT: 37,
27		NUMPAD_ADD: 107,
28		NUMPAD_DECIMAL: 110,
29		NUMPAD_DIVIDE: 111,
30		NUMPAD_ENTER: 108,
31		NUMPAD_MULTIPLY: 106,
32		NUMPAD_SUBTRACT: 109,
33		PAGE_DOWN: 34,
34		PAGE_UP: 33,
35		PERIOD: 190,
36		RIGHT: 39,
37		SPACE: 32,
38		TAB: 9,
39		UP: 38
40	}
41});
42
43// plugins
44$.fn.extend({
45	focus: (function( orig ) {
46		return function( delay, fn ) {
47			return typeof delay === "number" ?
48				this.each(function() {
49					var elem = this;
50					setTimeout(function() {
51						$( elem ).focus();
52						if ( fn ) {
53							fn.call( elem );
54						}
55					}, delay );
56				}) :
57				orig.apply( this, arguments );
58		};
59	})( $.fn.focus ),
60
61	scrollParent: function() {
62		var scrollParent;
63		if (($.ui.ie && (/(static|relative)/).test(this.css("position"))) || (/absolute/).test(this.css("position"))) {
64			scrollParent = this.parents().filter(function() {
65				return (/(relative|absolute|fixed)/).test($.css(this,"position")) && (/(auto|scroll)/).test($.css(this,"overflow")+$.css(this,"overflow-y")+$.css(this,"overflow-x"));
66			}).eq(0);
67		} else {
68			scrollParent = this.parents().filter(function() {
69				return (/(auto|scroll)/).test($.css(this,"overflow")+$.css(this,"overflow-y")+$.css(this,"overflow-x"));
70			}).eq(0);
71		}
72
73		return (/fixed/).test(this.css("position")) || !scrollParent.length ? $(document) : scrollParent;
74	},
75
76	zIndex: function( zIndex ) {
77		if ( zIndex !== undefined ) {
78			return this.css( "zIndex", zIndex );
79		}
80
81		if ( this.length ) {
82			var elem = $( this[ 0 ] ), position, value;
83			while ( elem.length && elem[ 0 ] !== document ) {
84				// Ignore z-index if position is set to a value where z-index is ignored by the browser
85				// This makes behavior of this function consistent across browsers
86				// WebKit always returns auto if the element is positioned
87				position = elem.css( "position" );
88				if ( position === "absolute" || position === "relative" || position === "fixed" ) {
89					// IE returns 0 when zIndex is not specified
90					// other browsers return a string
91					// we ignore the case of nested elements with an explicit value of 0
92					// <div style="z-index: -10;"><div style="z-index: 0;"></div></div>
93					value = parseInt( elem.css( "zIndex" ), 10 );
94					if ( !isNaN( value ) && value !== 0 ) {
95						return value;
96					}
97				}
98				elem = elem.parent();
99			}
100		}
101
102		return 0;
103	},
104
105	uniqueId: function() {
106		return this.each(function() {
107			if ( !this.id ) {
108				this.id = "ui-id-" + (++uuid);
109			}
110		});
111	},
112
113	removeUniqueId: function() {
114		return this.each(function() {
115			if ( runiqueId.test( this.id ) ) {
116				$( this ).removeAttr( "id" );
117			}
118		});
119	}
120});
121
122// selectors
123function focusable( element, isTabIndexNotNaN ) {
124	var map, mapName, img,
125		nodeName = element.nodeName.toLowerCase();
126	if ( "area" === nodeName ) {
127		map = element.parentNode;
128		mapName = map.name;
129		if ( !element.href || !mapName || map.nodeName.toLowerCase() !== "map" ) {
130			return false;
131		}
132		img = $( "img[usemap=#" + mapName + "]" )[0];
133		return !!img && visible( img );
134	}
135	return ( /input|select|textarea|button|object/.test( nodeName ) ?
136		!element.disabled :
137		"a" === nodeName ?
138			element.href || isTabIndexNotNaN :
139			isTabIndexNotNaN) &&
140		// the element and all of its ancestors must be visible
141		visible( element );
142}
143
144function visible( element ) {
145	return $.expr.filters.visible( element ) &&
146		!$( element ).parents().addBack().filter(function() {
147			return $.css( this, "visibility" ) === "hidden";
148		}).length;
149}
150
151$.extend( $.expr[ ":" ], {
152	data: $.expr.createPseudo ?
153		$.expr.createPseudo(function( dataName ) {
154			return function( elem ) {
155				return !!$.data( elem, dataName );
156			};
157		}) :
158		// support: jQuery <1.8
159		function( elem, i, match ) {
160			return !!$.data( elem, match[ 3 ] );
161		},
162
163	focusable: function( element ) {
164		return focusable( element, !isNaN( $.attr( element, "tabindex" ) ) );
165	},
166
167	tabbable: function( element ) {
168		var tabIndex = $.attr( element, "tabindex" ),
169			isTabIndexNaN = isNaN( tabIndex );
170		return ( isTabIndexNaN || tabIndex >= 0 ) && focusable( element, !isTabIndexNaN );
171	}
172});
173
174// support: jQuery <1.8
175if ( !$( "<a>" ).outerWidth( 1 ).jquery ) {
176	$.each( [ "Width", "Height" ], function( i, name ) {
177		var side = name === "Width" ? [ "Left", "Right" ] : [ "Top", "Bottom" ],
178			type = name.toLowerCase(),
179			orig = {
180				innerWidth: $.fn.innerWidth,
181				innerHeight: $.fn.innerHeight,
182				outerWidth: $.fn.outerWidth,
183				outerHeight: $.fn.outerHeight
184			};
185
186		function reduce( elem, size, border, margin ) {
187			$.each( side, function() {
188				size -= parseFloat( $.css( elem, "padding" + this ) ) || 0;
189				if ( border ) {
190					size -= parseFloat( $.css( elem, "border" + this + "Width" ) ) || 0;
191				}
192				if ( margin ) {
193					size -= parseFloat( $.css( elem, "margin" + this ) ) || 0;
194				}
195			});
196			return size;
197		}
198
199		$.fn[ "inner" + name ] = function( size ) {
200			if ( size === undefined ) {
201				return orig[ "inner" + name ].call( this );
202			}
203
204			return this.each(function() {
205				$( this ).css( type, reduce( this, size ) + "px" );
206			});
207		};
208
209		$.fn[ "outer" + name] = function( size, margin ) {
210			if ( typeof size !== "number" ) {
211				return orig[ "outer" + name ].call( this, size );
212			}
213
214			return this.each(function() {
215				$( this).css( type, reduce( this, size, true, margin ) + "px" );
216			});
217		};
218	});
219}
220
221// support: jQuery <1.8
222if ( !$.fn.addBack ) {
223	$.fn.addBack = function( selector ) {
224		return this.add( selector == null ?
225			this.prevObject : this.prevObject.filter( selector )
226		);
227	};
228}
229
230// support: jQuery 1.6.1, 1.6.2 (http://bugs.jquery.com/ticket/9413)
231if ( $( "<a>" ).data( "a-b", "a" ).removeData( "a-b" ).data( "a-b" ) ) {
232	$.fn.removeData = (function( removeData ) {
233		return function( key ) {
234			if ( arguments.length ) {
235				return removeData.call( this, $.camelCase( key ) );
236			} else {
237				return removeData.call( this );
238			}
239		};
240	})( $.fn.removeData );
241}
242
243
244
245
246
247// deprecated
248$.ui.ie = !!/msie [\w.]+/.exec( navigator.userAgent.toLowerCase() );
249
250$.support.selectstart = "onselectstart" in document.createElement( "div" );
251$.fn.extend({
252	disableSelection: function() {
253		return this.bind( ( $.support.selectstart ? "selectstart" : "mousedown" ) +
254			".ui-disableSelection", function( event ) {
255				event.preventDefault();
256			});
257	},
258
259	enableSelection: function() {
260		return this.unbind( ".ui-disableSelection" );
261	}
262});
263
264$.extend( $.ui, {
265	// $.ui.plugin is deprecated. Use $.widget() extensions instead.
266	plugin: {
267		add: function( module, option, set ) {
268			var i,
269				proto = $.ui[ module ].prototype;
270			for ( i in set ) {
271				proto.plugins[ i ] = proto.plugins[ i ] || [];
272				proto.plugins[ i ].push( [ option, set[ i ] ] );
273			}
274		},
275		call: function( instance, name, args ) {
276			var i,
277				set = instance.plugins[ name ];
278			if ( !set || !instance.element[ 0 ].parentNode || instance.element[ 0 ].parentNode.nodeType === 11 ) {
279				return;
280			}
281
282			for ( i = 0; i < set.length; i++ ) {
283				if ( instance.options[ set[ i ][ 0 ] ] ) {
284					set[ i ][ 1 ].apply( instance.element, args );
285				}
286			}
287		}
288	},
289
290	// only used by resizable
291	hasScroll: function( el, a ) {
292
293		//If overflow is hidden, the element might have extra content, but the user wants to hide it
294		if ( $( el ).css( "overflow" ) === "hidden") {
295			return false;
vendor: 6,505 bytes, lines 296-498
296		}
297
298		var scroll = ( a && a === "left" ) ? "scrollLeft" : "scrollTop",
299			has = false;
300
301		if ( el[ scroll ] > 0 ) {
302			return true;
303		}
304
305		// TODO: determine which cases actually cause this to happen
306		// if the element doesn't have the scroll set, see if it's possible to
307		// set the scroll
308		el[ scroll ] = 1;
309		has = ( el[ scroll ] > 0 );
310		el[ scroll ] = 0;
311		return has;
312	}
313});
314
315})( jQuery );
316(function( $, undefined ) {
317
318var uuid = 0,
319	slice = Array.prototype.slice,
320	_cleanData = $.cleanData;
321$.cleanData = function( elems ) {
322	for ( var i = 0, elem; (elem = elems[i]) != null; i++ ) {
323		try {
324			$( elem ).triggerHandler( "remove" );
325		// http://bugs.jquery.com/ticket/8235
326		} catch( e ) {}
327	}
328	_cleanData( elems );
329};
330
331$.widget = function( name, base, prototype ) {
332	var fullName, existingConstructor, constructor, basePrototype,
333		// proxiedPrototype allows the provided prototype to remain unmodified
334		// so that it can be used as a mixin for multiple widgets (#8876)
335		proxiedPrototype = {},
336		namespace = name.split( "." )[ 0 ];
337
338	name = name.split( "." )[ 1 ];
339	fullName = namespace + "-" + name;
340
341	if ( !prototype ) {
342		prototype = base;
343		base = $.Widget;
344	}
345
346	// create selector for plugin
347	$.expr[ ":" ][ fullName.toLowerCase() ] = function( elem ) {
348		return !!$.data( elem, fullName );
349	};
350
351	$[ namespace ] = $[ namespace ] || {};
352	existingConstructor = $[ namespace ][ name ];
353	constructor = $[ namespace ][ name ] = function( options, element ) {
354		// allow instantiation without "new" keyword
355		if ( !this._createWidget ) {
356			return new constructor( options, element );
357		}
358
359		// allow instantiation without initializing for simple inheritance
360		// must use "new" keyword (the code above always passes args)
361		if ( arguments.length ) {
362			this._createWidget( options, element );
363		}
364	};
365	// extend with the existing constructor to carry over any static properties
366	$.extend( constructor, existingConstructor, {
367		version: prototype.version,
368		// copy the object used to create the prototype in case we need to
369		// redefine the widget later
370		_proto: $.extend( {}, prototype ),
371		// track widgets that inherit from this widget in case this widget is
372		// redefined after a widget inherits from it
373		_childConstructors: []
374	});
375
376	basePrototype = new base();
377	// we need to make the options hash a property directly on the new instance
378	// otherwise we'll modify the options hash on the prototype that we're
379	// inheriting from
380	basePrototype.options = $.widget.extend( {}, basePrototype.options );
381	$.each( prototype, function( prop, value ) {
382		if ( !$.isFunction( value ) ) {
383			proxiedPrototype[ prop ] = value;
384			return;
385		}
386		proxiedPrototype[ prop ] = (function() {
387			var _super = function() {
388					return base.prototype[ prop ].apply( this, arguments );
389				},
390				_superApply = function( args ) {
391					return base.prototype[ prop ].apply( this, args );
392				};
393			return function() {
394				var __super = this._super,
395					__superApply = this._superApply,
396					returnValue;
397
398				this._super = _super;
399				this._superApply = _superApply;
400
401				returnValue = value.apply( this, arguments );
402
403				this._super = __super;
404				this._superApply = __superApply;
405
406				return returnValue;
407			};
408		})();
409	});
410	constructor.prototype = $.widget.extend( basePrototype, {
411		// TODO: remove support for widgetEventPrefix
412		// always use the name + a colon as the prefix, e.g., draggable:start
413		// don't prefix for widgets that aren't DOM-based
414		widgetEventPrefix: existingConstructor ? (basePrototype.widgetEventPrefix || name) : name
415	}, proxiedPrototype, {
416		constructor: constructor,
417		namespace: namespace,
418		widgetName: name,
419		widgetFullName: fullName
420	});
421
422	// If this widget is being redefined then we need to find all widgets that
423	// are inheriting from it and redefine all of them so that they inherit from
424	// the new version of this widget. We're essentially trying to replace one
425	// level in the prototype chain.
426	if ( existingConstructor ) {
427		$.each( existingConstructor._childConstructors, function( i, child ) {
428			var childPrototype = child.prototype;
429
430			// redefine the child widget using the same prototype that was
431			// originally used, but inherit from the new version of the base
432			$.widget( childPrototype.namespace + "." + childPrototype.widgetName, constructor, child._proto );
433		});
434		// remove the list of existing child constructors from the old constructor
435		// so the old child constructors can be garbage collected
436		delete existingConstructor._childConstructors;
437	} else {
438		base._childConstructors.push( constructor );
439	}
440
441	$.widget.bridge( name, constructor );
442};
443
444$.widget.extend = function( target ) {
445	var input = slice.call( arguments, 1 ),
446		inputIndex = 0,
447		inputLength = input.length,
448		key,
449		value;
450	for ( ; inputIndex < inputLength; inputIndex++ ) {
451		for ( key in input[ inputIndex ] ) {
452			value = input[ inputIndex ][ key ];
453			if ( input[ inputIndex ].hasOwnProperty( key ) && value !== undefined ) {
454				// Clone objects
455				if ( $.isPlainObject( value ) ) {
456					target[ key ] = $.isPlainObject( target[ key ] ) ?
457						$.widget.extend( {}, target[ key ], value ) :
458						// Don't extend strings, arrays, etc. with objects
459						$.widget.extend( {}, value );
460				// Copy everything else by reference
461				} else {
462					target[ key ] = value;
463				}
464			}
465		}
466	}
467	return target;
468};
469
470$.widget.bridge = function( name, object ) {
471	var fullName = object.prototype.widgetFullName || name;
472	$.fn[ name ] = function( options ) {
473		var isMethodCall = typeof options === "string",
474			args = slice.call( arguments, 1 ),
475			returnValue = this;
476
477		// allow multiple hashes to be passed on init
478		options = !isMethodCall && args.length ?
479			$.widget.extend.apply( null, [ options ].concat(args) ) :
480			options;
481
482		if ( isMethodCall ) {
483			this.each(function() {
484				var methodValue,
485					instance = $.data( this, fullName );
486				if ( !instance ) {
487					return $.error( "cannot call methods on " + name + " prior to initialization; " +
488						"attempted to call method '" + options + "'" );
489				}
490				if ( !$.isFunction( instance[options] ) || options.charAt( 0 ) === "_" ) {
491					return $.error( "no such method '" + options + "' for " + name + " widget instance" );
492				}
493				methodValue = instance[ options ].apply( instance, args );
494				if ( methodValue !== instance && methodValue !== undefined ) {
495					returnValue = methodValue && methodValue.jquery ?
496						returnValue.pushStack( methodValue.get() ) :
497						methodValue;
498					return false;
vendor: 8,806 bytes, lines 499-829
499				}
500			});
501		} else {
502			this.each(function() {
503				var instance = $.data( this, fullName );
504				if ( instance ) {
505					instance.option( options || {} )._init();
506				} else {
507					$.data( this, fullName, new object( options, this ) );
508				}
509			});
510		}
511
512		return returnValue;
513	};
514};
515
516$.Widget = function( /* options, element */ ) {};
517$.Widget._childConstructors = [];
518
519$.Widget.prototype = {
520	widgetName: "widget",
521	widgetEventPrefix: "",
522	defaultElement: "<div>",
523	options: {
524		disabled: false,
525
526		// callbacks
527		create: null
528	},
529	_createWidget: function( options, element ) {
530		element = $( element || this.defaultElement || this )[ 0 ];
531		this.element = $( element );
532		this.uuid = uuid++;
533		this.eventNamespace = "." + this.widgetName + this.uuid;
534		this.options = $.widget.extend( {},
535			this.options,
536			this._getCreateOptions(),
537			options );
538
539		this.bindings = $();
540		this.hoverable = $();
541		this.focusable = $();
542
543		if ( element !== this ) {
544			$.data( element, this.widgetFullName, this );
545			this._on( true, this.element, {
546				remove: function( event ) {
547					if ( event.target === element ) {
548						this.destroy();
549					}
550				}
551			});
552			this.document = $( element.style ?
553				// element within the document
554				element.ownerDocument :
555				// element is window or document
556				element.document || element );
557			this.window = $( this.document[0].defaultView || this.document[0].parentWindow );
558		}
559
560		this._create();
561		this._trigger( "create", null, this._getCreateEventData() );
562		this._init();
563	},
564	_getCreateOptions: $.noop,
565	_getCreateEventData: $.noop,
566	_create: $.noop,
567	_init: $.noop,
568
569	destroy: function() {
570		this._destroy();
571		// we can probably remove the unbind calls in 2.0
572		// all event bindings should go through this._on()
573		this.element
574			.unbind( this.eventNamespace )
575			// 1.9 BC for #7810
576			// TODO remove dual storage
577			.removeData( this.widgetName )
578			.removeData( this.widgetFullName )
579			// support: jquery <1.6.3
580			// http://bugs.jquery.com/ticket/9413
581			.removeData( $.camelCase( this.widgetFullName ) );
582		this.widget()
583			.unbind( this.eventNamespace )
584			.removeAttr( "aria-disabled" )
585			.removeClass(
586				this.widgetFullName + "-disabled " +
587				"ui-state-disabled" );
588
589		// clean up events and states
590		this.bindings.unbind( this.eventNamespace );
591		this.hoverable.removeClass( "ui-state-hover" );
592		this.focusable.removeClass( "ui-state-focus" );
593	},
594	_destroy: $.noop,
595
596	widget: function() {
597		return this.element;
598	},
599
600	option: function( key, value ) {
601		var options = key,
602			parts,
603			curOption,
604			i;
605
606		if ( arguments.length === 0 ) {
607			// don't return a reference to the internal hash
608			return $.widget.extend( {}, this.options );
609		}
610
611		if ( typeof key === "string" ) {
612			// handle nested keys, e.g., "foo.bar" => { foo: { bar: ___ } }
613			options = {};
614			parts = key.split( "." );
615			key = parts.shift();
616			if ( parts.length ) {
617				curOption = options[ key ] = $.widget.extend( {}, this.options[ key ] );
618				for ( i = 0; i < parts.length - 1; i++ ) {
619					curOption[ parts[ i ] ] = curOption[ parts[ i ] ] || {};
620					curOption = curOption[ parts[ i ] ];
621				}
622				key = parts.pop();
623				if ( arguments.length === 1 ) {
624					return curOption[ key ] === undefined ? null : curOption[ key ];
625				}
626				curOption[ key ] = value;
627			} else {
628				if ( arguments.length === 1 ) {
629					return this.options[ key ] === undefined ? null : this.options[ key ];
630				}
631				options[ key ] = value;
632			}
633		}
634
635		this._setOptions( options );
636
637		return this;
638	},
639	_setOptions: function( options ) {
640		var key;
641
642		for ( key in options ) {
643			this._setOption( key, options[ key ] );
644		}
645
646		return this;
647	},
648	_setOption: function( key, value ) {
649		this.options[ key ] = value;
650
651		if ( key === "disabled" ) {
652			this.widget()
653				.toggleClass( this.widgetFullName + "-disabled ui-state-disabled", !!value )
654				.attr( "aria-disabled", value );
655			this.hoverable.removeClass( "ui-state-hover" );
656			this.focusable.removeClass( "ui-state-focus" );
657		}
658
659		return this;
660	},
661
662	enable: function() {
663		return this._setOption( "disabled", false );
664	},
665	disable: function() {
666		return this._setOption( "disabled", true );
667	},
668
669	_on: function( suppressDisabledCheck, element, handlers ) {
670		var delegateElement,
671			instance = this;
672
673		// no suppressDisabledCheck flag, shuffle arguments
674		if ( typeof suppressDisabledCheck !== "boolean" ) {
675			handlers = element;
676			element = suppressDisabledCheck;
677			suppressDisabledCheck = false;
678		}
679
680		// no element argument, shuffle and use this.element
681		if ( !handlers ) {
682			handlers = element;
683			element = this.element;
684			delegateElement = this.widget();
685		} else {
686			// accept selectors, DOM elements
687			element = delegateElement = $( element );
688			this.bindings = this.bindings.add( element );
689		}
690
691		$.each( handlers, function( event, handler ) {
692			function handlerProxy() {
693				// allow widgets to customize the disabled handling
694				// - disabled as an array instead of boolean
695				// - disabled class as method for disabling individual parts
696				if ( !suppressDisabledCheck &&
697						( instance.options.disabled === true ||
698							$( this ).hasClass( "ui-state-disabled" ) ) ) {
699					return;
700				}
701				return ( typeof handler === "string" ? instance[ handler ] : handler )
702					.apply( instance, arguments );
703			}
704
705			// copy the guid so direct unbinding works
706			if ( typeof handler !== "string" ) {
707				handlerProxy.guid = handler.guid =
708					handler.guid || handlerProxy.guid || $.guid++;
709			}
710
711			var match = event.match( /^(\w+)\s*(.*)$/ ),
712				eventName = match[1] + instance.eventNamespace,
713				selector = match[2];
714			if ( selector ) {
715				delegateElement.delegate( selector, eventName, handlerProxy );
716			} else {
717				element.bind( eventName, handlerProxy );
718			}
719		});
720	},
721
722	_off: function( element, eventName ) {
723		eventName = (eventName || "").split( " " ).join( this.eventNamespace + " " ) + this.eventNamespace;
724		element.unbind( eventName ).undelegate( eventName );
725	},
726
727	_delay: function( handler, delay ) {
728		function handlerProxy() {
729			return ( typeof handler === "string" ? instance[ handler ] : handler )
730				.apply( instance, arguments );
731		}
732		var instance = this;
733		return setTimeout( handlerProxy, delay || 0 );
734	},
735
736	_hoverable: function( element ) {
737		this.hoverable = this.hoverable.add( element );
738		this._on( element, {
739			mouseenter: function( event ) {
740				$( event.currentTarget ).addClass( "ui-state-hover" );
741			},
742			mouseleave: function( event ) {
743				$( event.currentTarget ).removeClass( "ui-state-hover" );
744			}
745		});
746	},
747
748	_focusable: function( element ) {
749		this.focusable = this.focusable.add( element );
750		this._on( element, {
751			focusin: function( event ) {
752				$( event.currentTarget ).addClass( "ui-state-focus" );
753			},
754			focusout: function( event ) {
755				$( event.currentTarget ).removeClass( "ui-state-focus" );
756			}
757		});
758	},
759
760	_trigger: function( type, event, data ) {
761		var prop, orig,
762			callback = this.options[ type ];
763
764		data = data || {};
765		event = $.Event( event );
766		event.type = ( type === this.widgetEventPrefix ?
767			type :
768			this.widgetEventPrefix + type ).toLowerCase();
769		// the original event may come from any element
770		// so we need to reset the target on the new event
771		event.target = this.element[ 0 ];
772
773		// copy original event properties over to the new event
774		orig = event.originalEvent;
775		if ( orig ) {
776			for ( prop in orig ) {
777				if ( !( prop in event ) ) {
778					event[ prop ] = orig[ prop ];
779				}
780			}
781		}
782
783		this.element.trigger( event, data );
784		return !( $.isFunction( callback ) &&
785			callback.apply( this.element[0], [ event ].concat( data ) ) === false ||
786			event.isDefaultPrevented() );
787	}
788};
789
790$.each( { show: "fadeIn", hide: "fadeOut" }, function( method, defaultEffect ) {
791	$.Widget.prototype[ "_" + method ] = function( element, options, callback ) {
792		if ( typeof options === "string" ) {
793			options = { effect: options };
794		}
795		var hasOptions,
796			effectName = !options ?
797				method :
798				options === true || typeof options === "number" ?
799					defaultEffect :
800					options.effect || defaultEffect;
801		options = options || {};
802		if ( typeof options === "number" ) {
803			options = { duration: options };
804		}
805		hasOptions = !$.isEmptyObject( options );
806		options.complete = callback;
807		if ( options.delay ) {
808			element.delay( options.delay );
809		}
810		if ( hasOptions && $.effects && $.effects.effect[ effectName ] ) {
811			element[ method ]( options );
812		} else if ( effectName !== method && element[ effectName ] ) {
813			element[ effectName ]( options.duration, options.easing, callback );
814		} else {
815			element.queue(function( next ) {
816				$( this )[ method ]();
817				if ( callback ) {
818					callback.call( element[ 0 ] );
819				}
820				next();
821			});
822		}
823	};
824});
825
826})( jQuery );
827(function( $, undefined ) {
828
829var mouseHandled = false;
vendor: 113,122 bytes, lines 830-4609
830$( document ).mouseup( function() {
831	mouseHandled = false;
832});
833
834$.widget("ui.mouse", {
835	version: "1.10.4",
836	options: {
837		cancel: "input,textarea,button,select,option",
838		distance: 1,
839		delay: 0
840	},
841	_mouseInit: function() {
842		var that = this;
843
844		this.element
845			.bind("mousedown."+this.widgetName, function(event) {
846				return that._mouseDown(event);
847			})
848			.bind("click."+this.widgetName, function(event) {
849				if (true === $.data(event.target, that.widgetName + ".preventClickEvent")) {
850					$.removeData(event.target, that.widgetName + ".preventClickEvent");
851					event.stopImmediatePropagation();
852					return false;
853				}
854			});
855
856		this.started = false;
857	},
858
859	// TODO: make sure destroying one instance of mouse doesn't mess with
860	// other instances of mouse
861	_mouseDestroy: function() {
862		this.element.unbind("."+this.widgetName);
863		if ( this._mouseMoveDelegate ) {
864			$(document)
865				.unbind("mousemove."+this.widgetName, this._mouseMoveDelegate)
866				.unbind("mouseup."+this.widgetName, this._mouseUpDelegate);
867		}
868	},
869
870	_mouseDown: function(event) {
871		// don't let more than one widget handle mouseStart
872		if( mouseHandled ) { return; }
873
874		// we may have missed mouseup (out of window)
875		(this._mouseStarted && this._mouseUp(event));
876
877		this._mouseDownEvent = event;
878
879		var that = this,
880			btnIsLeft = (event.which === 1),
881			// event.target.nodeName works around a bug in IE 8 with
882			// disabled inputs (#7620)
883			elIsCancel = (typeof this.options.cancel === "string" && event.target.nodeName ? $(event.target).closest(this.options.cancel).length : false);
884		if (!btnIsLeft || elIsCancel || !this._mouseCapture(event)) {
885			return true;
886		}
887
888		this.mouseDelayMet = !this.options.delay;
889		if (!this.mouseDelayMet) {
890			this._mouseDelayTimer = setTimeout(function() {
891				that.mouseDelayMet = true;
892			}, this.options.delay);
893		}
894
895		if (this._mouseDistanceMet(event) && this._mouseDelayMet(event)) {
896			this._mouseStarted = (this._mouseStart(event) !== false);
897			if (!this._mouseStarted) {
898				event.preventDefault();
899				return true;
900			}
901		}
902
903		// Click event may never have fired (Gecko & Opera)
904		if (true === $.data(event.target, this.widgetName + ".preventClickEvent")) {
905			$.removeData(event.target, this.widgetName + ".preventClickEvent");
906		}
907
908		// these delegates are required to keep context
909		this._mouseMoveDelegate = function(event) {
910			return that._mouseMove(event);
911		};
912		this._mouseUpDelegate = function(event) {
913			return that._mouseUp(event);
914		};
915		$(document)
916			.bind("mousemove."+this.widgetName, this._mouseMoveDelegate)
917			.bind("mouseup."+this.widgetName, this._mouseUpDelegate);
918
919		event.preventDefault();
920
921		mouseHandled = true;
922		return true;
923	},
924
925	_mouseMove: function(event) {
926		// IE mouseup check - mouseup happened when mouse was out of window
927		if ($.ui.ie && ( !document.documentMode || document.documentMode < 9 ) && !event.button) {
928			return this._mouseUp(event);
929		}
930
931		if (this._mouseStarted) {
932			this._mouseDrag(event);
933			return event.preventDefault();
934		}
935
936		if (this._mouseDistanceMet(event) && this._mouseDelayMet(event)) {
937			this._mouseStarted =
938				(this._mouseStart(this._mouseDownEvent, event) !== false);
939			(this._mouseStarted ? this._mouseDrag(event) : this._mouseUp(event));
940		}
941
942		return !this._mouseStarted;
943	},
944
945	_mouseUp: function(event) {
946		$(document)
947			.unbind("mousemove."+this.widgetName, this._mouseMoveDelegate)
948			.unbind("mouseup."+this.widgetName, this._mouseUpDelegate);
949
950		if (this._mouseStarted) {
951			this._mouseStarted = false;
952
953			if (event.target === this._mouseDownEvent.target) {
954				$.data(event.target, this.widgetName + ".preventClickEvent", true);
955			}
956
957			this._mouseStop(event);
958		}
959
960		return false;
961	},
962
963	_mouseDistanceMet: function(event) {
964		return (Math.max(
965				Math.abs(this._mouseDownEvent.pageX - event.pageX),
966				Math.abs(this._mouseDownEvent.pageY - event.pageY)
967			) >= this.options.distance
968		);
969	},
970
971	_mouseDelayMet: function(/* event */) {
972		return this.mouseDelayMet;
973	},
974
975	// These are placeholder methods, to be overriden by extending plugin
976	_mouseStart: function(/* event */) {},
977	_mouseDrag: function(/* event */) {},
978	_mouseStop: function(/* event */) {},
979	_mouseCapture: function(/* event */) { return true; }
980});
981
982})(jQuery);
983(function( $, undefined ) {
984
985$.ui = $.ui || {};
986
987var cachedScrollbarWidth,
988	max = Math.max,
989	abs = Math.abs,
990	round = Math.round,
991	rhorizontal = /left|center|right/,
992	rvertical = /top|center|bottom/,
993	roffset = /[\+\-]\d+(\.[\d]+)?%?/,
994	rposition = /^\w+/,
995	rpercent = /%$/,
996	_position = $.fn.position;
997
998function getOffsets( offsets, width, height ) {
999	return [
1000		parseFloat( offsets[ 0 ] ) * ( rpercent.test( offsets[ 0 ] ) ? width / 100 : 1 ),
1001		parseFloat( offsets[ 1 ] ) * ( rpercent.test( offsets[ 1 ] ) ? height / 100 : 1 )
1002	];
1003}
1004
1005function parseCss( element, property ) {
1006	return parseInt( $.css( element, property ), 10 ) || 0;
1007}
1008
1009function getDimensions( elem ) {
1010	var raw = elem[0];
1011	if ( raw.nodeType === 9 ) {
1012		return {
1013			width: elem.width(),
1014			height: elem.height(),
1015			offset: { top: 0, left: 0 }
1016		};
1017	}
1018	if ( $.isWindow( raw ) ) {
1019		return {
1020			width: elem.width(),
1021			height: elem.height(),
1022			offset: { top: elem.scrollTop(), left: elem.scrollLeft() }
1023		};
1024	}
1025	if ( raw.preventDefault ) {
1026		return {
1027			width: 0,
1028			height: 0,
1029			offset: { top: raw.pageY, left: raw.pageX }
1030		};
1031	}
1032	return {
1033		width: elem.outerWidth(),
1034		height: elem.outerHeight(),
1035		offset: elem.offset()
1036	};
1037}
1038
1039$.position = {
1040	scrollbarWidth: function() {
1041		if ( cachedScrollbarWidth !== undefined ) {
1042			return cachedScrollbarWidth;
1043		}
1044		var w1, w2,
1045			div = $( "<div style='display:block;position:absolute;width:50px;height:50px;overflow:hidden;'><div style='height:100px;width:auto;'></div></div>" ),
1046			innerDiv = div.children()[0];
1047
1048		$( "body" ).append( div );
1049		w1 = innerDiv.offsetWidth;
1050		div.css( "overflow", "scroll" );
1051
1052		w2 = innerDiv.offsetWidth;
1053
1054		if ( w1 === w2 ) {
1055			w2 = div[0].clientWidth;
1056		}
1057
1058		div.remove();
1059
1060		return (cachedScrollbarWidth = w1 - w2);
1061	},
1062	getScrollInfo: function( within ) {
1063		var overflowX = within.isWindow || within.isDocument ? "" :
1064				within.element.css( "overflow-x" ),
1065			overflowY = within.isWindow || within.isDocument ? "" :
1066				within.element.css( "overflow-y" ),
1067			hasOverflowX = overflowX === "scroll" ||
1068				( overflowX === "auto" && within.width < within.element[0].scrollWidth ),
1069			hasOverflowY = overflowY === "scroll" ||
1070				( overflowY === "auto" && within.height < within.element[0].scrollHeight );
1071		return {
1072			width: hasOverflowY ? $.position.scrollbarWidth() : 0,
1073			height: hasOverflowX ? $.position.scrollbarWidth() : 0
1074		};
1075	},
1076	getWithinInfo: function( element ) {
1077		var withinElement = $( element || window ),
1078			isWindow = $.isWindow( withinElement[0] ),
1079			isDocument = !!withinElement[ 0 ] && withinElement[ 0 ].nodeType === 9;
1080		return {
1081			element: withinElement,
1082			isWindow: isWindow,
1083			isDocument: isDocument,
1084			offset: withinElement.offset() || { left: 0, top: 0 },
1085			scrollLeft: withinElement.scrollLeft(),
1086			scrollTop: withinElement.scrollTop(),
1087			width: isWindow ? withinElement.width() : withinElement.outerWidth(),
1088			height: isWindow ? withinElement.height() : withinElement.outerHeight()
1089		};
1090	}
1091};
1092
1093$.fn.position = function( options ) {
1094	if ( !options || !options.of ) {
1095		return _position.apply( this, arguments );
1096	}
1097
1098	// make a copy, we don't want to modify arguments
1099	options = $.extend( {}, options );
1100
1101	var atOffset, targetWidth, targetHeight, targetOffset, basePosition, dimensions,
1102		target = $( options.of ),
1103		within = $.position.getWithinInfo( options.within ),
1104		scrollInfo = $.position.getScrollInfo( within ),
1105		collision = ( options.collision || "flip" ).split( " " ),
1106		offsets = {};
1107
1108	dimensions = getDimensions( target );
1109	if ( target[0].preventDefault ) {
1110		// force left top to allow flipping
1111		options.at = "left top";
1112	}
1113	targetWidth = dimensions.width;
1114	targetHeight = dimensions.height;
1115	targetOffset = dimensions.offset;
1116	// clone to reuse original targetOffset later
1117	basePosition = $.extend( {}, targetOffset );
1118
1119	// force my and at to have valid horizontal and vertical positions
1120	// if a value is missing or invalid, it will be converted to center
1121	$.each( [ "my", "at" ], function() {
1122		var pos = ( options[ this ] || "" ).split( " " ),
1123			horizontalOffset,
1124			verticalOffset;
1125
1126		if ( pos.length === 1) {
1127			pos = rhorizontal.test( pos[ 0 ] ) ?
1128				pos.concat( [ "center" ] ) :
1129				rvertical.test( pos[ 0 ] ) ?
1130					[ "center" ].concat( pos ) :
1131					[ "center", "center" ];
1132		}
1133		pos[ 0 ] = rhorizontal.test( pos[ 0 ] ) ? pos[ 0 ] : "center";
1134		pos[ 1 ] = rvertical.test( pos[ 1 ] ) ? pos[ 1 ] : "center";
1135
1136		// calculate offsets
1137		horizontalOffset = roffset.exec( pos[ 0 ] );
1138		verticalOffset = roffset.exec( pos[ 1 ] );
1139		offsets[ this ] = [
1140			horizontalOffset ? horizontalOffset[ 0 ] : 0,
1141			verticalOffset ? verticalOffset[ 0 ] : 0
1142		];
1143
1144		// reduce to just the positions without the offsets
1145		options[ this ] = [
1146			rposition.exec( pos[ 0 ] )[ 0 ],
1147			rposition.exec( pos[ 1 ] )[ 0 ]
1148		];
1149	});
1150
1151	// normalize collision option
1152	if ( collision.length === 1 ) {
1153		collision[ 1 ] = collision[ 0 ];
1154	}
1155
1156	if ( options.at[ 0 ] === "right" ) {
1157		basePosition.left += targetWidth;
1158	} else if ( options.at[ 0 ] === "center" ) {
1159		basePosition.left += targetWidth / 2;
1160	}
1161
1162	if ( options.at[ 1 ] === "bottom" ) {
1163		basePosition.top += targetHeight;
1164	} else if ( options.at[ 1 ] === "center" ) {
1165		basePosition.top += targetHeight / 2;
1166	}
1167
1168	atOffset = getOffsets( offsets.at, targetWidth, targetHeight );
1169	basePosition.left += atOffset[ 0 ];
1170	basePosition.top += atOffset[ 1 ];
1171
1172	return this.each(function() {
1173		var collisionPosition, using,
1174			elem = $( this ),
1175			elemWidth = elem.outerWidth(),
1176			elemHeight = elem.outerHeight(),
1177			marginLeft = parseCss( this, "marginLeft" ),
1178			marginTop = parseCss( this, "marginTop" ),
1179			collisionWidth = elemWidth + marginLeft + parseCss( this, "marginRight" ) + scrollInfo.width,
1180			collisionHeight = elemHeight + marginTop + parseCss( this, "marginBottom" ) + scrollInfo.height,
1181			position = $.extend( {}, basePosition ),
1182			myOffset = getOffsets( offsets.my, elem.outerWidth(), elem.outerHeight() );
1183
1184		if ( options.my[ 0 ] === "right" ) {
1185			position.left -= elemWidth;
1186		} else if ( options.my[ 0 ] === "center" ) {
1187			position.left -= elemWidth / 2;
1188		}
1189
1190		if ( options.my[ 1 ] === "bottom" ) {
1191			position.top -= elemHeight;
1192		} else if ( options.my[ 1 ] === "center" ) {
1193			position.top -= elemHeight / 2;
1194		}
1195
1196		position.left += myOffset[ 0 ];
1197		position.top += myOffset[ 1 ];
1198
1199		// if the browser doesn't support fractions, then round for consistent results
1200		if ( !$.support.offsetFractions ) {
1201			position.left = round( position.left );
1202			position.top = round( position.top );
1203		}
1204
1205		collisionPosition = {
1206			marginLeft: marginLeft,
1207			marginTop: marginTop
1208		};
1209
1210		$.each( [ "left", "top" ], function( i, dir ) {
1211			if ( $.ui.position[ collision[ i ] ] ) {
1212				$.ui.position[ collision[ i ] ][ dir ]( position, {
1213					targetWidth: targetWidth,
1214					targetHeight: targetHeight,
1215					elemWidth: elemWidth,
1216					elemHeight: elemHeight,
1217					collisionPosition: collisionPosition,
1218					collisionWidth: collisionWidth,
1219					collisionHeight: collisionHeight,
1220					offset: [ atOffset[ 0 ] + myOffset[ 0 ], atOffset [ 1 ] + myOffset[ 1 ] ],
1221					my: options.my,
1222					at: options.at,
1223					within: within,
1224					elem : elem
1225				});
1226			}
1227		});
1228
1229		if ( options.using ) {
1230			// adds feedback as second argument to using callback, if present
1231			using = function( props ) {
1232				var left = targetOffset.left - position.left,
1233					right = left + targetWidth - elemWidth,
1234					top = targetOffset.top - position.top,
1235					bottom = top + targetHeight - elemHeight,
1236					feedback = {
1237						target: {
1238							element: target,
1239							left: targetOffset.left,
1240							top: targetOffset.top,
1241							width: targetWidth,
1242							height: targetHeight
1243						},
1244						element: {
1245							element: elem,
1246							left: position.left,
1247							top: position.top,
1248							width: elemWidth,
1249							height: elemHeight
1250						},
1251						horizontal: right < 0 ? "left" : left > 0 ? "right" : "center",
1252						vertical: bottom < 0 ? "top" : top > 0 ? "bottom" : "middle"
1253					};
1254				if ( targetWidth < elemWidth && abs( left + right ) < targetWidth ) {
1255					feedback.horizontal = "center";
1256				}
1257				if ( targetHeight < elemHeight && abs( top + bottom ) < targetHeight ) {
1258					feedback.vertical = "middle";
1259				}
1260				if ( max( abs( left ), abs( right ) ) > max( abs( top ), abs( bottom ) ) ) {
1261					feedback.important = "horizontal";
1262				} else {
1263					feedback.important = "vertical";
1264				}
1265				options.using.call( this, props, feedback );
1266			};
1267		}
1268
1269		elem.offset( $.extend( position, { using: using } ) );
1270	});
1271};
1272
1273$.ui.position = {
1274	fit: {
1275		left: function( position, data ) {
1276			var within = data.within,
1277				withinOffset = within.isWindow ? within.scrollLeft : within.offset.left,
1278				outerWidth = within.width,
1279				collisionPosLeft = position.left - data.collisionPosition.marginLeft,
1280				overLeft = withinOffset - collisionPosLeft,
1281				overRight = collisionPosLeft + data.collisionWidth - outerWidth - withinOffset,
1282				newOverRight;
1283
1284			// element is wider than within
1285			if ( data.collisionWidth > outerWidth ) {
1286				// element is initially over the left side of within
1287				if ( overLeft > 0 && overRight <= 0 ) {
1288					newOverRight = position.left + overLeft + data.collisionWidth - outerWidth - withinOffset;
1289					position.left += overLeft - newOverRight;
1290				// element is initially over right side of within
1291				} else if ( overRight > 0 && overLeft <= 0 ) {
1292					position.left = withinOffset;
1293				// element is initially over both left and right sides of within
1294				} else {
1295					if ( overLeft > overRight ) {
1296						position.left = withinOffset + outerWidth - data.collisionWidth;
1297					} else {
1298						position.left = withinOffset;
1299					}
1300				}
1301			// too far left -> align with left edge
1302			} else if ( overLeft > 0 ) {
1303				position.left += overLeft;
1304			// too far right -> align with right edge
1305			} else if ( overRight > 0 ) {
1306				position.left -= overRight;
1307			// adjust based on position and margin
1308			} else {
1309				position.left = max( position.left - collisionPosLeft, position.left );
1310			}
1311		},
1312		top: function( position, data ) {
1313			var within = data.within,
1314				withinOffset = within.isWindow ? within.scrollTop : within.offset.top,
1315				outerHeight = data.within.height,
1316				collisionPosTop = position.top - data.collisionPosition.marginTop,
1317				overTop = withinOffset - collisionPosTop,
1318				overBottom = collisionPosTop + data.collisionHeight - outerHeight - withinOffset,
1319				newOverBottom;
1320
1321			// element is taller than within
1322			if ( data.collisionHeight > outerHeight ) {
1323				// element is initially over the top of within
1324				if ( overTop > 0 && overBottom <= 0 ) {
1325					newOverBottom = position.top + overTop + data.collisionHeight - outerHeight - withinOffset;
1326					position.top += overTop - newOverBottom;
1327				// element is initially over bottom of within
1328				} else if ( overBottom > 0 && overTop <= 0 ) {
1329					position.top = withinOffset;
1330				// element is initially over both top and bottom of within
1331				} else {
1332					if ( overTop > overBottom ) {
1333						position.top = withinOffset + outerHeight - data.collisionHeight;
1334					} else {
1335						position.top = withinOffset;
1336					}
1337				}
1338			// too far up -> align with top
1339			} else if ( overTop > 0 ) {
1340				position.top += overTop;
1341			// too far down -> align with bottom edge
1342			} else if ( overBottom > 0 ) {
1343				position.top -= overBottom;
1344			// adjust based on position and margin
1345			} else {
1346				position.top = max( position.top - collisionPosTop, position.top );
1347			}
1348		}
1349	},
1350	flip: {
1351		left: function( position, data ) {
1352			var within = data.within,
1353				withinOffset = within.offset.left + within.scrollLeft,
1354				outerWidth = within.width,
1355				offsetLeft = within.isWindow ? within.scrollLeft : within.offset.left,
1356				collisionPosLeft = position.left - data.collisionPosition.marginLeft,
1357				overLeft = collisionPosLeft - offsetLeft,
1358				overRight = collisionPosLeft + data.collisionWidth - outerWidth - offsetLeft,
1359				myOffset = data.my[ 0 ] === "left" ?
1360					-data.elemWidth :
1361					data.my[ 0 ] === "right" ?
1362						data.elemWidth :
1363						0,
1364				atOffset = data.at[ 0 ] === "left" ?
1365					data.targetWidth :
1366					data.at[ 0 ] === "right" ?
1367						-data.targetWidth :
1368						0,
1369				offset = -2 * data.offset[ 0 ],
1370				newOverRight,
1371				newOverLeft;
1372
1373			if ( overLeft < 0 ) {
1374				newOverRight = position.left + myOffset + atOffset + offset + data.collisionWidth - outerWidth - withinOffset;
1375				if ( newOverRight < 0 || newOverRight < abs( overLeft ) ) {
1376					position.left += myOffset + atOffset + offset;
1377				}
1378			}
1379			else if ( overRight > 0 ) {
1380				newOverLeft = position.left - data.collisionPosition.marginLeft + myOffset + atOffset + offset - offsetLeft;
1381				if ( newOverLeft > 0 || abs( newOverLeft ) < overRight ) {
1382					position.left += myOffset + atOffset + offset;
1383				}
1384			}
1385		},
1386		top: function( position, data ) {
1387			var within = data.within,
1388				withinOffset = within.offset.top + within.scrollTop,
1389				outerHeight = within.height,
1390				offsetTop = within.isWindow ? within.scrollTop : within.offset.top,
1391				collisionPosTop = position.top - data.collisionPosition.marginTop,
1392				overTop = collisionPosTop - offsetTop,
1393				overBottom = collisionPosTop + data.collisionHeight - outerHeight - offsetTop,
1394				top = data.my[ 1 ] === "top",
1395				myOffset = top ?
1396					-data.elemHeight :
1397					data.my[ 1 ] === "bottom" ?
1398						data.elemHeight :
1399						0,
1400				atOffset = data.at[ 1 ] === "top" ?
1401					data.targetHeight :
1402					data.at[ 1 ] === "bottom" ?
1403						-data.targetHeight :
1404						0,
1405				offset = -2 * data.offset[ 1 ],
1406				newOverTop,
1407				newOverBottom;
1408			if ( overTop < 0 ) {
1409				newOverBottom = position.top + myOffset + atOffset + offset + data.collisionHeight - outerHeight - withinOffset;
1410				if ( ( position.top + myOffset + atOffset + offset) > overTop && ( newOverBottom < 0 || newOverBottom < abs( overTop ) ) ) {
1411					position.top += myOffset + atOffset + offset;
1412				}
1413			}
1414			else if ( overBottom > 0 ) {
1415				newOverTop = position.top - data.collisionPosition.marginTop + myOffset + atOffset + offset - offsetTop;
1416				if ( ( position.top + myOffset + atOffset + offset) > overBottom && ( newOverTop > 0 || abs( newOverTop ) < overBottom ) ) {
1417					position.top += myOffset + atOffset + offset;
1418				}
1419			}
1420		}
1421	},
1422	flipfit: {
1423		left: function() {
1424			$.ui.position.flip.left.apply( this, arguments );
1425			$.ui.position.fit.left.apply( this, arguments );
1426		},
1427		top: function() {
1428			$.ui.position.flip.top.apply( this, arguments );
1429			$.ui.position.fit.top.apply( this, arguments );
1430		}
1431	}
1432};
1433
1434// fraction support test
1435(function () {
1436	var testElement, testElementParent, testElementStyle, offsetLeft, i,
1437		body = document.getElementsByTagName( "body" )[ 0 ],
1438		div = document.createElement( "div" );
1439
1440	//Create a "fake body" for testing based on method used in jQuery.support
1441	testElement = document.createElement( body ? "div" : "body" );
1442	testElementStyle = {
1443		visibility: "hidden",
1444		width: 0,
1445		height: 0,
1446		border: 0,
1447		margin: 0,
1448		background: "none"
1449	};
1450	if ( body ) {
1451		$.extend( testElementStyle, {
1452			position: "absolute",
1453			left: "-1000px",
1454			top: "-1000px"
1455		});
1456	}
1457	for ( i in testElementStyle ) {
1458		testElement.style[ i ] = testElementStyle[ i ];
1459	}
1460	testElement.appendChild( div );
1461	testElementParent = body || document.documentElement;
1462	testElementParent.insertBefore( testElement, testElementParent.firstChild );
1463
1464	div.style.cssText = "position: absolute; left: 10.7432222px;";
1465
1466	offsetLeft = $( div ).offset().left;
1467	$.support.offsetFractions = offsetLeft > 10 && offsetLeft < 11;
1468
1469	testElement.innerHTML = "";
1470	testElementParent.removeChild( testElement );
1471})();
1472
1473}( jQuery ) );
1474(function( $, undefined ) {
1475
1476$.widget("ui.draggable", $.ui.mouse, {
1477	version: "1.10.4",
1478	widgetEventPrefix: "drag",
1479	options: {
1480		addClasses: true,
1481		appendTo: "parent",
1482		axis: false,
1483		connectToSortable: false,
1484		containment: false,
1485		cursor: "auto",
1486		cursorAt: false,
1487		grid: false,
1488		handle: false,
1489		helper: "original",
1490		iframeFix: false,
1491		opacity: false,
1492		refreshPositions: false,
1493		revert: false,
1494		revertDuration: 500,
1495		scope: "default",
1496		scroll: true,
1497		scrollSensitivity: 20,
1498		scrollSpeed: 20,
1499		snap: false,
1500		snapMode: "both",
1501		snapTolerance: 20,
1502		stack: false,
1503		zIndex: false,
1504
1505		// callbacks
1506		drag: null,
1507		start: null,
1508		stop: null
1509	},
1510	_create: function() {
1511
1512		if (this.options.helper === "original" && !(/^(?:r|a|f)/).test(this.element.css("position"))) {
1513			this.element[0].style.position = "relative";
1514		}
1515		if (this.options.addClasses){
1516			this.element.addClass("ui-draggable");
1517		}
1518		if (this.options.disabled){
1519			this.element.addClass("ui-draggable-disabled");
1520		}
1521
1522		this._mouseInit();
1523
1524	},
1525
1526	_destroy: function() {
1527		this.element.removeClass( "ui-draggable ui-draggable-dragging ui-draggable-disabled" );
1528		this._mouseDestroy();
1529	},
1530
1531	_mouseCapture: function(event) {
1532
1533		var o = this.options;
1534
1535		// among others, prevent a drag on a resizable-handle
1536		if (this.helper || o.disabled || $(event.target).closest(".ui-resizable-handle").length > 0) {
1537			return false;
1538		}
1539
1540		//Quit if we're not on a valid handle
1541		this.handle = this._getHandle(event);
1542		if (!this.handle) {
1543			return false;
1544		}
1545
1546		$(o.iframeFix === true ? "iframe" : o.iframeFix).each(function() {
1547			$("<div class='ui-draggable-iframeFix' style='background: #fff;'></div>")
1548			.css({
1549				width: this.offsetWidth+"px", height: this.offsetHeight+"px",
1550				position: "absolute", opacity: "0.001", zIndex: 1000
1551			})
1552			.css($(this).offset())
1553			.appendTo("body");
1554		});
1555
1556		return true;
1557
1558	},
1559
1560	_mouseStart: function(event) {
1561
1562		var o = this.options;
1563
1564		//Create and append the visible helper
1565		this.helper = this._createHelper(event);
1566
1567		this.helper.addClass("ui-draggable-dragging");
1568
1569		//Cache the helper size
1570		this._cacheHelperProportions();
1571
1572		//If ddmanager is used for droppables, set the global draggable
1573		if($.ui.ddmanager) {
1574			$.ui.ddmanager.current = this;
1575		}
1576
1577		/*
1578		 * - Position generation -
1579		 * This block generates everything position related - it's the core of draggables.
1580		 */
1581
1582		//Cache the margins of the original element
1583		this._cacheMargins();
1584
1585		//Store the helper's css position
1586		this.cssPosition = this.helper.css( "position" );
1587		this.scrollParent = this.helper.scrollParent();
1588		this.offsetParent = this.helper.offsetParent();
1589		this.offsetParentCssPosition = this.offsetParent.css( "position" );
1590
1591		//The element's absolute position on the page minus margins
1592		this.offset = this.positionAbs = this.element.offset();
1593		this.offset = {
1594			top: this.offset.top - this.margins.top,
1595			left: this.offset.left - this.margins.left
1596		};
1597
1598		//Reset scroll cache
1599		this.offset.scroll = false;
1600
1601		$.extend(this.offset, {
1602			click: { //Where the click happened, relative to the element
1603				left: event.pageX - this.offset.left,
1604				top: event.pageY - this.offset.top
1605			},
1606			parent: this._getParentOffset(),
1607			relative: this._getRelativeOffset() //This is a relative to absolute position minus the actual position calculation - only used for relative positioned helper
1608		});
1609
1610		//Generate the original position
1611		this.originalPosition = this.position = this._generatePosition(event);
1612		this.originalPageX = event.pageX;
1613		this.originalPageY = event.pageY;
1614
1615		//Adjust the mouse offset relative to the helper if "cursorAt" is supplied
1616		(o.cursorAt && this._adjustOffsetFromHelper(o.cursorAt));
1617
1618		//Set a containment if given in the options
1619		this._setContainment();
1620
1621		//Trigger event + callbacks
1622		if(this._trigger("start", event) === false) {
1623			this._clear();
1624			return false;
1625		}
1626
1627		//Recache the helper size
1628		this._cacheHelperProportions();
1629
1630		//Prepare the droppable offsets
1631		if ($.ui.ddmanager && !o.dropBehaviour) {
1632			$.ui.ddmanager.prepareOffsets(this, event);
1633		}
1634
1635
1636		this._mouseDrag(event, true); //Execute the drag once - this causes the helper not to be visible before getting its correct position
1637
1638		//If the ddmanager is used for droppables, inform the manager that dragging has started (see #5003)
1639		if ( $.ui.ddmanager ) {
1640			$.ui.ddmanager.dragStart(this, event);
1641		}
1642
1643		return true;
1644	},
1645
1646	_mouseDrag: function(event, noPropagation) {
1647		// reset any necessary cached properties (see #5009)
1648		if ( this.offsetParentCssPosition === "fixed" ) {
1649			this.offset.parent = this._getParentOffset();
1650		}
1651
1652		//Compute the helpers position
1653		this.position = this._generatePosition(event);
1654		this.positionAbs = this._convertPositionTo("absolute");
1655
1656		//Call plugins and callbacks and use the resulting position if something is returned
1657		if (!noPropagation) {
1658			var ui = this._uiHash();
1659			if(this._trigger("drag", event, ui) === false) {
1660				this._mouseUp({});
1661				return false;
1662			}
1663			this.position = ui.position;
1664		}
1665
1666		if(!this.options.axis || this.options.axis !== "y") {
1667			this.helper[0].style.left = this.position.left+"px";
1668		}
1669		if(!this.options.axis || this.options.axis !== "x") {
1670			this.helper[0].style.top = this.position.top+"px";
1671		}
1672		if($.ui.ddmanager) {
1673			$.ui.ddmanager.drag(this, event);
1674		}
1675
1676		return false;
1677	},
1678
1679	_mouseStop: function(event) {
1680
1681		//If we are using droppables, inform the manager about the drop
1682		var that = this,
1683			dropped = false;
1684		if ($.ui.ddmanager && !this.options.dropBehaviour) {
1685			dropped = $.ui.ddmanager.drop(this, event);
1686		}
1687
1688		//if a drop comes from outside (a sortable)
1689		if(this.dropped) {
1690			dropped = this.dropped;
1691			this.dropped = false;
1692		}
1693
1694		//if the original element is no longer in the DOM don't bother to continue (see #8269)
1695		if ( this.options.helper === "original" && !$.contains( this.element[ 0 ].ownerDocument, this.element[ 0 ] ) ) {
1696			return false;
1697		}
1698
1699		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))) {
1700			$(this.helper).animate(this.originalPosition, parseInt(this.options.revertDuration, 10), function() {
1701				if(that._trigger("stop", event) !== false) {
1702					that._clear();
1703				}
1704			});
1705		} else {
1706			if(this._trigger("stop", event) !== false) {
1707				this._clear();
1708			}
1709		}
1710
1711		return false;
1712	},
1713
1714	_mouseUp: function(event) {
1715		//Remove frame helpers
1716		$("div.ui-draggable-iframeFix").each(function() {
1717			this.parentNode.removeChild(this);
1718		});
1719
1720		//If the ddmanager is used for droppables, inform the manager that dragging has stopped (see #5003)
1721		if( $.ui.ddmanager ) {
1722			$.ui.ddmanager.dragStop(this, event);
1723		}
1724
1725		return $.ui.mouse.prototype._mouseUp.call(this, event);
1726	},
1727
1728	cancel: function() {
1729
1730		if(this.helper.is(".ui-draggable-dragging")) {
1731			this._mouseUp({});
1732		} else {
1733			this._clear();
1734		}
1735
1736		return this;
1737
1738	},
1739
1740	_getHandle: function(event) {
1741		return this.options.handle ?
1742			!!$( event.target ).closest( this.element.find( this.options.handle ) ).length :
1743			true;
1744	},
1745
1746	_createHelper: function(event) {
1747
1748		var o = this.options,
1749			helper = $.isFunction(o.helper) ? $(o.helper.apply(this.element[0], [event])) : (o.helper === "clone" ? this.element.clone().removeAttr("id") : this.element);
1750
1751		if(!helper.parents("body").length) {
1752			helper.appendTo((o.appendTo === "parent" ? this.element[0].parentNode : o.appendTo));
1753		}
1754
1755		if(helper[0] !== this.element[0] && !(/(fixed|absolute)/).test(helper.css("position"))) {
1756			helper.css("position", "absolute");
1757		}
1758
1759		return helper;
1760
1761	},
1762
1763	_adjustOffsetFromHelper: function(obj) {
1764		if (typeof obj === "string") {
1765			obj = obj.split(" ");
1766		}
1767		if ($.isArray(obj)) {
1768			obj = {left: +obj[0], top: +obj[1] || 0};
1769		}
1770		if ("left" in obj) {
1771			this.offset.click.left = obj.left + this.margins.left;
1772		}
1773		if ("right" in obj) {
1774			this.offset.click.left = this.helperProportions.width - obj.right + this.margins.left;
1775		}
1776		if ("top" in obj) {
1777			this.offset.click.top = obj.top + this.margins.top;
1778		}
1779		if ("bottom" in obj) {
1780			this.offset.click.top = this.helperProportions.height - obj.bottom + this.margins.top;
1781		}
1782	},
1783
1784	_getParentOffset: function() {
1785
1786		//Get the offsetParent and cache its position
1787		var po = this.offsetParent.offset();
1788
1789		// This is a special case where we need to modify a offset calculated on start, since the following happened:
1790		// 1. The position of the helper is absolute, so it's position is calculated based on the next positioned parent
1791		// 2. The actual offset parent is a child of the scroll parent, and the scroll parent isn't the document, which means that
1792		//    the scroll is included in the initial calculation of the offset of the parent, and never recalculated upon drag
1793		if(this.cssPosition === "absolute" && this.scrollParent[0] !== document && $.contains(this.scrollParent[0], this.offsetParent[0])) {
1794			po.left += this.scrollParent.scrollLeft();
1795			po.top += this.scrollParent.scrollTop();
1796		}
1797
1798		//This needs to be actually done for all browsers, since pageX/pageY includes this information
1799		//Ugly IE fix
1800		if((this.offsetParent[0] === document.body) ||
1801			(this.offsetParent[0].tagName && this.offsetParent[0].tagName.toLowerCase() === "html" && $.ui.ie)) {
1802			po = { top: 0, left: 0 };
1803		}
1804
1805		return {
1806			top: po.top + (parseInt(this.offsetParent.css("borderTopWidth"),10) || 0),
1807			left: po.left + (parseInt(this.offsetParent.css("borderLeftWidth"),10) || 0)
1808		};
1809
1810	},
1811
1812	_getRelativeOffset: function() {
1813
1814		if(this.cssPosition === "relative") {
1815			var p = this.element.position();
1816			return {
1817				top: p.top - (parseInt(this.helper.css("top"),10) || 0) + this.scrollParent.scrollTop(),
1818				left: p.left - (parseInt(this.helper.css("left"),10) || 0) + this.scrollParent.scrollLeft()
1819			};
1820		} else {
1821			return { top: 0, left: 0 };
1822		}
1823
1824	},
1825
1826	_cacheMargins: function() {
1827		this.margins = {
1828			left: (parseInt(this.element.css("marginLeft"),10) || 0),
1829			top: (parseInt(this.element.css("marginTop"),10) || 0),
1830			right: (parseInt(this.element.css("marginRight"),10) || 0),
1831			bottom: (parseInt(this.element.css("marginBottom"),10) || 0)
1832		};
1833	},
1834
1835	_cacheHelperProportions: function() {
1836		this.helperProportions = {
1837			width: this.helper.outerWidth(),
1838			height: this.helper.outerHeight()
1839		};
1840	},
1841
1842	_setContainment: function() {
1843
1844		var over, c, ce,
1845			o = this.options;
1846
1847		if ( !o.containment ) {
1848			this.containment = null;
1849			return;
1850		}
1851
1852		if ( o.containment === "window" ) {
1853			this.containment = [
1854				$( window ).scrollLeft() - this.offset.relative.left - this.offset.parent.left,
1855				$( window ).scrollTop() - this.offset.relative.top - this.offset.parent.top,
1856				$( window ).scrollLeft() + $( window ).width() - this.helperProportions.width - this.margins.left,
1857				$( window ).scrollTop() + ( $( window ).height() || document.body.parentNode.scrollHeight ) - this.helperProportions.height - this.margins.top
1858			];
1859			return;
1860		}
1861
1862		if ( o.containment === "document") {
1863			this.containment = [
1864				0,
1865				0,
1866				$( document ).width() - this.helperProportions.width - this.margins.left,
1867				( $( document ).height() || document.body.parentNode.scrollHeight ) - this.helperProportions.height - this.margins.top
1868			];
1869			return;
1870		}
1871
1872		if ( o.containment.constructor === Array ) {
1873			this.containment = o.containment;
1874			return;
1875		}
1876
1877		if ( o.containment === "parent" ) {
1878			o.containment = this.helper[ 0 ].parentNode;
1879		}
1880
1881		c = $( o.containment );
1882		ce = c[ 0 ];
1883
1884		if( !ce ) {
1885			return;
1886		}
1887
1888		over = c.css( "overflow" ) !== "hidden";
1889
1890		this.containment = [
1891			( parseInt( c.css( "borderLeftWidth" ), 10 ) || 0 ) + ( parseInt( c.css( "paddingLeft" ), 10 ) || 0 ),
1892			( parseInt( c.css( "borderTopWidth" ), 10 ) || 0 ) + ( parseInt( c.css( "paddingTop" ), 10 ) || 0 ) ,
1893			( over ? Math.max( ce.scrollWidth, ce.offsetWidth ) : ce.offsetWidth ) - ( parseInt( c.css( "borderRightWidth" ), 10 ) || 0 ) - ( parseInt( c.css( "paddingRight" ), 10 ) || 0 ) - this.helperProportions.width - this.margins.left - this.margins.right,
1894			( over ? Math.max( ce.scrollHeight, ce.offsetHeight ) : ce.offsetHeight ) - ( parseInt( c.css( "borderBottomWidth" ), 10 ) || 0 ) - ( parseInt( c.css( "paddingBottom" ), 10 ) || 0 ) - this.helperProportions.height - this.margins.top  - this.margins.bottom
1895		];
1896		this.relative_container = c;
1897	},
1898
1899	_convertPositionTo: function(d, pos) {
1900
1901		if(!pos) {
1902			pos = this.position;
1903		}
1904
1905		var mod = d === "absolute" ? 1 : -1,
1906			scroll = this.cssPosition === "absolute" && !( this.scrollParent[ 0 ] !== document && $.contains( this.scrollParent[ 0 ], this.offsetParent[ 0 ] ) ) ? this.offsetParent : this.scrollParent;
1907
1908		//Cache the scroll
1909		if (!this.offset.scroll) {
1910			this.offset.scroll = {top : scroll.scrollTop(), left : scroll.scrollLeft()};
1911		}
1912
1913		return {
1914			top: (
1915				pos.top	+																// The absolute mouse position
1916				this.offset.relative.top * mod +										// Only for relative positioned nodes: Relative offset from element to offset parent
1917				this.offset.parent.top * mod -										// The offsetParent's offset without borders (offset + border)
1918				( ( this.cssPosition === "fixed" ? -this.scrollParent.scrollTop() : this.offset.scroll.top ) * mod )
1919			),
1920			left: (
1921				pos.left +																// The absolute mouse position
1922				this.offset.relative.left * mod +										// Only for relative positioned nodes: Relative offset from element to offset parent
1923				this.offset.parent.left * mod	-										// The offsetParent's offset without borders (offset + border)
1924				( ( this.cssPosition === "fixed" ? -this.scrollParent.scrollLeft() : this.offset.scroll.left ) * mod )
1925			)
1926		};
1927
1928	},
1929
1930	_generatePosition: function(event) {
1931
1932		var containment, co, top, left,
1933			o = this.options,
1934			scroll = this.cssPosition === "absolute" && !( this.scrollParent[ 0 ] !== document && $.contains( this.scrollParent[ 0 ], this.offsetParent[ 0 ] ) ) ? this.offsetParent : this.scrollParent,
1935			pageX = event.pageX,
1936			pageY = event.pageY;
1937
1938		//Cache the scroll
1939		if (!this.offset.scroll) {
1940			this.offset.scroll = {top : scroll.scrollTop(), left : scroll.scrollLeft()};
1941		}
1942
1943		/*
1944		 * - Position constraining -
1945		 * Constrain the position to a mix of grid, containment.
1946		 */
1947
1948		// If we are not dragging yet, we won't check for options
1949		if ( this.originalPosition ) {
1950			if ( this.containment ) {
1951				if ( this.relative_container ){
1952					co = this.relative_container.offset();
1953					containment = [
1954						this.containment[ 0 ] + co.left,
1955						this.containment[ 1 ] + co.top,
1956						this.containment[ 2 ] + co.left,
1957						this.containment[ 3 ] + co.top
1958					];
1959				}
1960				else {
1961					containment = this.containment;
1962				}
1963
1964				if(event.pageX - this.offset.click.left < containment[0]) {
1965					pageX = containment[0] + this.offset.click.left;
1966				}
1967				if(event.pageY - this.offset.click.top < containment[1]) {
1968					pageY = containment[1] + this.offset.click.top;
1969				}
1970				if(event.pageX - this.offset.click.left > containment[2]) {
1971					pageX = containment[2] + this.offset.click.left;
1972				}
1973				if(event.pageY - this.offset.click.top > containment[3]) {
1974					pageY = containment[3] + this.offset.click.top;
1975				}
1976			}
1977
1978			if(o.grid) {
1979				//Check for grid elements set to 0 to prevent divide by 0 error causing invalid argument errors in IE (see ticket #6950)
1980				top = o.grid[1] ? this.originalPageY + Math.round((pageY - this.originalPageY) / o.grid[1]) * o.grid[1] : this.originalPageY;
1981				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;
1982
1983				left = o.grid[0] ? this.originalPageX + Math.round((pageX - this.originalPageX) / o.grid[0]) * o.grid[0] : this.originalPageX;
1984				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;
1985			}
1986
1987		}
1988
1989		return {
1990			top: (
1991				pageY -																	// The absolute mouse position
1992				this.offset.click.top	-												// Click offset (relative to the element)
1993				this.offset.relative.top -												// Only for relative positioned nodes: Relative offset from element to offset parent
1994				this.offset.parent.top +												// The offsetParent's offset without borders (offset + border)
1995				( this.cssPosition === "fixed" ? -this.scrollParent.scrollTop() : this.offset.scroll.top )
1996			),
1997			left: (
1998				pageX -																	// The absolute mouse position
1999				this.offset.click.left -												// Click offset (relative to the element)
2000				this.offset.relative.left -												// Only for relative positioned nodes: Relative offset from element to offset parent
2001				this.offset.parent.left +												// The offsetParent's offset without borders (offset + border)
2002				( this.cssPosition === "fixed" ? -this.scrollParent.scrollLeft() : this.offset.scroll.left )
2003			)
2004		};
2005
2006	},
2007
2008	_clear: function() {
2009		this.helper.removeClass("ui-draggable-dragging");
2010		if(this.helper[0] !== this.element[0] && !this.cancelHelperRemoval) {
2011			this.helper.remove();
2012		}
2013		this.helper = null;
2014		this.cancelHelperRemoval = false;
2015	},
2016
2017	// From now on bulk stuff - mainly helpers
2018
2019	_trigger: function(type, event, ui) {
2020		ui = ui || this._uiHash();
2021		$.ui.plugin.call(this, type, [event, ui]);
2022		//The absolute position has to be recalculated after plugins
2023		if(type === "drag") {
2024			this.positionAbs = this._convertPositionTo("absolute");
2025		}
2026		return $.Widget.prototype._trigger.call(this, type, event, ui);
2027	},
2028
2029	plugins: {},
2030
2031	_uiHash: function() {
2032		return {
2033			helper: this.helper,
2034			position: this.position,
2035			originalPosition: this.originalPosition,
2036			offset: this.positionAbs
2037		};
2038	}
2039
2040});
2041
2042$.ui.plugin.add("draggable", "connectToSortable", {
2043	start: function(event, ui) {
2044
2045		var inst = $(this).data("ui-draggable"), o = inst.options,
2046			uiSortable = $.extend({}, ui, { item: inst.element });
2047		inst.sortables = [];
2048		$(o.connectToSortable).each(function() {
2049			var sortable = $.data(this, "ui-sortable");
2050			if (sortable && !sortable.options.disabled) {
2051				inst.sortables.push({
2052					instance: sortable,
2053					shouldRevert: sortable.options.revert
2054				});
2055				sortable.refreshPositions();	// Call the sortable's refreshPositions at drag start to refresh the containerCache since the sortable container cache is used in drag and needs to be up to date (this will ensure it's initialised as well as being kept in step with any changes that might have happened on the page).
2056				sortable._trigger("activate", event, uiSortable);
2057			}
2058		});
2059
2060	},
2061	stop: function(event, ui) {
2062
2063		//If we are still over the sortable, we fake the stop event of the sortable, but also remove helper
2064		var inst = $(this).data("ui-draggable"),
2065			uiSortable = $.extend({}, ui, { item: inst.element });
2066
2067		$.each(inst.sortables, function() {
2068			if(this.instance.isOver) {
2069
2070				this.instance.isOver = 0;
2071
2072				inst.cancelHelperRemoval = true; //Don't remove the helper in the draggable instance
2073				this.instance.cancelHelperRemoval = false; //Remove it in the sortable instance (so sortable plugins like revert still work)
2074
2075				//The sortable revert is supported, and we have to set a temporary dropped variable on the draggable to support revert: "valid/invalid"
2076				if(this.shouldRevert) {
2077					this.instance.options.revert = this.shouldRevert;
2078				}
2079
2080				//Trigger the stop of the sortable
2081				this.instance._mouseStop(event);
2082
2083				this.instance.options.helper = this.instance.options._helper;
2084
2085				//If the helper has been the original item, restore properties in the sortable
2086				if(inst.options.helper === "original") {
2087					this.instance.currentItem.css({ top: "auto", left: "auto" });
2088				}
2089
2090			} else {
2091				this.instance.cancelHelperRemoval = false; //Remove the helper in the sortable instance
2092				this.instance._trigger("deactivate", event, uiSortable);
2093			}
2094
2095		});
2096
2097	},
2098	drag: function(event, ui) {
2099
2100		var inst = $(this).data("ui-draggable"), that = this;
2101
2102		$.each(inst.sortables, function() {
2103
2104			var innermostIntersecting = false,
2105				thisSortable = this;
2106
2107			//Copy over some variables to allow calling the sortable's native _intersectsWith
2108			this.instance.positionAbs = inst.positionAbs;
2109			this.instance.helperProportions = inst.helperProportions;
2110			this.instance.offset.click = inst.offset.click;
2111
2112			if(this.instance._intersectsWith(this.instance.containerCache)) {
2113				innermostIntersecting = true;
2114				$.each(inst.sortables, function () {
2115					this.instance.positionAbs = inst.positionAbs;
2116					this.instance.helperProportions = inst.helperProportions;
2117					this.instance.offset.click = inst.offset.click;
2118					if (this !== thisSortable &&
2119						this.instance._intersectsWith(this.instance.containerCache) &&
2120						$.contains(thisSortable.instance.element[0], this.instance.element[0])
2121					) {
2122						innermostIntersecting = false;
2123					}
2124					return innermostIntersecting;
2125				});
2126			}
2127
2128
2129			if(innermostIntersecting) {
2130				//If it intersects, we use a little isOver variable and set it once, so our move-in stuff gets fired only once
2131				if(!this.instance.isOver) {
2132
2133					this.instance.isOver = 1;
2134					//Now we fake the start of dragging for the sortable instance,
2135					//by cloning the list group item, appending it to the sortable and using it as inst.currentItem
2136					//We can then fire the start event of the sortable with our passed browser event, and our own helper (so it doesn't create a new one)
2137					this.instance.currentItem = $(that).clone().removeAttr("id").appendTo(this.instance.element).data("ui-sortable-item", true);
2138					this.instance.options._helper = this.instance.options.helper; //Store helper option to later restore it
2139					this.instance.options.helper = function() { return ui.helper[0]; };
2140
2141					event.target = this.instance.currentItem[0];
2142					this.instance._mouseCapture(event, true);
2143					this.instance._mouseStart(event, true, true);
2144
2145					//Because the browser event is way off the new appended portlet, we modify a couple of variables to reflect the changes
2146					this.instance.offset.click.top = inst.offset.click.top;
2147					this.instance.offset.click.left = inst.offset.click.left;
2148					this.instance.offset.parent.left -= inst.offset.parent.left - this.instance.offset.parent.left;
2149					this.instance.offset.parent.top -= inst.offset.parent.top - this.instance.offset.parent.top;
2150
2151					inst._trigger("toSortable", event);
2152					inst.dropped = this.instance.element; //draggable revert needs that
2153					//hack so receive/update callbacks work (mostly)
2154					inst.currentItem = inst.element;
2155					this.instance.fromOutside = inst;
2156
2157				}
2158
2159				//Provided we did all the previous steps, we can fire the drag event of the sortable on every draggable drag, when it intersects with the sortable
2160				if(this.instance.currentItem) {
2161					this.instance._mouseDrag(event);
2162				}
2163
2164			} else {
2165
2166				//If it doesn't intersect with the sortable, and it intersected before,
2167				//we fake the drag stop of the sortable, but make sure it doesn't remove the helper by using cancelHelperRemoval
2168				if(this.instance.isOver) {
2169
2170					this.instance.isOver = 0;
2171					this.instance.cancelHelperRemoval = true;
2172
2173					//Prevent reverting on this forced stop
2174					this.instance.options.revert = false;
2175
2176					// The out event needs to be triggered independently
2177					this.instance._trigger("out", event, this.instance._uiHash(this.instance));
2178
2179					this.instance._mouseStop(event, true);
2180					this.instance.options.helper = this.instance.options._helper;
2181
2182					//Now we remove our currentItem, the list group clone again, and the placeholder, and animate the helper back to it's original size
2183					this.instance.currentItem.remove();
2184					if(this.instance.placeholder) {
2185						this.instance.placeholder.remove();
2186					}
2187
2188					inst._trigger("fromSortable", event);
2189					inst.dropped = false; //draggable revert needs that
2190				}
2191
2192			}
2193
2194		});
2195
2196	}
2197});
2198
2199$.ui.plugin.add("draggable", "cursor", {
2200	start: function() {
2201		var t = $("body"), o = $(this).data("ui-draggable").options;
2202		if (t.css("cursor")) {
2203			o._cursor = t.css("cursor");
2204		}
2205		t.css("cursor", o.cursor);
2206	},
2207	stop: function() {
2208		var o = $(this).data("ui-draggable").options;
2209		if (o._cursor) {
2210			$("body").css("cursor", o._cursor);
2211		}
2212	}
2213});
2214
2215$.ui.plugin.add("draggable", "opacity", {
2216	start: function(event, ui) {
2217		var t = $(ui.helper), o = $(this).data("ui-draggable").options;
2218		if(t.css("opacity")) {
2219			o._opacity = t.css("opacity");
2220		}
2221		t.css("opacity", o.opacity);
2222	},
2223	stop: function(event, ui) {
2224		var o = $(this).data("ui-draggable").options;
2225		if(o._opacity) {
2226			$(ui.helper).css("opacity", o._opacity);
2227		}
2228	}
2229});
2230
2231$.ui.plugin.add("draggable", "scroll", {
2232	start: function() {
2233		var i = $(this).data("ui-draggable");
2234		if(i.scrollParent[0] !== document && i.scrollParent[0].tagName !== "HTML") {
2235			i.overflowOffset = i.scrollParent.offset();
2236		}
2237	},
2238	drag: function( event ) {
2239
2240		var i = $(this).data("ui-draggable"), o = i.options, scrolled = false;
2241
2242		if(i.scrollParent[0] !== document && i.scrollParent[0].tagName !== "HTML") {
2243
2244			if(!o.axis || o.axis !== "x") {
2245				if((i.overflowOffset.top + i.scrollParent[0].offsetHeight) - event.pageY < o.scrollSensitivity) {
2246					i.scrollParent[0].scrollTop = scrolled = i.scrollParent[0].scrollTop + o.scrollSpeed;
2247				} else if(event.pageY - i.overflowOffset.top < o.scrollSensitivity) {
2248					i.scrollParent[0].scrollTop = scrolled = i.scrollParent[0].scrollTop - o.scrollSpeed;
2249				}
2250			}
2251
2252			if(!o.axis || o.axis !== "y") {
2253				if((i.overflowOffset.left + i.scrollParent[0].offsetWidth) - event.pageX < o.scrollSensitivity) {
2254					i.scrollParent[0].scrollLeft = scrolled = i.scrollParent[0].scrollLeft + o.scrollSpeed;
2255				} else if(event.pageX - i.overflowOffset.left < o.scrollSensitivity) {
2256					i.scrollParent[0].scrollLeft = scrolled = i.scrollParent[0].scrollLeft - o.scrollSpeed;
2257				}
2258			}
2259
2260		} else {
2261
2262			if(!o.axis || o.axis !== "x") {
2263				if(event.pageY - $(document).scrollTop() < o.scrollSensitivity) {
2264					scrolled = $(document).scrollTop($(document).scrollTop() - o.scrollSpeed);
2265				} else if($(window).height() - (event.pageY - $(document).scrollTop()) < o.scrollSensitivity) {
2266					scrolled = $(document).scrollTop($(document).scrollTop() + o.scrollSpeed);
2267				}
2268			}
2269
2270			if(!o.axis || o.axis !== "y") {
2271				if(event.pageX - $(document).scrollLeft() < o.scrollSensitivity) {
2272					scrolled = $(document).scrollLeft($(document).scrollLeft() - o.scrollSpeed);
2273				} else if($(window).width() - (event.pageX - $(document).scrollLeft()) < o.scrollSensitivity) {
2274					scrolled = $(document).scrollLeft($(document).scrollLeft() + o.scrollSpeed);
2275				}
2276			}
2277
2278		}
2279
2280		if(scrolled !== false && $.ui.ddmanager && !o.dropBehaviour) {
2281			$.ui.ddmanager.prepareOffsets(i, event);
2282		}
2283
2284	}
2285});
2286
2287$.ui.plugin.add("draggable", "snap", {
2288	start: function() {
2289
2290		var i = $(this).data("ui-draggable"),
2291			o = i.options;
2292
2293		i.snapElements = [];
2294
2295		$(o.snap.constructor !== String ? ( o.snap.items || ":data(ui-draggable)" ) : o.snap).each(function() {
2296			var $t = $(this),
2297				$o = $t.offset();
2298			if(this !== i.element[0]) {
2299				i.snapElements.push({
2300					item: this,
2301					width: $t.outerWidth(), height: $t.outerHeight(),
2302					top: $o.top, left: $o.left
2303				});
2304			}
2305		});
2306
2307	},
2308	drag: function(event, ui) {
2309
2310		var ts, bs, ls, rs, l, r, t, b, i, first,
2311			inst = $(this).data("ui-draggable"),
2312			o = inst.options,
2313			d = o.snapTolerance,
2314			x1 = ui.offset.left, x2 = x1 + inst.helperProportions.width,
2315			y1 = ui.offset.top, y2 = y1 + inst.helperProportions.height;
2316
2317		for (i = inst.snapElements.length - 1; i >= 0; i--){
2318
2319			l = inst.snapElements[i].left;
2320			r = l + inst.snapElements[i].width;
2321			t = inst.snapElements[i].top;
2322			b = t + inst.snapElements[i].height;
2323
2324			if ( x2 < l - d || x1 > r + d || y2 < t - d || y1 > b + d || !$.contains( inst.snapElements[ i ].item.ownerDocument, inst.snapElements[ i ].item ) ) {
2325				if(inst.snapElements[i].snapping) {
2326					(inst.options.snap.release && inst.options.snap.release.call(inst.element, event, $.extend(inst._uiHash(), { snapItem: inst.snapElements[i].item })));
2327				}
2328				inst.snapElements[i].snapping = false;
2329				continue;
2330			}
2331
2332			if(o.snapMode !== "inner") {
2333				ts = Math.abs(t - y2) <= d;
2334				bs = Math.abs(b - y1) <= d;
2335				ls = Math.abs(l - x2) <= d;
2336				rs = Math.abs(r - x1) <= d;
2337				if(ts) {
2338					ui.position.top = inst._convertPositionTo("relative", { top: t - inst.helperProportions.height, left: 0 }).top - inst.margins.top;
2339				}
2340				if(bs) {
2341					ui.position.top = inst._convertPositionTo("relative", { top: b, left: 0 }).top - inst.margins.top;
2342				}
2343				if(ls) {
2344					ui.position.left = inst._convertPositionTo("relative", { top: 0, left: l - inst.helperProportions.width }).left - inst.margins.left;
2345				}
2346				if(rs) {
2347					ui.position.left = inst._convertPositionTo("relative", { top: 0, left: r }).left - inst.margins.left;
2348				}
2349			}
2350
2351			first = (ts || bs || ls || rs);
2352
2353			if(o.snapMode !== "outer") {
2354				ts = Math.abs(t - y1) <= d;
2355				bs = Math.abs(b - y2) <= d;
2356				ls = Math.abs(l - x1) <= d;
2357				rs = Math.abs(r - x2) <= d;
2358				if(ts) {
2359					ui.position.top = inst._convertPositionTo("relative", { top: t, left: 0 }).top - inst.margins.top;
2360				}
2361				if(bs) {
2362					ui.position.top = inst._convertPositionTo("relative", { top: b - inst.helperProportions.height, left: 0 }).top - inst.margins.top;
2363				}
2364				if(ls) {
2365					ui.position.left = inst._convertPositionTo("relative", { top: 0, left: l }).left - inst.margins.left;
2366				}
2367				if(rs) {
2368					ui.position.left = inst._convertPositionTo("relative", { top: 0, left: r - inst.helperProportions.width }).left - inst.margins.left;
2369				}
2370			}
2371
2372			if(!inst.snapElements[i].snapping && (ts || bs || ls || rs || first)) {
2373				(inst.options.snap.snap && inst.options.snap.snap.call(inst.element, event, $.extend(inst._uiHash(), { snapItem: inst.snapElements[i].item })));
2374			}
2375			inst.snapElements[i].snapping = (ts || bs || ls || rs || first);
2376
2377		}
2378
2379	}
2380});
2381
2382$.ui.plugin.add("draggable", "stack", {
2383	start: function() {
2384		var min,
2385			o = this.data("ui-draggable").options,
2386			group = $.makeArray($(o.stack)).sort(function(a,b) {
2387				return (parseInt($(a).css("zIndex"),10) || 0) - (parseInt($(b).css("zIndex"),10) || 0);
2388			});
2389
2390		if (!group.length) { return; }
2391
2392		min = parseInt($(group[0]).css("zIndex"), 10) || 0;
2393		$(group).each(function(i) {
2394			$(this).css("zIndex", min + i);
2395		});
2396		this.css("zIndex", (min + group.length));
2397	}
2398});
2399
2400$.ui.plugin.add("draggable", "zIndex", {
2401	start: function(event, ui) {
2402		var t = $(ui.helper), o = $(this).data("ui-draggable").options;
2403		if(t.css("zIndex")) {
2404			o._zIndex = t.css("zIndex");
2405		}
2406		t.css("zIndex", o.zIndex);
2407	},
2408	stop: function(event, ui) {
2409		var o = $(this).data("ui-draggable").options;
2410		if(o._zIndex) {
2411			$(ui.helper).css("zIndex", o._zIndex);
2412		}
2413	}
2414});
2415
2416})(jQuery);
2417(function( $, undefined ) {
2418
2419function isOverAxis( x, reference, size ) {
2420	return ( x > reference ) && ( x < ( reference + size ) );
2421}
2422
2423$.widget("ui.droppable", {
2424	version: "1.10.4",
2425	widgetEventPrefix: "drop",
2426	options: {
2427		accept: "*",
2428		activeClass: false,
2429		addClasses: true,
2430		greedy: false,
2431		hoverClass: false,
2432		scope: "default",
2433		tolerance: "intersect",
2434
2435		// callbacks
2436		activate: null,
2437		deactivate: null,
2438		drop: null,
2439		out: null,
2440		over: null
2441	},
2442	_create: function() {
2443
2444		var proportions,
2445			o = this.options,
2446			accept = o.accept;
2447
2448		this.isover = false;
2449		this.isout = true;
2450
2451		this.accept = $.isFunction(accept) ? accept : function(d) {
2452			return d.is(accept);
2453		};
2454
2455		this.proportions = function( /* valueToWrite */ ) {
2456			if ( arguments.length ) {
2457				// Store the droppable's proportions
2458				proportions = arguments[ 0 ];
2459			} else {
2460				// Retrieve or derive the droppable's proportions
2461				return proportions ?
2462					proportions :
2463					proportions = {
2464						width: this.element[ 0 ].offsetWidth,
2465						height: this.element[ 0 ].offsetHeight
2466					};
2467			}
2468		};
2469
2470		// Add the reference and positions to the manager
2471		$.ui.ddmanager.droppables[o.scope] = $.ui.ddmanager.droppables[o.scope] || [];
2472		$.ui.ddmanager.droppables[o.scope].push(this);
2473
2474		(o.addClasses && this.element.addClass("ui-droppable"));
2475
2476	},
2477
2478	_destroy: function() {
2479		var i = 0,
2480			drop = $.ui.ddmanager.droppables[this.options.scope];
2481
2482		for ( ; i < drop.length; i++ ) {
2483			if ( drop[i] === this ) {
2484				drop.splice(i, 1);
2485			}
2486		}
2487
2488		this.element.removeClass("ui-droppable ui-droppable-disabled");
2489	},
2490
2491	_setOption: function(key, value) {
2492
2493		if(key === "accept") {
2494			this.accept = $.isFunction(value) ? value : function(d) {
2495				return d.is(value);
2496			};
2497		}
2498		$.Widget.prototype._setOption.apply(this, arguments);
2499	},
2500
2501	_activate: function(event) {
2502		var draggable = $.ui.ddmanager.current;
2503		if(this.options.activeClass) {
2504			this.element.addClass(this.options.activeClass);
2505		}
2506		if(draggable){
2507			this._trigger("activate", event, this.ui(draggable));
2508		}
2509	},
2510
2511	_deactivate: function(event) {
2512		var draggable = $.ui.ddmanager.current;
2513		if(this.options.activeClass) {
2514			this.element.removeClass(this.options.activeClass);
2515		}
2516		if(draggable){
2517			this._trigger("deactivate", event, this.ui(draggable));
2518		}
2519	},
2520
2521	_over: function(event) {
2522
2523		var draggable = $.ui.ddmanager.current;
2524
2525		// Bail if draggable and droppable are same element
2526		if (!draggable || (draggable.currentItem || draggable.element)[0] === this.element[0]) {
2527			return;
2528		}
2529
2530		if (this.accept.call(this.element[0],(draggable.currentItem || draggable.element))) {
2531			if(this.options.hoverClass) {
2532				this.element.addClass(this.options.hoverClass);
2533			}
2534			this._trigger("over", event, this.ui(draggable));
2535		}
2536
2537	},
2538
2539	_out: function(event) {
2540
2541		var draggable = $.ui.ddmanager.current;
2542
2543		// Bail if draggable and droppable are same element
2544		if (!draggable || (draggable.currentItem || draggable.element)[0] === this.element[0]) {
2545			return;
2546		}
2547
2548		if (this.accept.call(this.element[0],(draggable.currentItem || draggable.element))) {
2549			if(this.options.hoverClass) {
2550				this.element.removeClass(this.options.hoverClass);
2551			}
2552			this._trigger("out", event, this.ui(draggable));
2553		}
2554
2555	},
2556
2557	_drop: function(event,custom) {
2558
2559		var draggable = custom || $.ui.ddmanager.current,
2560			childrenIntersection = false;
2561
2562		// Bail if draggable and droppable are same element
2563		if (!draggable || (draggable.currentItem || draggable.element)[0] === this.element[0]) {
2564			return false;
2565		}
2566
2567		this.element.find(":data(ui-droppable)").not(".ui-draggable-dragging").each(function() {
2568			var inst = $.data(this, "ui-droppable");
2569			if(
2570				inst.options.greedy &&
2571				!inst.options.disabled &&
2572				inst.options.scope === draggable.options.scope &&
2573				inst.accept.call(inst.element[0], (draggable.currentItem || draggable.element)) &&
2574				$.ui.intersect(draggable, $.extend(inst, { offset: inst.element.offset() }), inst.options.tolerance)
2575			) { childrenIntersection = true; return false; }
2576		});
2577		if(childrenIntersection) {
2578			return false;
2579		}
2580
2581		if(this.accept.call(this.element[0],(draggable.currentItem || draggable.element))) {
2582			if(this.options.activeClass) {
2583				this.element.removeClass(this.options.activeClass);
2584			}
2585			if(this.options.hoverClass) {
2586				this.element.removeClass(this.options.hoverClass);
2587			}
2588			this._trigger("drop", event, this.ui(draggable));
2589			return this.element;
2590		}
2591
2592		return false;
2593
2594	},
2595
2596	ui: function(c) {
2597		return {
2598			draggable: (c.currentItem || c.element),
2599			helper: c.helper,
2600			position: c.position,
2601			offset: c.positionAbs
2602		};
2603	}
2604
2605});
2606
2607$.ui.intersect = function(draggable, droppable, toleranceMode) {
2608
2609	if (!droppable.offset) {
2610		return false;
2611	}
2612
2613	var draggableLeft, draggableTop,
2614		x1 = (draggable.positionAbs || draggable.position.absolute).left,
2615		y1 = (draggable.positionAbs || draggable.position.absolute).top,
2616		x2 = x1 + draggable.helperProportions.width,
2617		y2 = y1 + draggable.helperProportions.height,
2618		l = droppable.offset.left,
2619		t = droppable.offset.top,
2620		r = l + droppable.proportions().width,
2621		b = t + droppable.proportions().height;
2622
2623	switch (toleranceMode) {
2624		case "fit":
2625			return (l <= x1 && x2 <= r && t <= y1 && y2 <= b);
2626		case "intersect":
2627			return (l < x1 + (draggable.helperProportions.width / 2) && // Right Half
2628				x2 - (draggable.helperProportions.width / 2) < r && // Left Half
2629				t < y1 + (draggable.helperProportions.height / 2) && // Bottom Half
2630				y2 - (draggable.helperProportions.height / 2) < b ); // Top Half
2631		case "pointer":
2632			draggableLeft = ((draggable.positionAbs || draggable.position.absolute).left + (draggable.clickOffset || draggable.offset.click).left);
2633			draggableTop = ((draggable.positionAbs || draggable.position.absolute).top + (draggable.clickOffset || draggable.offset.click).top);
2634			return isOverAxis( draggableTop, t, droppable.proportions().height ) && isOverAxis( draggableLeft, l, droppable.proportions().width );
2635		case "touch":
2636			return (
2637				(y1 >= t && y1 <= b) ||	// Top edge touching
2638				(y2 >= t && y2 <= b) ||	// Bottom edge touching
2639				(y1 < t && y2 > b)		// Surrounded vertically
2640			) && (
2641				(x1 >= l && x1 <= r) ||	// Left edge touching
2642				(x2 >= l && x2 <= r) ||	// Right edge touching
2643				(x1 < l && x2 > r)		// Surrounded horizontally
2644			);
2645		default:
2646			return false;
2647		}
2648
2649};
2650
2651/*
2652	This manager tracks offsets of draggables and droppables
2653*/
2654$.ui.ddmanager = {
2655	current: null,
2656	droppables: { "default": [] },
2657	prepareOffsets: function(t, event) {
2658
2659		var i, j,
2660			m = $.ui.ddmanager.droppables[t.options.scope] || [],
2661			type = event ? event.type : null, // workaround for #2317
2662			list = (t.currentItem || t.element).find(":data(ui-droppable)").addBack();
2663
2664		droppablesLoop: for (i = 0; i < m.length; i++) {
2665
2666			//No disabled and non-accepted
2667			if(m[i].options.disabled || (t && !m[i].accept.call(m[i].element[0],(t.currentItem || t.element)))) {
2668				continue;
2669			}
2670
2671			// Filter out elements in the current dragged item
2672			for (j=0; j < list.length; j++) {
2673				if(list[j] === m[i].element[0]) {
2674					m[i].proportions().height = 0;
2675					continue droppablesLoop;
2676				}
2677			}
2678
2679			m[i].visible = m[i].element.css("display") !== "none";
2680			if(!m[i].visible) {
2681				continue;
2682			}
2683
2684			//Activate the droppable if used directly from draggables
2685			if(type === "mousedown") {
2686				m[i]._activate.call(m[i], event);
2687			}
2688
2689			m[ i ].offset = m[ i ].element.offset();
2690			m[ i ].proportions({ width: m[ i ].element[ 0 ].offsetWidth, height: m[ i ].element[ 0 ].offsetHeight });
2691
2692		}
2693
2694	},
2695	drop: function(draggable, event) {
2696
2697		var dropped = false;
2698		// Create a copy of the droppables in case the list changes during the drop (#9116)
2699		$.each(($.ui.ddmanager.droppables[draggable.options.scope] || []).slice(), function() {
2700
2701			if(!this.options) {
2702				return;
2703			}
2704			if (!this.options.disabled && this.visible && $.ui.intersect(draggable, this, this.options.tolerance)) {
2705				dropped = this._drop.call(this, event) || dropped;
2706			}
2707
2708			if (!this.options.disabled && this.visible && this.accept.call(this.element[0],(draggable.currentItem || draggable.element))) {
2709				this.isout = true;
2710				this.isover = false;
2711				this._deactivate.call(this, event);
2712			}
2713
2714		});
2715		return dropped;
2716
2717	},
2718	dragStart: function( draggable, event ) {
2719		//Listen for scrolling so that if the dragging causes scrolling the position of the droppables can be recalculated (see #5003)
2720		draggable.element.parentsUntil( "body" ).bind( "scroll.droppable", function() {
2721			if( !draggable.options.refreshPositions ) {
2722				$.ui.ddmanager.prepareOffsets( draggable, event );
2723			}
2724		});
2725	},
2726	drag: function(draggable, event) {
2727
2728		//If you have a highly dynamic page, you might try this option. It renders positions every time you move the mouse.
2729		if(draggable.options.refreshPositions) {
2730			$.ui.ddmanager.prepareOffsets(draggable, event);
2731		}
2732
2733		//Run through all droppables and check their positions based on specific tolerance options
2734		$.each($.ui.ddmanager.droppables[draggable.options.scope] || [], function() {
2735
2736			if(this.options.disabled || this.greedyChild || !this.visible) {
2737				return;
2738			}
2739
2740			var parentInstance, scope, parent,
2741				intersects = $.ui.intersect(draggable, this, this.options.tolerance),
2742				c = !intersects && this.isover ? "isout" : (intersects && !this.isover ? "isover" : null);
2743			if(!c) {
2744				return;
2745			}
2746
2747			if (this.options.greedy) {
2748				// find droppable parents with same scope
2749				scope = this.options.scope;
2750				parent = this.element.parents(":data(ui-droppable)").filter(function () {
2751					return $.data(this, "ui-droppable").options.scope === scope;
2752				});
2753
2754				if (parent.length) {
2755					parentInstance = $.data(parent[0], "ui-droppable");
2756					parentInstance.greedyChild = (c === "isover");
2757				}
2758			}
2759
2760			// we just moved into a greedy child
2761			if (parentInstance && c === "isover") {
2762				parentInstance.isover = false;
2763				parentInstance.isout = true;
2764				parentInstance._out.call(parentInstance, event);
2765			}
2766
2767			this[c] = true;
2768			this[c === "isout" ? "isover" : "isout"] = false;
2769			this[c === "isover" ? "_over" : "_out"].call(this, event);
2770
2771			// we just moved out of a greedy child
2772			if (parentInstance && c === "isout") {
2773				parentInstance.isout = false;
2774				parentInstance.isover = true;
2775				parentInstance._over.call(parentInstance, event);
2776			}
2777		});
2778
2779	},
2780	dragStop: function( draggable, event ) {
2781		draggable.element.parentsUntil( "body" ).unbind( "scroll.droppable" );
2782		//Call prepareOffsets one final time since IE does not fire return scroll events when overflow was caused by drag (see #5003)
2783		if( !draggable.options.refreshPositions ) {
2784			$.ui.ddmanager.prepareOffsets( draggable, event );
2785		}
2786	}
2787};
2788
2789})(jQuery);
2790(function( $, undefined ) {
2791
2792function num(v) {
2793	return parseInt(v, 10) || 0;
2794}
2795
2796function isNumber(value) {
2797	return !isNaN(parseInt(value, 10));
2798}
2799
2800$.widget("ui.resizable", $.ui.mouse, {
2801	version: "1.10.4",
2802	widgetEventPrefix: "resize",
2803	options: {
2804		alsoResize: false,
2805		animate: false,
2806		animateDuration: "slow",
2807		animateEasing: "swing",
2808		aspectRatio: false,
2809		autoHide: false,
2810		containment: false,
2811		ghost: false,
2812		grid: false,
2813		handles: "e,s,se",
2814		helper: false,
2815		maxHeight: null,
2816		maxWidth: null,
2817		minHeight: 10,
2818		minWidth: 10,
2819		// See #7960
2820		zIndex: 90,
2821
2822		// callbacks
2823		resize: null,
2824		start: null,
2825		stop: null
2826	},
2827	_create: function() {
2828
2829		var n, i, handle, axis, hname,
2830			that = this,
2831			o = this.options;
2832		this.element.addClass("ui-resizable");
2833
2834		$.extend(this, {
2835			_aspectRatio: !!(o.aspectRatio),
2836			aspectRatio: o.aspectRatio,
2837			originalElement: this.element,
2838			_proportionallyResizeElements: [],
2839			_helper: o.helper || o.ghost || o.animate ? o.helper || "ui-resizable-helper" : null
2840		});
2841
2842		//Wrap the element if it cannot hold child nodes
2843		if(this.element[0].nodeName.match(/canvas|textarea|input|select|button|img/i)) {
2844
2845			//Create a wrapper element and set the wrapper to the new current internal element
2846			this.element.wrap(
2847				$("<div class='ui-wrapper' style='overflow: hidden;'></div>").css({
2848					position: this.element.css("position"),
2849					width: this.element.outerWidth(),
2850					height: this.element.outerHeight(),
2851					top: this.element.css("top"),
2852					left: this.element.css("left")
2853				})
2854			);
2855
2856			//Overwrite the original this.element
2857			this.element = this.element.parent().data(
2858				"ui-resizable", this.element.data("ui-resizable")
2859			);
2860
2861			this.elementIsWrapper = true;
2862
2863			//Move margins to the wrapper
2864			this.element.css({ marginLeft: this.originalElement.css("marginLeft"), marginTop: this.originalElement.css("marginTop"), marginRight: this.originalElement.css("marginRight"), marginBottom: this.originalElement.css("marginBottom") });
2865			this.originalElement.css({ marginLeft: 0, marginTop: 0, marginRight: 0, marginBottom: 0});
2866
2867			//Prevent Safari textarea resize
2868			this.originalResizeStyle = this.originalElement.css("resize");
2869			this.originalElement.css("resize", "none");
2870
2871			//Push the actual element to our proportionallyResize internal array
2872			this._proportionallyResizeElements.push(this.originalElement.css({ position: "static", zoom: 1, display: "block" }));
2873
2874			// avoid IE jump (hard set the margin)
2875			this.originalElement.css({ margin: this.originalElement.css("margin") });
2876
2877			// fix handlers offset
2878			this._proportionallyResize();
2879
2880		}
2881
2882		this.handles = o.handles || (!$(".ui-resizable-handle", this.element).length ? "e,s,se" : { n: ".ui-resizable-n", e: ".ui-resizable-e", s: ".ui-resizable-s", w: ".ui-resizable-w", se: ".ui-resizable-se", sw: ".ui-resizable-sw", ne: ".ui-resizable-ne", nw: ".ui-resizable-nw" });
2883		if(this.handles.constructor === String) {
2884
2885			if ( this.handles === "all") {
2886				this.handles = "n,e,s,w,se,sw,ne,nw";
2887			}
2888
2889			n = this.handles.split(",");
2890			this.handles = {};
2891
2892			for(i = 0; i < n.length; i++) {
2893
2894				handle = $.trim(n[i]);
2895				hname = "ui-resizable-"+handle;
2896				axis = $("<div class='ui-resizable-handle " + hname + "'></div>");
2897
2898				// Apply zIndex to all handles - see #7960
2899				axis.css({ zIndex: o.zIndex });
2900
2901				//TODO : What's going on here?
2902				if ("se" === handle) {
2903					axis.addClass("ui-icon ui-icon-gripsmall-diagonal-se");
2904				}
2905
2906				//Insert into internal handles object and append to element
2907				this.handles[handle] = ".ui-resizable-"+handle;
2908				this.element.append(axis);
2909			}
2910
2911		}
2912
2913		this._renderAxis = function(target) {
2914
2915			var i, axis, padPos, padWrapper;
2916
2917			target = target || this.element;
2918
2919			for(i in this.handles) {
2920
2921				if(this.handles[i].constructor === String) {
2922					this.handles[i] = $(this.handles[i], this.element).show();
2923				}
2924
2925				//Apply pad to wrapper element, needed to fix axis position (textarea, inputs, scrolls)
2926				if (this.elementIsWrapper && this.originalElement[0].nodeName.match(/textarea|input|select|button/i)) {
2927
2928					axis = $(this.handles[i], this.element);
2929
2930					//Checking the correct pad and border
2931					padWrapper = /sw|ne|nw|se|n|s/.test(i) ? axis.outerHeight() : axis.outerWidth();
2932
2933					//The padding type i have to apply...
2934					padPos = [ "padding",
2935						/ne|nw|n/.test(i) ? "Top" :
2936						/se|sw|s/.test(i) ? "Bottom" :
2937						/^e$/.test(i) ? "Right" : "Left" ].join("");
2938
2939					target.css(padPos, padWrapper);
2940
2941					this._proportionallyResize();
2942
2943				}
2944
2945				//TODO: What's that good for? There's not anything to be executed left
2946				if(!$(this.handles[i]).length) {
2947					continue;
2948				}
2949			}
2950		};
2951
2952		//TODO: make renderAxis a prototype function
2953		this._renderAxis(this.element);
2954
2955		this._handles = $(".ui-resizable-handle", this.element)
2956			.disableSelection();
2957
2958		//Matching axis name
2959		this._handles.mouseover(function() {
2960			if (!that.resizing) {
2961				if (this.className) {
2962					axis = this.className.match(/ui-resizable-(se|sw|ne|nw|n|e|s|w)/i);
2963				}
2964				//Axis, default = se
2965				that.axis = axis && axis[1] ? axis[1] : "se";
2966			}
2967		});
2968
2969		//If we want to auto hide the elements
2970		if (o.autoHide) {
2971			this._handles.hide();
2972			$(this.element)
2973				.addClass("ui-resizable-autohide")
2974				.mouseenter(function() {
2975					if (o.disabled) {
2976						return;
2977					}
2978					$(this).removeClass("ui-resizable-autohide");
2979					that._handles.show();
2980				})
2981				.mouseleave(function(){
2982					if (o.disabled) {
2983						return;
2984					}
2985					if (!that.resizing) {
2986						$(this).addClass("ui-resizable-autohide");
2987						that._handles.hide();
2988					}
2989				});
2990		}
2991
2992		//Initialize the mouse interaction
2993		this._mouseInit();
2994
2995	},
2996
2997	_destroy: function() {
2998
2999		this._mouseDestroy();
3000
3001		var wrapper,
3002			_destroy = function(exp) {
3003				$(exp).removeClass("ui-resizable ui-resizable-disabled ui-resizable-resizing")
3004					.removeData("resizable").removeData("ui-resizable").unbind(".resizable").find(".ui-resizable-handle").remove();
3005			};
3006
3007		//TODO: Unwrap at same DOM position
3008		if (this.elementIsWrapper) {
3009			_destroy(this.element);
3010			wrapper = this.element;
3011			this.originalElement.css({
3012				position: wrapper.css("position"),
3013				width: wrapper.outerWidth(),
3014				height: wrapper.outerHeight(),
3015				top: wrapper.css("top"),
3016				left: wrapper.css("left")
3017			}).insertAfter( wrapper );
3018			wrapper.remove();
3019		}
3020
3021		this.originalElement.css("resize", this.originalResizeStyle);
3022		_destroy(this.originalElement);
3023
3024		return this;
3025	},
3026
3027	_mouseCapture: function(event) {
3028		var i, handle,
3029			capture = false;
3030
3031		for (i in this.handles) {
3032			handle = $(this.handles[i])[0];
3033			if (handle === event.target || $.contains(handle, event.target)) {
3034				capture = true;
3035			}
3036		}
3037
3038		return !this.options.disabled && capture;
3039	},
3040
3041	_mouseStart: function(event) {
3042
3043		var curleft, curtop, cursor,
3044			o = this.options,
3045			iniPos = this.element.position(),
3046			el = this.element;
3047
3048		this.resizing = true;
3049
3050		// bugfix for http://dev.jquery.com/ticket/1749
3051		if ( (/absolute/).test( el.css("position") ) ) {
3052			el.css({ position: "absolute", top: el.css("top"), left: el.css("left") });
3053		} else if (el.is(".ui-draggable")) {
3054			el.css({ position: "absolute", top: iniPos.top, left: iniPos.left });
3055		}
3056
3057		this._renderProxy();
3058
3059		curleft = num(this.helper.css("left"));
3060		curtop = num(this.helper.css("top"));
3061
3062		if (o.containment) {
3063			curleft += $(o.containment).scrollLeft() || 0;
3064			curtop += $(o.containment).scrollTop() || 0;
3065		}
3066
3067		//Store needed variables
3068		this.offset = this.helper.offset();
3069		this.position = { left: curleft, top: curtop };
3070		this.size = this._helper ? { width: this.helper.width(), height: this.helper.height() } : { width: el.width(), height: el.height() };
3071		this.originalSize = this._helper ? { width: el.outerWidth(), height: el.outerHeight() } : { width: el.width(), height: el.height() };
3072		this.originalPosition = { left: curleft, top: curtop };
3073		this.sizeDiff = { width: el.outerWidth() - el.width(), height: el.outerHeight() - el.height() };
3074		this.originalMousePosition = { left: event.pageX, top: event.pageY };
3075
3076		//Aspect Ratio
3077		this.aspectRatio = (typeof o.aspectRatio === "number") ? o.aspectRatio : ((this.originalSize.width / this.originalSize.height) || 1);
3078
3079		cursor = $(".ui-resizable-" + this.axis).css("cursor");
3080		$("body").css("cursor", cursor === "auto" ? this.axis + "-resize" : cursor);
3081
3082		el.addClass("ui-resizable-resizing");
3083		this._propagate("start", event);
3084		return true;
3085	},
3086
3087	_mouseDrag: function(event) {
3088
3089		//Increase performance, avoid regex
3090		var data,
3091			el = this.helper, props = {},
3092			smp = this.originalMousePosition,
3093			a = this.axis,
3094			prevTop = this.position.top,
3095			prevLeft = this.position.left,
3096			prevWidth = this.size.width,
3097			prevHeight = this.size.height,
3098			dx = (event.pageX-smp.left)||0,
3099			dy = (event.pageY-smp.top)||0,
3100			trigger = this._change[a];
3101
3102		if (!trigger) {
3103			return false;
3104		}
3105
3106		// Calculate the attrs that will be change
3107		data = trigger.apply(this, [event, dx, dy]);
3108
3109		// Put this in the mouseDrag handler since the user can start pressing shift while resizing
3110		this._updateVirtualBoundaries(event.shiftKey);
3111		if (this._aspectRatio || event.shiftKey) {
3112			data = this._updateRatio(data, event);
3113		}
3114
3115		data = this._respectSize(data, event);
3116
3117		this._updateCache(data);
3118
3119		// plugins callbacks need to be called first
3120		this._propagate("resize", event);
3121
3122		if (this.position.top !== prevTop) {
3123			props.top = this.position.top + "px";
3124		}
3125		if (this.position.left !== prevLeft) {
3126			props.left = this.position.left + "px";
3127		}
3128		if (this.size.width !== prevWidth) {
3129			props.width = this.size.width + "px";
3130		}
3131		if (this.size.height !== prevHeight) {
3132			props.height = this.size.height + "px";
3133		}
3134		el.css(props);
3135
3136		if (!this._helper && this._proportionallyResizeElements.length) {
3137			this._proportionallyResize();
3138		}
3139
3140		// Call the user callback if the element was resized
3141		if ( ! $.isEmptyObject(props) ) {
3142			this._trigger("resize", event, this.ui());
3143		}
3144
3145		return false;
3146	},
3147
3148	_mouseStop: function(event) {
3149
3150		this.resizing = false;
3151		var pr, ista, soffseth, soffsetw, s, left, top,
3152			o = this.options, that = this;
3153
3154		if(this._helper) {
3155
3156			pr = this._proportionallyResizeElements;
3157			ista = pr.length && (/textarea/i).test(pr[0].nodeName);
3158			soffseth = ista && $.ui.hasScroll(pr[0], "left") /* TODO - jump height */ ? 0 : that.sizeDiff.height;
3159			soffsetw = ista ? 0 : that.sizeDiff.width;
3160
3161			s = { width: (that.helper.width()  - soffsetw), height: (that.helper.height() - soffseth) };
3162			left = (parseInt(that.element.css("left"), 10) + (that.position.left - that.originalPosition.left)) || null;
3163			top = (parseInt(that.element.css("top"), 10) + (that.position.top - that.originalPosition.top)) || null;
3164
3165			if (!o.animate) {
3166				this.element.css($.extend(s, { top: top, left: left }));
3167			}
3168
3169			that.helper.height(that.size.height);
3170			that.helper.width(that.size.width);
3171
3172			if (this._helper && !o.animate) {
3173				this._proportionallyResize();
3174			}
3175		}
3176
3177		$("body").css("cursor", "auto");
3178
3179		this.element.removeClass("ui-resizable-resizing");
3180
3181		this._propagate("stop", event);
3182
3183		if (this._helper) {
3184			this.helper.remove();
3185		}
3186
3187		return false;
3188
3189	},
3190
3191	_updateVirtualBoundaries: function(forceAspectRatio) {
3192		var pMinWidth, pMaxWidth, pMinHeight, pMaxHeight, b,
3193			o = this.options;
3194
3195		b = {
3196			minWidth: isNumber(o.minWidth) ? o.minWidth : 0,
3197			maxWidth: isNumber(o.maxWidth) ? o.maxWidth : Infinity,
3198			minHeight: isNumber(o.minHeight) ? o.minHeight : 0,
3199			maxHeight: isNumber(o.maxHeight) ? o.maxHeight : Infinity
3200		};
3201
3202		if(this._aspectRatio || forceAspectRatio) {
3203			// We want to create an enclosing box whose aspect ration is the requested one
3204			// First, compute the "projected" size for each dimension based on the aspect ratio and other dimension
3205			pMinWidth = b.minHeight * this.aspectRatio;
3206			pMinHeight = b.minWidth / this.aspectRatio;
3207			pMaxWidth = b.maxHeight * this.aspectRatio;
3208			pMaxHeight = b.maxWidth / this.aspectRatio;
3209
3210			if(pMinWidth > b.minWidth) {
3211				b.minWidth = pMinWidth;
3212			}
3213			if(pMinHeight > b.minHeight) {
3214				b.minHeight = pMinHeight;
3215			}
3216			if(pMaxWidth < b.maxWidth) {
3217				b.maxWidth = pMaxWidth;
3218			}
3219			if(pMaxHeight < b.maxHeight) {
3220				b.maxHeight = pMaxHeight;
3221			}
3222		}
3223		this._vBoundaries = b;
3224	},
3225
3226	_updateCache: function(data) {
3227		this.offset = this.helper.offset();
3228		if (isNumber(data.left)) {
3229			this.position.left = data.left;
3230		}
3231		if (isNumber(data.top)) {
3232			this.position.top = data.top;
3233		}
3234		if (isNumber(data.height)) {
3235			this.size.height = data.height;
3236		}
3237		if (isNumber(data.width)) {
3238			this.size.width = data.width;
3239		}
3240	},
3241
3242	_updateRatio: function( data ) {
3243
3244		var cpos = this.position,
3245			csize = this.size,
3246			a = this.axis;
3247
3248		if (isNumber(data.height)) {
3249			data.width = (data.height * this.aspectRatio);
3250		} else if (isNumber(data.width)) {
3251			data.height = (data.width / this.aspectRatio);
3252		}
3253
3254		if (a === "sw") {
3255			data.left = cpos.left + (csize.width - data.width);
3256			data.top = null;
3257		}
3258		if (a === "nw") {
3259			data.top = cpos.top + (csize.height - data.height);
3260			data.left = cpos.left + (csize.width - data.width);
3261		}
3262
3263		return data;
3264	},
3265
3266	_respectSize: function( data ) {
3267
3268		var o = this._vBoundaries,
3269			a = this.axis,
3270			ismaxw = isNumber(data.width) && o.maxWidth && (o.maxWidth < data.width), ismaxh = isNumber(data.height) && o.maxHeight && (o.maxHeight < data.height),
3271			isminw = isNumber(data.width) && o.minWidth && (o.minWidth > data.width), isminh = isNumber(data.height) && o.minHeight && (o.minHeight > data.height),
3272			dw = this.originalPosition.left + this.originalSize.width,
3273			dh = this.position.top + this.size.height,
3274			cw = /sw|nw|w/.test(a), ch = /nw|ne|n/.test(a);
3275		if (isminw) {
3276			data.width = o.minWidth;
3277		}
3278		if (isminh) {
3279			data.height = o.minHeight;
3280		}
3281		if (ismaxw) {
3282			data.width = o.maxWidth;
3283		}
3284		if (ismaxh) {
3285			data.height = o.maxHeight;
3286		}
3287
3288		if (isminw && cw) {
3289			data.left = dw - o.minWidth;
3290		}
3291		if (ismaxw && cw) {
3292			data.left = dw - o.maxWidth;
3293		}
3294		if (isminh && ch) {
3295			data.top = dh - o.minHeight;
3296		}
3297		if (ismaxh && ch) {
3298			data.top = dh - o.maxHeight;
3299		}
3300
3301		// fixing jump error on top/left - bug #2330
3302		if (!data.width && !data.height && !data.left && data.top) {
3303			data.top = null;
3304		} else if (!data.width && !data.height && !data.top && data.left) {
3305			data.left = null;
3306		}
3307
3308		return data;
3309	},
3310
3311	_proportionallyResize: function() {
3312
3313		if (!this._proportionallyResizeElements.length) {
3314			return;
3315		}
3316
3317		var i, j, borders, paddings, prel,
3318			element = this.helper || this.element;
3319
3320		for ( i=0; i < this._proportionallyResizeElements.length; i++) {
3321
3322			prel = this._proportionallyResizeElements[i];
3323
3324			if (!this.borderDif) {
3325				this.borderDif = [];
3326				borders = [prel.css("borderTopWidth"), prel.css("borderRightWidth"), prel.css("borderBottomWidth"), prel.css("borderLeftWidth")];
3327				paddings = [prel.css("paddingTop"), prel.css("paddingRight"), prel.css("paddingBottom"), prel.css("paddingLeft")];
3328
3329				for ( j = 0; j < borders.length; j++ ) {
3330					this.borderDif[ j ] = ( parseInt( borders[ j ], 10 ) || 0 ) + ( parseInt( paddings[ j ], 10 ) || 0 );
3331				}
3332			}
3333
3334			prel.css({
3335				height: (element.height() - this.borderDif[0] - this.borderDif[2]) || 0,
3336				width: (element.width() - this.borderDif[1] - this.borderDif[3]) || 0
3337			});
3338
3339		}
3340
3341	},
3342
3343	_renderProxy: function() {
3344
3345		var el = this.element, o = this.options;
3346		this.elementOffset = el.offset();
3347
3348		if(this._helper) {
3349
3350			this.helper = this.helper || $("<div style='overflow:hidden;'></div>");
3351
3352			this.helper.addClass(this._helper).css({
3353				width: this.element.outerWidth() - 1,
3354				height: this.element.outerHeight() - 1,
3355				position: "absolute",
3356				left: this.elementOffset.left +"px",
3357				top: this.elementOffset.top +"px",
3358				zIndex: ++o.zIndex //TODO: Don't modify option
3359			});
3360
3361			this.helper
3362				.appendTo("body")
3363				.disableSelection();
3364
3365		} else {
3366			this.helper = this.element;
3367		}
3368
3369	},
3370
3371	_change: {
3372		e: function(event, dx) {
3373			return { width: this.originalSize.width + dx };
3374		},
3375		w: function(event, dx) {
3376			var cs = this.originalSize, sp = this.originalPosition;
3377			return { left: sp.left + dx, width: cs.width - dx };
3378		},
3379		n: function(event, dx, dy) {
3380			var cs = this.originalSize, sp = this.originalPosition;
3381			return { top: sp.top + dy, height: cs.height - dy };
3382		},
3383		s: function(event, dx, dy) {
3384			return { height: this.originalSize.height + dy };
3385		},
3386		se: function(event, dx, dy) {
3387			return $.extend(this._change.s.apply(this, arguments), this._change.e.apply(this, [event, dx, dy]));
3388		},
3389		sw: function(event, dx, dy) {
3390			return $.extend(this._change.s.apply(this, arguments), this._change.w.apply(this, [event, dx, dy]));
3391		},
3392		ne: function(event, dx, dy) {
3393			return $.extend(this._change.n.apply(this, arguments), this._change.e.apply(this, [event, dx, dy]));
3394		},
3395		nw: function(event, dx, dy) {
3396			return $.extend(this._change.n.apply(this, arguments), this._change.w.apply(this, [event, dx, dy]));
3397		}
3398	},
3399
3400	_propagate: function(n, event) {
3401		$.ui.plugin.call(this, n, [event, this.ui()]);
3402		(n !== "resize" && this._trigger(n, event, this.ui()));
3403	},
3404
3405	plugins: {},
3406
3407	ui: function() {
3408		return {
3409			originalElement: this.originalElement,
3410			element: this.element,
3411			helper: this.helper,
3412			position: this.position,
3413			size: this.size,
3414			originalSize: this.originalSize,
3415			originalPosition: this.originalPosition
3416		};
3417	}
3418
3419});
3420
3421/*
3422 * Resizable Extensions
3423 */
3424
3425$.ui.plugin.add("resizable", "animate", {
3426
3427	stop: function( event ) {
3428		var that = $(this).data("ui-resizable"),
3429			o = that.options,
3430			pr = that._proportionallyResizeElements,
3431			ista = pr.length && (/textarea/i).test(pr[0].nodeName),
3432			soffseth = ista && $.ui.hasScroll(pr[0], "left") /* TODO - jump height */ ? 0 : that.sizeDiff.height,
3433			soffsetw = ista ? 0 : that.sizeDiff.width,
3434			style = { width: (that.size.width - soffsetw), height: (that.size.height - soffseth) },
3435			left = (parseInt(that.element.css("left"), 10) + (that.position.left - that.originalPosition.left)) || null,
3436			top = (parseInt(that.element.css("top"), 10) + (that.position.top - that.originalPosition.top)) || null;
3437
3438		that.element.animate(
3439			$.extend(style, top && left ? { top: top, left: left } : {}), {
3440				duration: o.animateDuration,
3441				easing: o.animateEasing,
3442				step: function() {
3443
3444					var data = {
3445						width: parseInt(that.element.css("width"), 10),
3446						height: parseInt(that.element.css("height"), 10),
3447						top: parseInt(that.element.css("top"), 10),
3448						left: parseInt(that.element.css("left"), 10)
3449					};
3450
3451					if (pr && pr.length) {
3452						$(pr[0]).css({ width: data.width, height: data.height });
3453					}
3454
3455					// propagating resize, and updating values for each animation step
3456					that._updateCache(data);
3457					that._propagate("resize", event);
3458
3459				}
3460			}
3461		);
3462	}
3463
3464});
3465
3466$.ui.plugin.add("resizable", "containment", {
3467
3468	start: function() {
3469		var element, p, co, ch, cw, width, height,
3470			that = $(this).data("ui-resizable"),
3471			o = that.options,
3472			el = that.element,
3473			oc = o.containment,
3474			ce = (oc instanceof $) ? oc.get(0) : (/parent/.test(oc)) ? el.parent().get(0) : oc;
3475
3476		if (!ce) {
3477			return;
3478		}
3479
3480		that.containerElement = $(ce);
3481
3482		if (/document/.test(oc) || oc === document) {
3483			that.containerOffset = { left: 0, top: 0 };
3484			that.containerPosition = { left: 0, top: 0 };
3485
3486			that.parentData = {
3487				element: $(document), left: 0, top: 0,
3488				width: $(document).width(), height: $(document).height() || document.body.parentNode.scrollHeight
3489			};
3490		}
3491
3492		// i'm a node, so compute top, left, right, bottom
3493		else {
3494			element = $(ce);
3495			p = [];
3496			$([ "Top", "Right", "Left", "Bottom" ]).each(function(i, name) { p[i] = num(element.css("padding" + name)); });
3497
3498			that.containerOffset = element.offset();
3499			that.containerPosition = element.position();
3500			that.containerSize = { height: (element.innerHeight() - p[3]), width: (element.innerWidth() - p[1]) };
3501
3502			co = that.containerOffset;
3503			ch = that.containerSize.height;
3504			cw = that.containerSize.width;
3505			width = ($.ui.hasScroll(ce, "left") ? ce.scrollWidth : cw );
3506			height = ($.ui.hasScroll(ce) ? ce.scrollHeight : ch);
3507
3508			that.parentData = {
3509				element: ce, left: co.left, top: co.top, width: width, height: height
3510			};
3511		}
3512	},
3513
3514	resize: function( event ) {
3515		var woset, hoset, isParent, isOffsetRelative,
3516			that = $(this).data("ui-resizable"),
3517			o = that.options,
3518			co = that.containerOffset, cp = that.position,
3519			pRatio = that._aspectRatio || event.shiftKey,
3520			cop = { top:0, left:0 }, ce = that.containerElement;
3521
3522		if (ce[0] !== document && (/static/).test(ce.css("position"))) {
3523			cop = co;
3524		}
3525
3526		if (cp.left < (that._helper ? co.left : 0)) {
3527			that.size.width = that.size.width + (that._helper ? (that.position.left - co.left) : (that.position.left - cop.left));
3528			if (pRatio) {
3529				that.size.height = that.size.width / that.aspectRatio;
3530			}
3531			that.position.left = o.helper ? co.left : 0;
3532		}
3533
3534		if (cp.top < (that._helper ? co.top : 0)) {
3535			that.size.height = that.size.height + (that._helper ? (that.position.top - co.top) : that.position.top);
3536			if (pRatio) {
3537				that.size.width = that.size.height * that.aspectRatio;
3538			}
3539			that.position.top = that._helper ? co.top : 0;
3540		}
3541
3542		that.offset.left = that.parentData.left+that.position.left;
3543		that.offset.top = that.parentData.top+that.position.top;
3544
3545		woset = Math.abs( (that._helper ? that.offset.left - cop.left : (that.offset.left - cop.left)) + that.sizeDiff.width );
3546		hoset = Math.abs( (that._helper ? that.offset.top - cop.top : (that.offset.top - co.top)) + that.sizeDiff.height );
3547
3548		isParent = that.containerElement.get(0) === that.element.parent().get(0);
3549		isOffsetRelative = /relative|absolute/.test(that.containerElement.css("position"));
3550
3551		if ( isParent && isOffsetRelative ) {
3552			woset -= Math.abs( that.parentData.left );
3553		}
3554
3555		if (woset + that.size.width >= that.parentData.width) {
3556			that.size.width = that.parentData.width - woset;
3557			if (pRatio) {
3558				that.size.height = that.size.width / that.aspectRatio;
3559			}
3560		}
3561
3562		if (hoset + that.size.height >= that.parentData.height) {
3563			that.size.height = that.parentData.height - hoset;
3564			if (pRatio) {
3565				that.size.width = that.size.height * that.aspectRatio;
3566			}
3567		}
3568	},
3569
3570	stop: function(){
3571		var that = $(this).data("ui-resizable"),
3572			o = that.options,
3573			co = that.containerOffset,
3574			cop = that.containerPosition,
3575			ce = that.containerElement,
3576			helper = $(that.helper),
3577			ho = helper.offset(),
3578			w = helper.outerWidth() - that.sizeDiff.width,
3579			h = helper.outerHeight() - that.sizeDiff.height;
3580
3581		if (that._helper && !o.animate && (/relative/).test(ce.css("position"))) {
3582			$(this).css({ left: ho.left - cop.left - co.left, width: w, height: h });
3583		}
3584
3585		if (that._helper && !o.animate && (/static/).test(ce.css("position"))) {
3586			$(this).css({ left: ho.left - cop.left - co.left, width: w, height: h });
3587		}
3588
3589	}
3590});
3591
3592$.ui.plugin.add("resizable", "alsoResize", {
3593
3594	start: function () {
3595		var that = $(this).data("ui-resizable"),
3596			o = that.options,
3597			_store = function (exp) {
3598				$(exp).each(function() {
3599					var el = $(this);
3600					el.data("ui-resizable-alsoresize", {
3601						width: parseInt(el.width(), 10), height: parseInt(el.height(), 10),
3602						left: parseInt(el.css("left"), 10), top: parseInt(el.css("top"), 10)
3603					});
3604				});
3605			};
3606
3607		if (typeof(o.alsoResize) === "object" && !o.alsoResize.parentNode) {
3608			if (o.alsoResize.length) { o.alsoResize = o.alsoResize[0]; _store(o.alsoResize); }
3609			else { $.each(o.alsoResize, function (exp) { _store(exp); }); }
3610		}else{
3611			_store(o.alsoResize);
3612		}
3613	},
3614
3615	resize: function (event, ui) {
3616		var that = $(this).data("ui-resizable"),
3617			o = that.options,
3618			os = that.originalSize,
3619			op = that.originalPosition,
3620			delta = {
3621				height: (that.size.height - os.height) || 0, width: (that.size.width - os.width) || 0,
3622				top: (that.position.top - op.top) || 0, left: (that.position.left - op.left) || 0
3623			},
3624
3625			_alsoResize = function (exp, c) {
3626				$(exp).each(function() {
3627					var el = $(this), start = $(this).data("ui-resizable-alsoresize"), style = {},
3628						css = c && c.length ? c : el.parents(ui.originalElement[0]).length ? ["width", "height"] : ["width", "height", "top", "left"];
3629
3630					$.each(css, function (i, prop) {
3631						var sum = (start[prop]||0) + (delta[prop]||0);
3632						if (sum && sum >= 0) {
3633							style[prop] = sum || null;
3634						}
3635					});
3636
3637					el.css(style);
3638				});
3639			};
3640
3641		if (typeof(o.alsoResize) === "object" && !o.alsoResize.nodeType) {
3642			$.each(o.alsoResize, function (exp, c) { _alsoResize(exp, c); });
3643		}else{
3644			_alsoResize(o.alsoResize);
3645		}
3646	},
3647
3648	stop: function () {
3649		$(this).removeData("resizable-alsoresize");
3650	}
3651});
3652
3653$.ui.plugin.add("resizable", "ghost", {
3654
3655	start: function() {
3656
3657		var that = $(this).data("ui-resizable"), o = that.options, cs = that.size;
3658
3659		that.ghost = that.originalElement.clone();
3660		that.ghost
3661			.css({ opacity: 0.25, display: "block", position: "relative", height: cs.height, width: cs.width, margin: 0, left: 0, top: 0 })
3662			.addClass("ui-resizable-ghost")
3663			.addClass(typeof o.ghost === "string" ? o.ghost : "");
3664
3665		that.ghost.appendTo(that.helper);
3666
3667	},
3668
3669	resize: function(){
3670		var that = $(this).data("ui-resizable");
3671		if (that.ghost) {
3672			that.ghost.css({ position: "relative", height: that.size.height, width: that.size.width });
3673		}
3674	},
3675
3676	stop: function() {
3677		var that = $(this).data("ui-resizable");
3678		if (that.ghost && that.helper) {
3679			that.helper.get(0).removeChild(that.ghost.get(0));
3680		}
3681	}
3682
3683});
3684
3685$.ui.plugin.add("resizable", "grid", {
3686
3687	resize: function() {
3688		var that = $(this).data("ui-resizable"),
3689			o = that.options,
3690			cs = that.size,
3691			os = that.originalSize,
3692			op = that.originalPosition,
3693			a = that.axis,
3694			grid = typeof o.grid === "number" ? [o.grid, o.grid] : o.grid,
3695			gridX = (grid[0]||1),
3696			gridY = (grid[1]||1),
3697			ox = Math.round((cs.width - os.width) / gridX) * gridX,
3698			oy = Math.round((cs.height - os.height) / gridY) * gridY,
3699			newWidth = os.width + ox,
3700			newHeight = os.height + oy,
3701			isMaxWidth = o.maxWidth && (o.maxWidth < newWidth),
3702			isMaxHeight = o.maxHeight && (o.maxHeight < newHeight),
3703			isMinWidth = o.minWidth && (o.minWidth > newWidth),
3704			isMinHeight = o.minHeight && (o.minHeight > newHeight);
3705
3706		o.grid = grid;
3707
3708		if (isMinWidth) {
3709			newWidth = newWidth + gridX;
3710		}
3711		if (isMinHeight) {
3712			newHeight = newHeight + gridY;
3713		}
3714		if (isMaxWidth) {
3715			newWidth = newWidth - gridX;
3716		}
3717		if (isMaxHeight) {
3718			newHeight = newHeight - gridY;
3719		}
3720
3721		if (/^(se|s|e)$/.test(a)) {
3722			that.size.width = newWidth;
3723			that.size.height = newHeight;
3724		} else if (/^(ne)$/.test(a)) {
3725			that.size.width = newWidth;
3726			that.size.height = newHeight;
3727			that.position.top = op.top - oy;
3728		} else if (/^(sw)$/.test(a)) {
3729			that.size.width = newWidth;
3730			that.size.height = newHeight;
3731			that.position.left = op.left - ox;
3732		} else {
3733			if ( newHeight - gridY > 0 ) {
3734				that.size.height = newHeight;
3735				that.position.top = op.top - oy;
3736			} else {
3737				that.size.height = gridY;
3738				that.position.top = op.top + os.height - gridY;
3739			}
3740			if ( newWidth - gridX > 0 ) {
3741				that.size.width = newWidth;
3742				that.position.left = op.left - ox;
3743			} else {
3744				that.size.width = gridX;
3745				that.position.left = op.left + os.width - gridX;
3746			}
3747		}
3748	}
3749
3750});
3751
3752})(jQuery);
3753(function( $, undefined ) {
3754
3755$.widget("ui.selectable", $.ui.mouse, {
3756	version: "1.10.4",
3757	options: {
3758		appendTo: "body",
3759		autoRefresh: true,
3760		distance: 0,
3761		filter: "*",
3762		tolerance: "touch",
3763
3764		// callbacks
3765		selected: null,
3766		selecting: null,
3767		start: null,
3768		stop: null,
3769		unselected: null,
3770		unselecting: null
3771	},
3772	_create: function() {
3773		var selectees,
3774			that = this;
3775
3776		this.element.addClass("ui-selectable");
3777
3778		this.dragged = false;
3779
3780		// cache selectee children based on filter
3781		this.refresh = function() {
3782			selectees = $(that.options.filter, that.element[0]);
3783			selectees.addClass("ui-selectee");
3784			selectees.each(function() {
3785				var $this = $(this),
3786					pos = $this.offset();
3787				$.data(this, "selectable-item", {
3788					element: this,
3789					$element: $this,
3790					left: pos.left,
3791					top: pos.top,
3792					right: pos.left + $this.outerWidth(),
3793					bottom: pos.top + $this.outerHeight(),
3794					startselected: false,
3795					selected: $this.hasClass("ui-selected"),
3796					selecting: $this.hasClass("ui-selecting"),
3797					unselecting: $this.hasClass("ui-unselecting")
3798				});
3799			});
3800		};
3801		this.refresh();
3802
3803		this.selectees = selectees.addClass("ui-selectee");
3804
3805		this._mouseInit();
3806
3807		this.helper = $("<div class='ui-selectable-helper'></div>");
3808	},
3809
3810	_destroy: function() {
3811		this.selectees
3812			.removeClass("ui-selectee")
3813			.removeData("selectable-item");
3814		this.element
3815			.removeClass("ui-selectable ui-selectable-disabled");
3816		this._mouseDestroy();
3817	},
3818
3819	_mouseStart: function(event) {
3820		var that = this,
3821			options = this.options;
3822
3823		this.opos = [event.pageX, event.pageY];
3824
3825		if (this.options.disabled) {
3826			return;
3827		}
3828
3829		this.selectees = $(options.filter, this.element[0]);
3830
3831		this._trigger("start", event);
3832
3833		$(options.appendTo).append(this.helper);
3834		// position helper (lasso)
3835		this.helper.css({
3836			"left": event.pageX,
3837			"top": event.pageY,
3838			"width": 0,
3839			"height": 0
3840		});
3841
3842		if (options.autoRefresh) {
3843			this.refresh();
3844		}
3845
3846		this.selectees.filter(".ui-selected").each(function() {
3847			var selectee = $.data(this, "selectable-item");
3848			selectee.startselected = true;
3849			if (!event.metaKey && !event.ctrlKey) {
3850				selectee.$element.removeClass("ui-selected");
3851				selectee.selected = false;
3852				selectee.$element.addClass("ui-unselecting");
3853				selectee.unselecting = true;
3854				// selectable UNSELECTING callback
3855				that._trigger("unselecting", event, {
3856					unselecting: selectee.element
3857				});
3858			}
3859		});
3860
3861		$(event.target).parents().addBack().each(function() {
3862			var doSelect,
3863				selectee = $.data(this, "selectable-item");
3864			if (selectee) {
3865				doSelect = (!event.metaKey && !event.ctrlKey) || !selectee.$element.hasClass("ui-selected");
3866				selectee.$element
3867					.removeClass(doSelect ? "ui-unselecting" : "ui-selected")
3868					.addClass(doSelect ? "ui-selecting" : "ui-unselecting");
3869				selectee.unselecting = !doSelect;
3870				selectee.selecting = doSelect;
3871				selectee.selected = doSelect;
3872				// selectable (UN)SELECTING callback
3873				if (doSelect) {
3874					that._trigger("selecting", event, {
3875						selecting: selectee.element
3876					});
3877				} else {
3878					that._trigger("unselecting", event, {
3879						unselecting: selectee.element
3880					});
3881				}
3882				return false;
3883			}
3884		});
3885
3886	},
3887
3888	_mouseDrag: function(event) {
3889
3890		this.dragged = true;
3891
3892		if (this.options.disabled) {
3893			return;
3894		}
3895
3896		var tmp,
3897			that = this,
3898			options = this.options,
3899			x1 = this.opos[0],
3900			y1 = this.opos[1],
3901			x2 = event.pageX,
3902			y2 = event.pageY;
3903
3904		if (x1 > x2) { tmp = x2; x2 = x1; x1 = tmp; }
3905		if (y1 > y2) { tmp = y2; y2 = y1; y1 = tmp; }
3906		this.helper.css({left: x1, top: y1, width: x2-x1, height: y2-y1});
3907
3908		this.selectees.each(function() {
3909			var selectee = $.data(this, "selectable-item"),
3910				hit = false;
3911
3912			//prevent helper from being selected if appendTo: selectable
3913			if (!selectee || selectee.element === that.element[0]) {
3914				return;
3915			}
3916
3917			if (options.tolerance === "touch") {
3918				hit = ( !(selectee.left > x2 || selectee.right < x1 || selectee.top > y2 || selectee.bottom < y1) );
3919			} else if (options.tolerance === "fit") {
3920				hit = (selectee.left > x1 && selectee.right < x2 && selectee.top > y1 && selectee.bottom < y2);
3921			}
3922
3923			if (hit) {
3924				// SELECT
3925				if (selectee.selected) {
3926					selectee.$element.removeClass("ui-selected");
3927					selectee.selected = false;
3928				}
3929				if (selectee.unselecting) {
3930					selectee.$element.removeClass("ui-unselecting");
3931					selectee.unselecting = false;
3932				}
3933				if (!selectee.selecting) {
3934					selectee.$element.addClass("ui-selecting");
3935					selectee.selecting = true;
3936					// selectable SELECTING callback
3937					that._trigger("selecting", event, {
3938						selecting: selectee.element
3939					});
3940				}
3941			} else {
3942				// UNSELECT
3943				if (selectee.selecting) {
3944					if ((event.metaKey || event.ctrlKey) && selectee.startselected) {
3945						selectee.$element.removeClass("ui-selecting");
3946						selectee.selecting = false;
3947						selectee.$element.addClass("ui-selected");
3948						selectee.selected = true;
3949					} else {
3950						selectee.$element.removeClass("ui-selecting");
3951						selectee.selecting = false;
3952						if (selectee.startselected) {
3953							selectee.$element.addClass("ui-unselecting");
3954							selectee.unselecting = true;
3955						}
3956						// selectable UNSELECTING callback
3957						that._trigger("unselecting", event, {
3958							unselecting: selectee.element
3959						});
3960					}
3961				}
3962				if (selectee.selected) {
3963					if (!event.metaKey && !event.ctrlKey && !selectee.startselected) {
3964						selectee.$element.removeClass("ui-selected");
3965						selectee.selected = false;
3966
3967						selectee.$element.addClass("ui-unselecting");
3968						selectee.unselecting = true;
3969						// selectable UNSELECTING callback
3970						that._trigger("unselecting", event, {
3971							unselecting: selectee.element
3972						});
3973					}
3974				}
3975			}
3976		});
3977
3978		return false;
3979	},
3980
3981	_mouseStop: function(event) {
3982		var that = this;
3983
3984		this.dragged = false;
3985
3986		$(".ui-unselecting", this.element[0]).each(function() {
3987			var selectee = $.data(this, "selectable-item");
3988			selectee.$element.removeClass("ui-unselecting");
3989			selectee.unselecting = false;
3990			selectee.startselected = false;
3991			that._trigger("unselected", event, {
3992				unselected: selectee.element
3993			});
3994		});
3995		$(".ui-selecting", this.element[0]).each(function() {
3996			var selectee = $.data(this, "selectable-item");
3997			selectee.$element.removeClass("ui-selecting").addClass("ui-selected");
3998			selectee.selecting = false;
3999			selectee.selected = true;
4000			selectee.startselected = true;
4001			that._trigger("selected", event, {
4002				selected: selectee.element
4003			});
4004		});
4005		this._trigger("stop", event);
4006
4007		this.helper.remove();
4008
4009		return false;
4010	}
4011
4012});
4013
4014})(jQuery);
4015(function( $, undefined ) {
4016
4017function isOverAxis( x, reference, size ) {
4018	return ( x > reference ) && ( x < ( reference + size ) );
4019}
4020
4021function isFloating(item) {
4022	return (/left|right/).test(item.css("float")) || (/inline|table-cell/).test(item.css("display"));
4023}
4024
4025$.widget("ui.sortable", $.ui.mouse, {
4026	version: "1.10.4",
4027	widgetEventPrefix: "sort",
4028	ready: false,
4029	options: {
4030		appendTo: "parent",
4031		axis: false,
4032		connectWith: false,
4033		containment: false,
4034		cursor: "auto",
4035		cursorAt: false,
4036		dropOnEmpty: true,
4037		forcePlaceholderSize: false,
4038		forceHelperSize: false,
4039		grid: false,
4040		handle: false,
4041		helper: "original",
4042		items: "> *",
4043		opacity: false,
4044		placeholder: false,
4045		revert: false,
4046		scroll: true,
4047		scrollSensitivity: 20,
4048		scrollSpeed: 20,
4049		scope: "default",
4050		tolerance: "intersect",
4051		zIndex: 1000,
4052
4053		// callbacks
4054		activate: null,
4055		beforeStop: null,
4056		change: null,
4057		deactivate: null,
4058		out: null,
4059		over: null,
4060		receive: null,
4061		remove: null,
4062		sort: null,
4063		start: null,
4064		stop: null,
4065		update: null
4066	},
4067	_create: function() {
4068
4069		var o = this.options;
4070		this.containerCache = {};
4071		this.element.addClass("ui-sortable");
4072
4073		//Get the items
4074		this.refresh();
4075
4076		//Let's determine if the items are being displayed horizontally
4077		this.floating = this.items.length ? o.axis === "x" || isFloating(this.items[0].item) : false;
4078
4079		//Let's determine the parent's offset
4080		this.offset = this.element.offset();
4081
4082		//Initialize mouse events for interaction
4083		this._mouseInit();
4084
4085		//We're ready to go
4086		this.ready = true;
4087
4088	},
4089
4090	_destroy: function() {
4091		this.element
4092			.removeClass("ui-sortable ui-sortable-disabled");
4093		this._mouseDestroy();
4094
4095		for ( var i = this.items.length - 1; i >= 0; i-- ) {
4096			this.items[i].item.removeData(this.widgetName + "-item");
4097		}
4098
4099		return this;
4100	},
4101
4102	_setOption: function(key, value){
4103		if ( key === "disabled" ) {
4104			this.options[ key ] = value;
4105
4106			this.widget().toggleClass( "ui-sortable-disabled", !!value );
4107		} else {
4108			// Don't call widget base _setOption for disable as it adds ui-state-disabled class
4109			$.Widget.prototype._setOption.apply(this, arguments);
4110		}
4111	},
4112
4113	_mouseCapture: function(event, overrideHandle) {
4114		var currentItem = null,
4115			validHandle = false,
4116			that = this;
4117
4118		if (this.reverting) {
4119			return false;
4120		}
4121
4122		if(this.options.disabled || this.options.type === "static") {
4123			return false;
4124		}
4125
4126		//We have to refresh the items data once first
4127		this._refreshItems(event);
4128
4129		//Find out if the clicked node (or one of its parents) is a actual item in this.items
4130		$(event.target).parents().each(function() {
4131			if($.data(this, that.widgetName + "-item") === that) {
4132				currentItem = $(this);
4133				return false;
4134			}
4135		});
4136		if($.data(event.target, that.widgetName + "-item") === that) {
4137			currentItem = $(event.target);
4138		}
4139
4140		if(!currentItem) {
4141			return false;
4142		}
4143		if(this.options.handle && !overrideHandle) {
4144			$(this.options.handle, currentItem).find("*").addBack().each(function() {
4145				if(this === event.target) {
4146					validHandle = true;
4147				}
4148			});
4149			if(!validHandle) {
4150				return false;
4151			}
4152		}
4153
4154		this.currentItem = currentItem;
4155		this._removeCurrentsFromItems();
4156		return true;
4157
4158	},
4159
4160	_mouseStart: function(event, overrideHandle, noActivation) {
4161
4162		var i, body,
4163			o = this.options;
4164
4165		this.currentContainer = this;
4166
4167		//We only need to call refreshPositions, because the refreshItems call has been moved to mouseCapture
4168		this.refreshPositions();
4169
4170		//Create and append the visible helper
4171		this.helper = this._createHelper(event);
4172
4173		//Cache the helper size
4174		this._cacheHelperProportions();
4175
4176		/*
4177		 * - Position generation -
4178		 * This block generates everything position related - it's the core of draggables.
4179		 */
4180
4181		//Cache the margins of the original element
4182		this._cacheMargins();
4183
4184		//Get the next scrolling parent
4185		this.scrollParent = this.helper.scrollParent();
4186
4187		//The element's absolute position on the page minus margins
4188		this.offset = this.currentItem.offset();
4189		this.offset = {
4190			top: this.offset.top - this.margins.top,
4191			left: this.offset.left - this.margins.left
4192		};
4193
4194		$.extend(this.offset, {
4195			click: { //Where the click happened, relative to the element
4196				left: event.pageX - this.offset.left,
4197				top: event.pageY - this.offset.top
4198			},
4199			parent: this._getParentOffset(),
4200			relative: this._getRelativeOffset() //This is a relative to absolute position minus the actual position calculation - only used for relative positioned helper
4201		});
4202
4203		// Only after we got the offset, we can change the helper's position to absolute
4204		// TODO: Still need to figure out a way to make relative sorting possible
4205		this.helper.css("position", "absolute");
4206		this.cssPosition = this.helper.css("position");
4207
4208		//Generate the original position
4209		this.originalPosition = this._generatePosition(event);
4210		this.originalPageX = event.pageX;
4211		this.originalPageY = event.pageY;
4212
4213		//Adjust the mouse offset relative to the helper if "cursorAt" is supplied
4214		(o.cursorAt && this._adjustOffsetFromHelper(o.cursorAt));
4215
4216		//Cache the former DOM position
4217		this.domPosition = { prev: this.currentItem.prev()[0], parent: this.currentItem.parent()[0] };
4218
4219		//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
4220		if(this.helper[0] !== this.currentItem[0]) {
4221			this.currentItem.hide();
4222		}
4223
4224		//Create the placeholder
4225		this._createPlaceholder();
4226
4227		//Set a containment if given in the options
4228		if(o.containment) {
4229			this._setContainment();
4230		}
4231
4232		if( o.cursor && o.cursor !== "auto" ) { // cursor option
4233			body = this.document.find( "body" );
4234
4235			// support: IE
4236			this.storedCursor = body.css( "cursor" );
4237			body.css( "cursor", o.cursor );
4238
4239			this.storedStylesheet = $( "<style>*{ cursor: "+o.cursor+" !important; }</style>" ).appendTo( body );
4240		}
4241
4242		if(o.opacity) { // opacity option
4243			if (this.helper.css("opacity")) {
4244				this._storedOpacity = this.helper.css("opacity");
4245			}
4246			this.helper.css("opacity", o.opacity);
4247		}
4248
4249		if(o.zIndex) { // zIndex option
4250			if (this.helper.css("zIndex")) {
4251				this._storedZIndex = this.helper.css("zIndex");
4252			}
4253			this.helper.css("zIndex", o.zIndex);
4254		}
4255
4256		//Prepare scrolling
4257		if(this.scrollParent[0] !== document && this.scrollParent[0].tagName !== "HTML") {
4258			this.overflowOffset = this.scrollParent.offset();
4259		}
4260
4261		//Call callbacks
4262		this._trigger("start", event, this._uiHash());
4263
4264		//Recache the helper size
4265		if(!this._preserveHelperProportions) {
4266			this._cacheHelperProportions();
4267		}
4268
4269
4270		//Post "activate" events to possible containers
4271		if( !noActivation ) {
4272			for ( i = this.containers.length - 1; i >= 0; i-- ) {
4273				this.containers[ i ]._trigger( "activate", event, this._uiHash( this ) );
4274			}
4275		}
4276
4277		//Prepare possible droppables
4278		if($.ui.ddmanager) {
4279			$.ui.ddmanager.current = this;
4280		}
4281
4282		if ($.ui.ddmanager && !o.dropBehaviour) {
4283			$.ui.ddmanager.prepareOffsets(this, event);
4284		}
4285
4286		this.dragging = true;
4287
4288		this.helper.addClass("ui-sortable-helper");
4289		this._mouseDrag(event); //Execute the drag once - this causes the helper not to be visible before getting its correct position
4290		return true;
4291
4292	},
4293
4294	_mouseDrag: function(event) {
4295		var i, item, itemElement, intersection,
4296			o = this.options,
4297			scrolled = false;
4298
4299		//Compute the helpers position
4300		this.position = this._generatePosition(event);
4301		this.positionAbs = this._convertPositionTo("absolute");
4302
4303		if (!this.lastPositionAbs) {
4304			this.lastPositionAbs = this.positionAbs;
4305		}
4306
4307		//Do scrolling
4308		if(this.options.scroll) {
4309			if(this.scrollParent[0] !== document && this.scrollParent[0].tagName !== "HTML") {
4310
4311				if((this.overflowOffset.top + this.scrollParent[0].offsetHeight) - event.pageY < o.scrollSensitivity) {
4312					this.scrollParent[0].scrollTop = scrolled = this.scrollParent[0].scrollTop + o.scrollSpeed;
4313				} else if(event.pageY - this.overflowOffset.top < o.scrollSensitivity) {
4314					this.scrollParent[0].scrollTop = scrolled = this.scrollParent[0].scrollTop - o.scrollSpeed;
4315				}
4316
4317				if((this.overflowOffset.left + this.scrollParent[0].offsetWidth) - event.pageX < o.scrollSensitivity) {
4318					this.scrollParent[0].scrollLeft = scrolled = this.scrollParent[0].scrollLeft + o.scrollSpeed;
4319				} else if(event.pageX - this.overflowOffset.left < o.scrollSensitivity) {
4320					this.scrollParent[0].scrollLeft = scrolled = this.scrollParent[0].scrollLeft - o.scrollSpeed;
4321				}
4322
4323			} else {
4324
4325				if(event.pageY - $(document).scrollTop() < o.scrollSensitivity) {
4326					scrolled = $(document).scrollTop($(document).scrollTop() - o.scrollSpeed);
4327				} else if($(window).height() - (event.pageY - $(document).scrollTop()) < o.scrollSensitivity) {
4328					scrolled = $(document).scrollTop($(document).scrollTop() + o.scrollSpeed);
4329				}
4330
4331				if(event.pageX - $(document).scrollLeft() < o.scrollSensitivity) {
4332					scrolled = $(document).scrollLeft($(document).scrollLeft() - o.scrollSpeed);
4333				} else if($(window).width() - (event.pageX - $(document).scrollLeft()) < o.scrollSensitivity) {
4334					scrolled = $(document).scrollLeft($(document).scrollLeft() + o.scrollSpeed);
4335				}
4336
4337			}
4338
4339			if(scrolled !== false && $.ui.ddmanager && !o.dropBehaviour) {
4340				$.ui.ddmanager.prepareOffsets(this, event);
4341			}
4342		}
4343
4344		//Regenerate the absolute position used for position checks
4345		this.positionAbs = this._convertPositionTo("absolute");
4346
4347		//Set the helper position
4348		if(!this.options.axis || this.options.axis !== "y") {
4349			this.helper[0].style.left = this.position.left+"px";
4350		}
4351		if(!this.options.axis || this.options.axis !== "x") {
4352			this.helper[0].style.top = this.position.top+"px";
4353		}
4354
4355		//Rearrange
4356		for (i = this.items.length - 1; i >= 0; i--) {
4357
4358			//Cache variables and intersection, continue if no intersection
4359			item = this.items[i];
4360			itemElement = item.item[0];
4361			intersection = this._intersectsWithPointer(item);
4362			if (!intersection) {
4363				continue;
4364			}
4365
4366			// Only put the placeholder inside the current Container, skip all
4367			// items from other containers. This works because when moving
4368			// an item from one container to another the
4369			// currentContainer is switched before the placeholder is moved.
4370			//
4371			// Without this, moving items in "sub-sortables" can cause
4372			// the placeholder to jitter beetween the outer and inner container.
4373			if (item.instance !== this.currentContainer) {
4374				continue;
4375			}
4376
4377			// cannot intersect with itself
4378			// no useless actions that have been done before
4379			// no action if the item moved is the parent of the item checked
4380			if (itemElement !== this.currentItem[0] &&
4381				this.placeholder[intersection === 1 ? "next" : "prev"]()[0] !== itemElement &&
4382				!$.contains(this.placeholder[0], itemElement) &&
4383				(this.options.type === "semi-dynamic" ? !$.contains(this.element[0], itemElement) : true)
4384			) {
4385
4386				this.direction = intersection === 1 ? "down" : "up";
4387
4388				if (this.options.tolerance === "pointer" || this._intersectsWithSides(item)) {
4389					this._rearrange(event, item);
4390				} else {
4391					break;
4392				}
4393
4394				this._trigger("change", event, this._uiHash());
4395				break;
4396			}
4397		}
4398
4399		//Post events to containers
4400		this._contactContainers(event);
4401
4402		//Interconnect with droppables
4403		if($.ui.ddmanager) {
4404			$.ui.ddmanager.drag(this, event);
4405		}
4406
4407		//Call callbacks
4408		this._trigger("sort", event, this._uiHash());
4409
4410		this.lastPositionAbs = this.positionAbs;
4411		return false;
4412
4413	},
4414
4415	_mouseStop: function(event, noPropagation) {
4416
4417		if(!event) {
4418			return;
4419		}
4420
4421		//If we are using droppables, inform the manager about the drop
4422		if ($.ui.ddmanager && !this.options.dropBehaviour) {
4423			$.ui.ddmanager.drop(this, event);
4424		}
4425
4426		if(this.options.revert) {
4427			var that = this,
4428				cur = this.placeholder.offset(),
4429				axis = this.options.axis,
4430				animation = {};
4431
4432			if ( !axis || axis === "x" ) {
4433				animation.left = cur.left - this.offset.parent.left - this.margins.left + (this.offsetParent[0] === document.body ? 0 : this.offsetParent[0].scrollLeft);
4434			}
4435			if ( !axis || axis === "y" ) {
4436				animation.top = cur.top - this.offset.parent.top - this.margins.top + (this.offsetParent[0] === document.body ? 0 : this.offsetParent[0].scrollTop);
4437			}
4438			this.reverting = true;
4439			$(this.helper).animate( animation, parseInt(this.options.revert, 10) || 500, function() {
4440				that._clear(event);
4441			});
4442		} else {
4443			this._clear(event, noPropagation);
4444		}
4445
4446		return false;
4447
4448	},
4449
4450	cancel: function() {
4451
4452		if(this.dragging) {
4453
4454			this._mouseUp({ target: null });
4455
4456			if(this.options.helper === "original") {
4457				this.currentItem.css(this._storedCSS).removeClass("ui-sortable-helper");
4458			} else {
4459				this.currentItem.show();
4460			}
4461
4462			//Post deactivating events to containers
4463			for (var i = this.containers.length - 1; i >= 0; i--){
4464				this.containers[i]._trigger("deactivate", null, this._uiHash(this));
4465				if(this.containers[i].containerCache.over) {
4466					this.containers[i]._trigger("out", null, this._uiHash(this));
4467					this.containers[i].containerCache.over = 0;
4468				}
4469			}
4470
4471		}
4472
4473		if (this.placeholder) {
4474			//$(this.placeholder[0]).remove(); would have been the jQuery way - unfortunately, it unbinds ALL events from the original node!
4475			if(this.placeholder[0].parentNode) {
4476				this.placeholder[0].parentNode.removeChild(this.placeholder[0]);
4477			}
4478			if(this.options.helper !== "original" && this.helper && this.helper[0].parentNode) {
4479				this.helper.remove();
4480			}
4481
4482			$.extend(this, {
4483				helper: null,
4484				dragging: false,
4485				reverting: false,
4486				_noFinalSort: null
4487			});
4488
4489			if(this.domPosition.prev) {
4490				$(this.domPosition.prev).after(this.currentItem);
4491			} else {
4492				$(this.domPosition.parent).prepend(this.currentItem);
4493			}
4494		}
4495
4496		return this;
4497
4498	},
4499
4500	serialize: function(o) {
4501
4502		var items = this._getItemsAsjQuery(o && o.connected),
4503			str = [];
4504		o = o || {};
4505
4506		$(items).each(function() {
4507			var res = ($(o.item || this).attr(o.attribute || "id") || "").match(o.expression || (/(.+)[\-=_](.+)/));
4508			if (res) {
4509				str.push((o.key || res[1]+"[]")+"="+(o.key && o.expression ? res[1] : res[2]));
4510			}
4511		});
4512
4513		if(!str.length && o.key) {
4514			str.push(o.key + "=");
4515		}
4516
4517		return str.join("&");
4518
4519	},
4520
4521	toArray: function(o) {
4522
4523		var items = this._getItemsAsjQuery(o && o.connected),
4524			ret = [];
4525
4526		o = o || {};
4527
4528		items.each(function() { ret.push($(o.item || this).attr(o.attribute || "id") || ""); });
4529		return ret;
4530
4531	},
4532
4533	/* Be careful with the following core functions */
4534	_intersectsWith: function(item) {
4535
4536		var x1 = this.positionAbs.left,
4537			x2 = x1 + this.helperProportions.width,
4538			y1 = this.positionAbs.top,
4539			y2 = y1 + this.helperProportions.height,
4540			l = item.left,
4541			r = l + item.width,
4542			t = item.top,
4543			b = t + item.height,
4544			dyClick = this.offset.click.top,
4545			dxClick = this.offset.click.left,
4546			isOverElementHeight = ( this.options.axis === "x" ) || ( ( y1 + dyClick ) > t && ( y1 + dyClick ) < b ),
4547			isOverElementWidth = ( this.options.axis === "y" ) || ( ( x1 + dxClick ) > l && ( x1 + dxClick ) < r ),
4548			isOverElement = isOverElementHeight && isOverElementWidth;
4549
4550		if ( this.options.tolerance === "pointer" ||
4551			this.options.forcePointerForContainers ||
4552			(this.options.tolerance !== "pointer" && this.helperProportions[this.floating ? "width" : "height"] > item[this.floating ? "width" : "height"])
4553		) {
4554			return isOverElement;
4555		} else {
4556
4557			return (l < x1 + (this.helperProportions.width / 2) && // Right Half
4558				x2 - (this.helperProportions.width / 2) < r && // Left Half
4559				t < y1 + (this.helperProportions.height / 2) && // Bottom Half
4560				y2 - (this.helperProportions.height / 2) < b ); // Top Half
4561
4562		}
4563	},
4564
4565	_intersectsWithPointer: function(item) {
4566
4567		var isOverElementHeight = (this.options.axis === "x") || isOverAxis(this.positionAbs.top + this.offset.click.top, item.top, item.height),
4568			isOverElementWidth = (this.options.axis === "y") || isOverAxis(this.positionAbs.left + this.offset.click.left, item.left, item.width),
4569			isOverElement = isOverElementHeight && isOverElementWidth,
4570			verticalDirection = this._getDragVerticalDirection(),
4571			horizontalDirection = this._getDragHorizontalDirection();
4572
4573		if (!isOverElement) {
4574			return false;
4575		}
4576
4577		return this.floating ?
4578			( ((horizontalDirection && horizontalDirection === "right") || verticalDirection === "down") ? 2 : 1 )
4579			: ( verticalDirection && (verticalDirection === "down" ? 2 : 1) );
4580
4581	},
4582
4583	_intersectsWithSides: function(item) {
4584
4585		var isOverBottomHalf = isOverAxis(this.positionAbs.top + this.offset.click.top, item.top + (item.height/2), item.height),
4586			isOverRightHalf = isOverAxis(this.positionAbs.left + this.offset.click.left, item.left + (item.width/2), item.width),
4587			verticalDirection = this._getDragVerticalDirection(),
4588			horizontalDirection = this._getDragHorizontalDirection();
4589
4590		if (this.floating && horizontalDirection) {
4591			return ((horizontalDirection === "right" && isOverRightHalf) || (horizontalDirection === "left" && !isOverRightHalf));
4592		} else {
4593			return verticalDirection && ((verticalDirection === "down" && isOverBottomHalf) || (verticalDirection === "up" && !isOverBottomHalf));
4594		}
4595
4596	},
4597
4598	_getDragVerticalDirection: function() {
4599		var delta = this.positionAbs.top - this.lastPositionAbs.top;
4600		return delta !== 0 && (delta > 0 ? "down" : "up");
4601	},
4602
4603	_getDragHorizontalDirection: function() {
4604		var delta = this.positionAbs.left - this.lastPositionAbs.left;
4605		return delta !== 0 && (delta > 0 ? "right" : "left");
4606	},
4607
4608	refresh: function(event) {
4609		this._refreshItems(event
vendor: 4,154 bytes, lines 4609-4745
4609);
4610		this.refreshPositions();
4611		return this;
4612	},
4613
4614	_connectWith: function() {
4615		var options = this.options;
4616		return options.connectWith.constructor === String ? [options.connectWith] : options.connectWith;
4617	},
4618
4619	_getItemsAsjQuery: function(connected) {
4620
4621		var i, j, cur, inst,
4622			items = [],
4623			queries = [],
4624			connectWith = this._connectWith();
4625
4626		if(connectWith && connected) {
4627			for (i = connectWith.length - 1; i >= 0; i--){
4628				cur = $(connectWith[i]);
4629				for ( j = cur.length - 1; j >= 0; j--){
4630					inst = $.data(cur[j], this.widgetFullName);
4631					if(inst && inst !== this && !inst.options.disabled) {
4632						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]);
4633					}
4634				}
4635			}
4636		}
4637
4638		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]);
4639
4640		function addItems() {
4641			items.push( this );
4642		}
4643		for (i = queries.length - 1; i >= 0; i--){
4644			queries[i][0].each( addItems );
4645		}
4646
4647		return $(items);
4648
4649	},
4650
4651	_removeCurrentsFromItems: function() {
4652
4653		var list = this.currentItem.find(":data(" + this.widgetName + "-item)");
4654
4655		this.items = $.grep(this.items, function (item) {
4656			for (var j=0; j < list.length; j++) {
4657				if(list[j] === item.item[0]) {
4658					return false;
4659				}
4660			}
4661			return true;
4662		});
4663
4664	},
4665
4666	_refreshItems: function(event) {
4667
4668		this.items = [];
4669		this.containers = [this];
4670
4671		var i, j, cur, inst, targetData, _queries, item, queriesLength,
4672			items = this.items,
4673			queries = [[$.isFunction(this.options.items) ? this.options.items.call(this.element[0], event, { item: this.currentItem }) : $(this.options.items, this.element), this]],
4674			connectWith = this._connectWith();
4675
4676		if(connectWith && this.ready) { //Shouldn't be run the first time through due to massive slow-down
4677			for (i = connectWith.length - 1; i >= 0; i--){
4678				cur = $(connectWith[i]);
4679				for (j = cur.length - 1; j >= 0; j--){
4680					inst = $.data(cur[j], this.widgetFullName);
4681					if(inst && inst !== this && !inst.options.disabled) {
4682						queries.push([$.isFunction(inst.options.items) ? inst.options.items.call(inst.element[0], event, { item: this.currentItem }) : $(inst.options.items, inst.element), inst]);
4683						this.containers.push(inst);
4684					}
4685				}
4686			}
4687		}
4688
4689		for (i = queries.length - 1; i >= 0; i--) {
4690			targetData = queries[i][1];
4691			_queries = queries[i][0];
4692
4693			for (j=0, queriesLength = _queries.length; j < queriesLength; j++) {
4694				item = $(_queries[j]);
4695
4696				item.data(this.widgetName + "-item", targetData); // Data for target checking (mouse manager)
4697
4698				items.push({
4699					item: item,
4700					instance: targetData,
4701					width: 0, height: 0,
4702					left: 0, top: 0
4703				});
4704			}
4705		}
4706
4707	},
4708
4709	refreshPositions: function(fast) {
4710
4711		//This has to be redone because due to the item being moved out/into the offsetParent, the offsetParent's position will change
4712		if(this.offsetParent && this.helper) {
4713			this.offset.parent = this._getParentOffset();
4714		}
4715
4716		var i, item, t, p;
4717
4718		for (i = this.items.length - 1; i >= 0; i--){
4719			item = this.items[i];
4720
4721			//We ignore calculating positions of all connected containers when we're not over them
4722			if(item.instance !== this.currentContainer && this.currentContainer && item.item[0] !== this.currentItem[0]) {
4723				continue;
4724			}
4725
4726			t = this.options.toleranceElement ? $(this.options.toleranceElement, item.item) : item.item;
4727
4728			if (!fast) {
4729				item.width = t.outerWidth();
4730				item.height = t.outerHeight();
4731			}
4732
4733			p = t.offset();
4734			item.left = p.left;
4735			item.top = p.top;
4736		}
4737
4738		if(this.options.custom && this.options.custom.refreshContainers) {
4739			this.options.custom.refreshContainers.call(this);
4740		} else {
4741			for (i = this.containers.length - 1; i >= 0; i--){
4742				p = this.containers[i].element.offset();
4743				this.containers[i].containerCache.left = p.left;
4744				this.containers[i].containerCache.top = p.top;
4745				this.containers[i].containerCache.width
vendor: 1,591 bytes, lines 4745-4792
4745	= this.containers[i].element.outerWidth();
4746				this.containers[i].containerCache.height = this.containers[i].element.outerHeight();
4747			}
4748		}
4749
4750		return this;
4751	},
4752
4753	_createPlaceholder: function(that) {
4754		that = that || this;
4755		var className,
4756			o = that.options;
4757
4758		if(!o.placeholder || o.placeholder.constructor === String) {
4759			className = o.placeholder;
4760			o.placeholder = {
4761				element: function() {
4762
4763					var nodeName = that.currentItem[0].nodeName.toLowerCase(),
4764						element = $( "<" + nodeName + ">", that.document[0] )
4765							.addClass(className || that.currentItem[0].className+" ui-sortable-placeholder")
4766							.removeClass("ui-sortable-helper");
4767
4768					if ( nodeName === "tr" ) {
4769						that.currentItem.children().each(function() {
4770							$( "<td>&#160;</td>", that.document[0] )
4771								.attr( "colspan", $( this ).attr( "colspan" ) || 1 )
4772								.appendTo( element );
4773						});
4774					} else if ( nodeName === "img" ) {
4775						element.attr( "src", that.currentItem.attr( "src" ) );
4776					}
4777
4778					if ( !className ) {
4779						element.css( "visibility", "hidden" );
4780					}
4781
4782					return element;
4783				},
4784				update: function(container, p) {
4785
4786					// 1. If a className is set as 'placeholder option, we don't force sizes - the class is responsible for that
4787					// 2. The option 'forcePlaceholderSize can be enabled to force it even if a class name is specified
4788					if(className && !o.forcePlaceholderSize) {
4789						return;
4790					}
4791
4792					//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
4793					if(!p.height()) { p.height(that.currentItem.innerHeight() - parseInt(that.currentItem.css("paddingTop")||0, 10) - parseInt(that.currentItem.css("paddingBottom")||0, 10)); }
4794					if(!p.width()) { p.width(that.currentItem.innerWidth() - parseInt(that.currentItem.css("paddingLeft")||0, 10) - parseInt(that.currentItem.css("paddingRight")||0, 10)); }
4795				}
4796			};
4797		}
4798
4799		//Create the placeholder
4800		that.placeholder = $(o.placeholder.element.call(that.element, that.currentItem));
4801
4802		//Append it after the actual current item
4803		that.currentItem.after(that.placeholder);
4804
4805		//Update the size of the placeholder (TODO: Logic to fuzzy, see line 316/317)
4806		o.placeholder.update(that, that.placeholder);
4807
4808	},
4809
4810	_contactContainers: function(event) {
4811		var i, j, dist, itemWithLeastDistance, posProperty, sizeProperty, base, cur, nearBottom, floating,
4812			innermostContainer = null,
4813			innermostIndex = null;
4814
4815		// get innermost container that intersects with item
4816		for (i = this.containers.length - 1; i >= 0; i--) {
4817
4818			// never consider a container that's located within the item itself
4819			if($.contains(this.currentItem[0], this.containers[i].element[0])) {
4820				continue;
4821			}
4822
4823			if(this._intersectsWith(this.containers[i].containerCache)) {
4824
4825				// if we've already found a container and it's more "inner" than this, then continue
4826				if(innermostContainer && $.contains(this.containers[i].element[0], innermostContainer.element[0])) {
4827					continue;
4828				}
4829
4830				innermostContainer = this.containers[i];
4831				innermostIndex = i;
4832
4833			} else {
4834				// container doesn't intersect. trigger "out" event if necessary
4835				if(this.containers[i].containerCache.over) {
4836					this.containers[i]._trigger("out", event, this._uiHash(this));
4837					this.containers[i].containerCache.over = 0;
4838				}
4839			}
4840
4841		}
4842
4843		// if no intersecting containers found, return
4844		if(!innermostContainer) {
4845			return;
4846		}
4847
4848		// move the item into the container if it's not there already
4849		if(this.containers.length === 1) {
4850			if (!this.containers[innermostIndex].containerCache.over) {
4851				this.containers[innermostIndex]._trigger("over", event, this._uiHash(this));
4852				this.containers[innermostIndex].containerCache.over = 1;
4853			}
4854		} else {
4855
4856			//When entering a new container, we will find the item with the least distance and append our item near it
4857			dist = 10000;
4858			itemWithLeastDistance = null;
4859			floating = innermostContainer.floating || isFloating(this.currentItem);
4860			posProperty = floating ? "left" : "top";
4861			sizeProperty = floating ? "width" : "height";
4862			base = this.positionAbs[posProperty] + this.offset.click[posProperty];
4863			for (j = this.items.length - 1; j >= 0; j--) {
4864				if(!$.contains(this.containers[innermostIndex].element[0], this.items[j].item[0])) {
4865					continue;
4866				}
4867				if(this.items[j].item[0] === this.currentItem[0]) {
4868					continue;
4869				}
4870				if (floating && !isOverAxis(this.positionAbs.top + this.offset.click.top, this.items[j].top, this.items[j].height)) {
4871					continue;
4872				}
4873				cur = this.items[j].item.offset()[posProperty];
4874				nearBottom = false;
4875				if(Math.abs(cur - base) > Math.abs(cur + this.items[j][sizeProperty] - base)){
4876					nearBottom = true;
4877					cur += this.items[j][sizeProperty];
4878				}
4879
4880				if(Math.abs(cur - base) < dist) {
4881					dist = Math.abs(cur - base); itemWithLeastDistance = this.items[j
vendor: 15,870 bytes, lines 4881-5287
4881];
4882					this.direction = nearBottom ? "up": "down";
4883				}
4884			}
4885
4886			//Check if dropOnEmpty is enabled
4887			if(!itemWithLeastDistance && !this.options.dropOnEmpty) {
4888				return;
4889			}
4890
4891			if(this.currentContainer === this.containers[innermostIndex]) {
4892				return;
4893			}
4894
4895			itemWithLeastDistance ? this._rearrange(event, itemWithLeastDistance, null, true) : this._rearrange(event, null, this.containers[innermostIndex].element, true);
4896			this._trigger("change", event, this._uiHash());
4897			this.containers[innermostIndex]._trigger("change", event, this._uiHash(this));
4898			this.currentContainer = this.containers[innermostIndex];
4899
4900			//Update the placeholder
4901			this.options.placeholder.update(this.currentContainer, this.placeholder);
4902
4903			this.containers[innermostIndex]._trigger("over", event, this._uiHash(this));
4904			this.containers[innermostIndex].containerCache.over = 1;
4905		}
4906
4907
4908	},
4909
4910	_createHelper: function(event) {
4911
4912		var o = this.options,
4913			helper = $.isFunction(o.helper) ? $(o.helper.apply(this.element[0], [event, this.currentItem])) : (o.helper === "clone" ? this.currentItem.clone() : this.currentItem);
4914
4915		//Add the helper to the DOM if that didn't happen already
4916		if(!helper.parents("body").length) {
4917			$(o.appendTo !== "parent" ? o.appendTo : this.currentItem[0].parentNode)[0].appendChild(helper[0]);
4918		}
4919
4920		if(helper[0] === this.currentItem[0]) {
4921			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") };
4922		}
4923
4924		if(!helper[0].style.width || o.forceHelperSize) {
4925			helper.width(this.currentItem.width());
4926		}
4927		if(!helper[0].style.height || o.forceHelperSize) {
4928			helper.height(this.currentItem.height());
4929		}
4930
4931		return helper;
4932
4933	},
4934
4935	_adjustOffsetFromHelper: function(obj) {
4936		if (typeof obj === "string") {
4937			obj = obj.split(" ");
4938		}
4939		if ($.isArray(obj)) {
4940			obj = {left: +obj[0], top: +obj[1] || 0};
4941		}
4942		if ("left" in obj) {
4943			this.offset.click.left = obj.left + this.margins.left;
4944		}
4945		if ("right" in obj) {
4946			this.offset.click.left = this.helperProportions.width - obj.right + this.margins.left;
4947		}
4948		if ("top" in obj) {
4949			this.offset.click.top = obj.top + this.margins.top;
4950		}
4951		if ("bottom" in obj) {
4952			this.offset.click.top = this.helperProportions.height - obj.bottom + this.margins.top;
4953		}
4954	},
4955
4956	_getParentOffset: function() {
4957
4958
4959		//Get the offsetParent and cache its position
4960		this.offsetParent = this.helper.offsetParent();
4961		var po = this.offsetParent.offset();
4962
4963		// This is a special case where we need to modify a offset calculated on start, since the following happened:
4964		// 1. The position of the helper is absolute, so it's position is calculated based on the next positioned parent
4965		// 2. The actual offset parent is a child of the scroll parent, and the scroll parent isn't the document, which means that
4966		//    the scroll is included in the initial calculation of the offset of the parent, and never recalculated upon drag
4967		if(this.cssPosition === "absolute" && this.scrollParent[0] !== document && $.contains(this.scrollParent[0], this.offsetParent[0])) {
4968			po.left += this.scrollParent.scrollLeft();
4969			po.top += this.scrollParent.scrollTop();
4970		}
4971
4972		// This needs to be actually done for all browsers, since pageX/pageY includes this information
4973		// with an ugly IE fix
4974		if( this.offsetParent[0] === document.body || (this.offsetParent[0].tagName && this.offsetParent[0].tagName.toLowerCase() === "html" && $.ui.ie)) {
4975			po = { top: 0, left: 0 };
4976		}
4977
4978		return {
4979			top: po.top + (parseInt(this.offsetParent.css("borderTopWidth"),10) || 0),
4980			left: po.left + (parseInt(this.offsetParent.css("borderLeftWidth"),10) || 0)
4981		};
4982
4983	},
4984
4985	_getRelativeOffset: function() {
4986
4987		if(this.cssPosition === "relative") {
4988			var p = this.currentItem.position();
4989			return {
4990				top: p.top - (parseInt(this.helper.css("top"),10) || 0) + this.scrollParent.scrollTop(),
4991				left: p.left - (parseInt(this.helper.css("left"),10) || 0) + this.scrollParent.scrollLeft()
4992			};
4993		} else {
4994			return { top: 0, left: 0 };
4995		}
4996
4997	},
4998
4999	_cacheMargins: function() {
5000		this.margins = {
5001			left: (parseInt(this.currentItem.css("marginLeft"),10) || 0),
5002			top: (parseInt(this.currentItem.css("marginTop"),10) || 0)
5003		};
5004	},
5005
5006	_cacheHelperProportions: function() {
5007		this.helperProportions = {
5008			width: this.helper.outerWidth(),
5009			height: this.helper.outerHeight()
5010		};
5011	},
5012
5013	_setContainment: function() {
5014
5015		var ce, co, over,
5016			o = this.options;
5017		if(o.containment === "parent") {
5018			o.containment = this.helper[0].parentNode;
5019		}
5020		if(o.containment === "document" || o.containment === "window") {
5021			this.containment = [
5022				0 - this.offset.relative.left - this.offset.parent.left,
5023				0 - this.offset.relative.top - this.offset.parent.top,
5024				$(o.containment === "document" ? document : window).width() - this.helperProportions.width - this.margins.left,
5025				($(o.containment === "document" ? document : window).height() || document.body.parentNode.scrollHeight) - this.helperProportions.height - this.margins.top
5026			];
5027		}
5028
5029		if(!(/^(document|window|parent)$/).test(o.containment)) {
5030			ce = $(o.containment)[0];
5031			co = $(o.containment).offset();
5032			over = ($(ce).css("overflow") !== "hidden");
5033
5034			this.containment = [
5035				co.left + (parseInt($(ce).css("borderLeftWidth"),10) || 0) + (parseInt($(ce).css("paddingLeft"),10) || 0) - this.margins.left,
5036				co.top + (parseInt($(ce).css("borderTopWidth"),10) || 0) + (parseInt($(ce).css("paddingTop"),10) || 0) - this.margins.top,
5037				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,
5038				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
5039			];
5040		}
5041
5042	},
5043
5044	_convertPositionTo: function(d, pos) {
5045
5046		if(!pos) {
5047			pos = this.position;
5048		}
5049		var mod = d === "absolute" ? 1 : -1,
5050			scroll = this.cssPosition === "absolute" && !(this.scrollParent[0] !== document && $.contains(this.scrollParent[0], this.offsetParent[0])) ? this.offsetParent : this.scrollParent,
5051			scrollIsRootNode = (/(html|body)/i).test(scroll[0].tagName);
5052
5053		return {
5054			top: (
5055				pos.top	+																// The absolute mouse position
5056				this.offset.relative.top * mod +										// Only for relative positioned nodes: Relative offset from element to offset parent
5057				this.offset.parent.top * mod -											// The offsetParent's offset without borders (offset + border)
5058				( ( this.cssPosition === "fixed" ? -this.scrollParent.scrollTop() : ( scrollIsRootNode ? 0 : scroll.scrollTop() ) ) * mod)
5059			),
5060			left: (
5061				pos.left +																// The absolute mouse position
5062				this.offset.relative.left * mod +										// Only for relative positioned nodes: Relative offset from element to offset parent
5063				this.offset.parent.left * mod	-										// The offsetParent's offset without borders (offset + border)
5064				( ( this.cssPosition === "fixed" ? -this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 : scroll.scrollLeft() ) * mod)
5065			)
5066		};
5067
5068	},
5069
5070	_generatePosition: function(event) {
5071
5072		var top, left,
5073			o = this.options,
5074			pageX = event.pageX,
5075			pageY = event.pageY,
5076			scroll = this.cssPosition === "absolute" && !(this.scrollParent[0] !== document && $.contains(this.scrollParent[0], this.offsetParent[0])) ? this.offsetParent : this.scrollParent, scrollIsRootNode = (/(html|body)/i).test(scroll[0].tagName);
5077
5078		// This is another very weird special case that only happens for relative elements:
5079		// 1. If the css position is relative
5080		// 2. and the scroll parent is the document or similar to the offset parent
5081		// we have to refresh the relative offset during the scroll so there are no jumps
5082		if(this.cssPosition === "relative" && !(this.scrollParent[0] !== document && this.scrollParent[0] !== this.offsetParent[0])) {
5083			this.offset.relative = this._getRelativeOffset();
5084		}
5085
5086		/*
5087		 * - Position constraining -
5088		 * Constrain the position to a mix of grid, containment.
5089		 */
5090
5091		if(this.originalPosition) { //If we are not dragging yet, we won't check for options
5092
5093			if(this.containment) {
5094				if(event.pageX - this.offset.click.left < this.containment[0]) {
5095					pageX = this.containment[0] + this.offset.click.left;
5096				}
5097				if(event.pageY - this.offset.click.top < this.containment[1]) {
5098					pageY = this.containment[1] + this.offset.click.top;
5099				}
5100				if(event.pageX - this.offset.click.left > this.containment[2]) {
5101					pageX = this.containment[2] + this.offset.click.left;
5102				}
5103				if(event.pageY - this.offset.click.top > this.containment[3]) {
5104					pageY = this.containment[3] + this.offset.click.top;
5105				}
5106			}
5107
5108			if(o.grid) {
5109				top = this.originalPageY + Math.round((pageY - this.originalPageY) / o.grid[1]) * o.grid[1];
5110				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;
5111
5112				left = this.originalPageX + Math.round((pageX - this.originalPageX) / o.grid[0]) * o.grid[0];
5113				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;
5114			}
5115
5116		}
5117
5118		return {
5119			top: (
5120				pageY -																// The absolute mouse position
5121				this.offset.click.top -													// Click offset (relative to the element)
5122				this.offset.relative.top	-											// Only for relative positioned nodes: Relative offset from element to offset parent
5123				this.offset.parent.top +												// The offsetParent's offset without borders (offset + border)
5124				( ( this.cssPosition === "fixed" ? -this.scrollParent.scrollTop() : ( scrollIsRootNode ? 0 : scroll.scrollTop() ) ))
5125			),
5126			left: (
5127				pageX -																// The absolute mouse position
5128				this.offset.click.left -												// Click offset (relative to the element)
5129				this.offset.relative.left	-											// Only for relative positioned nodes: Relative offset from element to offset parent
5130				this.offset.parent.left +												// The offsetParent's offset without borders (offset + border)
5131				( ( this.cssPosition === "fixed" ? -this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 : scroll.scrollLeft() ))
5132			)
5133		};
5134
5135	},
5136
5137	_rearrange: function(event, i, a, hardRefresh) {
5138
5139		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));
5140
5141		//Various things done here to improve the performance:
5142		// 1. we create a setTimeout, that calls refreshPositions
5143		// 2. on the instance, we have a counter variable, that get's higher after every append
5144		// 3. on the local scope, we copy the counter variable, and check in the timeout, if it's still the same
5145		// 4. this lets only the last addition to the timeout stack through
5146		this.counter = this.counter ? ++this.counter : 1;
5147		var counter = this.counter;
5148
5149		this._delay(function() {
5150			if(counter === this.counter) {
5151				this.refreshPositions(!hardRefresh); //Precompute after each DOM insertion, NOT on mousemove
5152			}
5153		});
5154
5155	},
5156
5157	_clear: function(event, noPropagation) {
5158
5159		this.reverting = false;
5160		// We delay all events that have to be triggered to after the point where the placeholder has been removed and
5161		// everything else normalized again
5162		var i,
5163			delayedTriggers = [];
5164
5165		// We first have to update the dom position of the actual currentItem
5166		// Note: don't do it if the current item is already removed (by a user), or it gets reappended (see #4088)
5167		if(!this._noFinalSort && this.currentItem.parent().length) {
5168			this.placeholder.before(this.currentItem);
5169		}
5170		this._noFinalSort = null;
5171
5172		if(this.helper[0] === this.currentItem[0]) {
5173			for(i in this._storedCSS) {
5174				if(this._storedCSS[i] === "auto" || this._storedCSS[i] === "static") {
5175					this._storedCSS[i] = "";
5176				}
5177			}
5178			this.currentItem.css(this._storedCSS).removeClass("ui-sortable-helper");
5179		} else {
5180			this.currentItem.show();
5181		}
5182
5183		if(this.fromOutside && !noPropagation) {
5184			delayedTriggers.push(function(event) { this._trigger("receive", event, this._uiHash(this.fromOutside)); });
5185		}
5186		if((this.fromOutside || this.domPosition.prev !== this.currentItem.prev().not(".ui-sortable-helper")[0] || this.domPosition.parent !== this.currentItem.parent()[0]) && !noPropagation) {
5187			delayedTriggers.push(function(event) { this._trigger("update", event, this._uiHash()); }); //Trigger update callback if the DOM position has changed
5188		}
5189
5190		// Check if the items Container has Changed and trigger appropriate
5191		// events.
5192		if (this !== this.currentContainer) {
5193			if(!noPropagation) {
5194				delayedTriggers.push(function(event) { this._trigger("remove", event, this._uiHash()); });
5195				delayedTriggers.push((function(c) { return function(event) { c._trigger("receive", event, this._uiHash(this)); };  }).call(this, this.currentContainer));
5196				delayedTriggers.push((function(c) { return function(event) { c._trigger("update", event, this._uiHash(this));  }; }).call(this, this.currentContainer));
5197			}
5198		}
5199
5200
5201		//Post events to containers
5202		function delayEvent( type, instance, container ) {
5203			return function( event ) {
5204				container._trigger( type, event, instance._uiHash( instance ) );
5205			};
5206		}
5207		for (i = this.containers.length - 1; i >= 0; i--){
5208			if (!noPropagation) {
5209				delayedTriggers.push( delayEvent( "deactivate", this, this.containers[ i ] ) );
5210			}
5211			if(this.containers[i].containerCache.over) {
5212				delayedTriggers.push( delayEvent( "out", this, this.containers[ i ] ) );
5213				this.containers[i].containerCache.over = 0;
5214			}
5215		}
5216
5217		//Do what was originally in plugins
5218		if ( this.storedCursor ) {
5219			this.document.find( "body" ).css( "cursor", this.storedCursor );
5220			this.storedStylesheet.remove();
5221		}
5222		if(this._storedOpacity) {
5223			this.helper.css("opacity", this._storedOpacity);
5224		}
5225		if(this._storedZIndex) {
5226			this.helper.css("zIndex", this._storedZIndex === "auto" ? "" : this._storedZIndex);
5227		}
5228
5229		this.dragging = false;
5230		if(this.cancelHelperRemoval) {
5231			if(!noPropagation) {
5232				this._trigger("beforeStop", event, this._uiHash());
5233				for (i=0; i < delayedTriggers.length; i++) {
5234					delayedTriggers[i].call(this, event);
5235				} //Trigger all delayed events
5236				this._trigger("stop", event, this._uiHash());
5237			}
5238
5239			this.fromOutside = false;
5240			return false;
5241		}
5242
5243		if(!noPropagation) {
5244			this._trigger("beforeStop", event, this._uiHash());
5245		}
5246
5247		//$(this.placeholder[0]).remove(); would have been the jQuery way - unfortunately, it unbinds ALL events from the original node!
5248		this.placeholder[0].parentNode.removeChild(this.placeholder[0]);
5249
5250		if(this.helper[0] !== this.currentItem[0]) {
5251			this.helper.remove();
5252		}
5253		this.helper = null;
5254
5255		if(!noPropagation) {
5256			for (i=0; i < delayedTriggers.length; i++) {
5257				delayedTriggers[i].call(this, event);
5258			} //Trigger all delayed events
5259			this._trigger("stop", event, this._uiHash());
5260		}
5261
5262		this.fromOutside = false;
5263		return true;
5264
5265	},
5266
5267	_trigger: function() {
5268		if ($.Widget.prototype._trigger.apply(this, arguments) === false) {
5269			this.cancel();
5270		}
5271	},
5272
5273	_uiHash: function(_inst) {
5274		var inst = _inst || this;
5275		return {
5276			helper: inst.helper,
5277			placeholder: inst.placeholder || $([]),
5278			position: inst.position,
5279			originalPosition: inst.originalPosition,
5280			offset: inst.positionAbs,
5281			item: inst.currentItem,
5282			sender: _inst ? _inst.element : null
5283		};
5284	}
5285
5286});
5287
vendor: 38,719 bytes, lines 5288-6728
5288})(jQuery);
5289(function( $, undefined ) {
5290
5291var uid = 0,
5292	hideProps = {},
5293	showProps = {};
5294
5295hideProps.height = hideProps.paddingTop = hideProps.paddingBottom =
5296	hideProps.borderTopWidth = hideProps.borderBottomWidth = "hide";
5297showProps.height = showProps.paddingTop = showProps.paddingBottom =
5298	showProps.borderTopWidth = showProps.borderBottomWidth = "show";
5299
5300$.widget( "ui.accordion", {
5301	version: "1.10.4",
5302	options: {
5303		active: 0,
5304		animate: {},
5305		collapsible: false,
5306		event: "click",
5307		header: "> li > :first-child,> :not(li):even",
5308		heightStyle: "auto",
5309		icons: {
5310			activeHeader: "ui-icon-triangle-1-s",
5311			header: "ui-icon-triangle-1-e"
5312		},
5313
5314		// callbacks
5315		activate: null,
5316		beforeActivate: null
5317	},
5318
5319	_create: function() {
5320		var options = this.options;
5321		this.prevShow = this.prevHide = $();
5322		this.element.addClass( "ui-accordion ui-widget ui-helper-reset" )
5323			// ARIA
5324			.attr( "role", "tablist" );
5325
5326		// don't allow collapsible: false and active: false / null
5327		if ( !options.collapsible && (options.active === false || options.active == null) ) {
5328			options.active = 0;
5329		}
5330
5331		this._processPanels();
5332		// handle negative values
5333		if ( options.active < 0 ) {
5334			options.active += this.headers.length;
5335		}
5336		this._refresh();
5337	},
5338
5339	_getCreateEventData: function() {
5340		return {
5341			header: this.active,
5342			panel: !this.active.length ? $() : this.active.next(),
5343			content: !this.active.length ? $() : this.active.next()
5344		};
5345	},
5346
5347	_createIcons: function() {
5348		var icons = this.options.icons;
5349		if ( icons ) {
5350			$( "<span>" )
5351				.addClass( "ui-accordion-header-icon ui-icon " + icons.header )
5352				.prependTo( this.headers );
5353			this.active.children( ".ui-accordion-header-icon" )
5354				.removeClass( icons.header )
5355				.addClass( icons.activeHeader );
5356			this.headers.addClass( "ui-accordion-icons" );
5357		}
5358	},
5359
5360	_destroyIcons: function() {
5361		this.headers
5362			.removeClass( "ui-accordion-icons" )
5363			.children( ".ui-accordion-header-icon" )
5364				.remove();
5365	},
5366
5367	_destroy: function() {
5368		var contents;
5369
5370		// clean up main element
5371		this.element
5372			.removeClass( "ui-accordion ui-widget ui-helper-reset" )
5373			.removeAttr( "role" );
5374
5375		// clean up headers
5376		this.headers
5377			.removeClass( "ui-accordion-header ui-accordion-header-active ui-helper-reset ui-state-default ui-corner-all ui-state-active ui-state-disabled ui-corner-top" )
5378			.removeAttr( "role" )
5379			.removeAttr( "aria-expanded" )
5380			.removeAttr( "aria-selected" )
5381			.removeAttr( "aria-controls" )
5382			.removeAttr( "tabIndex" )
5383			.each(function() {
5384				if ( /^ui-accordion/.test( this.id ) ) {
5385					this.removeAttribute( "id" );
5386				}
5387			});
5388		this._destroyIcons();
5389
5390		// clean up content panels
5391		contents = this.headers.next()
5392			.css( "display", "" )
5393			.removeAttr( "role" )
5394			.removeAttr( "aria-hidden" )
5395			.removeAttr( "aria-labelledby" )
5396			.removeClass( "ui-helper-reset ui-widget-content ui-corner-bottom ui-accordion-content ui-accordion-content-active ui-state-disabled" )
5397			.each(function() {
5398				if ( /^ui-accordion/.test( this.id ) ) {
5399					this.removeAttribute( "id" );
5400				}
5401			});
5402		if ( this.options.heightStyle !== "content" ) {
5403			contents.css( "height", "" );
5404		}
5405	},
5406
5407	_setOption: function( key, value ) {
5408		if ( key === "active" ) {
5409			// _activate() will handle invalid values and update this.options
5410			this._activate( value );
5411			return;
5412		}
5413
5414		if ( key === "event" ) {
5415			if ( this.options.event ) {
5416				this._off( this.headers, this.options.event );
5417			}
5418			this._setupEvents( value );
5419		}
5420
5421		this._super( key, value );
5422
5423		// setting collapsible: false while collapsed; open first panel
5424		if ( key === "collapsible" && !value && this.options.active === false ) {
5425			this._activate( 0 );
5426		}
5427
5428		if ( key === "icons" ) {
5429			this._destroyIcons();
5430			if ( value ) {
5431				this._createIcons();
5432			}
5433		}
5434
5435		// #5332 - opacity doesn't cascade to positioned elements in IE
5436		// so we need to add the disabled class to the headers and panels
5437		if ( key === "disabled" ) {
5438			this.headers.add( this.headers.next() )
5439				.toggleClass( "ui-state-disabled", !!value );
5440		}
5441	},
5442
5443	_keydown: function( event ) {
5444		if ( event.altKey || event.ctrlKey ) {
5445			return;
5446		}
5447
5448		var keyCode = $.ui.keyCode,
5449			length = this.headers.length,
5450			currentIndex = this.headers.index( event.target ),
5451			toFocus = false;
5452
5453		switch ( event.keyCode ) {
5454			case keyCode.RIGHT:
5455			case keyCode.DOWN:
5456				toFocus = this.headers[ ( currentIndex + 1 ) % length ];
5457				break;
5458			case keyCode.LEFT:
5459			case keyCode.UP:
5460				toFocus = this.headers[ ( currentIndex - 1 + length ) % length ];
5461				break;
5462			case keyCode.SPACE:
5463			case keyCode.ENTER:
5464				this._eventHandler( event );
5465				break;
5466			case keyCode.HOME:
5467				toFocus = this.headers[ 0 ];
5468				break;
5469			case keyCode.END:
5470				toFocus = this.headers[ length - 1 ];
5471				break;
5472		}
5473
5474		if ( toFocus ) {
5475			$( event.target ).attr( "tabIndex", -1 );
5476			$( toFocus ).attr( "tabIndex", 0 );
5477			toFocus.focus();
5478			event.preventDefault();
5479		}
5480	},
5481
5482	_panelKeyDown : function( event ) {
5483		if ( event.keyCode === $.ui.keyCode.UP && event.ctrlKey ) {
5484			$( event.currentTarget ).prev().focus();
5485		}
5486	},
5487
5488	refresh: function() {
5489		var options = this.options;
5490		this._processPanels();
5491
5492		// was collapsed or no panel
5493		if ( ( options.active === false && options.collapsible === true ) || !this.headers.length ) {
5494			options.active = false;
5495			this.active = $();
5496		// active false only when collapsible is true
5497		} else if ( options.active === false ) {
5498			this._activate( 0 );
5499		// was active, but active panel is gone
5500		} else if ( this.active.length && !$.contains( this.element[ 0 ], this.active[ 0 ] ) ) {
5501			// all remaining panel are disabled
5502			if ( this.headers.length === this.headers.find(".ui-state-disabled").length ) {
5503				options.active = false;
5504				this.active = $();
5505			// activate previous panel
5506			} else {
5507				this._activate( Math.max( 0, options.active - 1 ) );
5508			}
5509		// was active, active panel still exists
5510		} else {
5511			// make sure active index is correct
5512			options.active = this.headers.index( this.active );
5513		}
5514
5515		this._destroyIcons();
5516
5517		this._refresh();
5518	},
5519
5520	_processPanels: function() {
5521		this.headers = this.element.find( this.options.header )
5522			.addClass( "ui-accordion-header ui-helper-reset ui-state-default ui-corner-all" );
5523
5524		this.headers.next()
5525			.addClass( "ui-accordion-content ui-helper-reset ui-widget-content ui-corner-bottom" )
5526			.filter(":not(.ui-accordion-content-active)")
5527			.hide();
5528	},
5529
5530	_refresh: function() {
5531		var maxHeight,
5532			options = this.options,
5533			heightStyle = options.heightStyle,
5534			parent = this.element.parent(),
5535			accordionId = this.accordionId = "ui-accordion-" +
5536				(this.element.attr( "id" ) || ++uid);
5537
5538		this.active = this._findActive( options.active )
5539			.addClass( "ui-accordion-header-active ui-state-active ui-corner-top" )
5540			.removeClass( "ui-corner-all" );
5541		this.active.next()
5542			.addClass( "ui-accordion-content-active" )
5543			.show();
5544
5545		this.headers
5546			.attr( "role", "tab" )
5547			.each(function( i ) {
5548				var header = $( this ),
5549					headerId = header.attr( "id" ),
5550					panel = header.next(),
5551					panelId = panel.attr( "id" );
5552				if ( !headerId ) {
5553					headerId = accordionId + "-header-" + i;
5554					header.attr( "id", headerId );
5555				}
5556				if ( !panelId ) {
5557					panelId = accordionId + "-panel-" + i;
5558					panel.attr( "id", panelId );
5559				}
5560				header.attr( "aria-controls", panelId );
5561				panel.attr( "aria-labelledby", headerId );
5562			})
5563			.next()
5564				.attr( "role", "tabpanel" );
5565
5566		this.headers
5567			.not( this.active )
5568			.attr({
5569				"aria-selected": "false",
5570				"aria-expanded": "false",
5571				tabIndex: -1
5572			})
5573			.next()
5574				.attr({
5575					"aria-hidden": "true"
5576				})
5577				.hide();
5578
5579		// make sure at least one header is in the tab order
5580		if ( !this.active.length ) {
5581			this.headers.eq( 0 ).attr( "tabIndex", 0 );
5582		} else {
5583			this.active.attr({
5584				"aria-selected": "true",
5585				"aria-expanded": "true",
5586				tabIndex: 0
5587			})
5588			.next()
5589				.attr({
5590					"aria-hidden": "false"
5591				});
5592		}
5593
5594		this._createIcons();
5595
5596		this._setupEvents( options.event );
5597
5598		if ( heightStyle === "fill" ) {
5599			maxHeight = parent.height();
5600			this.element.siblings( ":visible" ).each(function() {
5601				var elem = $( this ),
5602					position = elem.css( "position" );
5603
5604				if ( position === "absolute" || position === "fixed" ) {
5605					return;
5606				}
5607				maxHeight -= elem.outerHeight( true );
5608			});
5609
5610			this.headers.each(function() {
5611				maxHeight -= $( this ).outerHeight( true );
5612			});
5613
5614			this.headers.next()
5615				.each(function() {
5616					$( this ).height( Math.max( 0, maxHeight -
5617						$( this ).innerHeight() + $( this ).height() ) );
5618				})
5619				.css( "overflow", "auto" );
5620		} else if ( heightStyle === "auto" ) {
5621			maxHeight = 0;
5622			this.headers.next()
5623				.each(function() {
5624					maxHeight = Math.max( maxHeight, $( this ).css( "height", "" ).height() );
5625				})
5626				.height( maxHeight );
5627		}
5628	},
5629
5630	_activate: function( index ) {
5631		var active = this._findActive( index )[ 0 ];
5632
5633		// trying to activate the already active panel
5634		if ( active === this.active[ 0 ] ) {
5635			return;
5636		}
5637
5638		// trying to collapse, simulate a click on the currently active header
5639		active = active || this.active[ 0 ];
5640
5641		this._eventHandler({
5642			target: active,
5643			currentTarget: active,
5644			preventDefault: $.noop
5645		});
5646	},
5647
5648	_findActive: function( selector ) {
5649		return typeof selector === "number" ? this.headers.eq( selector ) : $();
5650	},
5651
5652	_setupEvents: function( event ) {
5653		var events = {
5654			keydown: "_keydown"
5655		};
5656		if ( event ) {
5657			$.each( event.split(" "), function( index, eventName ) {
5658				events[ eventName ] = "_eventHandler";
5659			});
5660		}
5661
5662		this._off( this.headers.add( this.headers.next() ) );
5663		this._on( this.headers, events );
5664		this._on( this.headers.next(), { keydown: "_panelKeyDown" });
5665		this._hoverable( this.headers );
5666		this._focusable( this.headers );
5667	},
5668
5669	_eventHandler: function( event ) {
5670		var options = this.options,
5671			active = this.active,
5672			clicked = $( event.currentTarget ),
5673			clickedIsActive = clicked[ 0 ] === active[ 0 ],
5674			collapsing = clickedIsActive && options.collapsible,
5675			toShow = collapsing ? $() : clicked.next(),
5676			toHide = active.next(),
5677			eventData = {
5678				oldHeader: active,
5679				oldPanel: toHide,
5680				newHeader: collapsing ? $() : clicked,
5681				newPanel: toShow
5682			};
5683
5684		event.preventDefault();
5685
5686		if (
5687				// click on active header, but not collapsible
5688				( clickedIsActive && !options.collapsible ) ||
5689				// allow canceling activation
5690				( this._trigger( "beforeActivate", event, eventData ) === false ) ) {
5691			return;
5692		}
5693
5694		options.active = collapsing ? false : this.headers.index( clicked );
5695
5696		// when the call to ._toggle() comes after the class changes
5697		// it causes a very odd bug in IE 8 (see #6720)
5698		this.active = clickedIsActive ? $() : clicked;
5699		this._toggle( eventData );
5700
5701		// switch classes
5702		// corner classes on the previously active header stay after the animation
5703		active.removeClass( "ui-accordion-header-active ui-state-active" );
5704		if ( options.icons ) {
5705			active.children( ".ui-accordion-header-icon" )
5706				.removeClass( options.icons.activeHeader )
5707				.addClass( options.icons.header );
5708		}
5709
5710		if ( !clickedIsActive ) {
5711			clicked
5712				.removeClass( "ui-corner-all" )
5713				.addClass( "ui-accordion-header-active ui-state-active ui-corner-top" );
5714			if ( options.icons ) {
5715				clicked.children( ".ui-accordion-header-icon" )
5716					.removeClass( options.icons.header )
5717					.addClass( options.icons.activeHeader );
5718			}
5719
5720			clicked
5721				.next()
5722				.addClass( "ui-accordion-content-active" );
5723		}
5724	},
5725
5726	_toggle: function( data ) {
5727		var toShow = data.newPanel,
5728			toHide = this.prevShow.length ? this.prevShow : data.oldPanel;
5729
5730		// handle activating a panel during the animation for another activation
5731		this.prevShow.add( this.prevHide ).stop( true, true );
5732		this.prevShow = toShow;
5733		this.prevHide = toHide;
5734
5735		if ( this.options.animate ) {
5736			this._animate( toShow, toHide, data );
5737		} else {
5738			toHide.hide();
5739			toShow.show();
5740			this._toggleComplete( data );
5741		}
5742
5743		toHide.attr({
5744			"aria-hidden": "true"
5745		});
5746		toHide.prev().attr( "aria-selected", "false" );
5747		// if we're switching panels, remove the old header from the tab order
5748		// if we're opening from collapsed state, remove the previous header from the tab order
5749		// if we're collapsing, then keep the collapsing header in the tab order
5750		if ( toShow.length && toHide.length ) {
5751			toHide.prev().attr({
5752				"tabIndex": -1,
5753				"aria-expanded": "false"
5754			});
5755		} else if ( toShow.length ) {
5756			this.headers.filter(function() {
5757				return $( this ).attr( "tabIndex" ) === 0;
5758			})
5759			.attr( "tabIndex", -1 );
5760		}
5761
5762		toShow
5763			.attr( "aria-hidden", "false" )
5764			.prev()
5765				.attr({
5766					"aria-selected": "true",
5767					tabIndex: 0,
5768					"aria-expanded": "true"
5769				});
5770	},
5771
5772	_animate: function( toShow, toHide, data ) {
5773		var total, easing, duration,
5774			that = this,
5775			adjust = 0,
5776			down = toShow.length &&
5777				( !toHide.length || ( toShow.index() < toHide.index() ) ),
5778			animate = this.options.animate || {},
5779			options = down && animate.down || animate,
5780			complete = function() {
5781				that._toggleComplete( data );
5782			};
5783
5784		if ( typeof options === "number" ) {
5785			duration = options;
5786		}
5787		if ( typeof options === "string" ) {
5788			easing = options;
5789		}
5790		// fall back from options to animation in case of partial down settings
5791		easing = easing || options.easing || animate.easing;
5792		duration = duration || options.duration || animate.duration;
5793
5794		if ( !toHide.length ) {
5795			return toShow.animate( showProps, duration, easing, complete );
5796		}
5797		if ( !toShow.length ) {
5798			return toHide.animate( hideProps, duration, easing, complete );
5799		}
5800
5801		total = toShow.show().outerHeight();
5802		toHide.animate( hideProps, {
5803			duration: duration,
5804			easing: easing,
5805			step: function( now, fx ) {
5806				fx.now = Math.round( now );
5807			}
5808		});
5809		toShow
5810			.hide()
5811			.animate( showProps, {
5812				duration: duration,
5813				easing: easing,
5814				complete: complete,
5815				step: function( now, fx ) {
5816					fx.now = Math.round( now );
5817					if ( fx.prop !== "height" ) {
5818						adjust += fx.now;
5819					} else if ( that.options.heightStyle !== "content" ) {
5820						fx.now = Math.round( total - toHide.outerHeight() - adjust );
5821						adjust = 0;
5822					}
5823				}
5824			});
5825	},
5826
5827	_toggleComplete: function( data ) {
5828		var toHide = data.oldPanel;
5829
5830		toHide
5831			.removeClass( "ui-accordion-content-active" )
5832			.prev()
5833				.removeClass( "ui-corner-top" )
5834				.addClass( "ui-corner-all" );
5835
5836		// Work around for rendering bug in IE (#5421)
5837		if ( toHide.length ) {
5838			toHide.parent()[0].className = toHide.parent()[0].className;
5839		}
5840		this._trigger( "activate", null, data );
5841	}
5842});
5843
5844})( jQuery );
5845(function( $, undefined ) {
5846
5847$.widget( "ui.autocomplete", {
5848	version: "1.10.4",
5849	defaultElement: "<input>",
5850	options: {
5851		appendTo: null,
5852		autoFocus: false,
5853		delay: 300,
5854		minLength: 1,
5855		position: {
5856			my: "left top",
5857			at: "left bottom",
5858			collision: "none"
5859		},
5860		source: null,
5861
5862		// callbacks
5863		change: null,
5864		close: null,
5865		focus: null,
5866		open: null,
5867		response: null,
5868		search: null,
5869		select: null
5870	},
5871
5872	requestIndex: 0,
5873	pending: 0,
5874
5875	_create: function() {
5876		// Some browsers only repeat keydown events, not keypress events,
5877		// so we use the suppressKeyPress flag to determine if we've already
5878		// handled the keydown event. #7269
5879		// Unfortunately the code for & in keypress is the same as the up arrow,
5880		// so we use the suppressKeyPressRepeat flag to avoid handling keypress
5881		// events when we know the keydown event was used to modify the
5882		// search term. #7799
5883		var suppressKeyPress, suppressKeyPressRepeat, suppressInput,
5884			nodeName = this.element[0].nodeName.toLowerCase(),
5885			isTextarea = nodeName === "textarea",
5886			isInput = nodeName === "input";
5887
5888		this.isMultiLine =
5889			// Textareas are always multi-line
5890			isTextarea ? true :
5891			// Inputs are always single-line, even if inside a contentEditable element
5892			// IE also treats inputs as contentEditable
5893			isInput ? false :
5894			// All other element types are determined by whether or not they're contentEditable
5895			this.element.prop( "isContentEditable" );
5896
5897		this.valueMethod = this.element[ isTextarea || isInput ? "val" : "text" ];
5898		this.isNewMenu = true;
5899
5900		this.element
5901			.addClass( "ui-autocomplete-input" )
5902			.attr( "autocomplete", "off" );
5903
5904		this._on( this.element, {
5905			keydown: function( event ) {
5906				if ( this.element.prop( "readOnly" ) ) {
5907					suppressKeyPress = true;
5908					suppressInput = true;
5909					suppressKeyPressRepeat = true;
5910					return;
5911				}
5912
5913				suppressKeyPress = false;
5914				suppressInput = false;
5915				suppressKeyPressRepeat = false;
5916				var keyCode = $.ui.keyCode;
5917				switch( event.keyCode ) {
5918				case keyCode.PAGE_UP:
5919					suppressKeyPress = true;
5920					this._move( "previousPage", event );
5921					break;
5922				case keyCode.PAGE_DOWN:
5923					suppressKeyPress = true;
5924					this._move( "nextPage", event );
5925					break;
5926				case keyCode.UP:
5927					suppressKeyPress = true;
5928					this._keyEvent( "previous", event );
5929					break;
5930				case keyCode.DOWN:
5931					suppressKeyPress = true;
5932					this._keyEvent( "next", event );
5933					break;
5934				case keyCode.ENTER:
5935				case keyCode.NUMPAD_ENTER:
5936					// when menu is open and has focus
5937					if ( this.menu.active ) {
5938						// #6055 - Opera still allows the keypress to occur
5939						// which causes forms to submit
5940						suppressKeyPress = true;
5941						event.preventDefault();
5942						this.menu.select( event );
5943					}
5944					break;
5945				case keyCode.TAB:
5946					if ( this.menu.active ) {
5947						this.menu.select( event );
5948					}
5949					break;
5950				case keyCode.ESCAPE:
5951					if ( this.menu.element.is( ":visible" ) ) {
5952						this._value( this.term );
5953						this.close( event );
5954						// Different browsers have different default behavior for escape
5955						// Single press can mean undo or clear
5956						// Double press in IE means clear the whole form
5957						event.preventDefault();
5958					}
5959					break;
5960				default:
5961					suppressKeyPressRepeat = true;
5962					// search timeout should be triggered before the input value is changed
5963					this._searchTimeout( event );
5964					break;
5965				}
5966			},
5967			keypress: function( event ) {
5968				if ( suppressKeyPress ) {
5969					suppressKeyPress = false;
5970					if ( !this.isMultiLine || this.menu.element.is( ":visible" ) ) {
5971						event.preventDefault();
5972					}
5973					return;
5974				}
5975				if ( suppressKeyPressRepeat ) {
5976					return;
5977				}
5978
5979				// replicate some key handlers to allow them to repeat in Firefox and Opera
5980				var keyCode = $.ui.keyCode;
5981				switch( event.keyCode ) {
5982				case keyCode.PAGE_UP:
5983					this._move( "previousPage", event );
5984					break;
5985				case keyCode.PAGE_DOWN:
5986					this._move( "nextPage", event );
5987					break;
5988				case keyCode.UP:
5989					this._keyEvent( "previous", event );
5990					break;
5991				case keyCode.DOWN:
5992					this._keyEvent( "next", event );
5993					break;
5994				}
5995			},
5996			input: function( event ) {
5997				if ( suppressInput ) {
5998					suppressInput = false;
5999					event.preventDefault();
6000					return;
6001				}
6002				this._searchTimeout( event );
6003			},
6004			focus: function() {
6005				this.selectedItem = null;
6006				this.previous = this._value();
6007			},
6008			blur: function( event ) {
6009				if ( this.cancelBlur ) {
6010					delete this.cancelBlur;
6011					return;
6012				}
6013
6014				clearTimeout( this.searching );
6015				this.close( event );
6016				this._change( event );
6017			}
6018		});
6019
6020		this._initSource();
6021		this.menu = $( "<ul>" )
6022			.addClass( "ui-autocomplete ui-front" )
6023			.appendTo( this._appendTo() )
6024			.menu({
6025				// disable ARIA support, the live region takes care of that
6026				role: null
6027			})
6028			.hide()
6029			.data( "ui-menu" );
6030
6031		this._on( this.menu.element, {
6032			mousedown: function( event ) {
6033				// prevent moving focus out of the text field
6034				event.preventDefault();
6035
6036				// IE doesn't prevent moving focus even with event.preventDefault()
6037				// so we set a flag to know when we should ignore the blur event
6038				this.cancelBlur = true;
6039				this._delay(function() {
6040					delete this.cancelBlur;
6041				});
6042
6043				// clicking on the scrollbar causes focus to shift to the body
6044				// but we can't detect a mouseup or a click immediately afterward
6045				// so we have to track the next mousedown and close the menu if
6046				// the user clicks somewhere outside of the autocomplete
6047				var menuElement = this.menu.element[ 0 ];
6048				if ( !$( event.target ).closest( ".ui-menu-item" ).length ) {
6049					this._delay(function() {
6050						var that = this;
6051						this.document.one( "mousedown", function( event ) {
6052							if ( event.target !== that.element[ 0 ] &&
6053									event.target !== menuElement &&
6054									!$.contains( menuElement, event.target ) ) {
6055								that.close();
6056							}
6057						});
6058					});
6059				}
6060			},
6061			menufocus: function( event, ui ) {
6062				// support: Firefox
6063				// Prevent accidental activation of menu items in Firefox (#7024 #9118)
6064				if ( this.isNewMenu ) {
6065					this.isNewMenu = false;
6066					if ( event.originalEvent && /^mouse/.test( event.originalEvent.type ) ) {
6067						this.menu.blur();
6068
6069						this.document.one( "mousemove", function() {
6070							$( event.target ).trigger( event.originalEvent );
6071						});
6072
6073						return;
6074					}
6075				}
6076
6077				var item = ui.item.data( "ui-autocomplete-item" );
6078				if ( false !== this._trigger( "focus", event, { item: item } ) ) {
6079					// use value to match what will end up in the input, if it was a key event
6080					if ( event.originalEvent && /^key/.test( event.originalEvent.type ) ) {
6081						this._value( item.value );
6082					}
6083				} else {
6084					// Normally the input is populated with the item's value as the
6085					// menu is navigated, causing screen readers to notice a change and
6086					// announce the item. Since the focus event was canceled, this doesn't
6087					// happen, so we update the live region so that screen readers can
6088					// still notice the change and announce it.
6089					this.liveRegion.text( item.value );
6090				}
6091			},
6092			menuselect: function( event, ui ) {
6093				var item = ui.item.data( "ui-autocomplete-item" ),
6094					previous = this.previous;
6095
6096				// only trigger when focus was lost (click on menu)
6097				if ( this.element[0] !== this.document[0].activeElement ) {
6098					this.element.focus();
6099					this.previous = previous;
6100					// #6109 - IE triggers two focus events and the second
6101					// is asynchronous, so we need to reset the previous
6102					// term synchronously and asynchronously :-(
6103					this._delay(function() {
6104						this.previous = previous;
6105						this.selectedItem = item;
6106					});
6107				}
6108
6109				if ( false !== this._trigger( "select", event, { item: item } ) ) {
6110					this._value( item.value );
6111				}
6112				// reset the term after the select event
6113				// this allows custom select handling to work properly
6114				this.term = this._value();
6115
6116				this.close( event );
6117				this.selectedItem = item;
6118			}
6119		});
6120
6121		this.liveRegion = $( "<span>", {
6122				role: "status",
6123				"aria-live": "polite"
6124			})
6125			.addClass( "ui-helper-hidden-accessible" )
6126			.insertBefore( this.element );
6127
6128		// turning off autocomplete prevents the browser from remembering the
6129		// value when navigating through history, so we re-enable autocomplete
6130		// if the page is unloaded before the widget is destroyed. #7790
6131		this._on( this.window, {
6132			beforeunload: function() {
6133				this.element.removeAttr( "autocomplete" );
6134			}
6135		});
6136	},
6137
6138	_destroy: function() {
6139		clearTimeout( this.searching );
6140		this.element
6141			.removeClass( "ui-autocomplete-input" )
6142			.removeAttr( "autocomplete" );
6143		this.menu.element.remove();
6144		this.liveRegion.remove();
6145	},
6146
6147	_setOption: function( key, value ) {
6148		this._super( key, value );
6149		if ( key === "source" ) {
6150			this._initSource();
6151		}
6152		if ( key === "appendTo" ) {
6153			this.menu.element.appendTo( this._appendTo() );
6154		}
6155		if ( key === "disabled" && value && this.xhr ) {
6156			this.xhr.abort();
6157		}
6158	},
6159
6160	_appendTo: function() {
6161		var element = this.options.appendTo;
6162
6163		if ( element ) {
6164			element = element.jquery || element.nodeType ?
6165				$( element ) :
6166				this.document.find( element ).eq( 0 );
6167		}
6168
6169		if ( !element ) {
6170			element = this.element.closest( ".ui-front" );
6171		}
6172
6173		if ( !element.length ) {
6174			element = this.document[0].body;
6175		}
6176
6177		return element;
6178	},
6179
6180	_initSource: function() {
6181		var array, url,
6182			that = this;
6183		if ( $.isArray(this.options.source) ) {
6184			array = this.options.source;
6185			this.source = function( request, response ) {
6186				response( $.ui.autocomplete.filter( array, request.term ) );
6187			};
6188		} else if ( typeof this.options.source === "string" ) {
6189			url = this.options.source;
6190			this.source = function( request, response ) {
6191				if ( that.xhr ) {
6192					that.xhr.abort();
6193				}
6194				that.xhr = $.ajax({
6195					url: url,
6196					data: request,
6197					dataType: "json",
6198					success: function( data ) {
6199						response( data );
6200					},
6201					error: function() {
6202						response( [] );
6203					}
6204				});
6205			};
6206		} else {
6207			this.source = this.options.source;
6208		}
6209	},
6210
6211	_searchTimeout: function( event ) {
6212		clearTimeout( this.searching );
6213		this.searching = this._delay(function() {
6214			// only search if the value has changed
6215			if ( this.term !== this._value() ) {
6216				this.selectedItem = null;
6217				this.search( null, event );
6218			}
6219		}, this.options.delay );
6220	},
6221
6222	search: function( value, event ) {
6223		value = value != null ? value : this._value();
6224
6225		// always save the actual value, not the one passed as an argument
6226		this.term = this._value();
6227
6228		if ( value.length < this.options.minLength ) {
6229			return this.close( event );
6230		}
6231
6232		if ( this._trigger( "search", event ) === false ) {
6233			return;
6234		}
6235
6236		return this._search( value );
6237	},
6238
6239	_search: function( value ) {
6240		this.pending++;
6241		this.element.addClass( "ui-autocomplete-loading" );
6242		this.cancelSearch = false;
6243
6244		this.source( { term: value }, this._response() );
6245	},
6246
6247	_response: function() {
6248		var index = ++this.requestIndex;
6249
6250		return $.proxy(function( content ) {
6251			if ( index === this.requestIndex ) {
6252				this.__response( content );
6253			}
6254
6255			this.pending--;
6256			if ( !this.pending ) {
6257				this.element.removeClass( "ui-autocomplete-loading" );
6258			}
6259		}, this );
6260	},
6261
6262	__response: function( content ) {
6263		if ( content ) {
6264			content = this._normalize( content );
6265		}
6266		this._trigger( "response", null, { content: content } );
6267		if ( !this.options.disabled && content && content.length && !this.cancelSearch ) {
6268			this._suggest( content );
6269			this._trigger( "open" );
6270		} else {
6271			// use ._close() instead of .close() so we don't cancel future searches
6272			this._close();
6273		}
6274	},
6275
6276	close: function( event ) {
6277		this.cancelSearch = true;
6278		this._close( event );
6279	},
6280
6281	_close: function( event ) {
6282		if ( this.menu.element.is( ":visible" ) ) {
6283			this.menu.element.hide();
6284			this.menu.blur();
6285			this.isNewMenu = true;
6286			this._trigger( "close", event );
6287		}
6288	},
6289
6290	_change: function( event ) {
6291		if ( this.previous !== this._value() ) {
6292			this._trigger( "change", event, { item: this.selectedItem } );
6293		}
6294	},
6295
6296	_normalize: function( items ) {
6297		// assume all items have the right format when the first item is complete
6298		if ( items.length && items[0].label && items[0].value ) {
6299			return items;
6300		}
6301		return $.map( items, function( item ) {
6302			if ( typeof item === "string" ) {
6303				return {
6304					label: item,
6305					value: item
6306				};
6307			}
6308			return $.extend({
6309				label: item.label || item.value,
6310				value: item.value || item.label
6311			}, item );
6312		});
6313	},
6314
6315	_suggest: function( items ) {
6316		var ul = this.menu.element.empty();
6317		this._renderMenu( ul, items );
6318		this.isNewMenu = true;
6319		this.menu.refresh();
6320
6321		// size and position menu
6322		ul.show();
6323		this._resizeMenu();
6324		ul.position( $.extend({
6325			of: this.element
6326		}, this.options.position ));
6327
6328		if ( this.options.autoFocus ) {
6329			this.menu.next();
6330		}
6331	},
6332
6333	_resizeMenu: function() {
6334		var ul = this.menu.element;
6335		ul.outerWidth( Math.max(
6336			// Firefox wraps long text (possibly a rounding bug)
6337			// so we add 1px to avoid the wrapping (#7513)
6338			ul.width( "" ).outerWidth() + 1,
6339			this.element.outerWidth()
6340		) );
6341	},
6342
6343	_renderMenu: function( ul, items ) {
6344		var that = this;
6345		$.each( items, function( index, item ) {
6346			that._renderItemData( ul, item );
6347		});
6348	},
6349
6350	_renderItemData: function( ul, item ) {
6351		return this._renderItem( ul, item ).data( "ui-autocomplete-item", item );
6352	},
6353
6354	_renderItem: function( ul, item ) {
6355		return $( "<li>" )
6356			.append( $( "<a>" ).text( item.label ) )
6357			.appendTo( ul );
6358	},
6359
6360	_move: function( direction, event ) {
6361		if ( !this.menu.element.is( ":visible" ) ) {
6362			this.search( null, event );
6363			return;
6364		}
6365		if ( this.menu.isFirstItem() && /^previous/.test( direction ) ||
6366				this.menu.isLastItem() && /^next/.test( direction ) ) {
6367			this._value( this.term );
6368			this.menu.blur();
6369			return;
6370		}
6371		this.menu[ direction ]( event );
6372	},
6373
6374	widget: function() {
6375		return this.menu.element;
6376	},
6377
6378	_value: function() {
6379		return this.valueMethod.apply( this.element, arguments );
6380	},
6381
6382	_keyEvent: function( keyEvent, event ) {
6383		if ( !this.isMultiLine || this.menu.element.is( ":visible" ) ) {
6384			this._move( keyEvent, event );
6385
6386			// prevents moving cursor to beginning/end of the text field in some browsers
6387			event.preventDefault();
6388		}
6389	}
6390});
6391
6392$.extend( $.ui.autocomplete, {
6393	escapeRegex: function( value ) {
6394		return value.replace(/[\-\[\]{}()*+?.,\\\^$|#\s]/g, "\\$&");
6395	},
6396	filter: function(array, term) {
6397		var matcher = new RegExp( $.ui.autocomplete.escapeRegex(term), "i" );
6398		return $.grep( array, function(value) {
6399			return matcher.test( value.label || value.value || value );
6400		});
6401	}
6402});
6403
6404
6405// live region extension, adding a `messages` option
6406// NOTE: This is an experimental API. We are still investigating
6407// a full solution for string manipulation and internationalization.
6408$.widget( "ui.autocomplete", $.ui.autocomplete, {
6409	options: {
6410		messages: {
6411			noResults: "No search results.",
6412			results: function( amount ) {
6413				return amount + ( amount > 1 ? " results are" : " result is" ) +
6414					" available, use up and down arrow keys to navigate.";
6415			}
6416		}
6417	},
6418
6419	__response: function( content ) {
6420		var message;
6421		this._superApply( arguments );
6422		if ( this.options.disabled || this.cancelSearch ) {
6423			return;
6424		}
6425		if ( content && content.length ) {
6426			message = this.options.messages.results( content.length );
6427		} else {
6428			message = this.options.messages.noResults;
6429		}
6430		this.liveRegion.text( message );
6431	}
6432});
6433
6434}( jQuery ));
6435(function( $, undefined ) {
6436
6437var lastActive,
6438	baseClasses = "ui-button ui-widget ui-state-default ui-corner-all",
6439	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",
6440	formResetHandler = function() {
6441		var form = $( this );
6442		setTimeout(function() {
6443			form.find( ":ui-button" ).button( "refresh" );
6444		}, 1 );
6445	},
6446	radioGroup = function( radio ) {
6447		var name = radio.name,
6448			form = radio.form,
6449			radios = $( [] );
6450		if ( name ) {
6451			name = name.replace( /'/g, "\\'" );
6452			if ( form ) {
6453				radios = $( form ).find( "[name='" + name + "']" );
6454			} else {
6455				radios = $( "[name='" + name + "']", radio.ownerDocument )
6456					.filter(function() {
6457						return !this.form;
6458					});
6459			}
6460		}
6461		return radios;
6462	};
6463
6464$.widget( "ui.button", {
6465	version: "1.10.4",
6466	defaultElement: "<button>",
6467	options: {
6468		disabled: null,
6469		text: true,
6470		label: null,
6471		icons: {
6472			primary: null,
6473			secondary: null
6474		}
6475	},
6476	_create: function() {
6477		this.element.closest( "form" )
6478			.unbind( "reset" + this.eventNamespace )
6479			.bind( "reset" + this.eventNamespace, formResetHandler );
6480
6481		if ( typeof this.options.disabled !== "boolean" ) {
6482			this.options.disabled = !!this.element.prop( "disabled" );
6483		} else {
6484			this.element.prop( "disabled", this.options.disabled );
6485		}
6486
6487		this._determineButtonType();
6488		this.hasTitle = !!this.buttonElement.attr( "title" );
6489
6490		var that = this,
6491			options = this.options,
6492			toggleButton = this.type === "checkbox" || this.type === "radio",
6493			activeClass = !toggleButton ? "ui-state-active" : "";
6494
6495		if ( options.label === null ) {
6496			options.label = (this.type === "input" ? this.buttonElement.val() : this.buttonElement.html());
6497		}
6498
6499		this._hoverable( this.buttonElement );
6500
6501		this.buttonElement
6502			.addClass( baseClasses )
6503			.attr( "role", "button" )
6504			.bind( "mouseenter" + this.eventNamespace, function() {
6505				if ( options.disabled ) {
6506					return;
6507				}
6508				if ( this === lastActive ) {
6509					$( this ).addClass( "ui-state-active" );
6510				}
6511			})
6512			.bind( "mouseleave" + this.eventNamespace, function() {
6513				if ( options.disabled ) {
6514					return;
6515				}
6516				$( this ).removeClass( activeClass );
6517			})
6518			.bind( "click" + this.eventNamespace, function( event ) {
6519				if ( options.disabled ) {
6520					event.preventDefault();
6521					event.stopImmediatePropagation();
6522				}
6523			});
6524
6525		// Can't use _focusable() because the element that receives focus
6526		// and the element that gets the ui-state-focus class are different
6527		this._on({
6528			focus: function() {
6529				this.buttonElement.addClass( "ui-state-focus" );
6530			},
6531			blur: function() {
6532				this.buttonElement.removeClass( "ui-state-focus" );
6533			}
6534		});
6535
6536		if ( toggleButton ) {
6537			this.element.bind( "change" + this.eventNamespace, function() {
6538				that.refresh();
6539			});
6540		}
6541
6542		if ( this.type === "checkbox" ) {
6543			this.buttonElement.bind( "click" + this.eventNamespace, function() {
6544				if ( options.disabled ) {
6545					return false;
6546				}
6547			});
6548		} else if ( this.type === "radio" ) {
6549			this.buttonElement.bind( "click" + this.eventNamespace, function() {
6550				if ( options.disabled ) {
6551					return false;
6552				}
6553				$( this ).addClass( "ui-state-active" );
6554				that.buttonElement.attr( "aria-pressed", "true" );
6555
6556				var radio = that.element[ 0 ];
6557				radioGroup( radio )
6558					.not( radio )
6559					.map(function() {
6560						return $( this ).button( "widget" )[ 0 ];
6561					})
6562					.removeClass( "ui-state-active" )
6563					.attr( "aria-pressed", "false" );
6564			});
6565		} else {
6566			this.buttonElement
6567				.bind( "mousedown" + this.eventNamespace, function() {
6568					if ( options.disabled ) {
6569						return false;
6570					}
6571					$( this ).addClass( "ui-state-active" );
6572					lastActive = this;
6573					that.document.one( "mouseup", function() {
6574						lastActive = null;
6575					});
6576				})
6577				.bind( "mouseup" + this.eventNamespace, function() {
6578					if ( options.disabled ) {
6579						return false;
6580					}
6581					$( this ).removeClass( "ui-state-active" );
6582				})
6583				.bind( "keydown" + this.eventNamespace, function(event) {
6584					if ( options.disabled ) {
6585						return false;
6586					}
6587					if ( event.keyCode === $.ui.keyCode.SPACE || event.keyCode === $.ui.keyCode.ENTER ) {
6588						$( this ).addClass( "ui-state-active" );
6589					}
6590				})
6591				// see #8559, we bind to blur here in case the button element loses
6592				// focus between keydown and keyup, it would be left in an "active" state
6593				.bind( "keyup" + this.eventNamespace + " blur" + this.eventNamespace, function() {
6594					$( this ).removeClass( "ui-state-active" );
6595				});
6596
6597			if ( this.buttonElement.is("a") ) {
6598				this.buttonElement.keyup(function(event) {
6599					if ( event.keyCode === $.ui.keyCode.SPACE ) {
6600						// TODO pass through original event correctly (just as 2nd argument doesn't work)
6601						$( this ).click();
6602					}
6603				});
6604			}
6605		}
6606
6607		// TODO: pull out $.Widget's handling for the disabled option into
6608		// $.Widget.prototype._setOptionDisabled so it's easy to proxy and can
6609		// be overridden by individual plugins
6610		this._setOption( "disabled", options.disabled );
6611		this._resetButton();
6612	},
6613
6614	_determineButtonType: function() {
6615		var ancestor, labelSelector, checked;
6616
6617		if ( this.element.is("[type=checkbox]") ) {
6618			this.type = "checkbox";
6619		} else if ( this.element.is("[type=radio]") ) {
6620			this.type = "radio";
6621		} else if ( this.element.is("input") ) {
6622			this.type = "input";
6623		} else {
6624			this.type = "button";
6625		}
6626
6627		if ( this.type === "checkbox" || this.type === "radio" ) {
6628			// we don't search against the document in case the element
6629			// is disconnected from the DOM
6630			ancestor = this.element.parents().last();
6631			labelSelector = "label[for='" + this.element.attr("id") + "']";
6632			this.buttonElement = ancestor.find( labelSelector );
6633			if ( !this.buttonElement.length ) {
6634				ancestor = ancestor.length ? ancestor.siblings() : this.element.siblings();
6635				this.buttonElement = ancestor.filter( labelSelector );
6636				if ( !this.buttonElement.length ) {
6637					this.buttonElement = ancestor.find( labelSelector );
6638				}
6639			}
6640			this.element.addClass( "ui-helper-hidden-accessible" );
6641
6642			checked = this.element.is( ":checked" );
6643			if ( checked ) {
6644				this.buttonElement.addClass( "ui-state-active" );
6645			}
6646			this.buttonElement.prop( "aria-pressed", checked );
6647		} else {
6648			this.buttonElement = this.element;
6649		}
6650	},
6651
6652	widget: function() {
6653		return this.buttonElement;
6654	},
6655
6656	_destroy: function() {
6657		this.element
6658			.removeClass( "ui-helper-hidden-accessible" );
6659		this.buttonElement
6660			.removeClass( baseClasses + " ui-state-active " + typeClasses )
6661			.removeAttr( "role" )
6662			.removeAttr( "aria-pressed" )
6663			.html( this.buttonElement.find(".ui-button-text").html() );
6664
6665		if ( !this.hasTitle ) {
6666			this.buttonElement.removeAttr( "title" );
6667		}
6668	},
6669
6670	_setOption: function( key, value ) {
6671		this._super( key, value );
6672		if ( key === "disabled" ) {
6673			this.element.prop( "disabled", !!value );
6674			if ( value ) {
6675				this.buttonElement.removeClass( "ui-state-focus" );
6676			}
6677			return;
6678		}
6679		this._resetButton();
6680	},
6681
6682	refresh: function() {
6683		//See #8237 & #8828
6684		var isDisabled = this.element.is( "input, button" ) ? this.element.is( ":disabled" ) : this.element.hasClass( "ui-button-disabled" );
6685
6686		if ( isDisabled !== this.options.disabled ) {
6687			this._setOption( "disabled", isDisabled );
6688		}
6689		if ( this.type === "radio" ) {
6690			radioGroup( this.element[0] ).each(function() {
6691				if ( $( this ).is( ":checked" ) ) {
6692					$( this ).button( "widget" )
6693						.addClass( "ui-state-active" )
6694						.attr( "aria-pressed", "true" );
6695				} else {
6696					$( this ).button( "widget" )
6697						.removeClass( "ui-state-active" )
6698						.attr( "aria-pressed", "false" );
6699				}
6700			});
6701		} else if ( this.type === "checkbox" ) {
6702			if ( this.element.is( ":checked" ) ) {
6703				this.buttonElement
6704					.addClass( "ui-state-active" )
6705					.attr( "aria-pressed", "true" );
6706			} else {
6707				this.buttonElement
6708					.removeClass( "ui-state-active" )
6709					.attr( "aria-pressed", "false" );
6710			}
6711		}
6712	},
6713
6714	_resetButton: function() {
6715		if ( this.type === "input" ) {
6716			if ( this.options.label ) {
6717				this.element.val( this.options.label );
6718			}
6719			return;
6720		}
6721		var buttonElement = this.buttonElement.removeClass( typeClasses ),
6722			buttonText = $( "<span></span>", this.document[0] )
6723				.addClass( "ui-button-text" )
6724				.html( this.options.label )
6725				.appendTo( buttonElement.empty() )
6726				.text(),
6727			icons = this.options.icons,
6728			multipleIcons = icons.primary && icons.secondary,
vendor: 2,267 bytes, lines 6729-6818
6729			buttonClasses = [];
6730
6731		if ( icons.primary || icons.secondary ) {
6732			if ( this.options.text ) {
6733				buttonClasses.push( "ui-button-text-icon" + ( multipleIcons ? "s" : ( icons.primary ? "-primary" : "-secondary" ) ) );
6734			}
6735
6736			if ( icons.primary ) {
6737				buttonElement.prepend( "<span class='ui-button-icon-primary ui-icon " + icons.primary + "'></span>" );
6738			}
6739
6740			if ( icons.secondary ) {
6741				buttonElement.append( "<span class='ui-button-icon-secondary ui-icon " + icons.secondary + "'></span>" );
6742			}
6743
6744			if ( !this.options.text ) {
6745				buttonClasses.push( multipleIcons ? "ui-button-icons-only" : "ui-button-icon-only" );
6746
6747				if ( !this.hasTitle ) {
6748					buttonElement.attr( "title", $.trim( buttonText ) );
6749				}
6750			}
6751		} else {
6752			buttonClasses.push( "ui-button-text-only" );
6753		}
6754		buttonElement.addClass( buttonClasses.join( " " ) );
6755	}
6756});
6757
6758$.widget( "ui.buttonset", {
6759	version: "1.10.4",
6760	options: {
6761		items: "button, input[type=button], input[type=submit], input[type=reset], input[type=checkbox], input[type=radio], a, :data(ui-button)"
6762	},
6763
6764	_create: function() {
6765		this.element.addClass( "ui-buttonset" );
6766	},
6767
6768	_init: function() {
6769		this.refresh();
6770	},
6771
6772	_setOption: function( key, value ) {
6773		if ( key === "disabled" ) {
6774			this.buttons.button( "option", key, value );
6775		}
6776
6777		this._super( key, value );
6778	},
6779
6780	refresh: function() {
6781		var rtl = this.element.css( "direction" ) === "rtl";
6782
6783		this.buttons = this.element.find( this.options.items )
6784			.filter( ":ui-button" )
6785				.button( "refresh" )
6786			.end()
6787			.not( ":ui-button" )
6788				.button()
6789			.end()
6790			.map(function() {
6791				return $( this ).button( "widget" )[ 0 ];
6792			})
6793				.removeClass( "ui-corner-all ui-corner-left ui-corner-right" )
6794				.filter( ":first" )
6795					.addClass( rtl ? "ui-corner-right" : "ui-corner-left" )
6796				.end()
6797				.filter( ":last" )
6798					.addClass( rtl ? "ui-corner-left" : "ui-corner-right" )
6799				.end()
6800			.end();
6801	},
6802
6803	_destroy: function() {
6804		this.element.removeClass( "ui-buttonset" );
6805		this.buttons
6806			.map(function() {
6807				return $( this ).button( "widget" )[ 0 ];
6808			})
6809				.removeClass( "ui-corner-left ui-corner-right" )
6810			.end()
6811			.button( "destroy" );
6812	}
6813});
6814
6815}( jQuery ) );
6816(function( $, undefined ) {
6817
6818$.extend($.ui, { datepicker: { version: "1.10.4
vendor: 75,965 bytes, lines 6818-8838
6818" } });
6819
6820var PROP_NAME = "datepicker",
6821	instActive;
6822
6823/* Date picker manager.
6824   Use the singleton instance of this class, $.datepicker, to interact with the date picker.
6825   Settings for (groups of) date pickers are maintained in an instance object,
6826   allowing multiple different settings on the same page. */
6827
6828function Datepicker() {
6829	this._curInst = null; // The current instance in use
6830	this._keyEvent = false; // If the last event was a key event
6831	this._disabledInputs = []; // List of date picker inputs that have been disabled
6832	this._datepickerShowing = false; // True if the popup picker is showing , false if not
6833	this._inDialog = false; // True if showing within a "dialog", false if not
6834	this._mainDivId = "ui-datepicker-div"; // The ID of the main datepicker division
6835	this._inlineClass = "ui-datepicker-inline"; // The name of the inline marker class
6836	this._appendClass = "ui-datepicker-append"; // The name of the append marker class
6837	this._triggerClass = "ui-datepicker-trigger"; // The name of the trigger marker class
6838	this._dialogClass = "ui-datepicker-dialog"; // The name of the dialog marker class
6839	this._disableClass = "ui-datepicker-disabled"; // The name of the disabled covering marker class
6840	this._unselectableClass = "ui-datepicker-unselectable"; // The name of the unselectable cell marker class
6841	this._currentClass = "ui-datepicker-current-day"; // The name of the current day marker class
6842	this._dayOverClass = "ui-datepicker-days-cell-over"; // The name of the day hover marker class
6843	this.regional = []; // Available regional settings, indexed by language code
6844	this.regional[""] = { // Default regional settings
6845		closeText: "Done", // Display text for close link
6846		prevText: "Prev", // Display text for previous month link
6847		nextText: "Next", // Display text for next month link
6848		currentText: "Today", // Display text for current month link
6849		monthNames: ["January","February","March","April","May","June",
6850			"July","August","September","October","November","December"], // Names of months for drop-down and formatting
6851		monthNamesShort: ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"], // For formatting
6852		dayNames: ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"], // For formatting
6853		dayNamesShort: ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"], // For formatting
6854		dayNamesMin: ["Su","Mo","Tu","We","Th","Fr","Sa"], // Column headings for days starting at Sunday
6855		weekHeader: "Wk", // Column header for week of the year
6856		dateFormat: "mm/dd/yy", // See format options on parseDate
6857		firstDay: 0, // The first day of the week, Sun = 0, Mon = 1, ...
6858		isRTL: false, // True if right-to-left language, false if left-to-right
6859		showMonthAfterYear: false, // True if the year select precedes month, false for month then year
6860		yearSuffix: "" // Additional text to append to the year in the month headers
6861	};
6862	this._defaults = { // Global defaults for all the date picker instances
6863		showOn: "focus", // "focus" for popup on focus,
6864			// "button" for trigger button, or "both" for either
6865		showAnim: "fadeIn", // Name of jQuery animation for popup
6866		showOptions: {}, // Options for enhanced animations
6867		defaultDate: null, // Used when field is blank: actual date,
6868			// +/-number for offset from today, null for today
6869		appendText: "", // Display text following the input box, e.g. showing the format
6870		buttonText: "...", // Text for trigger button
6871		buttonImage: "", // URL for trigger button image
6872		buttonImageOnly: false, // True if the image appears alone, false if it appears on a button
6873		hideIfNoPrevNext: false, // True to hide next/previous month links
6874			// if not applicable, false to just disable them
6875		navigationAsDateFormat: false, // True if date formatting applied to prev/today/next links
6876		gotoCurrent: false, // True if today link goes back to current selection instead
6877		changeMonth: false, // True if month can be selected directly, false if only prev/next
6878		changeYear: false, // True if year can be selected directly, false if only prev/next
6879		yearRange: "c-10:c+10", // Range of years to display in drop-down,
6880			// either relative to today's year (-nn:+nn), relative to currently displayed year
6881			// (c-nn:c+nn), absolute (nnnn:nnnn), or a combination of the above (nnnn:-n)
6882		showOtherMonths: false, // True to show dates in other months, false to leave blank
6883		selectOtherMonths: false, // True to allow selection of dates in other months, false for unselectable
6884		showWeek: false, // True to show week of the year, false to not show it
6885		calculateWeek: this.iso8601Week, // How to calculate the week of the year,
6886			// takes a Date and returns the number of the week for it
6887		shortYearCutoff: "+10", // Short year values < this are in the current century,
6888			// > this are in the previous century,
6889			// string value starting with "+" for current year + value
6890		minDate: null, // The earliest selectable date, or null for no limit
6891		maxDate: null, // The latest selectable date, or null for no limit
6892		duration: "fast", // Duration of display/closure
6893		beforeShowDay: null, // Function that takes a date and returns an array with
6894			// [0] = true if selectable, false if not, [1] = custom CSS class name(s) or "",
6895			// [2] = cell title (optional), e.g. $.datepicker.noWeekends
6896		beforeShow: null, // Function that takes an input field and
6897			// returns a set of custom settings for the date picker
6898		onSelect: null, // Define a callback function when a date is selected
6899		onChangeMonthYear: null, // Define a callback function when the month or year is changed
6900		onClose: null, // Define a callback function when the datepicker is closed
6901		numberOfMonths: 1, // Number of months to show at a time
6902		showCurrentAtPos: 0, // The position in multipe months at which to show the current month (starting at 0)
6903		stepMonths: 1, // Number of months to step back/forward
6904		stepBigMonths: 12, // Number of months to step back/forward for the big links
6905		altField: "", // Selector for an alternate field to store selected dates into
6906		altFormat: "", // The date format to use for the alternate field
6907		constrainInput: true, // The input is constrained by the current date format
6908		showButtonPanel: false, // True to show button panel, false to not show it
6909		autoSize: false, // True to size the input for the date format, false to leave as is
6910		disabled: false // The initial disabled state
6911	};
6912	$.extend(this._defaults, this.regional[""]);
6913	this.dpDiv = bindHover($("<div id='" + this._mainDivId + "' class='ui-datepicker ui-widget ui-widget-content ui-helper-clearfix ui-corner-all'></div>"));
6914}
6915
6916$.extend(Datepicker.prototype, {
6917	/* Class name added to elements to indicate already configured with a date picker. */
6918	markerClassName: "hasDatepicker",
6919
6920	//Keep track of the maximum number of rows displayed (see #7043)
6921	maxRows: 4,
6922
6923	// TODO rename to "widget" when switching to widget factory
6924	_widgetDatepicker: function() {
6925		return this.dpDiv;
6926	},
6927
6928	/* Override the default settings for all instances of the date picker.
6929	 * @param  settings  object - the new settings to use as defaults (anonymous object)
6930	 * @return the manager object
6931	 */
6932	setDefaults: function(settings) {
6933		extendRemove(this._defaults, settings || {});
6934		return this;
6935	},
6936
6937	/* Attach the date picker to a jQuery selection.
6938	 * @param  target	element - the target input field or division or span
6939	 * @param  settings  object - the new settings to use for this date picker instance (anonymous)
6940	 */
6941	_attachDatepicker: function(target, settings) {
6942		var nodeName, inline, inst;
6943		nodeName = target.nodeName.toLowerCase();
6944		inline = (nodeName === "div" || nodeName === "span");
6945		if (!target.id) {
6946			this.uuid += 1;
6947			target.id = "dp" + this.uuid;
6948		}
6949		inst = this._newInst($(target), inline);
6950		inst.settings = $.extend({}, settings || {});
6951		if (nodeName === "input") {
6952			this._connectDatepicker(target, inst);
6953		} else if (inline) {
6954			this._inlineDatepicker(target, inst);
6955		}
6956	},
6957
6958	/* Create a new instance object. */
6959	_newInst: function(target, inline) {
6960		var id = target[0].id.replace(/([^A-Za-z0-9_\-])/g, "\\\\$1"); // escape jQuery meta chars
6961		return {id: id, input: target, // associated target
6962			selectedDay: 0, selectedMonth: 0, selectedYear: 0, // current selection
6963			drawMonth: 0, drawYear: 0, // month being drawn
6964			inline: inline, // is datepicker inline or not
6965			dpDiv: (!inline ? this.dpDiv : // presentation div
6966			bindHover($("<div class='" + this._inlineClass + " ui-datepicker ui-widget ui-widget-content ui-helper-clearfix ui-corner-all'></div>")))};
6967	},
6968
6969	/* Attach the date picker to an input field. */
6970	_connectDatepicker: function(target, inst) {
6971		var input = $(target);
6972		inst.append = $([]);
6973		inst.trigger = $([]);
6974		if (input.hasClass(this.markerClassName)) {
6975			return;
6976		}
6977		this._attachments(input, inst);
6978		input.addClass(this.markerClassName).keydown(this._doKeyDown).
6979			keypress(this._doKeyPress).keyup(this._doKeyUp);
6980		this._autoSize(inst);
6981		$.data(target, PROP_NAME, inst);
6982		//If disabled option is true, disable the datepicker once it has been attached to the input (see ticket #5665)
6983		if( inst.settings.disabled ) {
6984			this._disableDatepicker( target );
6985		}
6986	},
6987
6988	/* Make attachments based on settings. */
6989	_attachments: function(input, inst) {
6990		var showOn, buttonText, buttonImage,
6991			appendText = this._get(inst, "appendText"),
6992			isRTL = this._get(inst, "isRTL");
6993
6994		if (inst.append) {
6995			inst.append.remove();
6996		}
6997		if (appendText) {
6998			inst.append = $("<span class='" + this._appendClass + "'>" + appendText + "</span>");
6999			input[isRTL ? "before" : "after"](inst.append);
7000		}
7001
7002		input.unbind("focus", this._showDatepicker);
7003
7004		if (inst.trigger) {
7005			inst.trigger.remove();
7006		}
7007
7008		showOn = this._get(inst, "showOn");
7009		if (showOn === "focus" || showOn === "both") { // pop-up date picker when in the marked field
7010			input.focus(this._showDatepicker);
7011		}
7012		if (showOn === "button" || showOn === "both") { // pop-up date picker when button clicked
7013			buttonText = this._get(inst, "buttonText");
7014			buttonImage = this._get(inst, "buttonImage");
7015			inst.trigger = $(this._get(inst, "buttonImageOnly") ?
7016				$("<img/>").addClass(this._triggerClass).
7017					attr({ src: buttonImage, alt: buttonText, title: buttonText }) :
7018				$("<button type='button'></button>").addClass(this._triggerClass).
7019					html(!buttonImage ? buttonText : $("<img/>").attr(
7020					{ src:buttonImage, alt:buttonText, title:buttonText })));
7021			input[isRTL ? "before" : "after"](inst.trigger);
7022			inst.trigger.click(function() {
7023				if ($.datepicker._datepickerShowing && $.datepicker._lastInput === input[0]) {
7024					$.datepicker._hideDatepicker();
7025				} else if ($.datepicker._datepickerShowing && $.datepicker._lastInput !== input[0]) {
7026					$.datepicker._hideDatepicker();
7027					$.datepicker._showDatepicker(input[0]);
7028				} else {
7029					$.datepicker._showDatepicker(input[0]);
7030				}
7031				return false;
7032			});
7033		}
7034	},
7035
7036	/* Apply the maximum length for the date format. */
7037	_autoSize: function(inst) {
7038		if (this._get(inst, "autoSize") && !inst.inline) {
7039			var findMax, max, maxI, i,
7040				date = new Date(2009, 12 - 1, 20), // Ensure double digits
7041				dateFormat = this._get(inst, "dateFormat");
7042
7043			if (dateFormat.match(/[DM]/)) {
7044				findMax = function(names) {
7045					max = 0;
7046					maxI = 0;
7047					for (i = 0; i < names.length; i++) {
7048						if (names[i].length > max) {
7049							max = names[i].length;
7050							maxI = i;
7051						}
7052					}
7053					return maxI;
7054				};
7055				date.setMonth(findMax(this._get(inst, (dateFormat.match(/MM/) ?
7056					"monthNames" : "monthNamesShort"))));
7057				date.setDate(findMax(this._get(inst, (dateFormat.match(/DD/) ?
7058					"dayNames" : "dayNamesShort"))) + 20 - date.getDay());
7059			}
7060			inst.input.attr("size", this._formatDate(inst, date).length);
7061		}
7062	},
7063
7064	/* Attach an inline date picker to a div. */
7065	_inlineDatepicker: function(target, inst) {
7066		var divSpan = $(target);
7067		if (divSpan.hasClass(this.markerClassName)) {
7068			return;
7069		}
7070		divSpan.addClass(this.markerClassName).append(inst.dpDiv);
7071		$.data(target, PROP_NAME, inst);
7072		this._setDate(inst, this._getDefaultDate(inst), true);
7073		this._updateDatepicker(inst);
7074		this._updateAlternate(inst);
7075		//If disabled option is true, disable the datepicker before showing it (see ticket #5665)
7076		if( inst.settings.disabled ) {
7077			this._disableDatepicker( target );
7078		}
7079		// Set display:block in place of inst.dpDiv.show() which won't work on disconnected elements
7080		// http://bugs.jqueryui.com/ticket/7552 - A Datepicker created on a detached div has zero height
7081		inst.dpDiv.css( "display", "block" );
7082	},
7083
7084	/* Pop-up the date picker in a "dialog" box.
7085	 * @param  input element - ignored
7086	 * @param  date	string or Date - the initial date to display
7087	 * @param  onSelect  function - the function to call when a date is selected
7088	 * @param  settings  object - update the dialog date picker instance's settings (anonymous object)
7089	 * @param  pos int[2] - coordinates for the dialog's position within the screen or
7090	 *					event - with x/y coordinates or
7091	 *					leave empty for default (screen centre)
7092	 * @return the manager object
7093	 */
7094	_dialogDatepicker: function(input, date, onSelect, settings, pos) {
7095		var id, browserWidth, browserHeight, scrollX, scrollY,
7096			inst = this._dialogInst; // internal instance
7097
7098		if (!inst) {
7099			this.uuid += 1;
7100			id = "dp" + this.uuid;
7101			this._dialogInput = $("<input type='text' id='" + id +
7102				"' style='position: absolute; top: -100px; width: 0px;'/>");
7103			this._dialogInput.keydown(this._doKeyDown);
7104			$("body").append(this._dialogInput);
7105			inst = this._dialogInst = this._newInst(this._dialogInput, false);
7106			inst.settings = {};
7107			$.data(this._dialogInput[0], PROP_NAME, inst);
7108		}
7109		extendRemove(inst.settings, settings || {});
7110		date = (date && date.constructor === Date ? this._formatDate(inst, date) : date);
7111		this._dialogInput.val(date);
7112
7113		this._pos = (pos ? (pos.length ? pos : [pos.pageX, pos.pageY]) : null);
7114		if (!this._pos) {
7115			browserWidth = document.documentElement.clientWidth;
7116			browserHeight = document.documentElement.clientHeight;
7117			scrollX = document.documentElement.scrollLeft || document.body.scrollLeft;
7118			scrollY = document.documentElement.scrollTop || document.body.scrollTop;
7119			this._pos = // should use actual width/height below
7120				[(browserWidth / 2) - 100 + scrollX, (browserHeight / 2) - 150 + scrollY];
7121		}
7122
7123		// move input on screen for focus, but hidden behind dialog
7124		this._dialogInput.css("left", (this._pos[0] + 20) + "px").css("top", this._pos[1] + "px");
7125		inst.settings.onSelect = onSelect;
7126		this._inDialog = true;
7127		this.dpDiv.addClass(this._dialogClass);
7128		this._showDatepicker(this._dialogInput[0]);
7129		if ($.blockUI) {
7130			$.blockUI(this.dpDiv);
7131		}
7132		$.data(this._dialogInput[0], PROP_NAME, inst);
7133		return this;
7134	},
7135
7136	/* Detach a datepicker from its control.
7137	 * @param  target	element - the target input field or division or span
7138	 */
7139	_destroyDatepicker: function(target) {
7140		var nodeName,
7141			$target = $(target),
7142			inst = $.data(target, PROP_NAME);
7143
7144		if (!$target.hasClass(this.markerClassName)) {
7145			return;
7146		}
7147
7148		nodeName = target.nodeName.toLowerCase();
7149		$.removeData(target, PROP_NAME);
7150		if (nodeName === "input") {
7151			inst.append.remove();
7152			inst.trigger.remove();
7153			$target.removeClass(this.markerClassName).
7154				unbind("focus", this._showDatepicker).
7155				unbind("keydown", this._doKeyDown).
7156				unbind("keypress", this._doKeyPress).
7157				unbind("keyup", this._doKeyUp);
7158		} else if (nodeName === "div" || nodeName === "span") {
7159			$target.removeClass(this.markerClassName).empty();
7160		}
7161	},
7162
7163	/* Enable the date picker to a jQuery selection.
7164	 * @param  target	element - the target input field or division or span
7165	 */
7166	_enableDatepicker: function(target) {
7167		var nodeName, inline,
7168			$target = $(target),
7169			inst = $.data(target, PROP_NAME);
7170
7171		if (!$target.hasClass(this.markerClassName)) {
7172			return;
7173		}
7174
7175		nodeName = target.nodeName.toLowerCase();
7176		if (nodeName === "input") {
7177			target.disabled = false;
7178			inst.trigger.filter("button").
7179				each(function() { this.disabled = false; }).end().
7180				filter("img").css({opacity: "1.0", cursor: ""});
7181		} else if (nodeName === "div" || nodeName === "span") {
7182			inline = $target.children("." + this._inlineClass);
7183			inline.children().removeClass("ui-state-disabled");
7184			inline.find("select.ui-datepicker-month, select.ui-datepicker-year").
7185				prop("disabled", false);
7186		}
7187		this._disabledInputs = $.map(this._disabledInputs,
7188			function(value) { return (value === target ? null : value); }); // delete entry
7189	},
7190
7191	/* Disable the date picker to a jQuery selection.
7192	 * @param  target	element - the target input field or division or span
7193	 */
7194	_disableDatepicker: function(target) {
7195		var nodeName, inline,
7196			$target = $(target),
7197			inst = $.data(target, PROP_NAME);
7198
7199		if (!$target.hasClass(this.markerClassName)) {
7200			return;
7201		}
7202
7203		nodeName = target.nodeName.toLowerCase();
7204		if (nodeName === "input") {
7205			target.disabled = true;
7206			inst.trigger.filter("button").
7207				each(function() { this.disabled = true; }).end().
7208				filter("img").css({opacity: "0.5", cursor: "default"});
7209		} else if (nodeName === "div" || nodeName === "span") {
7210			inline = $target.children("." + this._inlineClass);
7211			inline.children().addClass("ui-state-disabled");
7212			inline.find("select.ui-datepicker-month, select.ui-datepicker-year").
7213				prop("disabled", true);
7214		}
7215		this._disabledInputs = $.map(this._disabledInputs,
7216			function(value) { return (value === target ? null : value); }); // delete entry
7217		this._disabledInputs[this._disabledInputs.length] = target;
7218	},
7219
7220	/* Is the first field in a jQuery collection disabled as a datepicker?
7221	 * @param  target	element - the target input field or division or span
7222	 * @return boolean - true if disabled, false if enabled
7223	 */
7224	_isDisabledDatepicker: function(target) {
7225		if (!target) {
7226			return false;
7227		}
7228		for (var i = 0; i < this._disabledInputs.length; i++) {
7229			if (this._disabledInputs[i] === target) {
7230				return true;
7231			}
7232		}
7233		return false;
7234	},
7235
7236	/* Retrieve the instance data for the target control.
7237	 * @param  target  element - the target input field or division or span
7238	 * @return  object - the associated instance data
7239	 * @throws  error if a jQuery problem getting data
7240	 */
7241	_getInst: function(target) {
7242		try {
7243			return $.data(target, PROP_NAME);
7244		}
7245		catch (err) {
7246			throw "Missing instance data for this datepicker";
7247		}
7248	},
7249
7250	/* Update or retrieve the settings for a date picker attached to an input field or division.
7251	 * @param  target  element - the target input field or division or span
7252	 * @param  name	object - the new settings to update or
7253	 *				string - the name of the setting to change or retrieve,
7254	 *				when retrieving also "all" for all instance settings or
7255	 *				"defaults" for all global defaults
7256	 * @param  value   any - the new value for the setting
7257	 *				(omit if above is an object or to retrieve a value)
7258	 */
7259	_optionDatepicker: function(target, name, value) {
7260		var settings, date, minDate, maxDate,
7261			inst = this._getInst(target);
7262
7263		if (arguments.length === 2 && typeof name === "string") {
7264			return (name === "defaults" ? $.extend({}, $.datepicker._defaults) :
7265				(inst ? (name === "all" ? $.extend({}, inst.settings) :
7266				this._get(inst, name)) : null));
7267		}
7268
7269		settings = name || {};
7270		if (typeof name === "string") {
7271			settings = {};
7272			settings[name] = value;
7273		}
7274
7275		if (inst) {
7276			if (this._curInst === inst) {
7277				this._hideDatepicker();
7278			}
7279
7280			date = this._getDateDatepicker(target, true);
7281			minDate = this._getMinMaxDate(inst, "min");
7282			maxDate = this._getMinMaxDate(inst, "max");
7283			extendRemove(inst.settings, settings);
7284			// reformat the old minDate/maxDate values if dateFormat changes and a new minDate/maxDate isn't provided
7285			if (minDate !== null && settings.dateFormat !== undefined && settings.minDate === undefined) {
7286				inst.settings.minDate = this._formatDate(inst, minDate);
7287			}
7288			if (maxDate !== null && settings.dateFormat !== undefined && settings.maxDate === undefined) {
7289				inst.settings.maxDate = this._formatDate(inst, maxDate);
7290			}
7291			if ( "disabled" in settings ) {
7292				if ( settings.disabled ) {
7293					this._disableDatepicker(target);
7294				} else {
7295					this._enableDatepicker(target);
7296				}
7297			}
7298			this._attachments($(target), inst);
7299			this._autoSize(inst);
7300			this._setDate(inst, date);
7301			this._updateAlternate(inst);
7302			this._updateDatepicker(inst);
7303		}
7304	},
7305
7306	// change method deprecated
7307	_changeDatepicker: function(target, name, value) {
7308		this._optionDatepicker(target, name, value);
7309	},
7310
7311	/* Redraw the date picker attached to an input field or division.
7312	 * @param  target  element - the target input field or division or span
7313	 */
7314	_refreshDatepicker: function(target) {
7315		var inst = this._getInst(target);
7316		if (inst) {
7317			this._updateDatepicker(inst);
7318		}
7319	},
7320
7321	/* Set the dates for a jQuery selection.
7322	 * @param  target element - the target input field or division or span
7323	 * @param  date	Date - the new date
7324	 */
7325	_setDateDatepicker: function(target, date) {
7326		var inst = this._getInst(target);
7327		if (inst) {
7328			this._setDate(inst, date);
7329			this._updateDatepicker(inst);
7330			this._updateAlternate(inst);
7331		}
7332	},
7333
7334	/* Get the date(s) for the first entry in a jQuery selection.
7335	 * @param  target element - the target input field or division or span
7336	 * @param  noDefault boolean - true if no default date is to be used
7337	 * @return Date - the current date
7338	 */
7339	_getDateDatepicker: function(target, noDefault) {
7340		var inst = this._getInst(target);
7341		if (inst && !inst.inline) {
7342			this._setDateFromField(inst, noDefault);
7343		}
7344		return (inst ? this._getDate(inst) : null);
7345	},
7346
7347	/* Handle keystrokes. */
7348	_doKeyDown: function(event) {
7349		var onSelect, dateStr, sel,
7350			inst = $.datepicker._getInst(event.target),
7351			handled = true,
7352			isRTL = inst.dpDiv.is(".ui-datepicker-rtl");
7353
7354		inst._keyEvent = true;
7355		if ($.datepicker._datepickerShowing) {
7356			switch (event.keyCode) {
7357				case 9: $.datepicker._hideDatepicker();
7358						handled = false;
7359						break; // hide on tab out
7360				case 13: sel = $("td." + $.datepicker._dayOverClass + ":not(." +
7361									$.datepicker._currentClass + ")", inst.dpDiv);
7362						if (sel[0]) {
7363							$.datepicker._selectDay(event.target, inst.selectedMonth, inst.selectedYear, sel[0]);
7364						}
7365
7366						onSelect = $.datepicker._get(inst, "onSelect");
7367						if (onSelect) {
7368							dateStr = $.datepicker._formatDate(inst);
7369
7370							// trigger custom callback
7371							onSelect.apply((inst.input ? inst.input[0] : null), [dateStr, inst]);
7372						} else {
7373							$.datepicker._hideDatepicker();
7374						}
7375
7376						return false; // don't submit the form
7377				case 27: $.datepicker._hideDatepicker();
7378						break; // hide on escape
7379				case 33: $.datepicker._adjustDate(event.target, (event.ctrlKey ?
7380							-$.datepicker._get(inst, "stepBigMonths") :
7381							-$.datepicker._get(inst, "stepMonths")), "M");
7382						break; // previous month/year on page up/+ ctrl
7383				case 34: $.datepicker._adjustDate(event.target, (event.ctrlKey ?
7384							+$.datepicker._get(inst, "stepBigMonths") :
7385							+$.datepicker._get(inst, "stepMonths")), "M");
7386						break; // next month/year on page down/+ ctrl
7387				case 35: if (event.ctrlKey || event.metaKey) {
7388							$.datepicker._clearDate(event.target);
7389						}
7390						handled = event.ctrlKey || event.metaKey;
7391						break; // clear on ctrl or command +end
7392				case 36: if (event.ctrlKey || event.metaKey) {
7393							$.datepicker._gotoToday(event.target);
7394						}
7395						handled = event.ctrlKey || event.metaKey;
7396						break; // current on ctrl or command +home
7397				case 37: if (event.ctrlKey || event.metaKey) {
7398							$.datepicker._adjustDate(event.target, (isRTL ? +1 : -1), "D");
7399						}
7400						handled = event.ctrlKey || event.metaKey;
7401						// -1 day on ctrl or command +left
7402						if (event.originalEvent.altKey) {
7403							$.datepicker._adjustDate(event.target, (event.ctrlKey ?
7404								-$.datepicker._get(inst, "stepBigMonths") :
7405								-$.datepicker._get(inst, "stepMonths")), "M");
7406						}
7407						// next month/year on alt +left on Mac
7408						break;
7409				case 38: if (event.ctrlKey || event.metaKey) {
7410							$.datepicker._adjustDate(event.target, -7, "D");
7411						}
7412						handled = event.ctrlKey || event.metaKey;
7413						break; // -1 week on ctrl or command +up
7414				case 39: if (event.ctrlKey || event.metaKey) {
7415							$.datepicker._adjustDate(event.target, (isRTL ? -1 : +1), "D");
7416						}
7417						handled = event.ctrlKey || event.metaKey;
7418						// +1 day on ctrl or command +right
7419						if (event.originalEvent.altKey) {
7420							$.datepicker._adjustDate(event.target, (event.ctrlKey ?
7421								+$.datepicker._get(inst, "stepBigMonths") :
7422								+$.datepicker._get(inst, "stepMonths")), "M");
7423						}
7424						// next month/year on alt +right
7425						break;
7426				case 40: if (event.ctrlKey || event.metaKey) {
7427							$.datepicker._adjustDate(event.target, +7, "D");
7428						}
7429						handled = event.ctrlKey || event.metaKey;
7430						break; // +1 week on ctrl or command +down
7431				default: handled = false;
7432			}
7433		} else if (event.keyCode === 36 && event.ctrlKey) { // display the date picker on ctrl+home
7434			$.datepicker._showDatepicker(this);
7435		} else {
7436			handled = false;
7437		}
7438
7439		if (handled) {
7440			event.preventDefault();
7441			event.stopPropagation();
7442		}
7443	},
7444
7445	/* Filter entered characters - based on date format. */
7446	_doKeyPress: function(event) {
7447		var chars, chr,
7448			inst = $.datepicker._getInst(event.target);
7449
7450		if ($.datepicker._get(inst, "constrainInput")) {
7451			chars = $.datepicker._possibleChars($.datepicker._get(inst, "dateFormat"));
7452			chr = String.fromCharCode(event.charCode == null ? event.keyCode : event.charCode);
7453			return event.ctrlKey || event.metaKey || (chr < " " || !chars || chars.indexOf(chr) > -1);
7454		}
7455	},
7456
7457	/* Synchronise manual entry and field/alternate field. */
7458	_doKeyUp: function(event) {
7459		var date,
7460			inst = $.datepicker._getInst(event.target);
7461
7462		if (inst.input.val() !== inst.lastVal) {
7463			try {
7464				date = $.datepicker.parseDate($.datepicker._get(inst, "dateFormat"),
7465					(inst.input ? inst.input.val() : null),
7466					$.datepicker._getFormatConfig(inst));
7467
7468				if (date) { // only if valid
7469					$.datepicker._setDateFromField(inst);
7470					$.datepicker._updateAlternate(inst);
7471					$.datepicker._updateDatepicker(inst);
7472				}
7473			}
7474			catch (err) {
7475			}
7476		}
7477		return true;
7478	},
7479
7480	/* Pop-up the date picker for a given input field.
7481	 * If false returned from beforeShow event handler do not show.
7482	 * @param  input  element - the input field attached to the date picker or
7483	 *					event - if triggered by focus
7484	 */
7485	_showDatepicker: function(input) {
7486		input = input.target || input;
7487		if (input.nodeName.toLowerCase() !== "input") { // find from button/image trigger
7488			input = $("input", input.parentNode)[0];
7489		}
7490
7491		if ($.datepicker._isDisabledDatepicker(input) || $.datepicker._lastInput === input) { // already here
7492			return;
7493		}
7494
7495		var inst, beforeShow, beforeShowSettings, isFixed,
7496			offset, showAnim, duration;
7497
7498		inst = $.datepicker._getInst(input);
7499		if ($.datepicker._curInst && $.datepicker._curInst !== inst) {
7500			$.datepicker._curInst.dpDiv.stop(true, true);
7501			if ( inst && $.datepicker._datepickerShowing ) {
7502				$.datepicker._hideDatepicker( $.datepicker._curInst.input[0] );
7503			}
7504		}
7505
7506		beforeShow = $.datepicker._get(inst, "beforeShow");
7507		beforeShowSettings = beforeShow ? beforeShow.apply(input, [input, inst]) : {};
7508		if(beforeShowSettings === false){
7509			return;
7510		}
7511		extendRemove(inst.settings, beforeShowSettings);
7512
7513		inst.lastVal = null;
7514		$.datepicker._lastInput = input;
7515		$.datepicker._setDateFromField(inst);
7516
7517		if ($.datepicker._inDialog) { // hide cursor
7518			input.value = "";
7519		}
7520		if (!$.datepicker._pos) { // position below input
7521			$.datepicker._pos = $.datepicker._findPos(input);
7522			$.datepicker._pos[1] += input.offsetHeight; // add the height
7523		}
7524
7525		isFixed = false;
7526		$(input).parents().each(function() {
7527			isFixed |= $(this).css("position") === "fixed";
7528			return !isFixed;
7529		});
7530
7531		offset = {left: $.datepicker._pos[0], top: $.datepicker._pos[1]};
7532		$.datepicker._pos = null;
7533		//to avoid flashes on Firefox
7534		inst.dpDiv.empty();
7535		// determine sizing offscreen
7536		inst.dpDiv.css({position: "absolute", display: "block", top: "-1000px"});
7537		$.datepicker._updateDatepicker(inst);
7538		// fix width for dynamic number of date pickers
7539		// and adjust position before showing
7540		offset = $.datepicker._checkOffset(inst, offset, isFixed);
7541		inst.dpDiv.css({position: ($.datepicker._inDialog && $.blockUI ?
7542			"static" : (isFixed ? "fixed" : "absolute")), display: "none",
7543			left: offset.left + "px", top: offset.top + "px"});
7544
7545		if (!inst.inline) {
7546			showAnim = $.datepicker._get(inst, "showAnim");
7547			duration = $.datepicker._get(inst, "duration");
7548			inst.dpDiv.zIndex($(input).zIndex()+1);
7549			$.datepicker._datepickerShowing = true;
7550
7551			if ( $.effects && $.effects.effect[ showAnim ] ) {
7552				inst.dpDiv.show(showAnim, $.datepicker._get(inst, "showOptions"), duration);
7553			} else {
7554				inst.dpDiv[showAnim || "show"](showAnim ? duration : null);
7555			}
7556
7557			if ( $.datepicker._shouldFocusInput( inst ) ) {
7558				inst.input.focus();
7559			}
7560
7561			$.datepicker._curInst = inst;
7562		}
7563	},
7564
7565	/* Generate the date picker content. */
7566	_updateDatepicker: function(inst) {
7567		this.maxRows = 4; //Reset the max number of rows being displayed (see #7043)
7568		instActive = inst; // for delegate hover events
7569		inst.dpDiv.empty().append(this._generateHTML(inst));
7570		this._attachHandlers(inst);
7571		inst.dpDiv.find("." + this._dayOverClass + " a").mouseover();
7572
7573		var origyearshtml,
7574			numMonths = this._getNumberOfMonths(inst),
7575			cols = numMonths[1],
7576			width = 17;
7577
7578		inst.dpDiv.removeClass("ui-datepicker-multi-2 ui-datepicker-multi-3 ui-datepicker-multi-4").width("");
7579		if (cols > 1) {
7580			inst.dpDiv.addClass("ui-datepicker-multi-" + cols).css("width", (width * cols) + "em");
7581		}
7582		inst.dpDiv[(numMonths[0] !== 1 || numMonths[1] !== 1 ? "add" : "remove") +
7583			"Class"]("ui-datepicker-multi");
7584		inst.dpDiv[(this._get(inst, "isRTL") ? "add" : "remove") +
7585			"Class"]("ui-datepicker-rtl");
7586
7587		if (inst === $.datepicker._curInst && $.datepicker._datepickerShowing && $.datepicker._shouldFocusInput( inst ) ) {
7588			inst.input.focus();
7589		}
7590
7591		// deffered render of the years select (to avoid flashes on Firefox)
7592		if( inst.yearshtml ){
7593			origyearshtml = inst.yearshtml;
7594			setTimeout(function(){
7595				//assure that inst.yearshtml didn't change.
7596				if( origyearshtml === inst.yearshtml && inst.yearshtml ){
7597					inst.dpDiv.find("select.ui-datepicker-year:first").replaceWith(inst.yearshtml);
7598				}
7599				origyearshtml = inst.yearshtml = null;
7600			}, 0);
7601		}
7602	},
7603
7604	// #6694 - don't focus the input if it's already focused
7605	// this breaks the change event in IE
7606	// Support: IE and jQuery <1.9
7607	_shouldFocusInput: function( inst ) {
7608		return inst.input && inst.input.is( ":visible" ) && !inst.input.is( ":disabled" ) && !inst.input.is( ":focus" );
7609	},
7610
7611	/* Check positioning to remain on screen. */
7612	_checkOffset: function(inst, offset, isFixed) {
7613		var dpWidth = inst.dpDiv.outerWidth(),
7614			dpHeight = inst.dpDiv.outerHeight(),
7615			inputWidth = inst.input ? inst.input.outerWidth() : 0,
7616			inputHeight = inst.input ? inst.input.outerHeight() : 0,
7617			viewWidth = document.documentElement.clientWidth + (isFixed ? 0 : $(document).scrollLeft()),
7618			viewHeight = document.documentElement.clientHeight + (isFixed ? 0 : $(document).scrollTop());
7619
7620		offset.left -= (this._get(inst, "isRTL") ? (dpWidth - inputWidth) : 0);
7621		offset.left -= (isFixed && offset.left === inst.input.offset().left) ? $(document).scrollLeft() : 0;
7622		offset.top -= (isFixed && offset.top === (inst.input.offset().top + inputHeight)) ? $(document).scrollTop() : 0;
7623
7624		// now check if datepicker is showing outside window viewport - move to a better place if so.
7625		offset.left -= Math.min(offset.left, (offset.left + dpWidth > viewWidth && viewWidth > dpWidth) ?
7626			Math.abs(offset.left + dpWidth - viewWidth) : 0);
7627		offset.top -= Math.min(offset.top, (offset.top + dpHeight > viewHeight && viewHeight > dpHeight) ?
7628			Math.abs(dpHeight + inputHeight) : 0);
7629
7630		return offset;
7631	},
7632
7633	/* Find an object's position on the screen. */
7634	_findPos: function(obj) {
7635		var position,
7636			inst = this._getInst(obj),
7637			isRTL = this._get(inst, "isRTL");
7638
7639		while (obj && (obj.type === "hidden" || obj.nodeType !== 1 || $.expr.filters.hidden(obj))) {
7640			obj = obj[isRTL ? "previousSibling" : "nextSibling"];
7641		}
7642
7643		position = $(obj).offset();
7644		return [position.left, position.top];
7645	},
7646
7647	/* Hide the date picker from view.
7648	 * @param  input  element - the input field attached to the date picker
7649	 */
7650	_hideDatepicker: function(input) {
7651		var showAnim, duration, postProcess, onClose,
7652			inst = this._curInst;
7653
7654		if (!inst || (input && inst !== $.data(input, PROP_NAME))) {
7655			return;
7656		}
7657
7658		if (this._datepickerShowing) {
7659			showAnim = this._get(inst, "showAnim");
7660			duration = this._get(inst, "duration");
7661			postProcess = function() {
7662				$.datepicker._tidyDialog(inst);
7663			};
7664
7665			// DEPRECATED: after BC for 1.8.x $.effects[ showAnim ] is not needed
7666			if ( $.effects && ( $.effects.effect[ showAnim ] || $.effects[ showAnim ] ) ) {
7667				inst.dpDiv.hide(showAnim, $.datepicker._get(inst, "showOptions"), duration, postProcess);
7668			} else {
7669				inst.dpDiv[(showAnim === "slideDown" ? "slideUp" :
7670					(showAnim === "fadeIn" ? "fadeOut" : "hide"))]((showAnim ? duration : null), postProcess);
7671			}
7672
7673			if (!showAnim) {
7674				postProcess();
7675			}
7676			this._datepickerShowing = false;
7677
7678			onClose = this._get(inst, "onClose");
7679			if (onClose) {
7680				onClose.apply((inst.input ? inst.input[0] : null), [(inst.input ? inst.input.val() : ""), inst]);
7681			}
7682
7683			this._lastInput = null;
7684			if (this._inDialog) {
7685				this._dialogInput.css({ position: "absolute", left: "0", top: "-100px" });
7686				if ($.blockUI) {
7687					$.unblockUI();
7688					$("body").append(this.dpDiv);
7689				}
7690			}
7691			this._inDialog = false;
7692		}
7693	},
7694
7695	/* Tidy up after a dialog display. */
7696	_tidyDialog: function(inst) {
7697		inst.dpDiv.removeClass(this._dialogClass).unbind(".ui-datepicker-calendar");
7698	},
7699
7700	/* Close date picker if clicked elsewhere. */
7701	_checkExternalClick: function(event) {
7702		if (!$.datepicker._curInst) {
7703			return;
7704		}
7705
7706		var $target = $(event.target),
7707			inst = $.datepicker._getInst($target[0]);
7708
7709		if ( ( ( $target[0].id !== $.datepicker._mainDivId &&
7710				$target.parents("#" + $.datepicker._mainDivId).length === 0 &&
7711				!$target.hasClass($.datepicker.markerClassName) &&
7712				!$target.closest("." + $.datepicker._triggerClass).length &&
7713				$.datepicker._datepickerShowing && !($.datepicker._inDialog && $.blockUI) ) ) ||
7714			( $target.hasClass($.datepicker.markerClassName) && $.datepicker._curInst !== inst ) ) {
7715				$.datepicker._hideDatepicker();
7716		}
7717	},
7718
7719	/* Adjust one of the date sub-fields. */
7720	_adjustDate: function(id, offset, period) {
7721		var target = $(id),
7722			inst = this._getInst(target[0]);
7723
7724		if (this._isDisabledDatepicker(target[0])) {
7725			return;
7726		}
7727		this._adjustInstDate(inst, offset +
7728			(period === "M" ? this._get(inst, "showCurrentAtPos") : 0), // undo positioning
7729			period);
7730		this._updateDatepicker(inst);
7731	},
7732
7733	/* Action for current link. */
7734	_gotoToday: function(id) {
7735		var date,
7736			target = $(id),
7737			inst = this._getInst(target[0]);
7738
7739		if (this._get(inst, "gotoCurrent") && inst.currentDay) {
7740			inst.selectedDay = inst.currentDay;
7741			inst.drawMonth = inst.selectedMonth = inst.currentMonth;
7742			inst.drawYear = inst.selectedYear = inst.currentYear;
7743		} else {
7744			date = new Date();
7745			inst.selectedDay = date.getDate();
7746			inst.drawMonth = inst.selectedMonth = date.getMonth();
7747			inst.drawYear = inst.selectedYear = date.getFullYear();
7748		}
7749		this._notifyChange(inst);
7750		this._adjustDate(target);
7751	},
7752
7753	/* Action for selecting a new month/year. */
7754	_selectMonthYear: function(id, select, period) {
7755		var target = $(id),
7756			inst = this._getInst(target[0]);
7757
7758		inst["selected" + (period === "M" ? "Month" : "Year")] =
7759		inst["draw" + (period === "M" ? "Month" : "Year")] =
7760			parseInt(select.options[select.selectedIndex].value,10);
7761
7762		this._notifyChange(inst);
7763		this._adjustDate(target);
7764	},
7765
7766	/* Action for selecting a day. */
7767	_selectDay: function(id, month, year, td) {
7768		var inst,
7769			target = $(id);
7770
7771		if ($(td).hasClass(this._unselectableClass) || this._isDisabledDatepicker(target[0])) {
7772			return;
7773		}
7774
7775		inst = this._getInst(target[0]);
7776		inst.selectedDay = inst.currentDay = $("a", td).html();
7777		inst.selectedMonth = inst.currentMonth = month;
7778		inst.selectedYear = inst.currentYear = year;
7779		this._selectDate(id, this._formatDate(inst,
7780			inst.currentDay, inst.currentMonth, inst.currentYear));
7781	},
7782
7783	/* Erase the input field and hide the date picker. */
7784	_clearDate: function(id) {
7785		var target = $(id);
7786		this._selectDate(target, "");
7787	},
7788
7789	/* Update the input field with the selected date. */
7790	_selectDate: function(id, dateStr) {
7791		var onSelect,
7792			target = $(id),
7793			inst = this._getInst(target[0]);
7794
7795		dateStr = (dateStr != null ? dateStr : this._formatDate(inst));
7796		if (inst.input) {
7797			inst.input.val(dateStr);
7798		}
7799		this._updateAlternate(inst);
7800
7801		onSelect = this._get(inst, "onSelect");
7802		if (onSelect) {
7803			onSelect.apply((inst.input ? inst.input[0] : null), [dateStr, inst]);  // trigger custom callback
7804		} else if (inst.input) {
7805			inst.input.trigger("change"); // fire the change event
7806		}
7807
7808		if (inst.inline){
7809			this._updateDatepicker(inst);
7810		} else {
7811			this._hideDatepicker();
7812			this._lastInput = inst.input[0];
7813			if (typeof(inst.input[0]) !== "object") {
7814				inst.input.focus(); // restore focus
7815			}
7816			this._lastInput = null;
7817		}
7818	},
7819
7820	/* Update any alternate field to synchronise with the main field. */
7821	_updateAlternate: function(inst) {
7822		var altFormat, date, dateStr,
7823			altField = this._get(inst, "altField");
7824
7825		if (altField) { // update alternate field too
7826			altFormat = this._get(inst, "altFormat") || this._get(inst, "dateFormat");
7827			date = this._getDate(inst);
7828			dateStr = this.formatDate(altFormat, date, this._getFormatConfig(inst));
7829			$(altField).each(function() { $(this).val(dateStr); });
7830		}
7831	},
7832
7833	/* Set as beforeShowDay function to prevent selection of weekends.
7834	 * @param  date  Date - the date to customise
7835	 * @return [boolean, string] - is this date selectable?, what is its CSS class?
7836	 */
7837	noWeekends: function(date) {
7838		var day = date.getDay();
7839		return [(day > 0 && day < 6), ""];
7840	},
7841
7842	/* Set as calculateWeek to determine the week of the year based on the ISO 8601 definition.
7843	 * @param  date  Date - the date to get the week for
7844	 * @return  number - the number of the week within the year that contains this date
7845	 */
7846	iso8601Week: function(date) {
7847		var time,
7848			checkDate = new Date(date.getTime());
7849
7850		// Find Thursday of this week starting on Monday
7851		checkDate.setDate(checkDate.getDate() + 4 - (checkDate.getDay() || 7));
7852
7853		time = checkDate.getTime();
7854		checkDate.setMonth(0); // Compare with Jan 1
7855		checkDate.setDate(1);
7856		return Math.floor(Math.round((time - checkDate) / 86400000) / 7) + 1;
7857	},
7858
7859	/* Parse a string value into a date object.
7860	 * See formatDate below for the possible formats.
7861	 *
7862	 * @param  format string - the expected format of the date
7863	 * @param  value string - the date in the above format
7864	 * @param  settings Object - attributes include:
7865	 *					shortYearCutoff  number - the cutoff year for determining the century (optional)
7866	 *					dayNamesShort	string[7] - abbreviated names of the days from Sunday (optional)
7867	 *					dayNames		string[7] - names of the days from Sunday (optional)
7868	 *					monthNamesShort string[12] - abbreviated names of the months (optional)
7869	 *					monthNames		string[12] - names of the months (optional)
7870	 * @return  Date - the extracted date value or null if value is blank
7871	 */
7872	parseDate: function (format, value, settings) {
7873		if (format == null || value == null) {
7874			throw "Invalid arguments";
7875		}
7876
7877		value = (typeof value === "object" ? value.toString() : value + "");
7878		if (value === "") {
7879			return null;
7880		}
7881
7882		var iFormat, dim, extra,
7883			iValue = 0,
7884			shortYearCutoffTemp = (settings ? settings.shortYearCutoff : null) || this._defaults.shortYearCutoff,
7885			shortYearCutoff = (typeof shortYearCutoffTemp !== "string" ? shortYearCutoffTemp :
7886				new Date().getFullYear() % 100 + parseInt(shortYearCutoffTemp, 10)),
7887			dayNamesShort = (settings ? settings.dayNamesShort : null) || this._defaults.dayNamesShort,
7888			dayNames = (settings ? settings.dayNames : null) || this._defaults.dayNames,
7889			monthNamesShort = (settings ? settings.monthNamesShort : null) || this._defaults.monthNamesShort,
7890			monthNames = (settings ? settings.monthNames : null) || this._defaults.monthNames,
7891			year = -1,
7892			month = -1,
7893			day = -1,
7894			doy = -1,
7895			literal = false,
7896			date,
7897			// Check whether a format character is doubled
7898			lookAhead = function(match) {
7899				var matches = (iFormat + 1 < format.length && format.charAt(iFormat + 1) === match);
7900				if (matches) {
7901					iFormat++;
7902				}
7903				return matches;
7904			},
7905			// Extract a number from the string value
7906			getNumber = function(match) {
7907				var isDoubled = lookAhead(match),
7908					size = (match === "@" ? 14 : (match === "!" ? 20 :
7909					(match === "y" && isDoubled ? 4 : (match === "o" ? 3 : 2)))),
7910					digits = new RegExp("^\\d{1," + size + "}"),
7911					num = value.substring(iValue).match(digits);
7912				if (!num) {
7913					throw "Missing number at position " + iValue;
7914				}
7915				iValue += num[0].length;
7916				return parseInt(num[0], 10);
7917			},
7918			// Extract a name from the string value and convert to an index
7919			getName = function(match, shortNames, longNames) {
7920				var index = -1,
7921					names = $.map(lookAhead(match) ? longNames : shortNames, function (v, k) {
7922						return [ [k, v] ];
7923					}).sort(function (a, b) {
7924						return -(a[1].length - b[1].length);
7925					});
7926
7927				$.each(names, function (i, pair) {
7928					var name = pair[1];
7929					if (value.substr(iValue, name.length).toLowerCase() === name.toLowerCase()) {
7930						index = pair[0];
7931						iValue += name.length;
7932						return false;
7933					}
7934				});
7935				if (index !== -1) {
7936					return index + 1;
7937				} else {
7938					throw "Unknown name at position " + iValue;
7939				}
7940			},
7941			// Confirm that a literal character matches the string value
7942			checkLiteral = function() {
7943				if (value.charAt(iValue) !== format.charAt(iFormat)) {
7944					throw "Unexpected literal at position " + iValue;
7945				}
7946				iValue++;
7947			};
7948
7949		for (iFormat = 0; iFormat < format.length; iFormat++) {
7950			if (literal) {
7951				if (format.charAt(iFormat) === "'" && !lookAhead("'")) {
7952					literal = false;
7953				} else {
7954					checkLiteral();
7955				}
7956			} else {
7957				switch (format.charAt(iFormat)) {
7958					case "d":
7959						day = getNumber("d");
7960						break;
7961					case "D":
7962						getName("D", dayNamesShort, dayNames);
7963						break;
7964					case "o":
7965						doy = getNumber("o");
7966						break;
7967					case "m":
7968						month = getNumber("m");
7969						break;
7970					case "M":
7971						month = getName("M", monthNamesShort, monthNames);
7972						break;
7973					case "y":
7974						year = getNumber("y");
7975						break;
7976					case "@":
7977						date = new Date(getNumber("@"));
7978						year = date.getFullYear();
7979						month = date.getMonth() + 1;
7980						day = date.getDate();
7981						break;
7982					case "!":
7983						date = new Date((getNumber("!") - this._ticksTo1970) / 10000);
7984						year = date.getFullYear();
7985						month = date.getMonth() + 1;
7986						day = date.getDate();
7987						break;
7988					case "'":
7989						if (lookAhead("'")){
7990							checkLiteral();
7991						} else {
7992							literal = true;
7993						}
7994						break;
7995					default:
7996						checkLiteral();
7997				}
7998			}
7999		}
8000
8001		if (iValue < value.length){
8002			extra = value.substr(iValue);
8003			if (!/^\s+/.test(extra)) {
8004				throw "Extra/unparsed characters found in date: " + extra;
8005			}
8006		}
8007
8008		if (year === -1) {
8009			year = new Date().getFullYear();
8010		} else if (year < 100) {
8011			year += new Date().getFullYear() - new Date().getFullYear() % 100 +
8012				(year <= shortYearCutoff ? 0 : -100);
8013		}
8014
8015		if (doy > -1) {
8016			month = 1;
8017			day = doy;
8018			do {
8019				dim = this._getDaysInMonth(year, month - 1);
8020				if (day <= dim) {
8021					break;
8022				}
8023				month++;
8024				day -= dim;
8025			} while (true);
8026		}
8027
8028		date = this._daylightSavingAdjust(new Date(year, month - 1, day));
8029		if (date.getFullYear() !== year || date.getMonth() + 1 !== month || date.getDate() !== day) {
8030			throw "Invalid date"; // E.g. 31/02/00
8031		}
8032		return date;
8033	},
8034
8035	/* Standard date formats. */
8036	ATOM: "yy-mm-dd", // RFC 3339 (ISO 8601)
8037	COOKIE: "D, dd M yy",
8038	ISO_8601: "yy-mm-dd",
8039	RFC_822: "D, d M y",
8040	RFC_850: "DD, dd-M-y",
8041	RFC_1036: "D, d M y",
8042	RFC_1123: "D, d M yy",
8043	RFC_2822: "D, d M yy",
8044	RSS: "D, d M y", // RFC 822
8045	TICKS: "!",
8046	TIMESTAMP: "@",
8047	W3C: "yy-mm-dd", // ISO 8601
8048
8049	_ticksTo1970: (((1970 - 1) * 365 + Math.floor(1970 / 4) - Math.floor(1970 / 100) +
8050		Math.floor(1970 / 400)) * 24 * 60 * 60 * 10000000),
8051
8052	/* Format a date object into a string value.
8053	 * The format can be combinations of the following:
8054	 * d  - day of month (no leading zero)
8055	 * dd - day of month (two digit)
8056	 * o  - day of year (no leading zeros)
8057	 * oo - day of year (three digit)
8058	 * D  - day name short
8059	 * DD - day name long
8060	 * m  - month of year (no leading zero)
8061	 * mm - month of year (two digit)
8062	 * M  - month name short
8063	 * MM - month name long
8064	 * y  - year (two digit)
8065	 * yy - year (four digit)
8066	 * @ - Unix timestamp (ms since 01/01/1970)
8067	 * ! - Windows ticks (100ns since 01/01/0001)
8068	 * "..." - literal text
8069	 * '' - single quote
8070	 *
8071	 * @param  format string - the desired format of the date
8072	 * @param  date Date - the date value to format
8073	 * @param  settings Object - attributes include:
8074	 *					dayNamesShort	string[7] - abbreviated names of the days from Sunday (optional)
8075	 *					dayNames		string[7] - names of the days from Sunday (optional)
8076	 *					monthNamesShort string[12] - abbreviated names of the months (optional)
8077	 *					monthNames		string[12] - names of the months (optional)
8078	 * @return  string - the date in the above format
8079	 */
8080	formatDate: function (format, date, settings) {
8081		if (!date) {
8082			return "";
8083		}
8084
8085		var iFormat,
8086			dayNamesShort = (settings ? settings.dayNamesShort : null) || this._defaults.dayNamesShort,
8087			dayNames = (settings ? settings.dayNames : null) || this._defaults.dayNames,
8088			monthNamesShort = (settings ? settings.monthNamesShort : null) || this._defaults.monthNamesShort,
8089			monthNames = (settings ? settings.monthNames : null) || this._defaults.monthNames,
8090			// Check whether a format character is doubled
8091			lookAhead = function(match) {
8092				var matches = (iFormat + 1 < format.length && format.charAt(iFormat + 1) === match);
8093				if (matches) {
8094					iFormat++;
8095				}
8096				return matches;
8097			},
8098			// Format a number, with leading zero if necessary
8099			formatNumber = function(match, value, len) {
8100				var num = "" + value;
8101				if (lookAhead(match)) {
8102					while (num.length < len) {
8103						num = "0" + num;
8104					}
8105				}
8106				return num;
8107			},
8108			// Format a name, short or long as requested
8109			formatName = function(match, value, shortNames, longNames) {
8110				return (lookAhead(match) ? longNames[value] : shortNames[value]);
8111			},
8112			output = "",
8113			literal = false;
8114
8115		if (date) {
8116			for (iFormat = 0; iFormat < format.length; iFormat++) {
8117				if (literal) {
8118					if (format.charAt(iFormat) === "'" && !lookAhead("'")) {
8119						literal = false;
8120					} else {
8121						output += format.charAt(iFormat);
8122					}
8123				} else {
8124					switch (format.charAt(iFormat)) {
8125						case "d":
8126							output += formatNumber("d", date.getDate(), 2);
8127							break;
8128						case "D":
8129							output += formatName("D", date.getDay(), dayNamesShort, dayNames);
8130							break;
8131						case "o":
8132							output += formatNumber("o",
8133								Math.round((new Date(date.getFullYear(), date.getMonth(), date.getDate()).getTime() - new Date(date.getFullYear(), 0, 0).getTime()) / 86400000), 3);
8134							break;
8135						case "m":
8136							output += formatNumber("m", date.getMonth() + 1, 2);
8137							break;
8138						case "M":
8139							output += formatName("M", date.getMonth(), monthNamesShort, monthNames);
8140							break;
8141						case "y":
8142							output += (lookAhead("y") ? date.getFullYear() :
8143								(date.getYear() % 100 < 10 ? "0" : "") + date.getYear() % 100);
8144							break;
8145						case "@":
8146							output += date.getTime();
8147							break;
8148						case "!":
8149							output += date.getTime() * 10000 + this._ticksTo1970;
8150							break;
8151						case "'":
8152							if (lookAhead("'")) {
8153								output += "'";
8154							} else {
8155								literal = true;
8156							}
8157							break;
8158						default:
8159							output += format.charAt(iFormat);
8160					}
8161				}
8162			}
8163		}
8164		return output;
8165	},
8166
8167	/* Extract all possible characters from the date format. */
8168	_possibleChars: function (format) {
8169		var iFormat,
8170			chars = "",
8171			literal = false,
8172			// Check whether a format character is doubled
8173			lookAhead = function(match) {
8174				var matches = (iFormat + 1 < format.length && format.charAt(iFormat + 1) === match);
8175				if (matches) {
8176					iFormat++;
8177				}
8178				return matches;
8179			};
8180
8181		for (iFormat = 0; iFormat < format.length; iFormat++) {
8182			if (literal) {
8183				if (format.charAt(iFormat) === "'" && !lookAhead("'")) {
8184					literal = false;
8185				} else {
8186					chars += format.charAt(iFormat);
8187				}
8188			} else {
8189				switch (format.charAt(iFormat)) {
8190					case "d": case "m": case "y": case "@":
8191						chars += "0123456789";
8192						break;
8193					case "D": case "M":
8194						return null; // Accept anything
8195					case "'":
8196						if (lookAhead("'")) {
8197							chars += "'";
8198						} else {
8199							literal = true;
8200						}
8201						break;
8202					default:
8203						chars += format.charAt(iFormat);
8204				}
8205			}
8206		}
8207		return chars;
8208	},
8209
8210	/* Get a setting value, defaulting if necessary. */
8211	_get: function(inst, name) {
8212		return inst.settings[name] !== undefined ?
8213			inst.settings[name] : this._defaults[name];
8214	},
8215
8216	/* Parse existing date and initialise date picker. */
8217	_setDateFromField: function(inst, noDefault) {
8218		if (inst.input.val() === inst.lastVal) {
8219			return;
8220		}
8221
8222		var dateFormat = this._get(inst, "dateFormat"),
8223			dates = inst.lastVal = inst.input ? inst.input.val() : null,
8224			defaultDate = this._getDefaultDate(inst),
8225			date = defaultDate,
8226			settings = this._getFormatConfig(inst);
8227
8228		try {
8229			date = this.parseDate(dateFormat, dates, settings) || defaultDate;
8230		} catch (event) {
8231			dates = (noDefault ? "" : dates);
8232		}
8233		inst.selectedDay = date.getDate();
8234		inst.drawMonth = inst.selectedMonth = date.getMonth();
8235		inst.drawYear = inst.selectedYear = date.getFullYear();
8236		inst.currentDay = (dates ? date.getDate() : 0);
8237		inst.currentMonth = (dates ? date.getMonth() : 0);
8238		inst.currentYear = (dates ? date.getFullYear() : 0);
8239		this._adjustInstDate(inst);
8240	},
8241
8242	/* Retrieve the default date shown on opening. */
8243	_getDefaultDate: function(inst) {
8244		return this._restrictMinMax(inst,
8245			this._determineDate(inst, this._get(inst, "defaultDate"), new Date()));
8246	},
8247
8248	/* A date may be specified as an exact value or a relative one. */
8249	_determineDate: function(inst, date, defaultDate) {
8250		var offsetNumeric = function(offset) {
8251				var date = new Date();
8252				date.setDate(date.getDate() + offset);
8253				return date;
8254			},
8255			offsetString = function(offset) {
8256				try {
8257					return $.datepicker.parseDate($.datepicker._get(inst, "dateFormat"),
8258						offset, $.datepicker._getFormatConfig(inst));
8259				}
8260				catch (e) {
8261					// Ignore
8262				}
8263
8264				var date = (offset.toLowerCase().match(/^c/) ?
8265					$.datepicker._getDate(inst) : null) || new Date(),
8266					year = date.getFullYear(),
8267					month = date.getMonth(),
8268					day = date.getDate(),
8269					pattern = /([+\-]?[0-9]+)\s*(d|D|w|W|m|M|y|Y)?/g,
8270					matches = pattern.exec(offset);
8271
8272				while (matches) {
8273					switch (matches[2] || "d") {
8274						case "d" : case "D" :
8275							day += parseInt(matches[1],10); break;
8276						case "w" : case "W" :
8277							day += parseInt(matches[1],10) * 7; break;
8278						case "m" : case "M" :
8279							month += parseInt(matches[1],10);
8280							day = Math.min(day, $.datepicker._getDaysInMonth(year, month));
8281							break;
8282						case "y": case "Y" :
8283							year += parseInt(matches[1],10);
8284							day = Math.min(day, $.datepicker._getDaysInMonth(year, month));
8285							break;
8286					}
8287					matches = pattern.exec(offset);
8288				}
8289				return new Date(year, month, day);
8290			},
8291			newDate = (date == null || date === "" ? defaultDate : (typeof date === "string" ? offsetString(date) :
8292				(typeof date === "number" ? (isNaN(date) ? defaultDate : offsetNumeric(date)) : new Date(date.getTime()))));
8293
8294		newDate = (newDate && newDate.toString() === "Invalid Date" ? defaultDate : newDate);
8295		if (newDate) {
8296			newDate.setHours(0);
8297			newDate.setMinutes(0);
8298			newDate.setSeconds(0);
8299			newDate.setMilliseconds(0);
8300		}
8301		return this._daylightSavingAdjust(newDate);
8302	},
8303
8304	/* Handle switch to/from daylight saving.
8305	 * Hours may be non-zero on daylight saving cut-over:
8306	 * > 12 when midnight changeover, but then cannot generate
8307	 * midnight datetime, so jump to 1AM, otherwise reset.
8308	 * @param  date  (Date) the date to check
8309	 * @return  (Date) the corrected date
8310	 */
8311	_daylightSavingAdjust: function(date) {
8312		if (!date) {
8313			return null;
8314		}
8315		date.setHours(date.getHours() > 12 ? date.getHours() + 2 : 0);
8316		return date;
8317	},
8318
8319	/* Set the date(s) directly. */
8320	_setDate: function(inst, date, noChange) {
8321		var clear = !date,
8322			origMonth = inst.selectedMonth,
8323			origYear = inst.selectedYear,
8324			newDate = this._restrictMinMax(inst, this._determineDate(inst, date, new Date()));
8325
8326		inst.selectedDay = inst.currentDay = newDate.getDate();
8327		inst.drawMonth = inst.selectedMonth = inst.currentMonth = newDate.getMonth();
8328		inst.drawYear = inst.selectedYear = inst.currentYear = newDate.getFullYear();
8329		if ((origMonth !== inst.selectedMonth || origYear !== inst.selectedYear) && !noChange) {
8330			this._notifyChange(inst);
8331		}
8332		this._adjustInstDate(inst);
8333		if (inst.input) {
8334			inst.input.val(clear ? "" : this._formatDate(inst));
8335		}
8336	},
8337
8338	/* Retrieve the date(s) directly. */
8339	_getDate: function(inst) {
8340		var startDate = (!inst.currentYear || (inst.input && inst.input.val() === "") ? null :
8341			this._daylightSavingAdjust(new Date(
8342			inst.currentYear, inst.currentMonth, inst.currentDay)));
8343			return startDate;
8344	},
8345
8346	/* Attach the onxxx handlers.  These are declared statically so
8347	 * they work with static code transformers like Caja.
8348	 */
8349	_attachHandlers: function(inst) {
8350		var stepMonths = this._get(inst, "stepMonths"),
8351			id = "#" + inst.id.replace( /\\\\/g, "\\" );
8352		inst.dpDiv.find("[data-handler]").map(function () {
8353			var handler = {
8354				prev: function () {
8355					$.datepicker._adjustDate(id, -stepMonths, "M");
8356				},
8357				next: function () {
8358					$.datepicker._adjustDate(id, +stepMonths, "M");
8359				},
8360				hide: function () {
8361					$.datepicker._hideDatepicker();
8362				},
8363				today: function () {
8364					$.datepicker._gotoToday(id);
8365				},
8366				selectDay: function () {
8367					$.datepicker._selectDay(id, +this.getAttribute("data-month"), +this.getAttribute("data-year"), this);
8368					return false;
8369				},
8370				selectMonth: function () {
8371					$.datepicker._selectMonthYear(id, this, "M");
8372					return false;
8373				},
8374				selectYear: function () {
8375					$.datepicker._selectMonthYear(id, this, "Y");
8376					return false;
8377				}
8378			};
8379			$(this).bind(this.getAttribute("data-event"), handler[this.getAttribute("data-handler")]);
8380		});
8381	},
8382
8383	/* Generate the HTML for the current state of the date picker. */
8384	_generateHTML: function(inst) {
8385		var maxDraw, prevText, prev, nextText, next, currentText, gotoDate,
8386			controls, buttonPanel, firstDay, showWeek, dayNames, dayNamesMin,
8387			monthNames, monthNamesShort, beforeShowDay, showOtherMonths,
8388			selectOtherMonths, defaultDate, html, dow, row, group, col, selectedDate,
8389			cornerClass, calender, thead, day, daysInMonth, leadDays, curRows, numRows,
8390			printDate, dRow, tbody, daySettings, otherMonth, unselectable,
8391			tempDate = new Date(),
8392			today = this._daylightSavingAdjust(
8393				new Date(tempDate.getFullYear(), tempDate.getMonth(), tempDate.getDate())), // clear time
8394			isRTL = this._get(inst, "isRTL"),
8395			showButtonPanel = this._get(inst, "showButtonPanel"),
8396			hideIfNoPrevNext = this._get(inst, "hideIfNoPrevNext"),
8397			navigationAsDateFormat = this._get(inst, "navigationAsDateFormat"),
8398			numMonths = this._getNumberOfMonths(inst),
8399			showCurrentAtPos = this._get(inst, "showCurrentAtPos"),
8400			stepMonths = this._get(inst, "stepMonths"),
8401			isMultiMonth = (numMonths[0] !== 1 || numMonths[1] !== 1),
8402			currentDate = this._daylightSavingAdjust((!inst.currentDay ? new Date(9999, 9, 9) :
8403				new Date(inst.currentYear, inst.currentMonth, inst.currentDay))),
8404			minDate = this._getMinMaxDate(inst, "min"),
8405			maxDate = this._getMinMaxDate(inst, "max"),
8406			drawMonth = inst.drawMonth - showCurrentAtPos,
8407			drawYear = inst.drawYear;
8408
8409		if (drawMonth < 0) {
8410			drawMonth += 12;
8411			drawYear--;
8412		}
8413		if (maxDate) {
8414			maxDraw = this._daylightSavingAdjust(new Date(maxDate.getFullYear(),
8415				maxDate.getMonth() - (numMonths[0] * numMonths[1]) + 1, maxDate.getDate()));
8416			maxDraw = (minDate && maxDraw < minDate ? minDate : maxDraw);
8417			while (this._daylightSavingAdjust(new Date(drawYear, drawMonth, 1)) > maxDraw) {
8418				drawMonth--;
8419				if (drawMonth < 0) {
8420					drawMonth = 11;
8421					drawYear--;
8422				}
8423			}
8424		}
8425		inst.drawMonth = drawMonth;
8426		inst.drawYear = drawYear;
8427
8428		prevText = this._get(inst, "prevText");
8429		prevText = (!navigationAsDateFormat ? prevText : this.formatDate(prevText,
8430			this._daylightSavingAdjust(new Date(drawYear, drawMonth - stepMonths, 1)),
8431			this._getFormatConfig(inst)));
8432
8433		prev = (this._canAdjustMonth(inst, -1, drawYear, drawMonth) ?
8434			"<a class='ui-datepicker-prev ui-corner-all' data-handler='prev' data-event='click'" +
8435			" title='" + prevText + "'><span class='ui-icon ui-icon-circle-triangle-" + ( isRTL ? "e" : "w") + "'>" + prevText + "</span></a>" :
8436			(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>"));
8437
8438		nextText = this._get(inst, "nextText");
8439		nextText = (!navigationAsDateFormat ? nextText : this.formatDate(nextText,
8440			this._daylightSavingAdjust(new Date(drawYear, drawMonth + stepMonths, 1)),
8441			this._getFormatConfig(inst)));
8442
8443		next = (this._canAdjustMonth(inst, +1, drawYear, drawMonth) ?
8444			"<a class='ui-datepicker-next ui-corner-all' data-handler='next' data-event='click'" +
8445			" title='" + nextText + "'><span class='ui-icon ui-icon-circle-triangle-" + ( isRTL ? "w" : "e") + "'>" + nextText + "</span></a>" :
8446			(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>"));
8447
8448		currentText = this._get(inst, "currentText");
8449		gotoDate = (this._get(inst, "gotoCurrent") && inst.currentDay ? currentDate : today);
8450		currentText = (!navigationAsDateFormat ? currentText :
8451			this.formatDate(currentText, gotoDate, this._getFormatConfig(inst)));
8452
8453		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'>" +
8454			this._get(inst, "closeText") + "</button>" : "");
8455
8456		buttonPanel = (showButtonPanel) ? "<div class='ui-datepicker-buttonpane ui-widget-content'>" + (isRTL ? controls : "") +
8457			(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'" +
8458			">" + currentText + "</button>" : "") + (isRTL ? "" : controls) + "</div>" : "";
8459
8460		firstDay = parseInt(this._get(inst, "firstDay"),10);
8461		firstDay = (isNaN(firstDay) ? 0 : firstDay);
8462
8463		showWeek = this._get(inst, "showWeek");
8464		dayNames = this._get(inst, "dayNames");
8465		dayNamesMin = this._get(inst, "dayNamesMin");
8466		monthNames = this._get(inst, "monthNames");
8467		monthNamesShort = this._get(inst, "monthNamesShort");
8468		beforeShowDay = this._get(inst, "beforeShowDay");
8469		showOtherMonths = this._get(inst, "showOtherMonths");
8470		selectOtherMonths = this._get(inst, "selectOtherMonths");
8471		defaultDate = this._getDefaultDate(inst);
8472		html = "";
8473		dow;
8474		for (row = 0; row < numMonths[0]; row++) {
8475			group = "";
8476			this.maxRows = 4;
8477			for (col = 0; col < numMonths[1]; col++) {
8478				selectedDate = this._daylightSavingAdjust(new Date(drawYear, drawMonth, inst.selectedDay));
8479				cornerClass = " ui-corner-all";
8480				calender = "";
8481				if (isMultiMonth) {
8482					calender += "<div class='ui-datepicker-group";
8483					if (numMonths[1] > 1) {
8484						switch (col) {
8485							case 0: calender += " ui-datepicker-group-first";
8486								cornerClass = " ui-corner-" + (isRTL ? "right" : "left"); break;
8487							case numMonths[1]-1: calender += " ui-datepicker-group-last";
8488								cornerClass = " ui-corner-" + (isRTL ? "left" : "right"); break;
8489							default: calender += " ui-datepicker-group-middle"; cornerClass = ""; break;
8490						}
8491					}
8492					calender += "'>";
8493				}
8494				calender += "<div class='ui-datepicker-header ui-widget-header ui-helper-clearfix" + cornerClass + "'>" +
8495					(/all|left/.test(cornerClass) && row === 0 ? (isRTL ? next : prev) : "") +
8496					(/all|right/.test(cornerClass) && row === 0 ? (isRTL ? prev : next) : "") +
8497					this._generateMonthYearHeader(inst, drawMonth, drawYear, minDate, maxDate,
8498					row > 0 || col > 0, monthNames, monthNamesShort) + // draw month headers
8499					"</div><table class='ui-datepicker-calendar'><thead>" +
8500					"<tr>";
8501				thead = (showWeek ? "<th class='ui-datepicker-week-col'>" + this._get(inst, "weekHeader") + "</th>" : "");
8502				for (dow = 0; dow < 7; dow++) { // days of the week
8503					day = (dow + firstDay) % 7;
8504					thead += "<th" + ((dow + firstDay + 6) % 7 >= 5 ? " class='ui-datepicker-week-end'" : "") + ">" +
8505						"<span title='" + dayNames[day] + "'>" + dayNamesMin[day] + "</span></th>";
8506				}
8507				calender += thead + "</tr></thead><tbody>";
8508				daysInMonth = this._getDaysInMonth(drawYear, drawMonth);
8509				if (drawYear === inst.selectedYear && drawMonth === inst.selectedMonth) {
8510					inst.selectedDay = Math.min(inst.selectedDay, daysInMonth);
8511				}
8512				leadDays = (this._getFirstDayOfMonth(drawYear, drawMonth) - firstDay + 7) % 7;
8513				curRows = Math.ceil((leadDays + daysInMonth) / 7); // calculate the number of rows to generate
8514				numRows = (isMultiMonth ? this.maxRows > curRows ? this.maxRows : curRows : curRows); //If multiple months, use the higher number of rows (see #7043)
8515				this.maxRows = numRows;
8516				printDate = this._daylightSavingAdjust(new Date(drawYear, drawMonth, 1 - leadDays));
8517				for (dRow = 0; dRow < numRows; dRow++) { // create date picker rows
8518					calender += "<tr>";
8519					tbody = (!showWeek ? "" : "<td class='ui-datepicker-week-col'>" +
8520						this._get(inst, "calculateWeek")(printDate) + "</td>");
8521					for (dow = 0; dow < 7; dow++) { // create date picker days
8522						daySettings = (beforeShowDay ?
8523							beforeShowDay.apply((inst.input ? inst.input[0] : null), [printDate]) : [true, ""]);
8524						otherMonth = (printDate.getMonth() !== drawMonth);
8525						unselectable = (otherMonth && !selectOtherMonths) || !daySettings[0] ||
8526							(minDate && printDate < minDate) || (maxDate && printDate > maxDate);
8527						tbody += "<td class='" +
8528							((dow + firstDay + 6) % 7 >= 5 ? " ui-datepicker-week-end" : "") + // highlight weekends
8529							(otherMonth ? " ui-datepicker-other-month" : "") + // highlight days from other months
8530							((printDate.getTime() === selectedDate.getTime() && drawMonth === inst.selectedMonth && inst._keyEvent) || // user pressed key
8531							(defaultDate.getTime() === printDate.getTime() && defaultDate.getTime() === selectedDate.getTime()) ?
8532							// or defaultDate is current printedDate and defaultDate is selectedDate
8533							" " + this._dayOverClass : "") + // highlight selected day
8534							(unselectable ? " " + this._unselectableClass + " ui-state-disabled": "") +  // highlight unselectable days
8535							(otherMonth && !showOtherMonths ? "" : " " + daySettings[1] + // highlight custom dates
8536							(printDate.getTime() === currentDate.getTime() ? " " + this._currentClass : "") + // highlight selected day
8537							(printDate.getTime() === today.getTime() ? " ui-datepicker-today" : "")) + "'" + // highlight today (if different)
8538							((!otherMonth || showOtherMonths) && daySettings[2] ? " title='" + daySettings[2].replace(/'/g, "&#39;") + "'" : "") + // cell title
8539							(unselectable ? "" : " data-handler='selectDay' data-event='click' data-month='" + printDate.getMonth() + "' data-year='" + printDate.getFullYear() + "'") + ">" + // actions
8540							(otherMonth && !showOtherMonths ? "&#xa0;" : // display for other months
8541							(unselectable ? "<span class='ui-state-default'>" + printDate.getDate() + "</span>" : "<a class='ui-state-default" +
8542							(printDate.getTime() === today.getTime() ? " ui-state-highlight" : "") +
8543							(printDate.getTime() === currentDate.getTime() ? " ui-state-active" : "") + // highlight selected day
8544							(otherMonth ? " ui-priority-secondary" : "") + // distinguish dates from other months
8545							"' href='#'>" + printDate.getDate() + "</a>")) + "</td>"; // display selectable date
8546						printDate.setDate(printDate.getDate() + 1);
8547						printDate = this._daylightSavingAdjust(printDate);
8548					}
8549					calender += tbody + "</tr>";
8550				}
8551				drawMonth++;
8552				if (drawMonth > 11) {
8553					drawMonth = 0;
8554					drawYear++;
8555				}
8556				calender += "</tbody></table>" + (isMultiMonth ? "</div>" +
8557							((numMonths[0] > 0 && col === numMonths[1]-1) ? "<div class='ui-datepicker-row-break'></div>" : "") : "");
8558				group += calender;
8559			}
8560			html += group;
8561		}
8562		html += buttonPanel;
8563		inst._keyEvent = false;
8564		return html;
8565	},
8566
8567	/* Generate the month and year header. */
8568	_generateMonthYearHeader: function(inst, drawMonth, drawYear, minDate, maxDate,
8569			secondary, monthNames, monthNamesShort) {
8570
8571		var inMinYear, inMaxYear, month, years, thisYear, determineYear, year, endYear,
8572			changeMonth = this._get(inst, "changeMonth"),
8573			changeYear = this._get(inst, "changeYear"),
8574			showMonthAfterYear = this._get(inst, "showMonthAfterYear"),
8575			html = "<div class='ui-datepicker-title'>",
8576			monthHtml = "";
8577
8578		// month selection
8579		if (secondary || !changeMonth) {
8580			monthHtml += "<span class='ui-datepicker-month'>" + monthNames[drawMonth] + "</span>";
8581		} else {
8582			inMinYear = (minDate && minDate.getFullYear() === drawYear);
8583			inMaxYear = (maxDate && maxDate.getFullYear() === drawYear);
8584			monthHtml += "<select class='ui-datepicker-month' data-handler='selectMonth' data-event='change'>";
8585			for ( month = 0; month < 12; month++) {
8586				if ((!inMinYear || month >= minDate.getMonth()) && (!inMaxYear || month <= maxDate.getMonth())) {
8587					monthHtml += "<option value='" + month + "'" +
8588						(month === drawMonth ? " selected='selected'" : "") +
8589						">" + monthNamesShort[month] + "</option>";
8590				}
8591			}
8592			monthHtml += "</select>";
8593		}
8594
8595		if (!showMonthAfterYear) {
8596			html += monthHtml + (secondary || !(changeMonth && changeYear) ? "&#xa0;" : "");
8597		}
8598
8599		// year selection
8600		if ( !inst.yearshtml ) {
8601			inst.yearshtml = "";
8602			if (secondary || !changeYear) {
8603				html += "<span class='ui-datepicker-year'>" + drawYear + "</span>";
8604			} else {
8605				// determine range of years to display
8606				years = this._get(inst, "yearRange").split(":");
8607				thisYear = new Date().getFullYear();
8608				determineYear = function(value) {
8609					var year = (value.match(/c[+\-].*/) ? drawYear + parseInt(value.substring(1), 10) :
8610						(value.match(/[+\-].*/) ? thisYear + parseInt(value, 10) :
8611						parseInt(value, 10)));
8612					return (isNaN(year) ? thisYear : year);
8613				};
8614				year = determineYear(years[0]);
8615				endYear = Math.max(year, determineYear(years[1] || ""));
8616				year = (minDate ? Math.max(year, minDate.getFullYear()) : year);
8617				endYear = (maxDate ? Math.min(endYear, maxDate.getFullYear()) : endYear);
8618				inst.yearshtml += "<select class='ui-datepicker-year' data-handler='selectYear' data-event='change'>";
8619				for (; year <= endYear; year++) {
8620					inst.yearshtml += "<option value='" + year + "'" +
8621						(year === drawYear ? " selected='selected'" : "") +
8622						">" + year + "</option>";
8623				}
8624				inst.yearshtml += "</select>";
8625
8626				html += inst.yearshtml;
8627				inst.yearshtml = null;
8628			}
8629		}
8630
8631		html += this._get(inst, "yearSuffix");
8632		if (showMonthAfterYear) {
8633			html += (secondary || !(changeMonth && changeYear) ? "&#xa0;" : "") + monthHtml;
8634		}
8635		html += "</div>"; // Close datepicker_header
8636		return html;
8637	},
8638
8639	/* Adjust one of the date sub-fields. */
8640	_adjustInstDate: function(inst, offset, period) {
8641		var year = inst.drawYear + (period === "Y" ? offset : 0),
8642			month = inst.drawMonth + (period === "M" ? offset : 0),
8643			day = Math.min(inst.selectedDay, this._getDaysInMonth(year, month)) + (period === "D" ? offset : 0),
8644			date = this._restrictMinMax(inst, this._daylightSavingAdjust(new Date(year, month, day)));
8645
8646		inst.selectedDay = date.getDate();
8647		inst.drawMonth = inst.selectedMonth = date.getMonth();
8648		inst.drawYear = inst.selectedYear = date.getFullYear();
8649		if (period === "M" || period === "Y") {
8650			this._notifyChange(inst);
8651		}
8652	},
8653
8654	/* Ensure a date is within any min/max bounds. */
8655	_restrictMinMax: function(inst, date) {
8656		var minDate = this._getMinMaxDate(inst, "min"),
8657			maxDate = this._getMinMaxDate(inst, "max"),
8658			newDate = (minDate && date < minDate ? minDate : date);
8659		return (maxDate && newDate > maxDate ? maxDate : newDate);
8660	},
8661
8662	/* Notify change of month/year. */
8663	_notifyChange: function(inst) {
8664		var onChange = this._get(inst, "onChangeMonthYear");
8665		if (onChange) {
8666			onChange.apply((inst.input ? inst.input[0] : null),
8667				[inst.selectedYear, inst.selectedMonth + 1, inst]);
8668		}
8669	},
8670
8671	/* Determine the number of months to show. */
8672	_getNumberOfMonths: function(inst) {
8673		var numMonths = this._get(inst, "numberOfMonths");
8674		return (numMonths == null ? [1, 1] : (typeof numMonths === "number" ? [1, numMonths] : numMonths));
8675	},
8676
8677	/* Determine the current maximum date - ensure no time components are set. */
8678	_getMinMaxDate: function(inst, minMax) {
8679		return this._determineDate(inst, this._get(inst, minMax + "Date"), null);
8680	},
8681
8682	/* Find the number of days in a given month. */
8683	_getDaysInMonth: function(year, month) {
8684		return 32 - this._daylightSavingAdjust(new Date(year, month, 32)).getDate();
8685	},
8686
8687	/* Find the day of the week of the first of a month. */
8688	_getFirstDayOfMonth: function(year, month) {
8689		return new Date(year, month, 1).getDay();
8690	},
8691
8692	/* Determines if we should allow a "next/prev" month display change. */
8693	_canAdjustMonth: function(inst, offset, curYear, curMonth) {
8694		var numMonths = this._getNumberOfMonths(inst),
8695			date = this._daylightSavingAdjust(new Date(curYear,
8696			curMonth + (offset < 0 ? offset : numMonths[0] * numMonths[1]), 1));
8697
8698		if (offset < 0) {
8699			date.setDate(this._getDaysInMonth(date.getFullYear(), date.getMonth()));
8700		}
8701		return this._isInRange(inst, date);
8702	},
8703
8704	/* Is the given date in the accepted range? */
8705	_isInRange: function(inst, date) {
8706		var yearSplit, currentYear,
8707			minDate = this._getMinMaxDate(inst, "min"),
8708			maxDate = this._getMinMaxDate(inst, "max"),
8709			minYear = null,
8710			maxYear = null,
8711			years = this._get(inst, "yearRange");
8712			if (years){
8713				yearSplit = years.split(":");
8714				currentYear = new Date().getFullYear();
8715				minYear = parseInt(yearSplit[0], 10);
8716				maxYear = parseInt(yearSplit[1], 10);
8717				if ( yearSplit[0].match(/[+\-].*/) ) {
8718					minYear += currentYear;
8719				}
8720				if ( yearSplit[1].match(/[+\-].*/) ) {
8721					maxYear += currentYear;
8722				}
8723			}
8724
8725		return ((!minDate || date.getTime() >= minDate.getTime()) &&
8726			(!maxDate || date.getTime() <= maxDate.getTime()) &&
8727			(!minYear || date.getFullYear() >= minYear) &&
8728			(!maxYear || date.getFullYear() <= maxYear));
8729	},
8730
8731	/* Provide the configuration settings for formatting/parsing. */
8732	_getFormatConfig: function(inst) {
8733		var shortYearCutoff = this._get(inst, "shortYearCutoff");
8734		shortYearCutoff = (typeof shortYearCutoff !== "string" ? shortYearCutoff :
8735			new Date().getFullYear() % 100 + parseInt(shortYearCutoff, 10));
8736		return {shortYearCutoff: shortYearCutoff,
8737			dayNamesShort: this._get(inst, "dayNamesShort"), dayNames: this._get(inst, "dayNames"),
8738			monthNamesShort: this._get(inst, "monthNamesShort"), monthNames: this._get(inst, "monthNames")};
8739	},
8740
8741	/* Format the given date for display. */
8742	_formatDate: function(inst, day, month, year) {
8743		if (!day) {
8744			inst.currentDay = inst.selectedDay;
8745			inst.currentMonth = inst.selectedMonth;
8746			inst.currentYear = inst.selectedYear;
8747		}
8748		var date = (day ? (typeof day === "object" ? day :
8749			this._daylightSavingAdjust(new Date(year, month, day))) :
8750			this._daylightSavingAdjust(new Date(inst.currentYear, inst.currentMonth, inst.currentDay)));
8751		return this.formatDate(this._get(inst, "dateFormat"), date, this._getFormatConfig(inst));
8752	}
8753});
8754
8755/*
8756 * Bind hover events for datepicker elements.
8757 * Done via delegate so the binding only occurs once in the lifetime of the parent div.
8758 * Global instActive, set by _updateDatepicker allows the handlers to find their way back to the active picker.
8759 */
8760function bindHover(dpDiv) {
8761	var selector = "button, .ui-datepicker-prev, .ui-datepicker-next, .ui-datepicker-calendar td a";
8762	return dpDiv.delegate(selector, "mouseout", function() {
8763			$(this).removeClass("ui-state-hover");
8764			if (this.className.indexOf("ui-datepicker-prev") !== -1) {
8765				$(this).removeClass("ui-datepicker-prev-hover");
8766			}
8767			if (this.className.indexOf("ui-datepicker-next") !== -1) {
8768				$(this).removeClass("ui-datepicker-next-hover");
8769			}
8770		})
8771		.delegate(selector, "mouseover", function(){
8772			if (!$.datepicker._isDisabledDatepicker( instActive.inline ? dpDiv.parent()[0] : instActive.input[0])) {
8773				$(this).parents(".ui-datepicker-calendar").find("a").removeClass("ui-state-hover");
8774				$(this).addClass("ui-state-hover");
8775				if (this.className.indexOf("ui-datepicker-prev") !== -1) {
8776					$(this).addClass("ui-datepicker-prev-hover");
8777				}
8778				if (this.className.indexOf("ui-datepicker-next") !== -1) {
8779					$(this).addClass("ui-datepicker-next-hover");
8780				}
8781			}
8782		});
8783}
8784
8785/* jQuery extend now ignores nulls! */
8786function extendRemove(target, props) {
8787	$.extend(target, props);
8788	for (var name in props) {
8789		if (props[name] == null) {
8790			target[name] = props[name];
8791		}
8792	}
8793	return target;
8794}
8795
8796/* Invoke the datepicker functionality.
8797   @param  options  string - a command, optionally followed by additional parameters or
8798					Object - settings for attaching new datepicker functionality
8799   @return  jQuery object */
8800$.fn.datepicker = function(options){
8801
8802	/* Verify an empty collection wasn't passed - Fixes #6976 */
8803	if ( !this.length ) {
8804		return this;
8805	}
8806
8807	/* Initialise the date picker. */
8808	if (!$.datepicker.initialized) {
8809		$(document).mousedown($.datepicker._checkExternalClick);
8810		$.datepicker.initialized = true;
8811	}
8812
8813	/* Append datepicker main container to body if not exist. */
8814	if ($("#"+$.datepicker._mainDivId).length === 0) {
8815		$("body").append($.datepicker.dpDiv);
8816	}
8817
8818	var otherArgs = Array.prototype.slice.call(arguments, 1);
8819	if (typeof options === "string" && (options === "isDisabled" || options === "getDate" || options === "widget")) {
8820		return $.datepicker["_" + options + "Datepicker"].
8821			apply($.datepicker, [this[0]].concat(otherArgs));
8822	}
8823	if (options === "option" && arguments.length === 2 && typeof arguments[1] === "string") {
8824		return $.datepicker["_" + options + "Datepicker"].
8825			apply($.datepicker, [this[0]].concat(otherArgs));
8826	}
8827	return this.each(function() {
8828		typeof options === "string" ?
8829			$.datepicker["_" + options + "Datepicker"].
8830				apply($.datepicker, [this].concat(otherArgs)) :
8831			$.datepicker._attachDatepicker(this, options);
8832	});
8833};
8834
8835$.datepicker = new Datepicker(); // singleton instance
8836$.datepicker.initialized = false;
8837$.datepicker.uuid = new Date().getTime();
8838$.datepicker.version = "1.10.
vendor: 18,167 bytes, lines 8838-9565
88384";
8839
8840})(jQuery);
8841(function( $, undefined ) {
8842
8843var sizeRelatedOptions = {
8844		buttons: true,
8845		height: true,
8846		maxHeight: true,
8847		maxWidth: true,
8848		minHeight: true,
8849		minWidth: true,
8850		width: true
8851	},
8852	resizableRelatedOptions = {
8853		maxHeight: true,
8854		maxWidth: true,
8855		minHeight: true,
8856		minWidth: true
8857	};
8858
8859$.widget( "ui.dialog", {
8860	version: "1.10.4",
8861	options: {
8862		appendTo: "body",
8863		autoOpen: true,
8864		buttons: [],
8865		closeOnEscape: true,
8866		closeText: "close",
8867		dialogClass: "",
8868		draggable: true,
8869		hide: null,
8870		height: "auto",
8871		maxHeight: null,
8872		maxWidth: null,
8873		minHeight: 150,
8874		minWidth: 150,
8875		modal: false,
8876		position: {
8877			my: "center",
8878			at: "center",
8879			of: window,
8880			collision: "fit",
8881			// Ensure the titlebar is always visible
8882			using: function( pos ) {
8883				var topOffset = $( this ).css( pos ).offset().top;
8884				if ( topOffset < 0 ) {
8885					$( this ).css( "top", pos.top - topOffset );
8886				}
8887			}
8888		},
8889		resizable: true,
8890		show: null,
8891		title: null,
8892		width: 300,
8893
8894		// callbacks
8895		beforeClose: null,
8896		close: null,
8897		drag: null,
8898		dragStart: null,
8899		dragStop: null,
8900		focus: null,
8901		open: null,
8902		resize: null,
8903		resizeStart: null,
8904		resizeStop: null
8905	},
8906
8907	_create: function() {
8908		this.originalCss = {
8909			display: this.element[0].style.display,
8910			width: this.element[0].style.width,
8911			minHeight: this.element[0].style.minHeight,
8912			maxHeight: this.element[0].style.maxHeight,
8913			height: this.element[0].style.height
8914		};
8915		this.originalPosition = {
8916			parent: this.element.parent(),
8917			index: this.element.parent().children().index( this.element )
8918		};
8919		this.originalTitle = this.element.attr("title");
8920		this.options.title = this.options.title || this.originalTitle;
8921
8922		this._createWrapper();
8923
8924		this.element
8925			.show()
8926			.removeAttr("title")
8927			.addClass("ui-dialog-content ui-widget-content")
8928			.appendTo( this.uiDialog );
8929
8930		this._createTitlebar();
8931		this._createButtonPane();
8932
8933		if ( this.options.draggable && $.fn.draggable ) {
8934			this._makeDraggable();
8935		}
8936		if ( this.options.resizable && $.fn.resizable ) {
8937			this._makeResizable();
8938		}
8939
8940		this._isOpen = false;
8941	},
8942
8943	_init: function() {
8944		if ( this.options.autoOpen ) {
8945			this.open();
8946		}
8947	},
8948
8949	_appendTo: function() {
8950		var element = this.options.appendTo;
8951		if ( element && (element.jquery || element.nodeType) ) {
8952			return $( element );
8953		}
8954		return this.document.find( element || "body" ).eq( 0 );
8955	},
8956
8957	_destroy: function() {
8958		var next,
8959			originalPosition = this.originalPosition;
8960
8961		this._destroyOverlay();
8962
8963		this.element
8964			.removeUniqueId()
8965			.removeClass("ui-dialog-content ui-widget-content")
8966			.css( this.originalCss )
8967			// Without detaching first, the following becomes really slow
8968			.detach();
8969
8970		this.uiDialog.stop( true, true ).remove();
8971
8972		if ( this.originalTitle ) {
8973			this.element.attr( "title", this.originalTitle );
8974		}
8975
8976		next = originalPosition.parent.children().eq( originalPosition.index );
8977		// Don't try to place the dialog next to itself (#8613)
8978		if ( next.length && next[0] !== this.element[0] ) {
8979			next.before( this.element );
8980		} else {
8981			originalPosition.parent.append( this.element );
8982		}
8983	},
8984
8985	widget: function() {
8986		return this.uiDialog;
8987	},
8988
8989	disable: $.noop,
8990	enable: $.noop,
8991
8992	close: function( event ) {
8993		var activeElement,
8994			that = this;
8995
8996		if ( !this._isOpen || this._trigger( "beforeClose", event ) === false ) {
8997			return;
8998		}
8999
9000		this._isOpen = false;
9001		this._destroyOverlay();
9002
9003		if ( !this.opener.filter(":focusable").focus().length ) {
9004
9005			// support: IE9
9006			// IE9 throws an "Unspecified error" accessing document.activeElement from an <iframe>
9007			try {
9008				activeElement = this.document[ 0 ].activeElement;
9009
9010				// Support: IE9, IE10
9011				// If the <body> is blurred, IE will switch windows, see #4520
9012				if ( activeElement && activeElement.nodeName.toLowerCase() !== "body" ) {
9013
9014					// Hiding a focused element doesn't trigger blur in WebKit
9015					// so in case we have nothing to focus on, explicitly blur the active element
9016					// https://bugs.webkit.org/show_bug.cgi?id=47182
9017					$( activeElement ).blur();
9018				}
9019			} catch ( error ) {}
9020		}
9021
9022		this._hide( this.uiDialog, this.options.hide, function() {
9023			that._trigger( "close", event );
9024		});
9025	},
9026
9027	isOpen: function() {
9028		return this._isOpen;
9029	},
9030
9031	moveToTop: function() {
9032		this._moveToTop();
9033	},
9034
9035	_moveToTop: function( event, silent ) {
9036		var moved = !!this.uiDialog.nextAll(":visible").insertBefore( this.uiDialog ).length;
9037		if ( moved && !silent ) {
9038			this._trigger( "focus", event );
9039		}
9040		return moved;
9041	},
9042
9043	open: function() {
9044		var that = this;
9045		if ( this._isOpen ) {
9046			if ( this._moveToTop() ) {
9047				this._focusTabbable();
9048			}
9049			return;
9050		}
9051
9052		this._isOpen = true;
9053		this.opener = $( this.document[0].activeElement );
9054
9055		this._size();
9056		this._position();
9057		this._createOverlay();
9058		this._moveToTop( null, true );
9059		this._show( this.uiDialog, this.options.show, function() {
9060			that._focusTabbable();
9061			that._trigger("focus");
9062		});
9063
9064		this._trigger("open");
9065	},
9066
9067	_focusTabbable: function() {
9068		// Set focus to the first match:
9069		// 1. First element inside the dialog matching [autofocus]
9070		// 2. Tabbable element inside the content element
9071		// 3. Tabbable element inside the buttonpane
9072		// 4. The close button
9073		// 5. The dialog itself
9074		var hasFocus = this.element.find("[autofocus]");
9075		if ( !hasFocus.length ) {
9076			hasFocus = this.element.find(":tabbable");
9077		}
9078		if ( !hasFocus.length ) {
9079			hasFocus = this.uiDialogButtonPane.find(":tabbable");
9080		}
9081		if ( !hasFocus.length ) {
9082			hasFocus = this.uiDialogTitlebarClose.filter(":tabbable");
9083		}
9084		if ( !hasFocus.length ) {
9085			hasFocus = this.uiDialog;
9086		}
9087		hasFocus.eq( 0 ).focus();
9088	},
9089
9090	_keepFocus: function( event ) {
9091		function checkFocus() {
9092			var activeElement = this.document[0].activeElement,
9093				isActive = this.uiDialog[0] === activeElement ||
9094					$.contains( this.uiDialog[0], activeElement );
9095			if ( !isActive ) {
9096				this._focusTabbable();
9097			}
9098		}
9099		event.preventDefault();
9100		checkFocus.call( this );
9101		// support: IE
9102		// IE <= 8 doesn't prevent moving focus even with event.preventDefault()
9103		// so we check again later
9104		this._delay( checkFocus );
9105	},
9106
9107	_createWrapper: function() {
9108		this.uiDialog = $("<div>")
9109			.addClass( "ui-dialog ui-widget ui-widget-content ui-corner-all ui-front " +
9110				this.options.dialogClass )
9111			.hide()
9112			.attr({
9113				// Setting tabIndex makes the div focusable
9114				tabIndex: -1,
9115				role: "dialog"
9116			})
9117			.appendTo( this._appendTo() );
9118
9119		this._on( this.uiDialog, {
9120			keydown: function( event ) {
9121				if ( this.options.closeOnEscape && !event.isDefaultPrevented() && event.keyCode &&
9122						event.keyCode === $.ui.keyCode.ESCAPE ) {
9123					event.preventDefault();
9124					this.close( event );
9125					return;
9126				}
9127
9128				// prevent tabbing out of dialogs
9129				if ( event.keyCode !== $.ui.keyCode.TAB ) {
9130					return;
9131				}
9132				var tabbables = this.uiDialog.find(":tabbable"),
9133					first = tabbables.filter(":first"),
9134					last  = tabbables.filter(":last");
9135
9136				if ( ( event.target === last[0] || event.target === this.uiDialog[0] ) && !event.shiftKey ) {
9137					first.focus( 1 );
9138					event.preventDefault();
9139				} else if ( ( event.target === first[0] || event.target === this.uiDialog[0] ) && event.shiftKey ) {
9140					last.focus( 1 );
9141					event.preventDefault();
9142				}
9143			},
9144			mousedown: function( event ) {
9145				if ( this._moveToTop( event ) ) {
9146					this._focusTabbable();
9147				}
9148			}
9149		});
9150
9151		// We assume that any existing aria-describedby attribute means
9152		// that the dialog content is marked up properly
9153		// otherwise we brute force the content as the description
9154		if ( !this.element.find("[aria-describedby]").length ) {
9155			this.uiDialog.attr({
9156				"aria-describedby": this.element.uniqueId().attr("id")
9157			});
9158		}
9159	},
9160
9161	_createTitlebar: function() {
9162		var uiDialogTitle;
9163
9164		this.uiDialogTitlebar = $("<div>")
9165			.addClass("ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix")
9166			.prependTo( this.uiDialog );
9167		this._on( this.uiDialogTitlebar, {
9168			mousedown: function( event ) {
9169				// Don't prevent click on close button (#8838)
9170				// Focusing a dialog that is partially scrolled out of view
9171				// causes the browser to scroll it into view, preventing the click event
9172				if ( !$( event.target ).closest(".ui-dialog-titlebar-close") ) {
9173					// Dialog isn't getting focus when dragging (#8063)
9174					this.uiDialog.focus();
9175				}
9176			}
9177		});
9178
9179		// support: IE
9180		// Use type="button" to prevent enter keypresses in textboxes from closing the
9181		// dialog in IE (#9312)
9182		this.uiDialogTitlebarClose = $( "<button type='button'></button>" )
9183			.button({
9184				label: this.options.closeText,
9185				icons: {
9186					primary: "ui-icon-closethick"
9187				},
9188				text: false
9189			})
9190			.addClass("ui-dialog-titlebar-close")
9191			.appendTo( this.uiDialogTitlebar );
9192		this._on( this.uiDialogTitlebarClose, {
9193			click: function( event ) {
9194				event.preventDefault();
9195				this.close( event );
9196			}
9197		});
9198
9199		uiDialogTitle = $("<span>")
9200			.uniqueId()
9201			.addClass("ui-dialog-title")
9202			.prependTo( this.uiDialogTitlebar );
9203		this._title( uiDialogTitle );
9204
9205		this.uiDialog.attr({
9206			"aria-labelledby": uiDialogTitle.attr("id")
9207		});
9208	},
9209
9210	_title: function( title ) {
9211		if ( !this.options.title ) {
9212			title.html("&#160;");
9213		}
9214		title.text( this.options.title );
9215	},
9216
9217	_createButtonPane: function() {
9218		this.uiDialogButtonPane = $("<div>")
9219			.addClass("ui-dialog-buttonpane ui-widget-content ui-helper-clearfix");
9220
9221		this.uiButtonSet = $("<div>")
9222			.addClass("ui-dialog-buttonset")
9223			.appendTo( this.uiDialogButtonPane );
9224
9225		this._createButtons();
9226	},
9227
9228	_createButtons: function() {
9229		var that = this,
9230			buttons = this.options.buttons;
9231
9232		// if we already have a button pane, remove it
9233		this.uiDialogButtonPane.remove();
9234		this.uiButtonSet.empty();
9235
9236		if ( $.isEmptyObject( buttons ) || ($.isArray( buttons ) && !buttons.length) ) {
9237			this.uiDialog.removeClass("ui-dialog-buttons");
9238			return;
9239		}
9240
9241		$.each( buttons, function( name, props ) {
9242			var click, buttonOptions;
9243			props = $.isFunction( props ) ?
9244				{ click: props, text: name } :
9245				props;
9246			// Default to a non-submitting button
9247			props = $.extend( { type: "button" }, props );
9248			// Change the context for the click callback to be the main element
9249			click = props.click;
9250			props.click = function() {
9251				click.apply( that.element[0], arguments );
9252			};
9253			buttonOptions = {
9254				icons: props.icons,
9255				text: props.showText
9256			};
9257			delete props.icons;
9258			delete props.showText;
9259			$( "<button></button>", props )
9260				.button( buttonOptions )
9261				.appendTo( that.uiButtonSet );
9262		});
9263		this.uiDialog.addClass("ui-dialog-buttons");
9264		this.uiDialogButtonPane.appendTo( this.uiDialog );
9265	},
9266
9267	_makeDraggable: function() {
9268		var that = this,
9269			options = this.options;
9270
9271		function filteredUi( ui ) {
9272			return {
9273				position: ui.position,
9274				offset: ui.offset
9275			};
9276		}
9277
9278		this.uiDialog.draggable({
9279			cancel: ".ui-dialog-content, .ui-dialog-titlebar-close",
9280			handle: ".ui-dialog-titlebar",
9281			containment: "document",
9282			start: function( event, ui ) {
9283				$( this ).addClass("ui-dialog-dragging");
9284				that._blockFrames();
9285				that._trigger( "dragStart", event, filteredUi( ui ) );
9286			},
9287			drag: function( event, ui ) {
9288				that._trigger( "drag", event, filteredUi( ui ) );
9289			},
9290			stop: function( event, ui ) {
9291				options.position = [
9292					ui.position.left - that.document.scrollLeft(),
9293					ui.position.top - that.document.scrollTop()
9294				];
9295				$( this ).removeClass("ui-dialog-dragging");
9296				that._unblockFrames();
9297				that._trigger( "dragStop", event, filteredUi( ui ) );
9298			}
9299		});
9300	},
9301
9302	_makeResizable: function() {
9303		var that = this,
9304			options = this.options,
9305			handles = options.resizable,
9306			// .ui-resizable has position: relative defined in the stylesheet
9307			// but dialogs have to use absolute or fixed positioning
9308			position = this.uiDialog.css("position"),
9309			resizeHandles = typeof handles === "string" ?
9310				handles	:
9311				"n,e,s,w,se,sw,ne,nw";
9312
9313		function filteredUi( ui ) {
9314			return {
9315				originalPosition: ui.originalPosition,
9316				originalSize: ui.originalSize,
9317				position: ui.position,
9318				size: ui.size
9319			};
9320		}
9321
9322		this.uiDialog.resizable({
9323			cancel: ".ui-dialog-content",
9324			containment: "document",
9325			alsoResize: this.element,
9326			maxWidth: options.maxWidth,
9327			maxHeight: options.maxHeight,
9328			minWidth: options.minWidth,
9329			minHeight: this._minHeight(),
9330			handles: resizeHandles,
9331			start: function( event, ui ) {
9332				$( this ).addClass("ui-dialog-resizing");
9333				that._blockFrames();
9334				that._trigger( "resizeStart", event, filteredUi( ui ) );
9335			},
9336			resize: function( event, ui ) {
9337				that._trigger( "resize", event, filteredUi( ui ) );
9338			},
9339			stop: function( event, ui ) {
9340				options.height = $( this ).height();
9341				options.width = $( this ).width();
9342				$( this ).removeClass("ui-dialog-resizing");
9343				that._unblockFrames();
9344				that._trigger( "resizeStop", event, filteredUi( ui ) );
9345			}
9346		})
9347		.css( "position", position );
9348	},
9349
9350	_minHeight: function() {
9351		var options = this.options;
9352
9353		return options.height === "auto" ?
9354			options.minHeight :
9355			Math.min( options.minHeight, options.height );
9356	},
9357
9358	_position: function() {
9359		// Need to show the dialog to get the actual offset in the position plugin
9360		var isVisible = this.uiDialog.is(":visible");
9361		if ( !isVisible ) {
9362			this.uiDialog.show();
9363		}
9364		this.uiDialog.position( this.options.position );
9365		if ( !isVisible ) {
9366			this.uiDialog.hide();
9367		}
9368	},
9369
9370	_setOptions: function( options ) {
9371		var that = this,
9372			resize = false,
9373			resizableOptions = {};
9374
9375		$.each( options, function( key, value ) {
9376			that._setOption( key, value );
9377
9378			if ( key in sizeRelatedOptions ) {
9379				resize = true;
9380			}
9381			if ( key in resizableRelatedOptions ) {
9382				resizableOptions[ key ] = value;
9383			}
9384		});
9385
9386		if ( resize ) {
9387			this._size();
9388			this._position();
9389		}
9390		if ( this.uiDialog.is(":data(ui-resizable)") ) {
9391			this.uiDialog.resizable( "option", resizableOptions );
9392		}
9393	},
9394
9395	_setOption: function( key, value ) {
9396		var isDraggable, isResizable,
9397			uiDialog = this.uiDialog;
9398
9399		if ( key === "dialogClass" ) {
9400			uiDialog
9401				.removeClass( this.options.dialogClass )
9402				.addClass( value );
9403		}
9404
9405		if ( key === "disabled" ) {
9406			return;
9407		}
9408
9409		this._super( key, value );
9410
9411		if ( key === "appendTo" ) {
9412			this.uiDialog.appendTo( this._appendTo() );
9413		}
9414
9415		if ( key === "buttons" ) {
9416			this._createButtons();
9417		}
9418
9419		if ( key === "closeText" ) {
9420			this.uiDialogTitlebarClose.button({
9421				// Ensure that we always pass a string
9422				label: "" + value
9423			});
9424		}
9425
9426		if ( key === "draggable" ) {
9427			isDraggable = uiDialog.is(":data(ui-draggable)");
9428			if ( isDraggable && !value ) {
9429				uiDialog.draggable("destroy");
9430			}
9431
9432			if ( !isDraggable && value ) {
9433				this._makeDraggable();
9434			}
9435		}
9436
9437		if ( key === "position" ) {
9438			this._position();
9439		}
9440
9441		if ( key === "resizable" ) {
9442			// currently resizable, becoming non-resizable
9443			isResizable = uiDialog.is(":data(ui-resizable)");
9444			if ( isResizable && !value ) {
9445				uiDialog.resizable("destroy");
9446			}
9447
9448			// currently resizable, changing handles
9449			if ( isResizable && typeof value === "string" ) {
9450				uiDialog.resizable( "option", "handles", value );
9451			}
9452
9453			// currently non-resizable, becoming resizable
9454			if ( !isResizable && value !== false ) {
9455				this._makeResizable();
9456			}
9457		}
9458
9459		if ( key === "title" ) {
9460			this._title( this.uiDialogTitlebar.find(".ui-dialog-title") );
9461		}
9462	},
9463
9464	_size: function() {
9465		// If the user has resized the dialog, the .ui-dialog and .ui-dialog-content
9466		// divs will both have width and height set, so we need to reset them
9467		var nonContentHeight, minContentHeight, maxContentHeight,
9468			options = this.options;
9469
9470		// Reset content sizing
9471		this.element.show().css({
9472			width: "auto",
9473			minHeight: 0,
9474			maxHeight: "none",
9475			height: 0
9476		});
9477
9478		if ( options.minWidth > options.width ) {
9479			options.width = options.minWidth;
9480		}
9481
9482		// reset wrapper sizing
9483		// determine the height of all the non-content elements
9484		nonContentHeight = this.uiDialog.css({
9485				height: "auto",
9486				width: options.width
9487			})
9488			.outerHeight();
9489		minContentHeight = Math.max( 0, options.minHeight - nonContentHeight );
9490		maxContentHeight = typeof options.maxHeight === "number" ?
9491			Math.max( 0, options.maxHeight - nonContentHeight ) :
9492			"none";
9493
9494		if ( options.height === "auto" ) {
9495			this.element.css({
9496				minHeight: minContentHeight,
9497				maxHeight: maxContentHeight,
9498				height: "auto"
9499			});
9500		} else {
9501			this.element.height( Math.max( 0, options.height - nonContentHeight ) );
9502		}
9503
9504		if (this.uiDialog.is(":data(ui-resizable)") ) {
9505			this.uiDialog.resizable( "option", "minHeight", this._minHeight() );
9506		}
9507	},
9508
9509	_blockFrames: function() {
9510		this.iframeBlocks = this.document.find( "iframe" ).map(function() {
9511			var iframe = $( this );
9512
9513			return $( "<div>" )
9514				.css({
9515					position: "absolute",
9516					width: iframe.outerWidth(),
9517					height: iframe.outerHeight()
9518				})
9519				.appendTo( iframe.parent() )
9520				.offset( iframe.offset() )[0];
9521		});
9522	},
9523
9524	_unblockFrames: function() {
9525		if ( this.iframeBlocks ) {
9526			this.iframeBlocks.remove();
9527			delete this.iframeBlocks;
9528		}
9529	},
9530
9531	_allowInteraction: function( event ) {
9532		if ( $( event.target ).closest(".ui-dialog").length ) {
9533			return true;
9534		}
9535
9536		// TODO: Remove hack when datepicker implements
9537		// the .ui-front logic (#8989)
9538		return !!$( event.target ).closest(".ui-datepicker").length;
9539	},
9540
9541	_createOverlay: function() {
9542		if ( !this.options.modal ) {
9543			return;
9544		}
9545
9546		var that = this,
9547			widgetFullName = this.widgetFullName;
9548		if ( !$.ui.dialog.overlayInstances ) {
9549			// Prevent use of anchors and inputs.
9550			// We use a delay in case the overlay is created from an
9551			// event that we're going to be cancelling. (#2804)
9552			this._delay(function() {
9553				// Handle .dialog().dialog("close") (#4065)
9554				if ( $.ui.dialog.overlayInstances ) {
9555					this.document.bind( "focusin.dialog", function( event ) {
9556						if ( !that._allowInteraction( event ) ) {
9557							event.preventDefault();
9558							$(".ui-dialog:visible:last .ui-dialog-content")
9559								.data( widgetFullName )._focusTabbable();
9560						}
9561					});
9562				}
9563			});
9564		}
9565
9566		this.overlay = $("<div>")
9567			.addClass("ui-widget-overlay ui-front")
9568			.appendTo( this._appendTo() );
9569		this._on( this.overlay, {
9570			mousedown: "_keepFocus"
9571		});
9572		$.ui.dialog.overlayInstances++;
9573	},
9574
9575	_destroyOverlay: function() {
9576		if ( !this.options.modal ) {
9577			return;
9578		}
9579
9580		if ( this.overlay ) {
9581			$.ui.dialog.overlayInstances--;
9582
9583			if ( !$.ui.dialog.overlayInstances ) {
9584				this.document.unbind( "focusin.dialog" );
9585			}
9586			this.overlay.remove();
9587			this.overlay = null;
9588		}
9589	}
9590});
9591
9592$.ui.dialog.overlayInstances = 0;
9593
9594// DEPRECATED
9595if ( $.uiBackCompat !== false ) {
9596	// position option with array notation
9597	// just override with old implementation
9598	$.widget( "ui.dialog", $.ui.dialog, {
9599		_position: function() {
9600			var position = this.options.position,
9601				myAt = [],
9602				offset = [ 0, 0 ],
9603				isVisible;
9604
9605			if ( position ) {
9606				if ( typeof position === "string" || (typeof position === "object" && "0" in position ) ) {
9607					myAt = position.split ? position.split(" ") : [ position[0], position[1] ];
9608					if ( myAt.length === 1 ) {
9609						myAt[1] = myAt[0];
9610					}
9611
9612					$.each( [ "left", "top" ], function( i, offsetPosition ) {
9613						if ( +myAt[ i ] === myAt[ i ] ) {
9614							offset[ i ] = myAt[ i ];
9615							myAt[ i ] = offsetPosition;
9616						}
9617					});
9618
9619					position = {
9620						my: myAt[0] + (offset[0] < 0 ? offset[0] : "+" + offset[0]) + " " +
9621							myAt[1] + (offset[1] < 0 ? offset[1] : "+" + offset[1]),
9622						at: myAt.join(" ")
9623					};
9624				}
9625
9626				position = $.extend( {}, $.ui.dialog.prototype.options.position, position );
9627			} else {
9628				position = $.ui.dialog.prototype.options.position;
9629			}
9630
9631			// need to show the dialog to get the actual offset in the position plugin
9632			isVisible = this.uiDialog.is(":visible");
9633			if ( !isVisible ) {
9634				this.uiDialog.show();
9635			}
9636			this.uiDialog.position( position );
9637			if ( !isVisible ) {
9638				this.uiDialog.hide();
9639			}
9640		}
9641	});
9642}
9643
9644}( jQuery ) );
9645(function( $, undefined ) {
9646
9647$.widget( "ui.menu", {
9648	version: "1.10.4",
9649	defaultElement: "<ul>",
9650	delay: 300,
9651	options: {
9652		icons: {
9653			submenu: "ui-icon-carat-1-e"
9654		},
9655		menus: "ul",
9656		position: {
9657			my: "left top",
9658			at: "right top"
9659		},
9660		role: "menu",
9661
9662		// callbacks
9663		blur: null,
9664		focus: null,
9665		select: null
9666	},
9667
9668	_create: function() {
9669		this.activeMenu = this.element;
9670		// flag used to prevent firing of the click handler
9671		// as the event bubbles up through nested menus
9672		this.mouseHandled = false;
9673		this.element
9674			.uniqueId()
9675			.addClass( "ui-menu ui-widget ui-widget-content ui-corner-all" )
9676			.toggleClass( "ui-menu-icons", !!this.element.find( ".ui-icon" ).length )
9677			.attr({
9678				role: this.options.role,
9679				tabIndex: 0
9680			})
9681			// need to catch all clicks on disabled menu
9682			// not possible through _on
9683			.bind( "click" + this.eventNamespace, $.proxy(function( event ) {
9684				if ( this.options.disabled ) {
9685					event.preventDefault();
9686				}
9687			}, this ));
9688
9689		if ( this.options.disabled ) {
9690			this.element
9691				.addClass( "ui-state-disabled" )
9692				.attr( "aria-disabled", "true" );
9693		}
9694
9695		this._on({
9696			// Prevent focus from sticking to links inside menu after clicking
9697			// them (focus should always stay on UL during navigation).
9698			"mousedown .ui-menu-item > a": function( event ) {
9699				event.preventDefault();
9700			},
9701			"click .ui-state-disabled > a": function( event ) {
9702				event.preventDefault();
9703			},
9704			"click .ui-menu-item:has(a)": function( event ) {
9705				var target = $( event.target ).closest( ".ui-menu-item" );
9706				if ( !this.mouseHandled && target.not( ".ui-state-disabled" ).length ) {
9707					this.select( event );
9708
9709					// Only set the mouseHandled flag if the event will bubble, see #9469.
9710					if ( !event.isPropagationStopped() ) {
9711						this.mouseHandled = true;
9712					}
9713
9714					// Open submenu on click
9715					if ( target.has( ".ui-menu" ).length ) {
9716						this.expand( event );
9717					} else if ( !this.element.is( ":focus" ) && $( this.document[ 0 ].activeElement ).closest( ".ui-menu" ).length ) {
9718
9719						// Redirect focus to the menu
9720						this.element.trigger( "focus", [ true ] );
9721
9722						// If the active item is on the top level, let it stay active.
9723						// Otherwise, blur the active item since it is no longer visible.
9724						if ( this.active && this.active.parents( ".ui-menu" ).length === 1 ) {
9725							clearTimeout( this.timer );
9726						}
9727					}
9728				}
9729			},
9730			"mouseenter .ui-menu-item": function( event ) {
9731				var target = $( event.currentTarget );
9732				// Remove ui-state-active class from siblings of the newly focused menu item
9733				// to avoid a jump caused by adjacent elements both having a class with a border
9734				target.siblings().children( ".ui-state-active" ).removeClass( "ui-state-active" );
9735				this.focus( event, target );
9736			},
9737			mouseleave: "collapseAll",
9738			"mouseleave .ui-menu": "collapseAll",
9739			focus: function( event, keepActiveItem ) {
9740				// If there's already an active item, keep it active
9741				// If not, activate the first item
9742				var item = this.active || this.element.children( ".ui-menu-item" ).eq( 0 );
9743
9744				if ( !keepActiveItem ) {
9745					this.focus( event, item );
9746				}
9747			},
9748			blur: function( event ) {
9749				this._delay(function() {
9750					if ( !$.contains( this.element[0], this.document[0].activeElement ) ) {
9751						this.collapseAll( event );
9752					}
9753				});
9754			},
9755			keydown: "_keydown"
9756		});
9757
9758		this.refresh();
9759
vendor: 134,356 bytes, lines 9760-15008
9760		// Clicks outside of a menu collapse any open menus
9761		this._on( this.document, {
9762			click: function( event ) {
9763				if ( !$( event.target ).closest( ".ui-menu" ).length ) {
9764					this.collapseAll( event );
9765				}
9766
9767				// Reset the mouseHandled flag
9768				this.mouseHandled = false;
9769			}
9770		});
9771	},
9772
9773	_destroy: function() {
9774		// Destroy (sub)menus
9775		this.element
9776			.removeAttr( "aria-activedescendant" )
9777			.find( ".ui-menu" ).addBack()
9778				.removeClass( "ui-menu ui-widget ui-widget-content ui-corner-all ui-menu-icons" )
9779				.removeAttr( "role" )
9780				.removeAttr( "tabIndex" )
9781				.removeAttr( "aria-labelledby" )
9782				.removeAttr( "aria-expanded" )
9783				.removeAttr( "aria-hidden" )
9784				.removeAttr( "aria-disabled" )
9785				.removeUniqueId()
9786				.show();
9787
9788		// Destroy menu items
9789		this.element.find( ".ui-menu-item" )
9790			.removeClass( "ui-menu-item" )
9791			.removeAttr( "role" )
9792			.removeAttr( "aria-disabled" )
9793			.children( "a" )
9794				.removeUniqueId()
9795				.removeClass( "ui-corner-all ui-state-hover" )
9796				.removeAttr( "tabIndex" )
9797				.removeAttr( "role" )
9798				.removeAttr( "aria-haspopup" )
9799				.children().each( function() {
9800					var elem = $( this );
9801					if ( elem.data( "ui-menu-submenu-carat" ) ) {
9802						elem.remove();
9803					}
9804				});
9805
9806		// Destroy menu dividers
9807		this.element.find( ".ui-menu-divider" ).removeClass( "ui-menu-divider ui-widget-content" );
9808	},
9809
9810	_keydown: function( event ) {
9811		var match, prev, character, skip, regex,
9812			preventDefault = true;
9813
9814		function escape( value ) {
9815			return value.replace( /[\-\[\]{}()*+?.,\\\^$|#\s]/g, "\\$&" );
9816		}
9817
9818		switch ( event.keyCode ) {
9819		case $.ui.keyCode.PAGE_UP:
9820			this.previousPage( event );
9821			break;
9822		case $.ui.keyCode.PAGE_DOWN:
9823			this.nextPage( event );
9824			break;
9825		case $.ui.keyCode.HOME:
9826			this._move( "first", "first", event );
9827			break;
9828		case $.ui.keyCode.END:
9829			this._move( "last", "last", event );
9830			break;
9831		case $.ui.keyCode.UP:
9832			this.previous( event );
9833			break;
9834		case $.ui.keyCode.DOWN:
9835			this.next( event );
9836			break;
9837		case $.ui.keyCode.LEFT:
9838			this.collapse( event );
9839			break;
9840		case $.ui.keyCode.RIGHT:
9841			if ( this.active && !this.active.is( ".ui-state-disabled" ) ) {
9842				this.expand( event );
9843			}
9844			break;
9845		case $.ui.keyCode.ENTER:
9846		case $.ui.keyCode.SPACE:
9847			this._activate( event );
9848			break;
9849		case $.ui.keyCode.ESCAPE:
9850			this.collapse( event );
9851			break;
9852		default:
9853			preventDefault = false;
9854			prev = this.previousFilter || "";
9855			character = String.fromCharCode( event.keyCode );
9856			skip = false;
9857
9858			clearTimeout( this.filterTimer );
9859
9860			if ( character === prev ) {
9861				skip = true;
9862			} else {
9863				character = prev + character;
9864			}
9865
9866			regex = new RegExp( "^" + escape( character ), "i" );
9867			match = this.activeMenu.children( ".ui-menu-item" ).filter(function() {
9868				return regex.test( $( this ).children( "a" ).text() );
9869			});
9870			match = skip && match.index( this.active.next() ) !== -1 ?
9871				this.active.nextAll( ".ui-menu-item" ) :
9872				match;
9873
9874			// If no matches on the current filter, reset to the last character pressed
9875			// to move down the menu to the first item that starts with that character
9876			if ( !match.length ) {
9877				character = String.fromCharCode( event.keyCode );
9878				regex = new RegExp( "^" + escape( character ), "i" );
9879				match = this.activeMenu.children( ".ui-menu-item" ).filter(function() {
9880					return regex.test( $( this ).children( "a" ).text() );
9881				});
9882			}
9883
9884			if ( match.length ) {
9885				this.focus( event, match );
9886				if ( match.length > 1 ) {
9887					this.previousFilter = character;
9888					this.filterTimer = this._delay(function() {
9889						delete this.previousFilter;
9890					}, 1000 );
9891				} else {
9892					delete this.previousFilter;
9893				}
9894			} else {
9895				delete this.previousFilter;
9896			}
9897		}
9898
9899		if ( preventDefault ) {
9900			event.preventDefault();
9901		}
9902	},
9903
9904	_activate: function( event ) {
9905		if ( !this.active.is( ".ui-state-disabled" ) ) {
9906			if ( this.active.children( "a[aria-haspopup='true']" ).length ) {
9907				this.expand( event );
9908			} else {
9909				this.select( event );
9910			}
9911		}
9912	},
9913
9914	refresh: function() {
9915		var menus,
9916			icon = this.options.icons.submenu,
9917			submenus = this.element.find( this.options.menus );
9918
9919		this.element.toggleClass( "ui-menu-icons", !!this.element.find( ".ui-icon" ).length );
9920
9921		// Initialize nested menus
9922		submenus.filter( ":not(.ui-menu)" )
9923			.addClass( "ui-menu ui-widget ui-widget-content ui-corner-all" )
9924			.hide()
9925			.attr({
9926				role: this.options.role,
9927				"aria-hidden": "true",
9928				"aria-expanded": "false"
9929			})
9930			.each(function() {
9931				var menu = $( this ),
9932					item = menu.prev( "a" ),
9933					submenuCarat = $( "<span>" )
9934						.addClass( "ui-menu-icon ui-icon " + icon )
9935						.data( "ui-menu-submenu-carat", true );
9936
9937				item
9938					.attr( "aria-haspopup", "true" )
9939					.prepend( submenuCarat );
9940				menu.attr( "aria-labelledby", item.attr( "id" ) );
9941			});
9942
9943		menus = submenus.add( this.element );
9944
9945		// Don't refresh list items that are already adapted
9946		menus.children( ":not(.ui-menu-item):has(a)" )
9947			.addClass( "ui-menu-item" )
9948			.attr( "role", "presentation" )
9949			.children( "a" )
9950				.uniqueId()
9951				.addClass( "ui-corner-all" )
9952				.attr({
9953					tabIndex: -1,
9954					role: this._itemRole()
9955				});
9956
9957		// Initialize unlinked menu-items containing spaces and/or dashes only as dividers
9958		menus.children( ":not(.ui-menu-item)" ).each(function() {
9959			var item = $( this );
9960			// hyphen, em dash, en dash
9961			if ( !/[^\-\u2014\u2013\s]/.test( item.text() ) ) {
9962				item.addClass( "ui-widget-content ui-menu-divider" );
9963			}
9964		});
9965
9966		// Add aria-disabled attribute to any disabled menu item
9967		menus.children( ".ui-state-disabled" ).attr( "aria-disabled", "true" );
9968
9969		// If the active item has been removed, blur the menu
9970		if ( this.active && !$.contains( this.element[ 0 ], this.active[ 0 ] ) ) {
9971			this.blur();
9972		}
9973	},
9974
9975	_itemRole: function() {
9976		return {
9977			menu: "menuitem",
9978			listbox: "option"
9979		}[ this.options.role ];
9980	},
9981
9982	_setOption: function( key, value ) {
9983		if ( key === "icons" ) {
9984			this.element.find( ".ui-menu-icon" )
9985				.removeClass( this.options.icons.submenu )
9986				.addClass( value.submenu );
9987		}
9988		this._super( key, value );
9989	},
9990
9991	focus: function( event, item ) {
9992		var nested, focused;
9993		this.blur( event, event && event.type === "focus" );
9994
9995		this._scrollIntoView( item );
9996
9997		this.active = item.first();
9998		focused = this.active.children( "a" ).addClass( "ui-state-focus" );
9999		// Only update aria-activedescendant if there's a role
10000		// otherwise we assume focus is managed elsewhere
10001		if ( this.options.role ) {
10002			this.element.attr( "aria-activedescendant", focused.attr( "id" ) );
10003		}
10004
10005		// Highlight active parent menu item, if any
10006		this.active
10007			.parent()
10008			.closest( ".ui-menu-item" )
10009			.children( "a:first" )
10010			.addClass( "ui-state-active" );
10011
10012		if ( event && event.type === "keydown" ) {
10013			this._close();
10014		} else {
10015			this.timer = this._delay(function() {
10016				this._close();
10017			}, this.delay );
10018		}
10019
10020		nested = item.children( ".ui-menu" );
10021		if ( nested.length && event && ( /^mouse/.test( event.type ) ) ) {
10022			this._startOpening(nested);
10023		}
10024		this.activeMenu = item.parent();
10025
10026		this._trigger( "focus", event, { item: item } );
10027	},
10028
10029	_scrollIntoView: function( item ) {
10030		var borderTop, paddingTop, offset, scroll, elementHeight, itemHeight;
10031		if ( this._hasScroll() ) {
10032			borderTop = parseFloat( $.css( this.activeMenu[0], "borderTopWidth" ) ) || 0;
10033			paddingTop = parseFloat( $.css( this.activeMenu[0], "paddingTop" ) ) || 0;
10034			offset = item.offset().top - this.activeMenu.offset().top - borderTop - paddingTop;
10035			scroll = this.activeMenu.scrollTop();
10036			elementHeight = this.activeMenu.height();
10037			itemHeight = item.height();
10038
10039			if ( offset < 0 ) {
10040				this.activeMenu.scrollTop( scroll + offset );
10041			} else if ( offset + itemHeight > elementHeight ) {
10042				this.activeMenu.scrollTop( scroll + offset - elementHeight + itemHeight );
10043			}
10044		}
10045	},
10046
10047	blur: function( event, fromFocus ) {
10048		if ( !fromFocus ) {
10049			clearTimeout( this.timer );
10050		}
10051
10052		if ( !this.active ) {
10053			return;
10054		}
10055
10056		this.active.children( "a" ).removeClass( "ui-state-focus" );
10057		this.active = null;
10058
10059		this._trigger( "blur", event, { item: this.active } );
10060	},
10061
10062	_startOpening: function( submenu ) {
10063		clearTimeout( this.timer );
10064
10065		// Don't open if already open fixes a Firefox bug that caused a .5 pixel
10066		// shift in the submenu position when mousing over the carat icon
10067		if ( submenu.attr( "aria-hidden" ) !== "true" ) {
10068			return;
10069		}
10070
10071		this.timer = this._delay(function() {
10072			this._close();
10073			this._open( submenu );
10074		}, this.delay );
10075	},
10076
10077	_open: function( submenu ) {
10078		var position = $.extend({
10079			of: this.active
10080		}, this.options.position );
10081
10082		clearTimeout( this.timer );
10083		this.element.find( ".ui-menu" ).not( submenu.parents( ".ui-menu" ) )
10084			.hide()
10085			.attr( "aria-hidden", "true" );
10086
10087		submenu
10088			.show()
10089			.removeAttr( "aria-hidden" )
10090			.attr( "aria-expanded", "true" )
10091			.position( position );
10092	},
10093
10094	collapseAll: function( event, all ) {
10095		clearTimeout( this.timer );
10096		this.timer = this._delay(function() {
10097			// If we were passed an event, look for the submenu that contains the event
10098			var currentMenu = all ? this.element :
10099				$( event && event.target ).closest( this.element.find( ".ui-menu" ) );
10100
10101			// If we found no valid submenu ancestor, use the main menu to close all sub menus anyway
10102			if ( !currentMenu.length ) {
10103				currentMenu = this.element;
10104			}
10105
10106			this._close( currentMenu );
10107
10108			this.blur( event );
10109			this.activeMenu = currentMenu;
10110		}, this.delay );
10111	},
10112
10113	// With no arguments, closes the currently active menu - if nothing is active
10114	// it closes all menus.  If passed an argument, it will search for menus BELOW
10115	_close: function( startMenu ) {
10116		if ( !startMenu ) {
10117			startMenu = this.active ? this.active.parent() : this.element;
10118		}
10119
10120		startMenu
10121			.find( ".ui-menu" )
10122				.hide()
10123				.attr( "aria-hidden", "true" )
10124				.attr( "aria-expanded", "false" )
10125			.end()
10126			.find( "a.ui-state-active" )
10127				.removeClass( "ui-state-active" );
10128	},
10129
10130	collapse: function( event ) {
10131		var newItem = this.active &&
10132			this.active.parent().closest( ".ui-menu-item", this.element );
10133		if ( newItem && newItem.length ) {
10134			this._close();
10135			this.focus( event, newItem );
10136		}
10137	},
10138
10139	expand: function( event ) {
10140		var newItem = this.active &&
10141			this.active
10142				.children( ".ui-menu " )
10143				.children( ".ui-menu-item" )
10144				.first();
10145
10146		if ( newItem && newItem.length ) {
10147			this._open( newItem.parent() );
10148
10149			// Delay so Firefox will not hide activedescendant change in expanding submenu from AT
10150			this._delay(function() {
10151				this.focus( event, newItem );
10152			});
10153		}
10154	},
10155
10156	next: function( event ) {
10157		this._move( "next", "first", event );
10158	},
10159
10160	previous: function( event ) {
10161		this._move( "prev", "last", event );
10162	},
10163
10164	isFirstItem: function() {
10165		return this.active && !this.active.prevAll( ".ui-menu-item" ).length;
10166	},
10167
10168	isLastItem: function() {
10169		return this.active && !this.active.nextAll( ".ui-menu-item" ).length;
10170	},
10171
10172	_move: function( direction, filter, event ) {
10173		var next;
10174		if ( this.active ) {
10175			if ( direction === "first" || direction === "last" ) {
10176				next = this.active
10177					[ direction === "first" ? "prevAll" : "nextAll" ]( ".ui-menu-item" )
10178					.eq( -1 );
10179			} else {
10180				next = this.active
10181					[ direction + "All" ]( ".ui-menu-item" )
10182					.eq( 0 );
10183			}
10184		}
10185		if ( !next || !next.length || !this.active ) {
10186			next = this.activeMenu.children( ".ui-menu-item" )[ filter ]();
10187		}
10188
10189		this.focus( event, next );
10190	},
10191
10192	nextPage: function( event ) {
10193		var item, base, height;
10194
10195		if ( !this.active ) {
10196			this.next( event );
10197			return;
10198		}
10199		if ( this.isLastItem() ) {
10200			return;
10201		}
10202		if ( this._hasScroll() ) {
10203			base = this.active.offset().top;
10204			height = this.element.height();
10205			this.active.nextAll( ".ui-menu-item" ).each(function() {
10206				item = $( this );
10207				return item.offset().top - base - height < 0;
10208			});
10209
10210			this.focus( event, item );
10211		} else {
10212			this.focus( event, this.activeMenu.children( ".ui-menu-item" )
10213				[ !this.active ? "first" : "last" ]() );
10214		}
10215	},
10216
10217	previousPage: function( event ) {
10218		var item, base, height;
10219		if ( !this.active ) {
10220			this.next( event );
10221			return;
10222		}
10223		if ( this.isFirstItem() ) {
10224			return;
10225		}
10226		if ( this._hasScroll() ) {
10227			base = this.active.offset().top;
10228			height = this.element.height();
10229			this.active.prevAll( ".ui-menu-item" ).each(function() {
10230				item = $( this );
10231				return item.offset().top - base + height > 0;
10232			});
10233
10234			this.focus( event, item );
10235		} else {
10236			this.focus( event, this.activeMenu.children( ".ui-menu-item" ).first() );
10237		}
10238	},
10239
10240	_hasScroll: function() {
10241		return this.element.outerHeight() < this.element.prop( "scrollHeight" );
10242	},
10243
10244	select: function( event ) {
10245		// TODO: It should never be possible to not have an active item at this
10246		// point, but the tests don't trigger mouseenter before click.
10247		this.active = this.active || $( event.target ).closest( ".ui-menu-item" );
10248		var ui = { item: this.active };
10249		if ( !this.active.has( ".ui-menu" ).length ) {
10250			this.collapseAll( event, true );
10251		}
10252		this._trigger( "select", event, ui );
10253	}
10254});
10255
10256}( jQuery ));
10257(function( $, undefined ) {
10258
10259$.widget( "ui.progressbar", {
10260	version: "1.10.4",
10261	options: {
10262		max: 100,
10263		value: 0,
10264
10265		change: null,
10266		complete: null
10267	},
10268
10269	min: 0,
10270
10271	_create: function() {
10272		// Constrain initial value
10273		this.oldValue = this.options.value = this._constrainedValue();
10274
10275		this.element
10276			.addClass( "ui-progressbar ui-widget ui-widget-content ui-corner-all" )
10277			.attr({
10278				// Only set static values, aria-valuenow and aria-valuemax are
10279				// set inside _refreshValue()
10280				role: "progressbar",
10281				"aria-valuemin": this.min
10282			});
10283
10284		this.valueDiv = $( "<div class='ui-progressbar-value ui-widget-header ui-corner-left'></div>" )
10285			.appendTo( this.element );
10286
10287		this._refreshValue();
10288	},
10289
10290	_destroy: function() {
10291		this.element
10292			.removeClass( "ui-progressbar ui-widget ui-widget-content ui-corner-all" )
10293			.removeAttr( "role" )
10294			.removeAttr( "aria-valuemin" )
10295			.removeAttr( "aria-valuemax" )
10296			.removeAttr( "aria-valuenow" );
10297
10298		this.valueDiv.remove();
10299	},
10300
10301	value: function( newValue ) {
10302		if ( newValue === undefined ) {
10303			return this.options.value;
10304		}
10305
10306		this.options.value = this._constrainedValue( newValue );
10307		this._refreshValue();
10308	},
10309
10310	_constrainedValue: function( newValue ) {
10311		if ( newValue === undefined ) {
10312			newValue = this.options.value;
10313		}
10314
10315		this.indeterminate = newValue === false;
10316
10317		// sanitize value
10318		if ( typeof newValue !== "number" ) {
10319			newValue = 0;
10320		}
10321
10322		return this.indeterminate ? false :
10323			Math.min( this.options.max, Math.max( this.min, newValue ) );
10324	},
10325
10326	_setOptions: function( options ) {
10327		// Ensure "value" option is set after other values (like max)
10328		var value = options.value;
10329		delete options.value;
10330
10331		this._super( options );
10332
10333		this.options.value = this._constrainedValue( value );
10334		this._refreshValue();
10335	},
10336
10337	_setOption: function( key, value ) {
10338		if ( key === "max" ) {
10339			// Don't allow a max less than min
10340			value = Math.max( this.min, value );
10341		}
10342
10343		this._super( key, value );
10344	},
10345
10346	_percentage: function() {
10347		return this.indeterminate ? 100 : 100 * ( this.options.value - this.min ) / ( this.options.max - this.min );
10348	},
10349
10350	_refreshValue: function() {
10351		var value = this.options.value,
10352			percentage = this._percentage();
10353
10354		this.valueDiv
10355			.toggle( this.indeterminate || value > this.min )
10356			.toggleClass( "ui-corner-right", value === this.options.max )
10357			.width( percentage.toFixed(0) + "%" );
10358
10359		this.element.toggleClass( "ui-progressbar-indeterminate", this.indeterminate );
10360
10361		if ( this.indeterminate ) {
10362			this.element.removeAttr( "aria-valuenow" );
10363			if ( !this.overlayDiv ) {
10364				this.overlayDiv = $( "<div class='ui-progressbar-overlay'></div>" ).appendTo( this.valueDiv );
10365			}
10366		} else {
10367			this.element.attr({
10368				"aria-valuemax": this.options.max,
10369				"aria-valuenow": value
10370			});
10371			if ( this.overlayDiv ) {
10372				this.overlayDiv.remove();
10373				this.overlayDiv = null;
10374			}
10375		}
10376
10377		if ( this.oldValue !== value ) {
10378			this.oldValue = value;
10379			this._trigger( "change" );
10380		}
10381		if ( value === this.options.max ) {
10382			this._trigger( "complete" );
10383		}
10384	}
10385});
10386
10387})( jQuery );
10388(function( $, undefined ) {
10389
10390// number of pages in a slider
10391// (how many times can you page up/down to go through the whole range)
10392var numPages = 5;
10393
10394$.widget( "ui.slider", $.ui.mouse, {
10395	version: "1.10.4",
10396	widgetEventPrefix: "slide",
10397
10398	options: {
10399		animate: false,
10400		distance: 0,
10401		max: 100,
10402		min: 0,
10403		orientation: "horizontal",
10404		range: false,
10405		step: 1,
10406		value: 0,
10407		values: null,
10408
10409		// callbacks
10410		change: null,
10411		slide: null,
10412		start: null,
10413		stop: null
10414	},
10415
10416	_create: function() {
10417		this._keySliding = false;
10418		this._mouseSliding = false;
10419		this._animateOff = true;
10420		this._handleIndex = null;
10421		this._detectOrientation();
10422		this._mouseInit();
10423
10424		this.element
10425			.addClass( "ui-slider" +
10426				" ui-slider-" + this.orientation +
10427				" ui-widget" +
10428				" ui-widget-content" +
10429				" ui-corner-all");
10430
10431		this._refresh();
10432		this._setOption( "disabled", this.options.disabled );
10433
10434		this._animateOff = false;
10435	},
10436
10437	_refresh: function() {
10438		this._createRange();
10439		this._createHandles();
10440		this._setupEvents();
10441		this._refreshValue();
10442	},
10443
10444	_createHandles: function() {
10445		var i, handleCount,
10446			options = this.options,
10447			existingHandles = this.element.find( ".ui-slider-handle" ).addClass( "ui-state-default ui-corner-all" ),
10448			handle = "<a class='ui-slider-handle ui-state-default ui-corner-all' href='#'></a>",
10449			handles = [];
10450
10451		handleCount = ( options.values && options.values.length ) || 1;
10452
10453		if ( existingHandles.length > handleCount ) {
10454			existingHandles.slice( handleCount ).remove();
10455			existingHandles = existingHandles.slice( 0, handleCount );
10456		}
10457
10458		for ( i = existingHandles.length; i < handleCount; i++ ) {
10459			handles.push( handle );
10460		}
10461
10462		this.handles = existingHandles.add( $( handles.join( "" ) ).appendTo( this.element ) );
10463
10464		this.handle = this.handles.eq( 0 );
10465
10466		this.handles.each(function( i ) {
10467			$( this ).data( "ui-slider-handle-index", i );
10468		});
10469	},
10470
10471	_createRange: function() {
10472		var options = this.options,
10473			classes = "";
10474
10475		if ( options.range ) {
10476			if ( options.range === true ) {
10477				if ( !options.values ) {
10478					options.values = [ this._valueMin(), this._valueMin() ];
10479				} else if ( options.values.length && options.values.length !== 2 ) {
10480					options.values = [ options.values[0], options.values[0] ];
10481				} else if ( $.isArray( options.values ) ) {
10482					options.values = options.values.slice(0);
10483				}
10484			}
10485
10486			if ( !this.range || !this.range.length ) {
10487				this.range = $( "<div></div>" )
10488					.appendTo( this.element );
10489
10490				classes = "ui-slider-range" +
10491				// note: this isn't the most fittingly semantic framework class for this element,
10492				// but worked best visually with a variety of themes
10493				" ui-widget-header ui-corner-all";
10494			} else {
10495				this.range.removeClass( "ui-slider-range-min ui-slider-range-max" )
10496					// Handle range switching from true to min/max
10497					.css({
10498						"left": "",
10499						"bottom": ""
10500					});
10501			}
10502
10503			this.range.addClass( classes +
10504				( ( options.range === "min" || options.range === "max" ) ? " ui-slider-range-" + options.range : "" ) );
10505		} else {
10506			if ( this.range ) {
10507				this.range.remove();
10508			}
10509			this.range = null;
10510		}
10511	},
10512
10513	_setupEvents: function() {
10514		var elements = this.handles.add( this.range ).filter( "a" );
10515		this._off( elements );
10516		this._on( elements, this._handleEvents );
10517		this._hoverable( elements );
10518		this._focusable( elements );
10519	},
10520
10521	_destroy: function() {
10522		this.handles.remove();
10523		if ( this.range ) {
10524			this.range.remove();
10525		}
10526
10527		this.element
10528			.removeClass( "ui-slider" +
10529				" ui-slider-horizontal" +
10530				" ui-slider-vertical" +
10531				" ui-widget" +
10532				" ui-widget-content" +
10533				" ui-corner-all" );
10534
10535		this._mouseDestroy();
10536	},
10537
10538	_mouseCapture: function( event ) {
10539		var position, normValue, distance, closestHandle, index, allowed, offset, mouseOverHandle,
10540			that = this,
10541			o = this.options;
10542
10543		if ( o.disabled ) {
10544			return false;
10545		}
10546
10547		this.elementSize = {
10548			width: this.element.outerWidth(),
10549			height: this.element.outerHeight()
10550		};
10551		this.elementOffset = this.element.offset();
10552
10553		position = { x: event.pageX, y: event.pageY };
10554		normValue = this._normValueFromMouse( position );
10555		distance = this._valueMax() - this._valueMin() + 1;
10556		this.handles.each(function( i ) {
10557			var thisDistance = Math.abs( normValue - that.values(i) );
10558			if (( distance > thisDistance ) ||
10559				( distance === thisDistance &&
10560					(i === that._lastChangedValue || that.values(i) === o.min ))) {
10561				distance = thisDistance;
10562				closestHandle = $( this );
10563				index = i;
10564			}
10565		});
10566
10567		allowed = this._start( event, index );
10568		if ( allowed === false ) {
10569			return false;
10570		}
10571		this._mouseSliding = true;
10572
10573		this._handleIndex = index;
10574
10575		closestHandle
10576			.addClass( "ui-state-active" )
10577			.focus();
10578
10579		offset = closestHandle.offset();
10580		mouseOverHandle = !$( event.target ).parents().addBack().is( ".ui-slider-handle" );
10581		this._clickOffset = mouseOverHandle ? { left: 0, top: 0 } : {
10582			left: event.pageX - offset.left - ( closestHandle.width() / 2 ),
10583			top: event.pageY - offset.top -
10584				( closestHandle.height() / 2 ) -
10585				( parseInt( closestHandle.css("borderTopWidth"), 10 ) || 0 ) -
10586				( parseInt( closestHandle.css("borderBottomWidth"), 10 ) || 0) +
10587				( parseInt( closestHandle.css("marginTop"), 10 ) || 0)
10588		};
10589
10590		if ( !this.handles.hasClass( "ui-state-hover" ) ) {
10591			this._slide( event, index, normValue );
10592		}
10593		this._animateOff = true;
10594		return true;
10595	},
10596
10597	_mouseStart: function() {
10598		return true;
10599	},
10600
10601	_mouseDrag: function( event ) {
10602		var position = { x: event.pageX, y: event.pageY },
10603			normValue = this._normValueFromMouse( position );
10604
10605		this._slide( event, this._handleIndex, normValue );
10606
10607		return false;
10608	},
10609
10610	_mouseStop: function( event ) {
10611		this.handles.removeClass( "ui-state-active" );
10612		this._mouseSliding = false;
10613
10614		this._stop( event, this._handleIndex );
10615		this._change( event, this._handleIndex );
10616
10617		this._handleIndex = null;
10618		this._clickOffset = null;
10619		this._animateOff = false;
10620
10621		return false;
10622	},
10623
10624	_detectOrientation: function() {
10625		this.orientation = ( this.options.orientation === "vertical" ) ? "vertical" : "horizontal";
10626	},
10627
10628	_normValueFromMouse: function( position ) {
10629		var pixelTotal,
10630			pixelMouse,
10631			percentMouse,
10632			valueTotal,
10633			valueMouse;
10634
10635		if ( this.orientation === "horizontal" ) {
10636			pixelTotal = this.elementSize.width;
10637			pixelMouse = position.x - this.elementOffset.left - ( this._clickOffset ? this._clickOffset.left : 0 );
10638		} else {
10639			pixelTotal = this.elementSize.height;
10640			pixelMouse = position.y - this.elementOffset.top - ( this._clickOffset ? this._clickOffset.top : 0 );
10641		}
10642
10643		percentMouse = ( pixelMouse / pixelTotal );
10644		if ( percentMouse > 1 ) {
10645			percentMouse = 1;
10646		}
10647		if ( percentMouse < 0 ) {
10648			percentMouse = 0;
10649		}
10650		if ( this.orientation === "vertical" ) {
10651			percentMouse = 1 - percentMouse;
10652		}
10653
10654		valueTotal = this._valueMax() - this._valueMin();
10655		valueMouse = this._valueMin() + percentMouse * valueTotal;
10656
10657		return this._trimAlignValue( valueMouse );
10658	},
10659
10660	_start: function( event, index ) {
10661		var uiHash = {
10662			handle: this.handles[ index ],
10663			value: this.value()
10664		};
10665		if ( this.options.values && this.options.values.length ) {
10666			uiHash.value = this.values( index );
10667			uiHash.values = this.values();
10668		}
10669		return this._trigger( "start", event, uiHash );
10670	},
10671
10672	_slide: function( event, index, newVal ) {
10673		var otherVal,
10674			newValues,
10675			allowed;
10676
10677		if ( this.options.values && this.options.values.length ) {
10678			otherVal = this.values( index ? 0 : 1 );
10679
10680			if ( ( this.options.values.length === 2 && this.options.range === true ) &&
10681					( ( index === 0 && newVal > otherVal) || ( index === 1 && newVal < otherVal ) )
10682				) {
10683				newVal = otherVal;
10684			}
10685
10686			if ( newVal !== this.values( index ) ) {
10687				newValues = this.values();
10688				newValues[ index ] = newVal;
10689				// A slide can be canceled by returning false from the slide callback
10690				allowed = this._trigger( "slide", event, {
10691					handle: this.handles[ index ],
10692					value: newVal,
10693					values: newValues
10694				} );
10695				otherVal = this.values( index ? 0 : 1 );
10696				if ( allowed !== false ) {
10697					this.values( index, newVal );
10698				}
10699			}
10700		} else {
10701			if ( newVal !== this.value() ) {
10702				// A slide can be canceled by returning false from the slide callback
10703				allowed = this._trigger( "slide", event, {
10704					handle: this.handles[ index ],
10705					value: newVal
10706				} );
10707				if ( allowed !== false ) {
10708					this.value( newVal );
10709				}
10710			}
10711		}
10712	},
10713
10714	_stop: function( event, index ) {
10715		var uiHash = {
10716			handle: this.handles[ index ],
10717			value: this.value()
10718		};
10719		if ( this.options.values && this.options.values.length ) {
10720			uiHash.value = this.values( index );
10721			uiHash.values = this.values();
10722		}
10723
10724		this._trigger( "stop", event, uiHash );
10725	},
10726
10727	_change: function( event, index ) {
10728		if ( !this._keySliding && !this._mouseSliding ) {
10729			var uiHash = {
10730				handle: this.handles[ index ],
10731				value: this.value()
10732			};
10733			if ( this.options.values && this.options.values.length ) {
10734				uiHash.value = this.values( index );
10735				uiHash.values = this.values();
10736			}
10737
10738			//store the last changed value index for reference when handles overlap
10739			this._lastChangedValue = index;
10740
10741			this._trigger( "change", event, uiHash );
10742		}
10743	},
10744
10745	value: function( newValue ) {
10746		if ( arguments.length ) {
10747			this.options.value = this._trimAlignValue( newValue );
10748			this._refreshValue();
10749			this._change( null, 0 );
10750			return;
10751		}
10752
10753		return this._value();
10754	},
10755
10756	values: function( index, newValue ) {
10757		var vals,
10758			newValues,
10759			i;
10760
10761		if ( arguments.length > 1 ) {
10762			this.options.values[ index ] = this._trimAlignValue( newValue );
10763			this._refreshValue();
10764			this._change( null, index );
10765			return;
10766		}
10767
10768		if ( arguments.length ) {
10769			if ( $.isArray( arguments[ 0 ] ) ) {
10770				vals = this.options.values;
10771				newValues = arguments[ 0 ];
10772				for ( i = 0; i < vals.length; i += 1 ) {
10773					vals[ i ] = this._trimAlignValue( newValues[ i ] );
10774					this._change( null, i );
10775				}
10776				this._refreshValue();
10777			} else {
10778				if ( this.options.values && this.options.values.length ) {
10779					return this._values( index );
10780				} else {
10781					return this.value();
10782				}
10783			}
10784		} else {
10785			return this._values();
10786		}
10787	},
10788
10789	_setOption: function( key, value ) {
10790		var i,
10791			valsLength = 0;
10792
10793		if ( key === "range" && this.options.range === true ) {
10794			if ( value === "min" ) {
10795				this.options.value = this._values( 0 );
10796				this.options.values = null;
10797			} else if ( value === "max" ) {
10798				this.options.value = this._values( this.options.values.length-1 );
10799				this.options.values = null;
10800			}
10801		}
10802
10803		if ( $.isArray( this.options.values ) ) {
10804			valsLength = this.options.values.length;
10805		}
10806
10807		$.Widget.prototype._setOption.apply( this, arguments );
10808
10809		switch ( key ) {
10810			case "orientation":
10811				this._detectOrientation();
10812				this.element
10813					.removeClass( "ui-slider-horizontal ui-slider-vertical" )
10814					.addClass( "ui-slider-" + this.orientation );
10815				this._refreshValue();
10816				break;
10817			case "value":
10818				this._animateOff = true;
10819				this._refreshValue();
10820				this._change( null, 0 );
10821				this._animateOff = false;
10822				break;
10823			case "values":
10824				this._animateOff = true;
10825				this._refreshValue();
10826				for ( i = 0; i < valsLength; i += 1 ) {
10827					this._change( null, i );
10828				}
10829				this._animateOff = false;
10830				break;
10831			case "min":
10832			case "max":
10833				this._animateOff = true;
10834				this._refreshValue();
10835				this._animateOff = false;
10836				break;
10837			case "range":
10838				this._animateOff = true;
10839				this._refresh();
10840				this._animateOff = false;
10841				break;
10842		}
10843	},
10844
10845	//internal value getter
10846	// _value() returns value trimmed by min and max, aligned by step
10847	_value: function() {
10848		var val = this.options.value;
10849		val = this._trimAlignValue( val );
10850
10851		return val;
10852	},
10853
10854	//internal values getter
10855	// _values() returns array of values trimmed by min and max, aligned by step
10856	// _values( index ) returns single value trimmed by min and max, aligned by step
10857	_values: function( index ) {
10858		var val,
10859			vals,
10860			i;
10861
10862		if ( arguments.length ) {
10863			val = this.options.values[ index ];
10864			val = this._trimAlignValue( val );
10865
10866			return val;
10867		} else if ( this.options.values && this.options.values.length ) {
10868			// .slice() creates a copy of the array
10869			// this copy gets trimmed by min and max and then returned
10870			vals = this.options.values.slice();
10871			for ( i = 0; i < vals.length; i+= 1) {
10872				vals[ i ] = this._trimAlignValue( vals[ i ] );
10873			}
10874
10875			return vals;
10876		} else {
10877			return [];
10878		}
10879	},
10880
10881	// returns the step-aligned value that val is closest to, between (inclusive) min and max
10882	_trimAlignValue: function( val ) {
10883		if ( val <= this._valueMin() ) {
10884			return this._valueMin();
10885		}
10886		if ( val >= this._valueMax() ) {
10887			return this._valueMax();
10888		}
10889		var step = ( this.options.step > 0 ) ? this.options.step : 1,
10890			valModStep = (val - this._valueMin()) % step,
10891			alignValue = val - valModStep;
10892
10893		if ( Math.abs(valModStep) * 2 >= step ) {
10894			alignValue += ( valModStep > 0 ) ? step : ( -step );
10895		}
10896
10897		// Since JavaScript has problems with large floats, round
10898		// the final value to 5 digits after the decimal point (see #4124)
10899		return parseFloat( alignValue.toFixed(5) );
10900	},
10901
10902	_valueMin: function() {
10903		return this.options.min;
10904	},
10905
10906	_valueMax: function() {
10907		return this.options.max;
10908	},
10909
10910	_refreshValue: function() {
10911		var lastValPercent, valPercent, value, valueMin, valueMax,
10912			oRange = this.options.range,
10913			o = this.options,
10914			that = this,
10915			animate = ( !this._animateOff ) ? o.animate : false,
10916			_set = {};
10917
10918		if ( this.options.values && this.options.values.length ) {
10919			this.handles.each(function( i ) {
10920				valPercent = ( that.values(i) - that._valueMin() ) / ( that._valueMax() - that._valueMin() ) * 100;
10921				_set[ that.orientation === "horizontal" ? "left" : "bottom" ] = valPercent + "%";
10922				$( this ).stop( 1, 1 )[ animate ? "animate" : "css" ]( _set, o.animate );
10923				if ( that.options.range === true ) {
10924					if ( that.orientation === "horizontal" ) {
10925						if ( i === 0 ) {
10926							that.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { left: valPercent + "%" }, o.animate );
10927						}
10928						if ( i === 1 ) {
10929							that.range[ animate ? "animate" : "css" ]( { width: ( valPercent - lastValPercent ) + "%" }, { queue: false, duration: o.animate } );
10930						}
10931					} else {
10932						if ( i === 0 ) {
10933							that.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { bottom: ( valPercent ) + "%" }, o.animate );
10934						}
10935						if ( i === 1 ) {
10936							that.range[ animate ? "animate" : "css" ]( { height: ( valPercent - lastValPercent ) + "%" }, { queue: false, duration: o.animate } );
10937						}
10938					}
10939				}
10940				lastValPercent = valPercent;
10941			});
10942		} else {
10943			value = this.value();
10944			valueMin = this._valueMin();
10945			valueMax = this._valueMax();
10946			valPercent = ( valueMax !== valueMin ) ?
10947					( value - valueMin ) / ( valueMax - valueMin ) * 100 :
10948					0;
10949			_set[ this.orientation === "horizontal" ? "left" : "bottom" ] = valPercent + "%";
10950			this.handle.stop( 1, 1 )[ animate ? "animate" : "css" ]( _set, o.animate );
10951
10952			if ( oRange === "min" && this.orientation === "horizontal" ) {
10953				this.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { width: valPercent + "%" }, o.animate );
10954			}
10955			if ( oRange === "max" && this.orientation === "horizontal" ) {
10956				this.range[ animate ? "animate" : "css" ]( { width: ( 100 - valPercent ) + "%" }, { queue: false, duration: o.animate } );
10957			}
10958			if ( oRange === "min" && this.orientation === "vertical" ) {
10959				this.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { height: valPercent + "%" }, o.animate );
10960			}
10961			if ( oRange === "max" && this.orientation === "vertical" ) {
10962				this.range[ animate ? "animate" : "css" ]( { height: ( 100 - valPercent ) + "%" }, { queue: false, duration: o.animate } );
10963			}
10964		}
10965	},
10966
10967	_handleEvents: {
10968		keydown: function( event ) {
10969			var allowed, curVal, newVal, step,
10970				index = $( event.target ).data( "ui-slider-handle-index" );
10971
10972			switch ( event.keyCode ) {
10973				case $.ui.keyCode.HOME:
10974				case $.ui.keyCode.END:
10975				case $.ui.keyCode.PAGE_UP:
10976				case $.ui.keyCode.PAGE_DOWN:
10977				case $.ui.keyCode.UP:
10978				case $.ui.keyCode.RIGHT:
10979				case $.ui.keyCode.DOWN:
10980				case $.ui.keyCode.LEFT:
10981					event.preventDefault();
10982					if ( !this._keySliding ) {
10983						this._keySliding = true;
10984						$( event.target ).addClass( "ui-state-active" );
10985						allowed = this._start( event, index );
10986						if ( allowed === false ) {
10987							return;
10988						}
10989					}
10990					break;
10991			}
10992
10993			step = this.options.step;
10994			if ( this.options.values && this.options.values.length ) {
10995				curVal = newVal = this.values( index );
10996			} else {
10997				curVal = newVal = this.value();
10998			}
10999
11000			switch ( event.keyCode ) {
11001				case $.ui.keyCode.HOME:
11002					newVal = this._valueMin();
11003					break;
11004				case $.ui.keyCode.END:
11005					newVal = this._valueMax();
11006					break;
11007				case $.ui.keyCode.PAGE_UP:
11008					newVal = this._trimAlignValue( curVal + ( (this._valueMax() - this._valueMin()) / numPages ) );
11009					break;
11010				case $.ui.keyCode.PAGE_DOWN:
11011					newVal = this._trimAlignValue( curVal - ( (this._valueMax() - this._valueMin()) / numPages ) );
11012					break;
11013				case $.ui.keyCode.UP:
11014				case $.ui.keyCode.RIGHT:
11015					if ( curVal === this._valueMax() ) {
11016						return;
11017					}
11018					newVal = this._trimAlignValue( curVal + step );
11019					break;
11020				case $.ui.keyCode.DOWN:
11021				case $.ui.keyCode.LEFT:
11022					if ( curVal === this._valueMin() ) {
11023						return;
11024					}
11025					newVal = this._trimAlignValue( curVal - step );
11026					break;
11027			}
11028
11029			this._slide( event, index, newVal );
11030		},
11031		click: function( event ) {
11032			event.preventDefault();
11033		},
11034		keyup: function( event ) {
11035			var index = $( event.target ).data( "ui-slider-handle-index" );
11036
11037			if ( this._keySliding ) {
11038				this._keySliding = false;
11039				this._stop( event, index );
11040				this._change( event, index );
11041				$( event.target ).removeClass( "ui-state-active" );
11042			}
11043		}
11044	}
11045
11046});
11047
11048}(jQuery));
11049(function( $ ) {
11050
11051function modifier( fn ) {
11052	return function() {
11053		var previous = this.element.val();
11054		fn.apply( this, arguments );
11055		this._refresh();
11056		if ( previous !== this.element.val() ) {
11057			this._trigger( "change" );
11058		}
11059	};
11060}
11061
11062$.widget( "ui.spinner", {
11063	version: "1.10.4",
11064	defaultElement: "<input>",
11065	widgetEventPrefix: "spin",
11066	options: {
11067		culture: null,
11068		icons: {
11069			down: "ui-icon-triangle-1-s",
11070			up: "ui-icon-triangle-1-n"
11071		},
11072		incremental: true,
11073		max: null,
11074		min: null,
11075		numberFormat: null,
11076		page: 10,
11077		step: 1,
11078
11079		change: null,
11080		spin: null,
11081		start: null,
11082		stop: null
11083	},
11084
11085	_create: function() {
11086		// handle string values that need to be parsed
11087		this._setOption( "max", this.options.max );
11088		this._setOption( "min", this.options.min );
11089		this._setOption( "step", this.options.step );
11090
11091		// Only format if there is a value, prevents the field from being marked
11092		// as invalid in Firefox, see #9573.
11093		if ( this.value() !== "" ) {
11094			// Format the value, but don't constrain.
11095			this._value( this.element.val(), true );
11096		}
11097
11098		this._draw();
11099		this._on( this._events );
11100		this._refresh();
11101
11102		// turning off autocomplete prevents the browser from remembering the
11103		// value when navigating through history, so we re-enable autocomplete
11104		// if the page is unloaded before the widget is destroyed. #7790
11105		this._on( this.window, {
11106			beforeunload: function() {
11107				this.element.removeAttr( "autocomplete" );
11108			}
11109		});
11110	},
11111
11112	_getCreateOptions: function() {
11113		var options = {},
11114			element = this.element;
11115
11116		$.each( [ "min", "max", "step" ], function( i, option ) {
11117			var value = element.attr( option );
11118			if ( value !== undefined && value.length ) {
11119				options[ option ] = value;
11120			}
11121		});
11122
11123		return options;
11124	},
11125
11126	_events: {
11127		keydown: function( event ) {
11128			if ( this._start( event ) && this._keydown( event ) ) {
11129				event.preventDefault();
11130			}
11131		},
11132		keyup: "_stop",
11133		focus: function() {
11134			this.previous = this.element.val();
11135		},
11136		blur: function( event ) {
11137			if ( this.cancelBlur ) {
11138				delete this.cancelBlur;
11139				return;
11140			}
11141
11142			this._stop();
11143			this._refresh();
11144			if ( this.previous !== this.element.val() ) {
11145				this._trigger( "change", event );
11146			}
11147		},
11148		mousewheel: function( event, delta ) {
11149			if ( !delta ) {
11150				return;
11151			}
11152			if ( !this.spinning && !this._start( event ) ) {
11153				return false;
11154			}
11155
11156			this._spin( (delta > 0 ? 1 : -1) * this.options.step, event );
11157			clearTimeout( this.mousewheelTimer );
11158			this.mousewheelTimer = this._delay(function() {
11159				if ( this.spinning ) {
11160					this._stop( event );
11161				}
11162			}, 100 );
11163			event.preventDefault();
11164		},
11165		"mousedown .ui-spinner-button": function( event ) {
11166			var previous;
11167
11168			// We never want the buttons to have focus; whenever the user is
11169			// interacting with the spinner, the focus should be on the input.
11170			// If the input is focused then this.previous is properly set from
11171			// when the input first received focus. If the input is not focused
11172			// then we need to set this.previous based on the value before spinning.
11173			previous = this.element[0] === this.document[0].activeElement ?
11174				this.previous : this.element.val();
11175			function checkFocus() {
11176				var isActive = this.element[0] === this.document[0].activeElement;
11177				if ( !isActive ) {
11178					this.element.focus();
11179					this.previous = previous;
11180					// support: IE
11181					// IE sets focus asynchronously, so we need to check if focus
11182					// moved off of the input because the user clicked on the button.
11183					this._delay(function() {
11184						this.previous = previous;
11185					});
11186				}
11187			}
11188
11189			// ensure focus is on (or stays on) the text field
11190			event.preventDefault();
11191			checkFocus.call( this );
11192
11193			// support: IE
11194			// IE doesn't prevent moving focus even with event.preventDefault()
11195			// so we set a flag to know when we should ignore the blur event
11196			// and check (again) if focus moved off of the input.
11197			this.cancelBlur = true;
11198			this._delay(function() {
11199				delete this.cancelBlur;
11200				checkFocus.call( this );
11201			});
11202
11203			if ( this._start( event ) === false ) {
11204				return;
11205			}
11206
11207			this._repeat( null, $( event.currentTarget ).hasClass( "ui-spinner-up" ) ? 1 : -1, event );
11208		},
11209		"mouseup .ui-spinner-button": "_stop",
11210		"mouseenter .ui-spinner-button": function( event ) {
11211			// button will add ui-state-active if mouse was down while mouseleave and kept down
11212			if ( !$( event.currentTarget ).hasClass( "ui-state-active" ) ) {
11213				return;
11214			}
11215
11216			if ( this._start( event ) === false ) {
11217				return false;
11218			}
11219			this._repeat( null, $( event.currentTarget ).hasClass( "ui-spinner-up" ) ? 1 : -1, event );
11220		},
11221		// TODO: do we really want to consider this a stop?
11222		// shouldn't we just stop the repeater and wait until mouseup before
11223		// we trigger the stop event?
11224		"mouseleave .ui-spinner-button": "_stop"
11225	},
11226
11227	_draw: function() {
11228		var uiSpinner = this.uiSpinner = this.element
11229			.addClass( "ui-spinner-input" )
11230			.attr( "autocomplete", "off" )
11231			.wrap( this._uiSpinnerHtml() )
11232			.parent()
11233				// add buttons
11234				.append( this._buttonHtml() );
11235
11236		this.element.attr( "role", "spinbutton" );
11237
11238		// button bindings
11239		this.buttons = uiSpinner.find( ".ui-spinner-button" )
11240			.attr( "tabIndex", -1 )
11241			.button()
11242			.removeClass( "ui-corner-all" );
11243
11244		// IE 6 doesn't understand height: 50% for the buttons
11245		// unless the wrapper has an explicit height
11246		if ( this.buttons.height() > Math.ceil( uiSpinner.height() * 0.5 ) &&
11247				uiSpinner.height() > 0 ) {
11248			uiSpinner.height( uiSpinner.height() );
11249		}
11250
11251		// disable spinner if element was already disabled
11252		if ( this.options.disabled ) {
11253			this.disable();
11254		}
11255	},
11256
11257	_keydown: function( event ) {
11258		var options = this.options,
11259			keyCode = $.ui.keyCode;
11260
11261		switch ( event.keyCode ) {
11262		case keyCode.UP:
11263			this._repeat( null, 1, event );
11264			return true;
11265		case keyCode.DOWN:
11266			this._repeat( null, -1, event );
11267			return true;
11268		case keyCode.PAGE_UP:
11269			this._repeat( null, options.page, event );
11270			return true;
11271		case keyCode.PAGE_DOWN:
11272			this._repeat( null, -options.page, event );
11273			return true;
11274		}
11275
11276		return false;
11277	},
11278
11279	_uiSpinnerHtml: function() {
11280		return "<span class='ui-spinner ui-widget ui-widget-content ui-corner-all'></span>";
11281	},
11282
11283	_buttonHtml: function() {
11284		return "" +
11285			"<a class='ui-spinner-button ui-spinner-up ui-corner-tr'>" +
11286				"<span class='ui-icon " + this.options.icons.up + "'>&#9650;</span>" +
11287			"</a>" +
11288			"<a class='ui-spinner-button ui-spinner-down ui-corner-br'>" +
11289				"<span class='ui-icon " + this.options.icons.down + "'>&#9660;</span>" +
11290			"</a>";
11291	},
11292
11293	_start: function( event ) {
11294		if ( !this.spinning && this._trigger( "start", event ) === false ) {
11295			return false;
11296		}
11297
11298		if ( !this.counter ) {
11299			this.counter = 1;
11300		}
11301		this.spinning = true;
11302		return true;
11303	},
11304
11305	_repeat: function( i, steps, event ) {
11306		i = i || 500;
11307
11308		clearTimeout( this.timer );
11309		this.timer = this._delay(function() {
11310			this._repeat( 40, steps, event );
11311		}, i );
11312
11313		this._spin( steps * this.options.step, event );
11314	},
11315
11316	_spin: function( step, event ) {
11317		var value = this.value() || 0;
11318
11319		if ( !this.counter ) {
11320			this.counter = 1;
11321		}
11322
11323		value = this._adjustValue( value + step * this._increment( this.counter ) );
11324
11325		if ( !this.spinning || this._trigger( "spin", event, { value: value } ) !== false) {
11326			this._value( value );
11327			this.counter++;
11328		}
11329	},
11330
11331	_increment: function( i ) {
11332		var incremental = this.options.incremental;
11333
11334		if ( incremental ) {
11335			return $.isFunction( incremental ) ?
11336				incremental( i ) :
11337				Math.floor( i*i*i/50000 - i*i/500 + 17*i/200 + 1 );
11338		}
11339
11340		return 1;
11341	},
11342
11343	_precision: function() {
11344		var precision = this._precisionOf( this.options.step );
11345		if ( this.options.min !== null ) {
11346			precision = Math.max( precision, this._precisionOf( this.options.min ) );
11347		}
11348		return precision;
11349	},
11350
11351	_precisionOf: function( num ) {
11352		var str = num.toString(),
11353			decimal = str.indexOf( "." );
11354		return decimal === -1 ? 0 : str.length - decimal - 1;
11355	},
11356
11357	_adjustValue: function( value ) {
11358		var base, aboveMin,
11359			options = this.options;
11360
11361		// make sure we're at a valid step
11362		// - find out where we are relative to the base (min or 0)
11363		base = options.min !== null ? options.min : 0;
11364		aboveMin = value - base;
11365		// - round to the nearest step
11366		aboveMin = Math.round(aboveMin / options.step) * options.step;
11367		// - rounding is based on 0, so adjust back to our base
11368		value = base + aboveMin;
11369
11370		// fix precision from bad JS floating point math
11371		value = parseFloat( value.toFixed( this._precision() ) );
11372
11373		// clamp the value
11374		if ( options.max !== null && value > options.max) {
11375			return options.max;
11376		}
11377		if ( options.min !== null && value < options.min ) {
11378			return options.min;
11379		}
11380
11381		return value;
11382	},
11383
11384	_stop: function( event ) {
11385		if ( !this.spinning ) {
11386			return;
11387		}
11388
11389		clearTimeout( this.timer );
11390		clearTimeout( this.mousewheelTimer );
11391		this.counter = 0;
11392		this.spinning = false;
11393		this._trigger( "stop", event );
11394	},
11395
11396	_setOption: function( key, value ) {
11397		if ( key === "culture" || key === "numberFormat" ) {
11398			var prevValue = this._parse( this.element.val() );
11399			this.options[ key ] = value;
11400			this.element.val( this._format( prevValue ) );
11401			return;
11402		}
11403
11404		if ( key === "max" || key === "min" || key === "step" ) {
11405			if ( typeof value === "string" ) {
11406				value = this._parse( value );
11407			}
11408		}
11409		if ( key === "icons" ) {
11410			this.buttons.first().find( ".ui-icon" )
11411				.removeClass( this.options.icons.up )
11412				.addClass( value.up );
11413			this.buttons.last().find( ".ui-icon" )
11414				.removeClass( this.options.icons.down )
11415				.addClass( value.down );
11416		}
11417
11418		this._super( key, value );
11419
11420		if ( key === "disabled" ) {
11421			if ( value ) {
11422				this.element.prop( "disabled", true );
11423				this.buttons.button( "disable" );
11424			} else {
11425				this.element.prop( "disabled", false );
11426				this.buttons.button( "enable" );
11427			}
11428		}
11429	},
11430
11431	_setOptions: modifier(function( options ) {
11432		this._super( options );
11433		this._value( this.element.val() );
11434	}),
11435
11436	_parse: function( val ) {
11437		if ( typeof val === "string" && val !== "" ) {
11438			val = window.Globalize && this.options.numberFormat ?
11439				Globalize.parseFloat( val, 10, this.options.culture ) : +val;
11440		}
11441		return val === "" || isNaN( val ) ? null : val;
11442	},
11443
11444	_format: function( value ) {
11445		if ( value === "" ) {
11446			return "";
11447		}
11448		return window.Globalize && this.options.numberFormat ?
11449			Globalize.format( value, this.options.numberFormat, this.options.culture ) :
11450			value;
11451	},
11452
11453	_refresh: function() {
11454		this.element.attr({
11455			"aria-valuemin": this.options.min,
11456			"aria-valuemax": this.options.max,
11457			// TODO: what should we do with values that can't be parsed?
11458			"aria-valuenow": this._parse( this.element.val() )
11459		});
11460	},
11461
11462	// update the value without triggering change
11463	_value: function( value, allowAny ) {
11464		var parsed;
11465		if ( value !== "" ) {
11466			parsed = this._parse( value );
11467			if ( parsed !== null ) {
11468				if ( !allowAny ) {
11469					parsed = this._adjustValue( parsed );
11470				}
11471				value = this._format( parsed );
11472			}
11473		}
11474		this.element.val( value );
11475		this._refresh();
11476	},
11477
11478	_destroy: function() {
11479		this.element
11480			.removeClass( "ui-spinner-input" )
11481			.prop( "disabled", false )
11482			.removeAttr( "autocomplete" )
11483			.removeAttr( "role" )
11484			.removeAttr( "aria-valuemin" )
11485			.removeAttr( "aria-valuemax" )
11486			.removeAttr( "aria-valuenow" );
11487		this.uiSpinner.replaceWith( this.element );
11488	},
11489
11490	stepUp: modifier(function( steps ) {
11491		this._stepUp( steps );
11492	}),
11493	_stepUp: function( steps ) {
11494		if ( this._start() ) {
11495			this._spin( (steps || 1) * this.options.step );
11496			this._stop();
11497		}
11498	},
11499
11500	stepDown: modifier(function( steps ) {
11501		this._stepDown( steps );
11502	}),
11503	_stepDown: function( steps ) {
11504		if ( this._start() ) {
11505			this._spin( (steps || 1) * -this.options.step );
11506			this._stop();
11507		}
11508	},
11509
11510	pageUp: modifier(function( pages ) {
11511		this._stepUp( (pages || 1) * this.options.page );
11512	}),
11513
11514	pageDown: modifier(function( pages ) {
11515		this._stepDown( (pages || 1) * this.options.page );
11516	}),
11517
11518	value: function( newVal ) {
11519		if ( !arguments.length ) {
11520			return this._parse( this.element.val() );
11521		}
11522		modifier( this._value ).call( this, newVal );
11523	},
11524
11525	widget: function() {
11526		return this.uiSpinner;
11527	}
11528});
11529
11530}( jQuery ) );
11531(function( $, undefined ) {
11532
11533var tabId = 0,
11534	rhash = /#.*$/;
11535
11536function getNextTabId() {
11537	return ++tabId;
11538}
11539
11540function isLocal( anchor ) {
11541	// support: IE7
11542	// IE7 doesn't normalize the href property when set via script (#9317)
11543	anchor = anchor.cloneNode( false );
11544
11545	return anchor.hash.length > 1 &&
11546		decodeURIComponent( anchor.href.replace( rhash, "" ) ) ===
11547			decodeURIComponent( location.href.replace( rhash, "" ) );
11548}
11549
11550$.widget( "ui.tabs", {
11551	version: "1.10.4",
11552	delay: 300,
11553	options: {
11554		active: null,
11555		collapsible: false,
11556		event: "click",
11557		heightStyle: "content",
11558		hide: null,
11559		show: null,
11560
11561		// callbacks
11562		activate: null,
11563		beforeActivate: null,
11564		beforeLoad: null,
11565		load: null
11566	},
11567
11568	_create: function() {
11569		var that = this,
11570			options = this.options;
11571
11572		this.running = false;
11573
11574		this.element
11575			.addClass( "ui-tabs ui-widget ui-widget-content ui-corner-all" )
11576			.toggleClass( "ui-tabs-collapsible", options.collapsible )
11577			// Prevent users from focusing disabled tabs via click
11578			.delegate( ".ui-tabs-nav > li", "mousedown" + this.eventNamespace, function( event ) {
11579				if ( $( this ).is( ".ui-state-disabled" ) ) {
11580					event.preventDefault();
11581				}
11582			})
11583			// support: IE <9
11584			// Preventing the default action in mousedown doesn't prevent IE
11585			// from focusing the element, so if the anchor gets focused, blur.
11586			// We don't have to worry about focusing the previously focused
11587			// element since clicking on a non-focusable element should focus
11588			// the body anyway.
11589			.delegate( ".ui-tabs-anchor", "focus" + this.eventNamespace, function() {
11590				if ( $( this ).closest( "li" ).is( ".ui-state-disabled" ) ) {
11591					this.blur();
11592				}
11593			});
11594
11595		this._processTabs();
11596		options.active = this._initialActive();
11597
11598		// Take disabling tabs via class attribute from HTML
11599		// into account and update option properly.
11600		if ( $.isArray( options.disabled ) ) {
11601			options.disabled = $.unique( options.disabled.concat(
11602				$.map( this.tabs.filter( ".ui-state-disabled" ), function( li ) {
11603					return that.tabs.index( li );
11604				})
11605			) ).sort();
11606		}
11607
11608		// check for length avoids error when initializing empty list
11609		if ( this.options.active !== false && this.anchors.length ) {
11610			this.active = this._findActive( options.active );
11611		} else {
11612			this.active = $();
11613		}
11614
11615		this._refresh();
11616
11617		if ( this.active.length ) {
11618			this.load( options.active );
11619		}
11620	},
11621
11622	_initialActive: function() {
11623		var active = this.options.active,
11624			collapsible = this.options.collapsible,
11625			locationHash = location.hash.substring( 1 );
11626
11627		if ( active === null ) {
11628			// check the fragment identifier in the URL
11629			if ( locationHash ) {
11630				this.tabs.each(function( i, tab ) {
11631					if ( $( tab ).attr( "aria-controls" ) === locationHash ) {
11632						active = i;
11633						return false;
11634					}
11635				});
11636			}
11637
11638			// check for a tab marked active via a class
11639			if ( active === null ) {
11640				active = this.tabs.index( this.tabs.filter( ".ui-tabs-active" ) );
11641			}
11642
11643			// no active tab, set to false
11644			if ( active === null || active === -1 ) {
11645				active = this.tabs.length ? 0 : false;
11646			}
11647		}
11648
11649		// handle numbers: negative, out of range
11650		if ( active !== false ) {
11651			active = this.tabs.index( this.tabs.eq( active ) );
11652			if ( active === -1 ) {
11653				active = collapsible ? false : 0;
11654			}
11655		}
11656
11657		// don't allow collapsible: false and active: false
11658		if ( !collapsible && active === false && this.anchors.length ) {
11659			active = 0;
11660		}
11661
11662		return active;
11663	},
11664
11665	_getCreateEventData: function() {
11666		return {
11667			tab: this.active,
11668			panel: !this.active.length ? $() : this._getPanelForTab( this.active )
11669		};
11670	},
11671
11672	_tabKeydown: function( event ) {
11673		var focusedTab = $( this.document[0].activeElement ).closest( "li" ),
11674			selectedIndex = this.tabs.index( focusedTab ),
11675			goingForward = true;
11676
11677		if ( this._handlePageNav( event ) ) {
11678			return;
11679		}
11680
11681		switch ( event.keyCode ) {
11682			case $.ui.keyCode.RIGHT:
11683			case $.ui.keyCode.DOWN:
11684				selectedIndex++;
11685				break;
11686			case $.ui.keyCode.UP:
11687			case $.ui.keyCode.LEFT:
11688				goingForward = false;
11689				selectedIndex--;
11690				break;
11691			case $.ui.keyCode.END:
11692				selectedIndex = this.anchors.length - 1;
11693				break;
11694			case $.ui.keyCode.HOME:
11695				selectedIndex = 0;
11696				break;
11697			case $.ui.keyCode.SPACE:
11698				// Activate only, no collapsing
11699				event.preventDefault();
11700				clearTimeout( this.activating );
11701				this._activate( selectedIndex );
11702				return;
11703			case $.ui.keyCode.ENTER:
11704				// Toggle (cancel delayed activation, allow collapsing)
11705				event.preventDefault();
11706				clearTimeout( this.activating );
11707				// Determine if we should collapse or activate
11708				this._activate( selectedIndex === this.options.active ? false : selectedIndex );
11709				return;
11710			default:
11711				return;
11712		}
11713
11714		// Focus the appropriate tab, based on which key was pressed
11715		event.preventDefault();
11716		clearTimeout( this.activating );
11717		selectedIndex = this._focusNextTab( selectedIndex, goingForward );
11718
11719		// Navigating with control key will prevent automatic activation
11720		if ( !event.ctrlKey ) {
11721			// Update aria-selected immediately so that AT think the tab is already selected.
11722			// Otherwise AT may confuse the user by stating that they need to activate the tab,
11723			// but the tab will already be activated by the time the announcement finishes.
11724			focusedTab.attr( "aria-selected", "false" );
11725			this.tabs.eq( selectedIndex ).attr( "aria-selected", "true" );
11726
11727			this.activating = this._delay(function() {
11728				this.option( "active", selectedIndex );
11729			}, this.delay );
11730		}
11731	},
11732
11733	_panelKeydown: function( event ) {
11734		if ( this._handlePageNav( event ) ) {
11735			return;
11736		}
11737
11738		// Ctrl+up moves focus to the current tab
11739		if ( event.ctrlKey && event.keyCode === $.ui.keyCode.UP ) {
11740			event.preventDefault();
11741			this.active.focus();
11742		}
11743	},
11744
11745	// Alt+page up/down moves focus to the previous/next tab (and activates)
11746	_handlePageNav: function( event ) {
11747		if ( event.altKey && event.keyCode === $.ui.keyCode.PAGE_UP ) {
11748			this._activate( this._focusNextTab( this.options.active - 1, false ) );
11749			return true;
11750		}
11751		if ( event.altKey && event.keyCode === $.ui.keyCode.PAGE_DOWN ) {
11752			this._activate( this._focusNextTab( this.options.active + 1, true ) );
11753			return true;
11754		}
11755	},
11756
11757	_findNextTab: function( index, goingForward ) {
11758		var lastTabIndex = this.tabs.length - 1;
11759
11760		function constrain() {
11761			if ( index > lastTabIndex ) {
11762				index = 0;
11763			}
11764			if ( index < 0 ) {
11765				index = lastTabIndex;
11766			}
11767			return index;
11768		}
11769
11770		while ( $.inArray( constrain(), this.options.disabled ) !== -1 ) {
11771			index = goingForward ? index + 1 : index - 1;
11772		}
11773
11774		return index;
11775	},
11776
11777	_focusNextTab: function( index, goingForward ) {
11778		index = this._findNextTab( index, goingForward );
11779		this.tabs.eq( index ).focus();
11780		return index;
11781	},
11782
11783	_setOption: function( key, value ) {
11784		if ( key === "active" ) {
11785			// _activate() will handle invalid values and update this.options
11786			this._activate( value );
11787			return;
11788		}
11789
11790		if ( key === "disabled" ) {
11791			// don't use the widget factory's disabled handling
11792			this._setupDisabled( value );
11793			return;
11794		}
11795
11796		this._super( key, value);
11797
11798		if ( key === "collapsible" ) {
11799			this.element.toggleClass( "ui-tabs-collapsible", value );
11800			// Setting collapsible: false while collapsed; open first panel
11801			if ( !value && this.options.active === false ) {
11802				this._activate( 0 );
11803			}
11804		}
11805
11806		if ( key === "event" ) {
11807			this._setupEvents( value );
11808		}
11809
11810		if ( key === "heightStyle" ) {
11811			this._setupHeightStyle( value );
11812		}
11813	},
11814
11815	_tabId: function( tab ) {
11816		return tab.attr( "aria-controls" ) || "ui-tabs-" + getNextTabId();
11817	},
11818
11819	_sanitizeSelector: function( hash ) {
11820		return hash ? hash.replace( /[!"$%&'()*+,.\/:;<=>?@\[\]\^`{|}~]/g, "\\$&" ) : "";
11821	},
11822
11823	refresh: function() {
11824		var options = this.options,
11825			lis = this.tablist.children( ":has(a[href])" );
11826
11827		// get disabled tabs from class attribute from HTML
11828		// this will get converted to a boolean if needed in _refresh()
11829		options.disabled = $.map( lis.filter( ".ui-state-disabled" ), function( tab ) {
11830			return lis.index( tab );
11831		});
11832
11833		this._processTabs();
11834
11835		// was collapsed or no tabs
11836		if ( options.active === false || !this.anchors.length ) {
11837			options.active = false;
11838			this.active = $();
11839		// was active, but active tab is gone
11840		} else if ( this.active.length && !$.contains( this.tablist[ 0 ], this.active[ 0 ] ) ) {
11841			// all remaining tabs are disabled
11842			if ( this.tabs.length === options.disabled.length ) {
11843				options.active = false;
11844				this.active = $();
11845			// activate previous tab
11846			} else {
11847				this._activate( this._findNextTab( Math.max( 0, options.active - 1 ), false ) );
11848			}
11849		// was active, active tab still exists
11850		} else {
11851			// make sure active index is correct
11852			options.active = this.tabs.index( this.active );
11853		}
11854
11855		this._refresh();
11856	},
11857
11858	_refresh: function() {
11859		this._setupDisabled( this.options.disabled );
11860		this._setupEvents( this.options.event );
11861		this._setupHeightStyle( this.options.heightStyle );
11862
11863		this.tabs.not( this.active ).attr({
11864			"aria-selected": "false",
11865			tabIndex: -1
11866		});
11867		this.panels.not( this._getPanelForTab( this.active ) )
11868			.hide()
11869			.attr({
11870				"aria-expanded": "false",
11871				"aria-hidden": "true"
11872			});
11873
11874		// Make sure one tab is in the tab order
11875		if ( !this.active.length ) {
11876			this.tabs.eq( 0 ).attr( "tabIndex", 0 );
11877		} else {
11878			this.active
11879				.addClass( "ui-tabs-active ui-state-active" )
11880				.attr({
11881					"aria-selected": "true",
11882					tabIndex: 0
11883				});
11884			this._getPanelForTab( this.active )
11885				.show()
11886				.attr({
11887					"aria-expanded": "true",
11888					"aria-hidden": "false"
11889				});
11890		}
11891	},
11892
11893	_processTabs: function() {
11894		var that = this;
11895
11896		this.tablist = this._getList()
11897			.addClass( "ui-tabs-nav ui-helper-reset ui-helper-clearfix ui-widget-header ui-corner-all" )
11898			.attr( "role", "tablist" );
11899
11900		this.tabs = this.tablist.find( "> li:has(a[href])" )
11901			.addClass( "ui-state-default ui-corner-top" )
11902			.attr({
11903				role: "tab",
11904				tabIndex: -1
11905			});
11906
11907		this.anchors = this.tabs.map(function() {
11908				return $( "a", this )[ 0 ];
11909			})
11910			.addClass( "ui-tabs-anchor" )
11911			.attr({
11912				role: "presentation",
11913				tabIndex: -1
11914			});
11915
11916		this.panels = $();
11917
11918		this.anchors.each(function( i, anchor ) {
11919			var selector, panel, panelId,
11920				anchorId = $( anchor ).uniqueId().attr( "id" ),
11921				tab = $( anchor ).closest( "li" ),
11922				originalAriaControls = tab.attr( "aria-controls" );
11923
11924			// inline tab
11925			if ( isLocal( anchor ) ) {
11926				selector = anchor.hash;
11927				panel = that.element.find( that._sanitizeSelector( selector ) );
11928			// remote tab
11929			} else {
11930				panelId = that._tabId( tab );
11931				selector = "#" + panelId;
11932				panel = that.element.find( selector );
11933				if ( !panel.length ) {
11934					panel = that._createPanel( panelId );
11935					panel.insertAfter( that.panels[ i - 1 ] || that.tablist );
11936				}
11937				panel.attr( "aria-live", "polite" );
11938			}
11939
11940			if ( panel.length) {
11941				that.panels = that.panels.add( panel );
11942			}
11943			if ( originalAriaControls ) {
11944				tab.data( "ui-tabs-aria-controls", originalAriaControls );
11945			}
11946			tab.attr({
11947				"aria-controls": selector.substring( 1 ),
11948				"aria-labelledby": anchorId
11949			});
11950			panel.attr( "aria-labelledby", anchorId );
11951		});
11952
11953		this.panels
11954			.addClass( "ui-tabs-panel ui-widget-content ui-corner-bottom" )
11955			.attr( "role", "tabpanel" );
11956	},
11957
11958	// allow overriding how to find the list for rare usage scenarios (#7715)
11959	_getList: function() {
11960		return this.tablist || this.element.find( "ol,ul" ).eq( 0 );
11961	},
11962
11963	_createPanel: function( id ) {
11964		return $( "<div>" )
11965			.attr( "id", id )
11966			.addClass( "ui-tabs-panel ui-widget-content ui-corner-bottom" )
11967			.data( "ui-tabs-destroy", true );
11968	},
11969
11970	_setupDisabled: function( disabled ) {
11971		if ( $.isArray( disabled ) ) {
11972			if ( !disabled.length ) {
11973				disabled = false;
11974			} else if ( disabled.length === this.anchors.length ) {
11975				disabled = true;
11976			}
11977		}
11978
11979		// disable tabs
11980		for ( var i = 0, li; ( li = this.tabs[ i ] ); i++ ) {
11981			if ( disabled === true || $.inArray( i, disabled ) !== -1 ) {
11982				$( li )
11983					.addClass( "ui-state-disabled" )
11984					.attr( "aria-disabled", "true" );
11985			} else {
11986				$( li )
11987					.removeClass( "ui-state-disabled" )
11988					.removeAttr( "aria-disabled" );
11989			}
11990		}
11991
11992		this.options.disabled = disabled;
11993	},
11994
11995	_setupEvents: function( event ) {
11996		var events = {
11997			click: function( event ) {
11998				event.preventDefault();
11999			}
12000		};
12001		if ( event ) {
12002			$.each( event.split(" "), function( index, eventName ) {
12003				events[ eventName ] = "_eventHandler";
12004			});
12005		}
12006
12007		this._off( this.anchors.add( this.tabs ).add( this.panels ) );
12008		this._on( this.anchors, events );
12009		this._on( this.tabs, { keydown: "_tabKeydown" } );
12010		this._on( this.panels, { keydown: "_panelKeydown" } );
12011
12012		this._focusable( this.tabs );
12013		this._hoverable( this.tabs );
12014	},
12015
12016	_setupHeightStyle: function( heightStyle ) {
12017		var maxHeight,
12018			parent = this.element.parent();
12019
12020		if ( heightStyle === "fill" ) {
12021			maxHeight = parent.height();
12022			maxHeight -= this.element.outerHeight() - this.element.height();
12023
12024			this.element.siblings( ":visible" ).each(function() {
12025				var elem = $( this ),
12026					position = elem.css( "position" );
12027
12028				if ( position === "absolute" || position === "fixed" ) {
12029					return;
12030				}
12031				maxHeight -= elem.outerHeight( true );
12032			});
12033
12034			this.element.children().not( this.panels ).each(function() {
12035				maxHeight -= $( this ).outerHeight( true );
12036			});
12037
12038			this.panels.each(function() {
12039				$( this ).height( Math.max( 0, maxHeight -
12040					$( this ).innerHeight() + $( this ).height() ) );
12041			})
12042			.css( "overflow", "auto" );
12043		} else if ( heightStyle === "auto" ) {
12044			maxHeight = 0;
12045			this.panels.each(function() {
12046				maxHeight = Math.max( maxHeight, $( this ).height( "" ).height() );
12047			}).height( maxHeight );
12048		}
12049	},
12050
12051	_eventHandler: function( event ) {
12052		var options = this.options,
12053			active = this.active,
12054			anchor = $( event.currentTarget ),
12055			tab = anchor.closest( "li" ),
12056			clickedIsActive = tab[ 0 ] === active[ 0 ],
12057			collapsing = clickedIsActive && options.collapsible,
12058			toShow = collapsing ? $() : this._getPanelForTab( tab ),
12059			toHide = !active.length ? $() : this._getPanelForTab( active ),
12060			eventData = {
12061				oldTab: active,
12062				oldPanel: toHide,
12063				newTab: collapsing ? $() : tab,
12064				newPanel: toShow
12065			};
12066
12067		event.preventDefault();
12068
12069		if ( tab.hasClass( "ui-state-disabled" ) ||
12070				// tab is already loading
12071				tab.hasClass( "ui-tabs-loading" ) ||
12072				// can't switch durning an animation
12073				this.running ||
12074				// click on active header, but not collapsible
12075				( clickedIsActive && !options.collapsible ) ||
12076				// allow canceling activation
12077				( this._trigger( "beforeActivate", event, eventData ) === false ) ) {
12078			return;
12079		}
12080
12081		options.active = collapsing ? false : this.tabs.index( tab );
12082
12083		this.active = clickedIsActive ? $() : tab;
12084		if ( this.xhr ) {
12085			this.xhr.abort();
12086		}
12087
12088		if ( !toHide.length && !toShow.length ) {
12089			$.error( "jQuery UI Tabs: Mismatching fragment identifier." );
12090		}
12091
12092		if ( toShow.length ) {
12093			this.load( this.tabs.index( tab ), event );
12094		}
12095		this._toggle( event, eventData );
12096	},
12097
12098	// handles show/hide for selecting tabs
12099	_toggle: function( event, eventData ) {
12100		var that = this,
12101			toShow = eventData.newPanel,
12102			toHide = eventData.oldPanel;
12103
12104		this.running = true;
12105
12106		function complete() {
12107			that.running = false;
12108			that._trigger( "activate", event, eventData );
12109		}
12110
12111		function show() {
12112			eventData.newTab.closest( "li" ).addClass( "ui-tabs-active ui-state-active" );
12113
12114			if ( toShow.length && that.options.show ) {
12115				that._show( toShow, that.options.show, complete );
12116			} else {
12117				toShow.show();
12118				complete();
12119			}
12120		}
12121
12122		// start out by hiding, then showing, then completing
12123		if ( toHide.length && this.options.hide ) {
12124			this._hide( toHide, this.options.hide, function() {
12125				eventData.oldTab.closest( "li" ).removeClass( "ui-tabs-active ui-state-active" );
12126				show();
12127			});
12128		} else {
12129			eventData.oldTab.closest( "li" ).removeClass( "ui-tabs-active ui-state-active" );
12130			toHide.hide();
12131			show();
12132		}
12133
12134		toHide.attr({
12135			"aria-expanded": "false",
12136			"aria-hidden": "true"
12137		});
12138		eventData.oldTab.attr( "aria-selected", "false" );
12139		// If we're switching tabs, remove the old tab from the tab order.
12140		// If we're opening from collapsed state, remove the previous tab from the tab order.
12141		// If we're collapsing, then keep the collapsing tab in the tab order.
12142		if ( toShow.length && toHide.length ) {
12143			eventData.oldTab.attr( "tabIndex", -1 );
12144		} else if ( toShow.length ) {
12145			this.tabs.filter(function() {
12146				return $( this ).attr( "tabIndex" ) === 0;
12147			})
12148			.attr( "tabIndex", -1 );
12149		}
12150
12151		toShow.attr({
12152			"aria-expanded": "true",
12153			"aria-hidden": "false"
12154		});
12155		eventData.newTab.attr({
12156			"aria-selected": "true",
12157			tabIndex: 0
12158		});
12159	},
12160
12161	_activate: function( index ) {
12162		var anchor,
12163			active = this._findActive( index );
12164
12165		// trying to activate the already active panel
12166		if ( active[ 0 ] === this.active[ 0 ] ) {
12167			return;
12168		}
12169
12170		// trying to collapse, simulate a click on the current active header
12171		if ( !active.length ) {
12172			active = this.active;
12173		}
12174
12175		anchor = active.find( ".ui-tabs-anchor" )[ 0 ];
12176		this._eventHandler({
12177			target: anchor,
12178			currentTarget: anchor,
12179			preventDefault: $.noop
12180		});
12181	},
12182
12183	_findActive: function( index ) {
12184		return index === false ? $() : this.tabs.eq( index );
12185	},
12186
12187	_getIndex: function( index ) {
12188		// meta-function to give users option to provide a href string instead of a numerical index.
12189		if ( typeof index === "string" ) {
12190			index = this.anchors.index( this.anchors.filter( "[href$='" + index + "']" ) );
12191		}
12192
12193		return index;
12194	},
12195
12196	_destroy: function() {
12197		if ( this.xhr ) {
12198			this.xhr.abort();
12199		}
12200
12201		this.element.removeClass( "ui-tabs ui-widget ui-widget-content ui-corner-all ui-tabs-collapsible" );
12202
12203		this.tablist
12204			.removeClass( "ui-tabs-nav ui-helper-reset ui-helper-clearfix ui-widget-header ui-corner-all" )
12205			.removeAttr( "role" );
12206
12207		this.anchors
12208			.removeClass( "ui-tabs-anchor" )
12209			.removeAttr( "role" )
12210			.removeAttr( "tabIndex" )
12211			.removeUniqueId();
12212
12213		this.tabs.add( this.panels ).each(function() {
12214			if ( $.data( this, "ui-tabs-destroy" ) ) {
12215				$( this ).remove();
12216			} else {
12217				$( this )
12218					.removeClass( "ui-state-default ui-state-active ui-state-disabled " +
12219						"ui-corner-top ui-corner-bottom ui-widget-content ui-tabs-active ui-tabs-panel" )
12220					.removeAttr( "tabIndex" )
12221					.removeAttr( "aria-live" )
12222					.removeAttr( "aria-busy" )
12223					.removeAttr( "aria-selected" )
12224					.removeAttr( "aria-labelledby" )
12225					.removeAttr( "aria-hidden" )
12226					.removeAttr( "aria-expanded" )
12227					.removeAttr( "role" );
12228			}
12229		});
12230
12231		this.tabs.each(function() {
12232			var li = $( this ),
12233				prev = li.data( "ui-tabs-aria-controls" );
12234			if ( prev ) {
12235				li
12236					.attr( "aria-controls", prev )
12237					.removeData( "ui-tabs-aria-controls" );
12238			} else {
12239				li.removeAttr( "aria-controls" );
12240			}
12241		});
12242
12243		this.panels.show();
12244
12245		if ( this.options.heightStyle !== "content" ) {
12246			this.panels.css( "height", "" );
12247		}
12248	},
12249
12250	enable: function( index ) {
12251		var disabled = this.options.disabled;
12252		if ( disabled === false ) {
12253			return;
12254		}
12255
12256		if ( index === undefined ) {
12257			disabled = false;
12258		} else {
12259			index = this._getIndex( index );
12260			if ( $.isArray( disabled ) ) {
12261				disabled = $.map( disabled, function( num ) {
12262					return num !== index ? num : null;
12263				});
12264			} else {
12265				disabled = $.map( this.tabs, function( li, num ) {
12266					return num !== index ? num : null;
12267				});
12268			}
12269		}
12270		this._setupDisabled( disabled );
12271	},
12272
12273	disable: function( index ) {
12274		var disabled = this.options.disabled;
12275		if ( disabled === true ) {
12276			return;
12277		}
12278
12279		if ( index === undefined ) {
12280			disabled = true;
12281		} else {
12282			index = this._getIndex( index );
12283			if ( $.inArray( index, disabled ) !== -1 ) {
12284				return;
12285			}
12286			if ( $.isArray( disabled ) ) {
12287				disabled = $.merge( [ index ], disabled ).sort();
12288			} else {
12289				disabled = [ index ];
12290			}
12291		}
12292		this._setupDisabled( disabled );
12293	},
12294
12295	load: function( index, event ) {
12296		index = this._getIndex( index );
12297		var that = this,
12298			tab = this.tabs.eq( index ),
12299			anchor = tab.find( ".ui-tabs-anchor" ),
12300			panel = this._getPanelForTab( tab ),
12301			eventData = {
12302				tab: tab,
12303				panel: panel
12304			};
12305
12306		// not remote
12307		if ( isLocal( anchor[ 0 ] ) ) {
12308			return;
12309		}
12310
12311		this.xhr = $.ajax( this._ajaxSettings( anchor, event, eventData ) );
12312
12313		// support: jQuery <1.8
12314		// jQuery <1.8 returns false if the request is canceled in beforeSend,
12315		// but as of 1.8, $.ajax() always returns a jqXHR object.
12316		if ( this.xhr && this.xhr.statusText !== "canceled" ) {
12317			tab.addClass( "ui-tabs-loading" );
12318			panel.attr( "aria-busy", "true" );
12319
12320			this.xhr
12321				.success(function( response ) {
12322					// support: jQuery <1.8
12323					// http://bugs.jquery.com/ticket/11778
12324					setTimeout(function() {
12325						panel.html( response );
12326						that._trigger( "load", event, eventData );
12327					}, 1 );
12328				})
12329				.complete(function( jqXHR, status ) {
12330					// support: jQuery <1.8
12331					// http://bugs.jquery.com/ticket/11778
12332					setTimeout(function() {
12333						if ( status === "abort" ) {
12334							that.panels.stop( false, true );
12335						}
12336
12337						tab.removeClass( "ui-tabs-loading" );
12338						panel.removeAttr( "aria-busy" );
12339
12340						if ( jqXHR === that.xhr ) {
12341							delete that.xhr;
12342						}
12343					}, 1 );
12344				});
12345		}
12346	},
12347
12348	_ajaxSettings: function( anchor, event, eventData ) {
12349		var that = this;
12350		return {
12351			url: anchor.attr( "href" ),
12352			beforeSend: function( jqXHR, settings ) {
12353				return that._trigger( "beforeLoad", event,
12354					$.extend( { jqXHR : jqXHR, ajaxSettings: settings }, eventData ) );
12355			}
12356		};
12357	},
12358
12359	_getPanelForTab: function( tab ) {
12360		var id = $( tab ).attr( "aria-controls" );
12361		return this.element.find( this._sanitizeSelector( "#" + id ) );
12362	}
12363});
12364
12365})( jQuery );
12366(function( $ ) {
12367
12368var increments = 0;
12369
12370function addDescribedBy( elem, id ) {
12371	var describedby = (elem.attr( "aria-describedby" ) || "").split( /\s+/ );
12372	describedby.push( id );
12373	elem
12374		.data( "ui-tooltip-id", id )
12375		.attr( "aria-describedby", $.trim( describedby.join( " " ) ) );
12376}
12377
12378function removeDescribedBy( elem ) {
12379	var id = elem.data( "ui-tooltip-id" ),
12380		describedby = (elem.attr( "aria-describedby" ) || "").split( /\s+/ ),
12381		index = $.inArray( id, describedby );
12382	if ( index !== -1 ) {
12383		describedby.splice( index, 1 );
12384	}
12385
12386	elem.removeData( "ui-tooltip-id" );
12387	describedby = $.trim( describedby.join( " " ) );
12388	if ( describedby ) {
12389		elem.attr( "aria-describedby", describedby );
12390	} else {
12391		elem.removeAttr( "aria-describedby" );
12392	}
12393}
12394
12395$.widget( "ui.tooltip", {
12396	version: "1.10.4",
12397	options: {
12398		content: function() {
12399			// support: IE<9, Opera in jQuery <1.7
12400			// .text() can't accept undefined, so coerce to a string
12401			var title = $( this ).attr( "title" ) || "";
12402			// Escape title, since we're going from an attribute to raw HTML
12403			return $( "<a>" ).text( title ).html();
12404		},
12405		hide: true,
12406		// Disabled elements have inconsistent behavior across browsers (#8661)
12407		items: "[title]:not([disabled])",
12408		position: {
12409			my: "left top+15",
12410			at: "left bottom",
12411			collision: "flipfit flip"
12412		},
12413		show: true,
12414		tooltipClass: null,
12415		track: false,
12416
12417		// callbacks
12418		close: null,
12419		open: null
12420	},
12421
12422	_create: function() {
12423		this._on({
12424			mouseover: "open",
12425			focusin: "open"
12426		});
12427
12428		// IDs of generated tooltips, needed for destroy
12429		this.tooltips = {};
12430		// IDs of parent tooltips where we removed the title attribute
12431		this.parents = {};
12432
12433		if ( this.options.disabled ) {
12434			this._disable();
12435		}
12436	},
12437
12438	_setOption: function( key, value ) {
12439		var that = this;
12440
12441		if ( key === "disabled" ) {
12442			this[ value ? "_disable" : "_enable" ]();
12443			this.options[ key ] = value;
12444			// disable element style changes
12445			return;
12446		}
12447
12448		this._super( key, value );
12449
12450		if ( key === "content" ) {
12451			$.each( this.tooltips, function( id, element ) {
12452				that._updateContent( element );
12453			});
12454		}
12455	},
12456
12457	_disable: function() {
12458		var that = this;
12459
12460		// close open tooltips
12461		$.each( this.tooltips, function( id, element ) {
12462			var event = $.Event( "blur" );
12463			event.target = event.currentTarget = element[0];
12464			that.close( event, true );
12465		});
12466
12467		// remove title attributes to prevent native tooltips
12468		this.element.find( this.options.items ).addBack().each(function() {
12469			var element = $( this );
12470			if ( element.is( "[title]" ) ) {
12471				element
12472					.data( "ui-tooltip-title", element.attr( "title" ) )
12473					.attr( "title", "" );
12474			}
12475		});
12476	},
12477
12478	_enable: function() {
12479		// restore title attributes
12480		this.element.find( this.options.items ).addBack().each(function() {
12481			var element = $( this );
12482			if ( element.data( "ui-tooltip-title" ) ) {
12483				element.attr( "title", element.data( "ui-tooltip-title" ) );
12484			}
12485		});
12486	},
12487
12488	open: function( event ) {
12489		var that = this,
12490			target = $( event ? event.target : this.element )
12491				// we need closest here due to mouseover bubbling,
12492				// but always pointing at the same event target
12493				.closest( this.options.items );
12494
12495		// No element to show a tooltip for or the tooltip is already open
12496		if ( !target.length || target.data( "ui-tooltip-id" ) ) {
12497			return;
12498		}
12499
12500		if ( target.attr( "title" ) ) {
12501			target.data( "ui-tooltip-title", target.attr( "title" ) );
12502		}
12503
12504		target.data( "ui-tooltip-open", true );
12505
12506		// kill parent tooltips, custom or native, for hover
12507		if ( event && event.type === "mouseover" ) {
12508			target.parents().each(function() {
12509				var parent = $( this ),
12510					blurEvent;
12511				if ( parent.data( "ui-tooltip-open" ) ) {
12512					blurEvent = $.Event( "blur" );
12513					blurEvent.target = blurEvent.currentTarget = this;
12514					that.close( blurEvent, true );
12515				}
12516				if ( parent.attr( "title" ) ) {
12517					parent.uniqueId();
12518					that.parents[ this.id ] = {
12519						element: this,
12520						title: parent.attr( "title" )
12521					};
12522					parent.attr( "title", "" );
12523				}
12524			});
12525		}
12526
12527		this._updateContent( target, event );
12528	},
12529
12530	_updateContent: function( target, event ) {
12531		var content,
12532			contentOption = this.options.content,
12533			that = this,
12534			eventType = event ? event.type : null;
12535
12536		if ( typeof contentOption === "string" ) {
12537			return this._open( event, target, contentOption );
12538		}
12539
12540		content = contentOption.call( target[0], function( response ) {
12541			// ignore async response if tooltip was closed already
12542			if ( !target.data( "ui-tooltip-open" ) ) {
12543				return;
12544			}
12545			// IE may instantly serve a cached response for ajax requests
12546			// delay this call to _open so the other call to _open runs first
12547			that._delay(function() {
12548				// jQuery creates a special event for focusin when it doesn't
12549				// exist natively. To improve performance, the native event
12550				// object is reused and the type is changed. Therefore, we can't
12551				// rely on the type being correct after the event finished
12552				// bubbling, so we set it back to the previous value. (#8740)
12553				if ( event ) {
12554					event.type = eventType;
12555				}
12556				this._open( event, target, response );
12557			});
12558		});
12559		if ( content ) {
12560			this._open( event, target, content );
12561		}
12562	},
12563
12564	_open: function( event, target, content ) {
12565		var tooltip, events, delayedShow,
12566			positionOption = $.extend( {}, this.options.position );
12567
12568		if ( !content ) {
12569			return;
12570		}
12571
12572		// Content can be updated multiple times. If the tooltip already
12573		// exists, then just update the content and bail.
12574		tooltip = this._find( target );
12575		if ( tooltip.length ) {
12576			tooltip.find( ".ui-tooltip-content" ).html( content );
12577			return;
12578		}
12579
12580		// if we have a title, clear it to prevent the native tooltip
12581		// we have to check first to avoid defining a title if none exists
12582		// (we don't want to cause an element to start matching [title])
12583		//
12584		// We use removeAttr only for key events, to allow IE to export the correct
12585		// accessible attributes. For mouse events, set to empty string to avoid
12586		// native tooltip showing up (happens only when removing inside mouseover).
12587		if ( target.is( "[title]" ) ) {
12588			if ( event && event.type === "mouseover" ) {
12589				target.attr( "title", "" );
12590			} else {
12591				target.removeAttr( "title" );
12592			}
12593		}
12594
12595		tooltip = this._tooltip( target );
12596		addDescribedBy( target, tooltip.attr( "id" ) );
12597		tooltip.find( ".ui-tooltip-content" ).html( content );
12598
12599		function position( event ) {
12600			positionOption.of = event;
12601			if ( tooltip.is( ":hidden" ) ) {
12602				return;
12603			}
12604			tooltip.position( positionOption );
12605		}
12606		if ( this.options.track && event && /^mouse/.test( event.type ) ) {
12607			this._on( this.document, {
12608				mousemove: position
12609			});
12610			// trigger once to override element-relative positioning
12611			position( event );
12612		} else {
12613			tooltip.position( $.extend({
12614				of: target
12615			}, this.options.position ) );
12616		}
12617
12618		tooltip.hide();
12619
12620		this._show( tooltip, this.options.show );
12621		// Handle tracking tooltips that are shown with a delay (#8644). As soon
12622		// as the tooltip is visible, position the tooltip using the most recent
12623		// event.
12624		if ( this.options.show && this.options.show.delay ) {
12625			delayedShow = this.delayedShow = setInterval(function() {
12626				if ( tooltip.is( ":visible" ) ) {
12627					position( positionOption.of );
12628					clearInterval( delayedShow );
12629				}
12630			}, $.fx.interval );
12631		}
12632
12633		this._trigger( "open", event, { tooltip: tooltip } );
12634
12635		events = {
12636			keyup: function( event ) {
12637				if ( event.keyCode === $.ui.keyCode.ESCAPE ) {
12638					var fakeEvent = $.Event(event);
12639					fakeEvent.currentTarget = target[0];
12640					this.close( fakeEvent, true );
12641				}
12642			},
12643			remove: function() {
12644				this._removeTooltip( tooltip );
12645			}
12646		};
12647		if ( !event || event.type === "mouseover" ) {
12648			events.mouseleave = "close";
12649		}
12650		if ( !event || event.type === "focusin" ) {
12651			events.focusout = "close";
12652		}
12653		this._on( true, target, events );
12654	},
12655
12656	close: function( event ) {
12657		var that = this,
12658			target = $( event ? event.currentTarget : this.element ),
12659			tooltip = this._find( target );
12660
12661		// disabling closes the tooltip, so we need to track when we're closing
12662		// to avoid an infinite loop in case the tooltip becomes disabled on close
12663		if ( this.closing ) {
12664			return;
12665		}
12666
12667		// Clear the interval for delayed tracking tooltips
12668		clearInterval( this.delayedShow );
12669
12670		// only set title if we had one before (see comment in _open())
12671		if ( target.data( "ui-tooltip-title" ) ) {
12672			target.attr( "title", target.data( "ui-tooltip-title" ) );
12673		}
12674
12675		removeDescribedBy( target );
12676
12677		tooltip.stop( true );
12678		this._hide( tooltip, this.options.hide, function() {
12679			that._removeTooltip( $( this ) );
12680		});
12681
12682		target.removeData( "ui-tooltip-open" );
12683		this._off( target, "mouseleave focusout keyup" );
12684		// Remove 'remove' binding only on delegated targets
12685		if ( target[0] !== this.element[0] ) {
12686			this._off( target, "remove" );
12687		}
12688		this._off( this.document, "mousemove" );
12689
12690		if ( event && event.type === "mouseleave" ) {
12691			$.each( this.parents, function( id, parent ) {
12692				$( parent.element ).attr( "title", parent.title );
12693				delete that.parents[ id ];
12694			});
12695		}
12696
12697		this.closing = true;
12698		this._trigger( "close", event, { tooltip: tooltip } );
12699		this.closing = false;
12700	},
12701
12702	_tooltip: function( element ) {
12703		var id = "ui-tooltip-" + increments++,
12704			tooltip = $( "<div>" )
12705				.attr({
12706					id: id,
12707					role: "tooltip"
12708				})
12709				.addClass( "ui-tooltip ui-widget ui-corner-all ui-widget-content " +
12710					( this.options.tooltipClass || "" ) );
12711		$( "<div>" )
12712			.addClass( "ui-tooltip-content" )
12713			.appendTo( tooltip );
12714		tooltip.appendTo( this.document[0].body );
12715		this.tooltips[ id ] = element;
12716		return tooltip;
12717	},
12718
12719	_find: function( target ) {
12720		var id = target.data( "ui-tooltip-id" );
12721		return id ? $( "#" + id ) : $();
12722	},
12723
12724	_removeTooltip: function( tooltip ) {
12725		tooltip.remove();
12726		delete this.tooltips[ tooltip.attr( "id" ) ];
12727	},
12728
12729	_destroy: function() {
12730		var that = this;
12731
12732		// close open tooltips
12733		$.each( this.tooltips, function( id, element ) {
12734			// Delegate to close method to handle common cleanup
12735			var event = $.Event( "blur" );
12736			event.target = event.currentTarget = element[0];
12737			that.close( event, true );
12738
12739			// Remove immediately; destroying an open tooltip doesn't use the
12740			// hide animation
12741			$( "#" + id ).remove();
12742
12743			// Restore the title
12744			if ( element.data( "ui-tooltip-title" ) ) {
12745				element.attr( "title", element.data( "ui-tooltip-title" ) );
12746				element.removeData( "ui-tooltip-title" );
12747			}
12748		});
12749	}
12750});
12751
12752}( jQuery ) );
12753(function($, undefined) {
12754
12755var dataSpace = "ui-effects-";
12756
12757$.effects = {
12758	effect: {}
12759};
12760
12761/*!
12762 * jQuery Color Animations v2.1.2
12763 * https://github.com/jquery/jquery-color
12764 *
12765 * Copyright 2013 jQuery Foundation and other contributors
12766 * Released under the MIT license.
12767 * http://jquery.org/license
12768 *
12769 * Date: Wed Jan 16 08:47:09 2013 -0600
12770 */
12771(function( jQuery, undefined ) {
12772
12773	var stepHooks = "backgroundColor borderBottomColor borderLeftColor borderRightColor borderTopColor color columnRuleColor outlineColor textDecorationColor textEmphasisColor",
12774
12775	// plusequals test for += 100 -= 100
12776	rplusequals = /^([\-+])=\s*(\d+\.?\d*)/,
12777	// a set of RE's that can match strings and generate color tuples.
12778	stringParsers = [{
12779			re: /rgba?\(\s*(\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(\d{1,3})\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/,
12780			parse: function( execResult ) {
12781				return [
12782					execResult[ 1 ],
12783					execResult[ 2 ],
12784					execResult[ 3 ],
12785					execResult[ 4 ]
12786				];
12787			}
12788		}, {
12789			re: /rgba?\(\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/,
12790			parse: function( execResult ) {
12791				return [
12792					execResult[ 1 ] * 2.55,
12793					execResult[ 2 ] * 2.55,
12794					execResult[ 3 ] * 2.55,
12795					execResult[ 4 ]
12796				];
12797			}
12798		}, {
12799			// this regex ignores A-F because it's compared against an already lowercased string
12800			re: /#([a-f0-9]{2})([a-f0-9]{2})([a-f0-9]{2})/,
12801			parse: function( execResult ) {
12802				return [
12803					parseInt( execResult[ 1 ], 16 ),
12804					parseInt( execResult[ 2 ], 16 ),
12805					parseInt( execResult[ 3 ], 16 )
12806				];
12807			}
12808		}, {
12809			// this regex ignores A-F because it's compared against an already lowercased string
12810			re: /#([a-f0-9])([a-f0-9])([a-f0-9])/,
12811			parse: function( execResult ) {
12812				return [
12813					parseInt( execResult[ 1 ] + execResult[ 1 ], 16 ),
12814					parseInt( execResult[ 2 ] + execResult[ 2 ], 16 ),
12815					parseInt( execResult[ 3 ] + execResult[ 3 ], 16 )
12816				];
12817			}
12818		}, {
12819			re: /hsla?\(\s*(\d+(?:\.\d+)?)\s*,\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/,
12820			space: "hsla",
12821			parse: function( execResult ) {
12822				return [
12823					execResult[ 1 ],
12824					execResult[ 2 ] / 100,
12825					execResult[ 3 ] / 100,
12826					execResult[ 4 ]
12827				];
12828			}
12829		}],
12830
12831	// jQuery.Color( )
12832	color = jQuery.Color = function( color, green, blue, alpha ) {
12833		return new jQuery.Color.fn.parse( color, green, blue, alpha );
12834	},
12835	spaces = {
12836		rgba: {
12837			props: {
12838				red: {
12839					idx: 0,
12840					type: "byte"
12841				},
12842				green: {
12843					idx: 1,
12844					type: "byte"
12845				},
12846				blue: {
12847					idx: 2,
12848					type: "byte"
12849				}
12850			}
12851		},
12852
12853		hsla: {
12854			props: {
12855				hue: {
12856					idx: 0,
12857					type: "degrees"
12858				},
12859				saturation: {
12860					idx: 1,
12861					type: "percent"
12862				},
12863				lightness: {
12864					idx: 2,
12865					type: "percent"
12866				}
12867			}
12868		}
12869	},
12870	propTypes = {
12871		"byte": {
12872			floor: true,
12873			max: 255
12874		},
12875		"percent": {
12876			max: 1
12877		},
12878		"degrees": {
12879			mod: 360,
12880			floor: true
12881		}
12882	},
12883	support = color.support = {},
12884
12885	// element for support tests
12886	supportElem = jQuery( "<p>" )[ 0 ],
12887
12888	// colors = jQuery.Color.names
12889	colors,
12890
12891	// local aliases of functions called often
12892	each = jQuery.each;
12893
12894// determine rgba support immediately
12895supportElem.style.cssText = "background-color:rgba(1,1,1,.5)";
12896support.rgba = supportElem.style.backgroundColor.indexOf( "rgba" ) > -1;
12897
12898// define cache name and alpha properties
12899// for rgba and hsla spaces
12900each( spaces, function( spaceName, space ) {
12901	space.cache = "_" + spaceName;
12902	space.props.alpha = {
12903		idx: 3,
12904		type: "percent",
12905		def: 1
12906	};
12907});
12908
12909function clamp( value, prop, allowEmpty ) {
12910	var type = propTypes[ prop.type ] || {};
12911
12912	if ( value == null ) {
12913		return (allowEmpty || !prop.def) ? null : prop.def;
12914	}
12915
12916	// ~~ is an short way of doing floor for positive numbers
12917	value = type.floor ? ~~value : parseFloat( value );
12918
12919	// IE will pass in empty strings as value for alpha,
12920	// which will hit this case
12921	if ( isNaN( value ) ) {
12922		return prop.def;
12923	}
12924
12925	if ( type.mod ) {
12926		// we add mod before modding to make sure that negatives values
12927		// get converted properly: -10 -> 350
12928		return (value + type.mod) % type.mod;
12929	}
12930
12931	// for now all property types without mod have min and max
12932	return 0 > value ? 0 : type.max < value ? type.max : value;
12933}
12934
12935function stringParse( string ) {
12936	var inst = color(),
12937		rgba = inst._rgba = [];
12938
12939	string = string.toLowerCase();
12940
12941	each( stringParsers, function( i, parser ) {
12942		var parsed,
12943			match = parser.re.exec( string ),
12944			values = match && parser.parse( match ),
12945			spaceName = parser.space || "rgba";
12946
12947		if ( values ) {
12948			parsed = inst[ spaceName ]( values );
12949
12950			// if this was an rgba parse the assignment might happen twice
12951			// oh well....
12952			inst[ spaces[ spaceName ].cache ] = parsed[ spaces[ spaceName ].cache ];
12953			rgba = inst._rgba = parsed._rgba;
12954
12955			// exit each( stringParsers ) here because we matched
12956			return false;
12957		}
12958	});
12959
12960	// Found a stringParser that handled it
12961	if ( rgba.length ) {
12962
12963		// if this came from a parsed string, force "transparent" when alpha is 0
12964		// chrome, (and maybe others) return "transparent" as rgba(0,0,0,0)
12965		if ( rgba.join() === "0,0,0,0" ) {
12966			jQuery.extend( rgba, colors.transparent );
12967		}
12968		return inst;
12969	}
12970
12971	// named colors
12972	return colors[ string ];
12973}
12974
12975color.fn = jQuery.extend( color.prototype, {
12976	parse: function( red, green, blue, alpha ) {
12977		if ( red === undefined ) {
12978			this._rgba = [ null, null, null, null ];
12979			return this;
12980		}
12981		if ( red.jquery || red.nodeType ) {
12982			red = jQuery( red ).css( green );
12983			green = undefined;
12984		}
12985
12986		var inst = this,
12987			type = jQuery.type( red ),
12988			rgba = this._rgba = [];
12989
12990		// more than 1 argument specified - assume ( red, green, blue, alpha )
12991		if ( green !== undefined ) {
12992			red = [ red, green, blue, alpha ];
12993			type = "array";
12994		}
12995
12996		if ( type === "string" ) {
12997			return this.parse( stringParse( red ) || colors._default );
12998		}
12999
13000		if ( type === "array" ) {
13001			each( spaces.rgba.props, function( key, prop ) {
13002				rgba[ prop.idx ] = clamp( red[ prop.idx ], prop );
13003			});
13004			return this;
13005		}
13006
13007		if ( type === "object" ) {
13008			if ( red instanceof color ) {
13009				each( spaces, function( spaceName, space ) {
13010					if ( red[ space.cache ] ) {
13011						inst[ space.cache ] = red[ space.cache ].slice();
13012					}
13013				});
13014			} else {
13015				each( spaces, function( spaceName, space ) {
13016					var cache = space.cache;
13017					each( space.props, function( key, prop ) {
13018
13019						// if the cache doesn't exist, and we know how to convert
13020						if ( !inst[ cache ] && space.to ) {
13021
13022							// if the value was null, we don't need to copy it
13023							// if the key was alpha, we don't need to copy it either
13024							if ( key === "alpha" || red[ key ] == null ) {
13025								return;
13026							}
13027							inst[ cache ] = space.to( inst._rgba );
13028						}
13029
13030						// this is the only case where we allow nulls for ALL properties.
13031						// call clamp with alwaysAllowEmpty
13032						inst[ cache ][ prop.idx ] = clamp( red[ key ], prop, true );
13033					});
13034
13035					// everything defined but alpha?
13036					if ( inst[ cache ] && jQuery.inArray( null, inst[ cache ].slice( 0, 3 ) ) < 0 ) {
13037						// use the default of 1
13038						inst[ cache ][ 3 ] = 1;
13039						if ( space.from ) {
13040							inst._rgba = space.from( inst[ cache ] );
13041						}
13042					}
13043				});
13044			}
13045			return this;
13046		}
13047	},
13048	is: function( compare ) {
13049		var is = color( compare ),
13050			same = true,
13051			inst = this;
13052
13053		each( spaces, function( _, space ) {
13054			var localCache,
13055				isCache = is[ space.cache ];
13056			if (isCache) {
13057				localCache = inst[ space.cache ] || space.to && space.to( inst._rgba ) || [];
13058				each( space.props, function( _, prop ) {
13059					if ( isCache[ prop.idx ] != null ) {
13060						same = ( isCache[ prop.idx ] === localCache[ prop.idx ] );
13061						return same;
13062					}
13063				});
13064			}
13065			return same;
13066		});
13067		return same;
13068	},
13069	_space: function() {
13070		var used = [],
13071			inst = this;
13072		each( spaces, function( spaceName, space ) {
13073			if ( inst[ space.cache ] ) {
13074				used.push( spaceName );
13075			}
13076		});
13077		return used.pop();
13078	},
13079	transition: function( other, distance ) {
13080		var end = color( other ),
13081			spaceName = end._space(),
13082			space = spaces[ spaceName ],
13083			startColor = this.alpha() === 0 ? color( "transparent" ) : this,
13084			start = startColor[ space.cache ] || space.to( startColor._rgba ),
13085			result = start.slice();
13086
13087		end = end[ space.cache ];
13088		each( space.props, function( key, prop ) {
13089			var index = prop.idx,
13090				startValue = start[ index ],
13091				endValue = end[ index ],
13092				type = propTypes[ prop.type ] || {};
13093
13094			// if null, don't override start value
13095			if ( endValue === null ) {
13096				return;
13097			}
13098			// if null - use end
13099			if ( startValue === null ) {
13100				result[ index ] = endValue;
13101			} else {
13102				if ( type.mod ) {
13103					if ( endValue - startValue > type.mod / 2 ) {
13104						startValue += type.mod;
13105					} else if ( startValue - endValue > type.mod / 2 ) {
13106						startValue -= type.mod;
13107					}
13108				}
13109				result[ index ] = clamp( ( endValue - startValue ) * distance + startValue, prop );
13110			}
13111		});
13112		return this[ spaceName ]( result );
13113	},
13114	blend: function( opaque ) {
13115		// if we are already opaque - return ourself
13116		if ( this._rgba[ 3 ] === 1 ) {
13117			return this;
13118		}
13119
13120		var rgb = this._rgba.slice(),
13121			a = rgb.pop(),
13122			blend = color( opaque )._rgba;
13123
13124		return color( jQuery.map( rgb, function( v, i ) {
13125			return ( 1 - a ) * blend[ i ] + a * v;
13126		}));
13127	},
13128	toRgbaString: function() {
13129		var prefix = "rgba(",
13130			rgba = jQuery.map( this._rgba, function( v, i ) {
13131				return v == null ? ( i > 2 ? 1 : 0 ) : v;
13132			});
13133
13134		if ( rgba[ 3 ] === 1 ) {
13135			rgba.pop();
13136			prefix = "rgb(";
13137		}
13138
13139		return prefix + rgba.join() + ")";
13140	},
13141	toHslaString: function() {
13142		var prefix = "hsla(",
13143			hsla = jQuery.map( this.hsla(), function( v, i ) {
13144				if ( v == null ) {
13145					v = i > 2 ? 1 : 0;
13146				}
13147
13148				// catch 1 and 2
13149				if ( i && i < 3 ) {
13150					v = Math.round( v * 100 ) + "%";
13151				}
13152				return v;
13153			});
13154
13155		if ( hsla[ 3 ] === 1 ) {
13156			hsla.pop();
13157			prefix = "hsl(";
13158		}
13159		return prefix + hsla.join() + ")";
13160	},
13161	toHexString: function( includeAlpha ) {
13162		var rgba = this._rgba.slice(),
13163			alpha = rgba.pop();
13164
13165		if ( includeAlpha ) {
13166			rgba.push( ~~( alpha * 255 ) );
13167		}
13168
13169		return "#" + jQuery.map( rgba, function( v ) {
13170
13171			// default to 0 when nulls exist
13172			v = ( v || 0 ).toString( 16 );
13173			return v.length === 1 ? "0" + v : v;
13174		}).join("");
13175	},
13176	toString: function() {
13177		return this._rgba[ 3 ] === 0 ? "transparent" : this.toRgbaString();
13178	}
13179});
13180color.fn.parse.prototype = color.fn;
13181
13182// hsla conversions adapted from:
13183// https://code.google.com/p/maashaack/source/browse/packages/graphics/trunk/src/graphics/colors/HUE2RGB.as?r=5021
13184
13185function hue2rgb( p, q, h ) {
13186	h = ( h + 1 ) % 1;
13187	if ( h * 6 < 1 ) {
13188		return p + (q - p) * h * 6;
13189	}
13190	if ( h * 2 < 1) {
13191		return q;
13192	}
13193	if ( h * 3 < 2 ) {
13194		return p + (q - p) * ((2/3) - h) * 6;
13195	}
13196	return p;
13197}
13198
13199spaces.hsla.to = function ( rgba ) {
13200	if ( rgba[ 0 ] == null || rgba[ 1 ] == null || rgba[ 2 ] == null ) {
13201		return [ null, null, null, rgba[ 3 ] ];
13202	}
13203	var r = rgba[ 0 ] / 255,
13204		g = rgba[ 1 ] / 255,
13205		b = rgba[ 2 ] / 255,
13206		a = rgba[ 3 ],
13207		max = Math.max( r, g, b ),
13208		min = Math.min( r, g, b ),
13209		diff = max - min,
13210		add = max + min,
13211		l = add * 0.5,
13212		h, s;
13213
13214	if ( min === max ) {
13215		h = 0;
13216	} else if ( r === max ) {
13217		h = ( 60 * ( g - b ) / diff ) + 360;
13218	} else if ( g === max ) {
13219		h = ( 60 * ( b - r ) / diff ) + 120;
13220	} else {
13221		h = ( 60 * ( r - g ) / diff ) + 240;
13222	}
13223
13224	// chroma (diff) == 0 means greyscale which, by definition, saturation = 0%
13225	// otherwise, saturation is based on the ratio of chroma (diff) to lightness (add)
13226	if ( diff === 0 ) {
13227		s = 0;
13228	} else if ( l <= 0.5 ) {
13229		s = diff / add;
13230	} else {
13231		s = diff / ( 2 - add );
13232	}
13233	return [ Math.round(h) % 360, s, l, a == null ? 1 : a ];
13234};
13235
13236spaces.hsla.from = function ( hsla ) {
13237	if ( hsla[ 0 ] == null || hsla[ 1 ] == null || hsla[ 2 ] == null ) {
13238		return [ null, null, null, hsla[ 3 ] ];
13239	}
13240	var h = hsla[ 0 ] / 360,
13241		s = hsla[ 1 ],
13242		l = hsla[ 2 ],
13243		a = hsla[ 3 ],
13244		q = l <= 0.5 ? l * ( 1 + s ) : l + s - l * s,
13245		p = 2 * l - q;
13246
13247	return [
13248		Math.round( hue2rgb( p, q, h + ( 1 / 3 ) ) * 255 ),
13249		Math.round( hue2rgb( p, q, h ) * 255 ),
13250		Math.round( hue2rgb( p, q, h - ( 1 / 3 ) ) * 255 ),
13251		a
13252	];
13253};
13254
13255
13256each( spaces, function( spaceName, space ) {
13257	var props = space.props,
13258		cache = space.cache,
13259		to = space.to,
13260		from = space.from;
13261
13262	// makes rgba() and hsla()
13263	color.fn[ spaceName ] = function( value ) {
13264
13265		// generate a cache for this space if it doesn't exist
13266		if ( to && !this[ cache ] ) {
13267			this[ cache ] = to( this._rgba );
13268		}
13269		if ( value === undefined ) {
13270			return this[ cache ].slice();
13271		}
13272
13273		var ret,
13274			type = jQuery.type( value ),
13275			arr = ( type === "array" || type === "object" ) ? value : arguments,
13276			local = this[ cache ].slice();
13277
13278		each( props, function( key, prop ) {
13279			var val = arr[ type === "object" ? key : prop.idx ];
13280			if ( val == null ) {
13281				val = local[ prop.idx ];
13282			}
13283			local[ prop.idx ] = clamp( val, prop );
13284		});
13285
13286		if ( from ) {
13287			ret = color( from( local ) );
13288			ret[ cache ] = local;
13289			return ret;
13290		} else {
13291			return color( local );
13292		}
13293	};
13294
13295	// makes red() green() blue() alpha() hue() saturation() lightness()
13296	each( props, function( key, prop ) {
13297		// alpha is included in more than one space
13298		if ( color.fn[ key ] ) {
13299			return;
13300		}
13301		color.fn[ key ] = function( value ) {
13302			var vtype = jQuery.type( value ),
13303				fn = ( key === "alpha" ? ( this._hsla ? "hsla" : "rgba" ) : spaceName ),
13304				local = this[ fn ](),
13305				cur = local[ prop.idx ],
13306				match;
13307
13308			if ( vtype === "undefined" ) {
13309				return cur;
13310			}
13311
13312			if ( vtype === "function" ) {
13313				value = value.call( this, cur );
13314				vtype = jQuery.type( value );
13315			}
13316			if ( value == null && prop.empty ) {
13317				return this;
13318			}
13319			if ( vtype === "string" ) {
13320				match = rplusequals.exec( value );
13321				if ( match ) {
13322					value = cur + parseFloat( match[ 2 ] ) * ( match[ 1 ] === "+" ? 1 : -1 );
13323				}
13324			}
13325			local[ prop.idx ] = value;
13326			return this[ fn ]( local );
13327		};
13328	});
13329});
13330
13331// add cssHook and .fx.step function for each named hook.
13332// accept a space separated string of properties
13333color.hook = function( hook ) {
13334	var hooks = hook.split( " " );
13335	each( hooks, function( i, hook ) {
13336		jQuery.cssHooks[ hook ] = {
13337			set: function( elem, value ) {
13338				var parsed, curElem,
13339					backgroundColor = "";
13340
13341				if ( value !== "transparent" && ( jQuery.type( value ) !== "string" || ( parsed = stringParse( value ) ) ) ) {
13342					value = color( parsed || value );
13343					if ( !support.rgba && value._rgba[ 3 ] !== 1 ) {
13344						curElem = hook === "backgroundColor" ? elem.parentNode : elem;
13345						while (
13346							(backgroundColor === "" || backgroundColor === "transparent") &&
13347							curElem && curElem.style
13348						) {
13349							try {
13350								backgroundColor = jQuery.css( curElem, "backgroundColor" );
13351								curElem = curElem.parentNode;
13352							} catch ( e ) {
13353							}
13354						}
13355
13356						value = value.blend( backgroundColor && backgroundColor !== "transparent" ?
13357							backgroundColor :
13358							"_default" );
13359					}
13360
13361					value = value.toRgbaString();
13362				}
13363				try {
13364					elem.style[ hook ] = value;
13365				} catch( e ) {
13366					// wrapped to prevent IE from throwing errors on "invalid" values like 'auto' or 'inherit'
13367				}
13368			}
13369		};
13370		jQuery.fx.step[ hook ] = function( fx ) {
13371			if ( !fx.colorInit ) {
13372				fx.start = color( fx.elem, hook );
13373				fx.end = color( fx.end );
13374				fx.colorInit = true;
13375			}
13376			jQuery.cssHooks[ hook ].set( fx.elem, fx.start.transition( fx.end, fx.pos ) );
13377		};
13378	});
13379
13380};
13381
13382color.hook( stepHooks );
13383
13384jQuery.cssHooks.borderColor = {
13385	expand: function( value ) {
13386		var expanded = {};
13387
13388		each( [ "Top", "Right", "Bottom", "Left" ], function( i, part ) {
13389			expanded[ "border" + part + "Color" ] = value;
13390		});
13391		return expanded;
13392	}
13393};
13394
13395// Basic color names only.
13396// Usage of any of the other color names requires adding yourself or including
13397// jquery.color.svg-names.js.
13398colors = jQuery.Color.names = {
13399	// 4.1. Basic color keywords
13400	aqua: "#00ffff",
13401	black: "#000000",
13402	blue: "#0000ff",
13403	fuchsia: "#ff00ff",
13404	gray: "#808080",
13405	green: "#008000",
13406	lime: "#00ff00",
13407	maroon: "#800000",
13408	navy: "#000080",
13409	olive: "#808000",
13410	purple: "#800080",
13411	red: "#ff0000",
13412	silver: "#c0c0c0",
13413	teal: "#008080",
13414	white: "#ffffff",
13415	yellow: "#ffff00",
13416
13417	// 4.2.3. "transparent" color keyword
13418	transparent: [ null, null, null, 0 ],
13419
13420	_default: "#ffffff"
13421};
13422
13423})( jQuery );
13424
13425
13426/******************************************************************************/
13427/****************************** CLASS ANIMATIONS ******************************/
13428/******************************************************************************/
13429(function() {
13430
13431var classAnimationActions = [ "add", "remove", "toggle" ],
13432	shorthandStyles = {
13433		border: 1,
13434		borderBottom: 1,
13435		borderColor: 1,
13436		borderLeft: 1,
13437		borderRight: 1,
13438		borderTop: 1,
13439		borderWidth: 1,
13440		margin: 1,
13441		padding: 1
13442	};
13443
13444$.each([ "borderLeftStyle", "borderRightStyle", "borderBottomStyle", "borderTopStyle" ], function( _, prop ) {
13445	$.fx.step[ prop ] = function( fx ) {
13446		if ( fx.end !== "none" && !fx.setAttr || fx.pos === 1 && !fx.setAttr ) {
13447			jQuery.style( fx.elem, prop, fx.end );
13448			fx.setAttr = true;
13449		}
13450	};
13451});
13452
13453function getElementStyles( elem ) {
13454	var key, len,
13455		style = elem.ownerDocument.defaultView ?
13456			elem.ownerDocument.defaultView.getComputedStyle( elem, null ) :
13457			elem.currentStyle,
13458		styles = {};
13459
13460	if ( style && style.length && style[ 0 ] && style[ style[ 0 ] ] ) {
13461		len = style.length;
13462		while ( len-- ) {
13463			key = style[ len ];
13464			if ( typeof style[ key ] === "string" ) {
13465				styles[ $.camelCase( key ) ] = style[ key ];
13466			}
13467		}
13468	// support: Opera, IE <9
13469	} else {
13470		for ( key in style ) {
13471			if ( typeof style[ key ] === "string" ) {
13472				styles[ key ] = style[ key ];
13473			}
13474		}
13475	}
13476
13477	return styles;
13478}
13479
13480
13481function styleDifference( oldStyle, newStyle ) {
13482	var diff = {},
13483		name, value;
13484
13485	for ( name in newStyle ) {
13486		value = newStyle[ name ];
13487		if ( oldStyle[ name ] !== value ) {
13488			if ( !shorthandStyles[ name ] ) {
13489				if ( $.fx.step[ name ] || !isNaN( parseFloat( value ) ) ) {
13490					diff[ name ] = value;
13491				}
13492			}
13493		}
13494	}
13495
13496	return diff;
13497}
13498
13499// support: jQuery <1.8
13500if ( !$.fn.addBack ) {
13501	$.fn.addBack = function( selector ) {
13502		return this.add( selector == null ?
13503			this.prevObject : this.prevObject.filter( selector )
13504		);
13505	};
13506}
13507
13508$.effects.animateClass = function( value, duration, easing, callback ) {
13509	var o = $.speed( duration, easing, callback );
13510
13511	return this.queue( function() {
13512		var animated = $( this ),
13513			baseClass = animated.attr( "class" ) || "",
13514			applyClassChange,
13515			allAnimations = o.children ? animated.find( "*" ).addBack() : animated;
13516
13517		// map the animated objects to store the original styles.
13518		allAnimations = allAnimations.map(function() {
13519			var el = $( this );
13520			return {
13521				el: el,
13522				start: getElementStyles( this )
13523			};
13524		});
13525
13526		// apply class change
13527		applyClassChange = function() {
13528			$.each( classAnimationActions, function(i, action) {
13529				if ( value[ action ] ) {
13530					animated[ action + "Class" ]( value[ action ] );
13531				}
13532			});
13533		};
13534		applyClassChange();
13535
13536		// map all animated objects again - calculate new styles and diff
13537		allAnimations = allAnimations.map(function() {
13538			this.end = getElementStyles( this.el[ 0 ] );
13539			this.diff = styleDifference( this.start, this.end );
13540			return this;
13541		});
13542
13543		// apply original class
13544		animated.attr( "class", baseClass );
13545
13546		// map all animated objects again - this time collecting a promise
13547		allAnimations = allAnimations.map(function() {
13548			var styleInfo = this,
13549				dfd = $.Deferred(),
13550				opts = $.extend({}, o, {
13551					queue: false,
13552					complete: function() {
13553						dfd.resolve( styleInfo );
13554					}
13555				});
13556
13557			this.el.animate( this.diff, opts );
13558			return dfd.promise();
13559		});
13560
13561		// once all animations have completed:
13562		$.when.apply( $, allAnimations.get() ).done(function() {
13563
13564			// set the final class
13565			applyClassChange();
13566
13567			// for each animated element,
13568			// clear all css properties that were animated
13569			$.each( arguments, function() {
13570				var el = this.el;
13571				$.each( this.diff, function(key) {
13572					el.css( key, "" );
13573				});
13574			});
13575
13576			// this is guarnteed to be there if you use jQuery.speed()
13577			// it also handles dequeuing the next anim...
13578			o.complete.call( animated[ 0 ] );
13579		});
13580	});
13581};
13582
13583$.fn.extend({
13584	addClass: (function( orig ) {
13585		return function( classNames, speed, easing, callback ) {
13586			return speed ?
13587				$.effects.animateClass.call( this,
13588					{ add: classNames }, speed, easing, callback ) :
13589				orig.apply( this, arguments );
13590		};
13591	})( $.fn.addClass ),
13592
13593	removeClass: (function( orig ) {
13594		return function( classNames, speed, easing, callback ) {
13595			return arguments.length > 1 ?
13596				$.effects.animateClass.call( this,
13597					{ remove: classNames }, speed, easing, callback ) :
13598				orig.apply( this, arguments );
13599		};
13600	})( $.fn.removeClass ),
13601
13602	toggleClass: (function( orig ) {
13603		return function( classNames, force, speed, easing, callback ) {
13604			if ( typeof force === "boolean" || force === undefined ) {
13605				if ( !speed ) {
13606					// without speed parameter
13607					return orig.apply( this, arguments );
13608				} else {
13609					return $.effects.animateClass.call( this,
13610						(force ? { add: classNames } : { remove: classNames }),
13611						speed, easing, callback );
13612				}
13613			} else {
13614				// without force parameter
13615				return $.effects.animateClass.call( this,
13616					{ toggle: classNames }, force, speed, easing );
13617			}
13618		};
13619	})( $.fn.toggleClass ),
13620
13621	switchClass: function( remove, add, speed, easing, callback) {
13622		return $.effects.animateClass.call( this, {
13623			add: add,
13624			remove: remove
13625		}, speed, easing, callback );
13626	}
13627});
13628
13629})();
13630
13631/******************************************************************************/
13632/*********************************** EFFECTS **********************************/
13633/******************************************************************************/
13634
13635(function() {
13636
13637$.extend( $.effects, {
13638	version: "1.10.4",
13639
13640	// Saves a set of properties in a data storage
13641	save: function( element, set ) {
13642		for( var i=0; i < set.length; i++ ) {
13643			if ( set[ i ] !== null ) {
13644				element.data( dataSpace + set[ i ], element[ 0 ].style[ set[ i ] ] );
13645			}
13646		}
13647	},
13648
13649	// Restores a set of previously saved properties from a data storage
13650	restore: function( element, set ) {
13651		var val, i;
13652		for( i=0; i < set.length; i++ ) {
13653			if ( set[ i ] !== null ) {
13654				val = element.data( dataSpace + set[ i ] );
13655				// support: jQuery 1.6.2
13656				// http://bugs.jquery.com/ticket/9917
13657				// jQuery 1.6.2 incorrectly returns undefined for any falsy value.
13658				// We can't differentiate between "" and 0 here, so we just assume
13659				// empty string since it's likely to be a more common value...
13660				if ( val === undefined ) {
13661					val = "";
13662				}
13663				element.css( set[ i ], val );
13664			}
13665		}
13666	},
13667
13668	setMode: function( el, mode ) {
13669		if (mode === "toggle") {
13670			mode = el.is( ":hidden" ) ? "show" : "hide";
13671		}
13672		return mode;
13673	},
13674
13675	// Translates a [top,left] array into a baseline value
13676	// this should be a little more flexible in the future to handle a string & hash
13677	getBaseline: function( origin, original ) {
13678		var y, x;
13679		switch ( origin[ 0 ] ) {
13680			case "top": y = 0; break;
13681			case "middle": y = 0.5; break;
13682			case "bottom": y = 1; break;
13683			default: y = origin[ 0 ] / original.height;
13684		}
13685		switch ( origin[ 1 ] ) {
13686			case "left": x = 0; break;
13687			case "center": x = 0.5; break;
13688			case "right": x = 1; break;
13689			default: x = origin[ 1 ] / original.width;
13690		}
13691		return {
13692			x: x,
13693			y: y
13694		};
13695	},
13696
13697	// Wraps the element around a wrapper that copies position properties
13698	createWrapper: function( element ) {
13699
13700		// if the element is already wrapped, return it
13701		if ( element.parent().is( ".ui-effects-wrapper" )) {
13702			return element.parent();
13703		}
13704
13705		// wrap the element
13706		var props = {
13707				width: element.outerWidth(true),
13708				height: element.outerHeight(true),
13709				"float": element.css( "float" )
13710			},
13711			wrapper = $( "<div></div>" )
13712				.addClass( "ui-effects-wrapper" )
13713				.css({
13714					fontSize: "100%",
13715					background: "transparent",
13716					border: "none",
13717					margin: 0,
13718					padding: 0
13719				}),
13720			// Store the size in case width/height are defined in % - Fixes #5245
13721			size = {
13722				width: element.width(),
13723				height: element.height()
13724			},
13725			active = document.activeElement;
13726
13727		// support: Firefox
13728		// Firefox incorrectly exposes anonymous content
13729		// https://bugzilla.mozilla.org/show_bug.cgi?id=561664
13730		try {
13731			active.id;
13732		} catch( e ) {
13733			active = document.body;
13734		}
13735
13736		element.wrap( wrapper );
13737
13738		// Fixes #7595 - Elements lose focus when wrapped.
13739		if ( element[ 0 ] === active || $.contains( element[ 0 ], active ) ) {
13740			$( active ).focus();
13741		}
13742
13743		wrapper = element.parent(); //Hotfix for jQuery 1.4 since some change in wrap() seems to actually lose the reference to the wrapped element
13744
13745		// transfer positioning properties to the wrapper
13746		if ( element.css( "position" ) === "static" ) {
13747			wrapper.css({ position: "relative" });
13748			element.css({ position: "relative" });
13749		} else {
13750			$.extend( props, {
13751				position: element.css( "position" ),
13752				zIndex: element.css( "z-index" )
13753			});
13754			$.each([ "top", "left", "bottom", "right" ], function(i, pos) {
13755				props[ pos ] = element.css( pos );
13756				if ( isNaN( parseInt( props[ pos ], 10 ) ) ) {
13757					props[ pos ] = "auto";
13758				}
13759			});
13760			element.css({
13761				position: "relative",
13762				top: 0,
13763				left: 0,
13764				right: "auto",
13765				bottom: "auto"
13766			});
13767		}
13768		element.css(size);
13769
13770		return wrapper.css( props ).show();
13771	},
13772
13773	removeWrapper: function( element ) {
13774		var active = document.activeElement;
13775
13776		if ( element.parent().is( ".ui-effects-wrapper" ) ) {
13777			element.parent().replaceWith( element );
13778
13779			// Fixes #7595 - Elements lose focus when wrapped.
13780			if ( element[ 0 ] === active || $.contains( element[ 0 ], active ) ) {
13781				$( active ).focus();
13782			}
13783		}
13784
13785
13786		return element;
13787	},
13788
13789	setTransition: function( element, list, factor, value ) {
13790		value = value || {};
13791		$.each( list, function( i, x ) {
13792			var unit = element.cssUnit( x );
13793			if ( unit[ 0 ] > 0 ) {
13794				value[ x ] = unit[ 0 ] * factor + unit[ 1 ];
13795			}
13796		});
13797		return value;
13798	}
13799});
13800
13801// return an effect options object for the given parameters:
13802function _normalizeArguments( effect, options, speed, callback ) {
13803
13804	// allow passing all options as the first parameter
13805	if ( $.isPlainObject( effect ) ) {
13806		options = effect;
13807		effect = effect.effect;
13808	}
13809
13810	// convert to an object
13811	effect = { effect: effect };
13812
13813	// catch (effect, null, ...)
13814	if ( options == null ) {
13815		options = {};
13816	}
13817
13818	// catch (effect, callback)
13819	if ( $.isFunction( options ) ) {
13820		callback = options;
13821		speed = null;
13822		options = {};
13823	}
13824
13825	// catch (effect, speed, ?)
13826	if ( typeof options === "number" || $.fx.speeds[ options ] ) {
13827		callback = speed;
13828		speed = options;
13829		options = {};
13830	}
13831
13832	// catch (effect, options, callback)
13833	if ( $.isFunction( speed ) ) {
13834		callback = speed;
13835		speed = null;
13836	}
13837
13838	// add options to effect
13839	if ( options ) {
13840		$.extend( effect, options );
13841	}
13842
13843	speed = speed || options.duration;
13844	effect.duration = $.fx.off ? 0 :
13845		typeof speed === "number" ? speed :
13846		speed in $.fx.speeds ? $.fx.speeds[ speed ] :
13847		$.fx.speeds._default;
13848
13849	effect.complete = callback || options.complete;
13850
13851	return effect;
13852}
13853
13854function standardAnimationOption( option ) {
13855	// Valid standard speeds (nothing, number, named speed)
13856	if ( !option || typeof option === "number" || $.fx.speeds[ option ] ) {
13857		return true;
13858	}
13859
13860	// Invalid strings - treat as "normal" speed
13861	if ( typeof option === "string" && !$.effects.effect[ option ] ) {
13862		return true;
13863	}
13864
13865	// Complete callback
13866	if ( $.isFunction( option ) ) {
13867		return true;
13868	}
13869
13870	// Options hash (but not naming an effect)
13871	if ( typeof option === "object" && !option.effect ) {
13872		return true;
13873	}
13874
13875	// Didn't match any standard API
13876	return false;
13877}
13878
13879$.fn.extend({
13880	effect: function( /* effect, options, speed, callback */ ) {
13881		var args = _normalizeArguments.apply( this, arguments ),
13882			mode = args.mode,
13883			queue = args.queue,
13884			effectMethod = $.effects.effect[ args.effect ];
13885
13886		if ( $.fx.off || !effectMethod ) {
13887			// delegate to the original method (e.g., .show()) if possible
13888			if ( mode ) {
13889				return this[ mode ]( args.duration, args.complete );
13890			} else {
13891				return this.each( function() {
13892					if ( args.complete ) {
13893						args.complete.call( this );
13894					}
13895				});
13896			}
13897		}
13898
13899		function run( next ) {
13900			var elem = $( this ),
13901				complete = args.complete,
13902				mode = args.mode;
13903
13904			function done() {
13905				if ( $.isFunction( complete ) ) {
13906					complete.call( elem[0] );
13907				}
13908				if ( $.isFunction( next ) ) {
13909					next();
13910				}
13911			}
13912
13913			// If the element already has the correct final state, delegate to
13914			// the core methods so the internal tracking of "olddisplay" works.
13915			if ( elem.is( ":hidden" ) ? mode === "hide" : mode === "show" ) {
13916				elem[ mode ]();
13917				done();
13918			} else {
13919				effectMethod.call( elem[0], args, done );
13920			}
13921		}
13922
13923		return queue === false ? this.each( run ) : this.queue( queue || "fx", run );
13924	},
13925
13926	show: (function( orig ) {
13927		return function( option ) {
13928			if ( standardAnimationOption( option ) ) {
13929				return orig.apply( this, arguments );
13930			} else {
13931				var args = _normalizeArguments.apply( this, arguments );
13932				args.mode = "show";
13933				return this.effect.call( this, args );
13934			}
13935		};
13936	})( $.fn.show ),
13937
13938	hide: (function( orig ) {
13939		return function( option ) {
13940			if ( standardAnimationOption( option ) ) {
13941				return orig.apply( this, arguments );
13942			} else {
13943				var args = _normalizeArguments.apply( this, arguments );
13944				args.mode = "hide";
13945				return this.effect.call( this, args );
13946			}
13947		};
13948	})( $.fn.hide ),
13949
13950	toggle: (function( orig ) {
13951		return function( option ) {
13952			if ( standardAnimationOption( option ) || typeof option === "boolean" ) {
13953				return orig.apply( this, arguments );
13954			} else {
13955				var args = _normalizeArguments.apply( this, arguments );
13956				args.mode = "toggle";
13957				return this.effect.call( this, args );
13958			}
13959		};
13960	})( $.fn.toggle ),
13961
13962	// helper functions
13963	cssUnit: function(key) {
13964		var style = this.css( key ),
13965			val = [];
13966
13967		$.each( [ "em", "px", "%", "pt" ], function( i, unit ) {
13968			if ( style.indexOf( unit ) > 0 ) {
13969				val = [ parseFloat( style ), unit ];
13970			}
13971		});
13972		return val;
13973	}
13974});
13975
13976})();
13977
13978/******************************************************************************/
13979/*********************************** EASING ***********************************/
13980/******************************************************************************/
13981
13982(function() {
13983
13984// based on easing equations from Robert Penner (http://www.robertpenner.com/easing)
13985
13986var baseEasings = {};
13987
13988$.each( [ "Quad", "Cubic", "Quart", "Quint", "Expo" ], function( i, name ) {
13989	baseEasings[ name ] = function( p ) {
13990		return Math.pow( p, i + 2 );
13991	};
13992});
13993
13994$.extend( baseEasings, {
13995	Sine: function ( p ) {
13996		return 1 - Math.cos( p * Math.PI / 2 );
13997	},
13998	Circ: function ( p ) {
13999		return 1 - Math.sqrt( 1 - p * p );
14000	},
14001	Elastic: function( p ) {
14002		return p === 0 || p === 1 ? p :
14003			-Math.pow( 2, 8 * (p - 1) ) * Math.sin( ( (p - 1) * 80 - 7.5 ) * Math.PI / 15 );
14004	},
14005	Back: function( p ) {
14006		return p * p * ( 3 * p - 2 );
14007	},
14008	Bounce: function ( p ) {
14009		var pow2,
14010			bounce = 4;
14011
14012		while ( p < ( ( pow2 = Math.pow( 2, --bounce ) ) - 1 ) / 11 ) {}
14013		return 1 / Math.pow( 4, 3 - bounce ) - 7.5625 * Math.pow( ( pow2 * 3 - 2 ) / 22 - p, 2 );
14014	}
14015});
14016
14017$.each( baseEasings, function( name, easeIn ) {
14018	$.easing[ "easeIn" + name ] = easeIn;
14019	$.easing[ "easeOut" + name ] = function( p ) {
14020		return 1 - easeIn( 1 - p );
14021	};
14022	$.easing[ "easeInOut" + name ] = function( p ) {
14023		return p < 0.5 ?
14024			easeIn( p * 2 ) / 2 :
14025			1 - easeIn( p * -2 + 2 ) / 2;
14026	};
14027});
14028
14029})();
14030
14031})(jQuery);
14032(function( $, undefined ) {
14033
14034var rvertical = /up|down|vertical/,
14035	rpositivemotion = /up|left|vertical|horizontal/;
14036
14037$.effects.effect.blind = function( o, done ) {
14038	// Create element
14039	var el = $( this ),
14040		props = [ "position", "top", "bottom", "left", "right", "height", "width" ],
14041		mode = $.effects.setMode( el, o.mode || "hide" ),
14042		direction = o.direction || "up",
14043		vertical = rvertical.test( direction ),
14044		ref = vertical ? "height" : "width",
14045		ref2 = vertical ? "top" : "left",
14046		motion = rpositivemotion.test( direction ),
14047		animation = {},
14048		show = mode === "show",
14049		wrapper, distance, margin;
14050
14051	// if already wrapped, the wrapper's properties are my property. #6245
14052	if ( el.parent().is( ".ui-effects-wrapper" ) ) {
14053		$.effects.save( el.parent(), props );
14054	} else {
14055		$.effects.save( el, props );
14056	}
14057	el.show();
14058	wrapper = $.effects.createWrapper( el ).css({
14059		overflow: "hidden"
14060	});
14061
14062	distance = wrapper[ ref ]();
14063	margin = parseFloat( wrapper.css( ref2 ) ) || 0;
14064
14065	animation[ ref ] = show ? distance : 0;
14066	if ( !motion ) {
14067		el
14068			.css( vertical ? "bottom" : "right", 0 )
14069			.css( vertical ? "top" : "left", "auto" )
14070			.css({ position: "absolute" });
14071
14072		animation[ ref2 ] = show ? margin : distance + margin;
14073	}
14074
14075	// start at 0 if we are showing
14076	if ( show ) {
14077		wrapper.css( ref, 0 );
14078		if ( ! motion ) {
14079			wrapper.css( ref2, margin + distance );
14080		}
14081	}
14082
14083	// Animate
14084	wrapper.animate( animation, {
14085		duration: o.duration,
14086		easing: o.easing,
14087		queue: false,
14088		complete: function() {
14089			if ( mode === "hide" ) {
14090				el.hide();
14091			}
14092			$.effects.restore( el, props );
14093			$.effects.removeWrapper( el );
14094			done();
14095		}
14096	});
14097
14098};
14099
14100})(jQuery);
14101(function( $, undefined ) {
14102
14103$.effects.effect.bounce = function( o, done ) {
14104	var el = $( this ),
14105		props = [ "position", "top", "bottom", "left", "right", "height", "width" ],
14106
14107		// defaults:
14108		mode = $.effects.setMode( el, o.mode || "effect" ),
14109		hide = mode === "hide",
14110		show = mode === "show",
14111		direction = o.direction || "up",
14112		distance = o.distance,
14113		times = o.times || 5,
14114
14115		// number of internal animations
14116		anims = times * 2 + ( show || hide ? 1 : 0 ),
14117		speed = o.duration / anims,
14118		easing = o.easing,
14119
14120		// utility:
14121		ref = ( direction === "up" || direction === "down" ) ? "top" : "left",
14122		motion = ( direction === "up" || direction === "left" ),
14123		i,
14124		upAnim,
14125		downAnim,
14126
14127		// we will need to re-assemble the queue to stack our animations in place
14128		queue = el.queue(),
14129		queuelen = queue.length;
14130
14131	// Avoid touching opacity to prevent clearType and PNG issues in IE
14132	if ( show || hide ) {
14133		props.push( "opacity" );
14134	}
14135
14136	$.effects.save( el, props );
14137	el.show();
14138	$.effects.createWrapper( el ); // Create Wrapper
14139
14140	// default distance for the BIGGEST bounce is the outer Distance / 3
14141	if ( !distance ) {
14142		distance = el[ ref === "top" ? "outerHeight" : "outerWidth" ]() / 3;
14143	}
14144
14145	if ( show ) {
14146		downAnim = { opacity: 1 };
14147		downAnim[ ref ] = 0;
14148
14149		// if we are showing, force opacity 0 and set the initial position
14150		// then do the "first" animation
14151		el.css( "opacity", 0 )
14152			.css( ref, motion ? -distance * 2 : distance * 2 )
14153			.animate( downAnim, speed, easing );
14154	}
14155
14156	// start at the smallest distance if we are hiding
14157	if ( hide ) {
14158		distance = distance / Math.pow( 2, times - 1 );
14159	}
14160
14161	downAnim = {};
14162	downAnim[ ref ] = 0;
14163	// Bounces up/down/left/right then back to 0 -- times * 2 animations happen here
14164	for ( i = 0; i < times; i++ ) {
14165		upAnim = {};
14166		upAnim[ ref ] = ( motion ? "-=" : "+=" ) + distance;
14167
14168		el.animate( upAnim, speed, easing )
14169			.animate( downAnim, speed, easing );
14170
14171		distance = hide ? distance * 2 : distance / 2;
14172	}
14173
14174	// Last Bounce when Hiding
14175	if ( hide ) {
14176		upAnim = { opacity: 0 };
14177		upAnim[ ref ] = ( motion ? "-=" : "+=" ) + distance;
14178
14179		el.animate( upAnim, speed, easing );
14180	}
14181
14182	el.queue(function() {
14183		if ( hide ) {
14184			el.hide();
14185		}
14186		$.effects.restore( el, props );
14187		$.effects.removeWrapper( el );
14188		done();
14189	});
14190
14191	// inject all the animations we just queued to be first in line (after "inprogress")
14192	if ( queuelen > 1) {
14193		queue.splice.apply( queue,
14194			[ 1, 0 ].concat( queue.splice( queuelen, anims + 1 ) ) );
14195	}
14196	el.dequeue();
14197
14198};
14199
14200})(jQuery);
14201(function( $, undefined ) {
14202
14203$.effects.effect.clip = function( o, done ) {
14204	// Create element
14205	var el = $( this ),
14206		props = [ "position", "top", "bottom", "left", "right", "height", "width" ],
14207		mode = $.effects.setMode( el, o.mode || "hide" ),
14208		show = mode === "show",
14209		direction = o.direction || "vertical",
14210		vert = direction === "vertical",
14211		size = vert ? "height" : "width",
14212		position = vert ? "top" : "left",
14213		animation = {},
14214		wrapper, animate, distance;
14215
14216	// Save & Show
14217	$.effects.save( el, props );
14218	el.show();
14219
14220	// Create Wrapper
14221	wrapper = $.effects.createWrapper( el ).css({
14222		overflow: "hidden"
14223	});
14224	animate = ( el[0].tagName === "IMG" ) ? wrapper : el;
14225	distance = animate[ size ]();
14226
14227	// Shift
14228	if ( show ) {
14229		animate.css( size, 0 );
14230		animate.css( position, distance / 2 );
14231	}
14232
14233	// Create Animation Object:
14234	animation[ size ] = show ? distance : 0;
14235	animation[ position ] = show ? 0 : distance / 2;
14236
14237	// Animate
14238	animate.animate( animation, {
14239		queue: false,
14240		duration: o.duration,
14241		easing: o.easing,
14242		complete: function() {
14243			if ( !show ) {
14244				el.hide();
14245			}
14246			$.effects.restore( el, props );
14247			$.effects.removeWrapper( el );
14248			done();
14249		}
14250	});
14251
14252};
14253
14254})(jQuery);
14255(function( $, undefined ) {
14256
14257$.effects.effect.drop = function( o, done ) {
14258
14259	var el = $( this ),
14260		props = [ "position", "top", "bottom", "left", "right", "opacity", "height", "width" ],
14261		mode = $.effects.setMode( el, o.mode || "hide" ),
14262		show = mode === "show",
14263		direction = o.direction || "left",
14264		ref = ( direction === "up" || direction === "down" ) ? "top" : "left",
14265		motion = ( direction === "up" || direction === "left" ) ? "pos" : "neg",
14266		animation = {
14267			opacity: show ? 1 : 0
14268		},
14269		distance;
14270
14271	// Adjust
14272	$.effects.save( el, props );
14273	el.show();
14274	$.effects.createWrapper( el );
14275
14276	distance = o.distance || el[ ref === "top" ? "outerHeight": "outerWidth" ]( true ) / 2;
14277
14278	if ( show ) {
14279		el
14280			.css( "opacity", 0 )
14281			.css( ref, motion === "pos" ? -distance : distance );
14282	}
14283
14284	// Animation
14285	animation[ ref ] = ( show ?
14286		( motion === "pos" ? "+=" : "-=" ) :
14287		( motion === "pos" ? "-=" : "+=" ) ) +
14288		distance;
14289
14290	// Animate
14291	el.animate( animation, {
14292		queue: false,
14293		duration: o.duration,
14294		easing: o.easing,
14295		complete: function() {
14296			if ( mode === "hide" ) {
14297				el.hide();
14298			}
14299			$.effects.restore( el, props );
14300			$.effects.removeWrapper( el );
14301			done();
14302		}
14303	});
14304};
14305
14306})(jQuery);
14307(function( $, undefined ) {
14308
14309$.effects.effect.explode = function( o, done ) {
14310
14311	var rows = o.pieces ? Math.round( Math.sqrt( o.pieces ) ) : 3,
14312		cells = rows,
14313		el = $( this ),
14314		mode = $.effects.setMode( el, o.mode || "hide" ),
14315		show = mode === "show",
14316
14317		// show and then visibility:hidden the element before calculating offset
14318		offset = el.show().css( "visibility", "hidden" ).offset(),
14319
14320		// width and height of a piece
14321		width = Math.ceil( el.outerWidth() / cells ),
14322		height = Math.ceil( el.outerHeight() / rows ),
14323		pieces = [],
14324
14325		// loop
14326		i, j, left, top, mx, my;
14327
14328	// children animate complete:
14329	function childComplete() {
14330		pieces.push( this );
14331		if ( pieces.length === rows * cells ) {
14332			animComplete();
14333		}
14334	}
14335
14336	// clone the element for each row and cell.
14337	for( i = 0; i < rows ; i++ ) { // ===>
14338		top = offset.top + i * height;
14339		my = i - ( rows - 1 ) / 2 ;
14340
14341		for( j = 0; j < cells ; j++ ) { // |||
14342			left = offset.left + j * width;
14343			mx = j - ( cells - 1 ) / 2 ;
14344
14345			// Create a clone of the now hidden main element that will be absolute positioned
14346			// within a wrapper div off the -left and -top equal to size of our pieces
14347			el
14348				.clone()
14349				.appendTo( "body" )
14350				.wrap( "<div></div>" )
14351				.css({
14352					position: "absolute",
14353					visibility: "visible",
14354					left: -j * width,
14355					top: -i * height
14356				})
14357
14358			// select the wrapper - make it overflow: hidden and absolute positioned based on
14359			// where the original was located +left and +top equal to the size of pieces
14360				.parent()
14361				.addClass( "ui-effects-explode" )
14362				.css({
14363					position: "absolute",
14364					overflow: "hidden",
14365					width: width,
14366					height: height,
14367					left: left + ( show ? mx * width : 0 ),
14368					top: top + ( show ? my * height : 0 ),
14369					opacity: show ? 0 : 1
14370				}).animate({
14371					left: left + ( show ? 0 : mx * width ),
14372					top: top + ( show ? 0 : my * height ),
14373					opacity: show ? 1 : 0
14374				}, o.duration || 500, o.easing, childComplete );
14375		}
14376	}
14377
14378	function animComplete() {
14379		el.css({
14380			visibility: "visible"
14381		});
14382		$( pieces ).remove();
14383		if ( !show ) {
14384			el.hide();
14385		}
14386		done();
14387	}
14388};
14389
14390})(jQuery);
14391(function( $, undefined ) {
14392
14393$.effects.effect.fade = function( o, done ) {
14394	var el = $( this ),
14395		mode = $.effects.setMode( el, o.mode || "toggle" );
14396
14397	el.animate({
14398		opacity: mode
14399	}, {
14400		queue: false,
14401		duration: o.duration,
14402		easing: o.easing,
14403		complete: done
14404	});
14405};
14406
14407})( jQuery );
14408(function( $, undefined ) {
14409
14410$.effects.effect.fold = function( o, done ) {
14411
14412	// Create element
14413	var el = $( this ),
14414		props = [ "position", "top", "bottom", "left", "right", "height", "width" ],
14415		mode = $.effects.setMode( el, o.mode || "hide" ),
14416		show = mode === "show",
14417		hide = mode === "hide",
14418		size = o.size || 15,
14419		percent = /([0-9]+)%/.exec( size ),
14420		horizFirst = !!o.horizFirst,
14421		widthFirst = show !== horizFirst,
14422		ref = widthFirst ? [ "width", "height" ] : [ "height", "width" ],
14423		duration = o.duration / 2,
14424		wrapper, distance,
14425		animation1 = {},
14426		animation2 = {};
14427
14428	$.effects.save( el, props );
14429	el.show();
14430
14431	// Create Wrapper
14432	wrapper = $.effects.createWrapper( el ).css({
14433		overflow: "hidden"
14434	});
14435	distance = widthFirst ?
14436		[ wrapper.width(), wrapper.height() ] :
14437		[ wrapper.height(), wrapper.width() ];
14438
14439	if ( percent ) {
14440		size = parseInt( percent[ 1 ], 10 ) / 100 * distance[ hide ? 0 : 1 ];
14441	}
14442	if ( show ) {
14443		wrapper.css( horizFirst ? {
14444			height: 0,
14445			width: size
14446		} : {
14447			height: size,
14448			width: 0
14449		});
14450	}
14451
14452	// Animation
14453	animation1[ ref[ 0 ] ] = show ? distance[ 0 ] : size;
14454	animation2[ ref[ 1 ] ] = show ? distance[ 1 ] : 0;
14455
14456	// Animate
14457	wrapper
14458		.animate( animation1, duration, o.easing )
14459		.animate( animation2, duration, o.easing, function() {
14460			if ( hide ) {
14461				el.hide();
14462			}
14463			$.effects.restore( el, props );
14464			$.effects.removeWrapper( el );
14465			done();
14466		});
14467
14468};
14469
14470})(jQuery);
14471(function( $, undefined ) {
14472
14473$.effects.effect.highlight = function( o, done ) {
14474	var elem = $( this ),
14475		props = [ "backgroundImage", "backgroundColor", "opacity" ],
14476		mode = $.effects.setMode( elem, o.mode || "show" ),
14477		animation = {
14478			backgroundColor: elem.css( "backgroundColor" )
14479		};
14480
14481	if (mode === "hide") {
14482		animation.opacity = 0;
14483	}
14484
14485	$.effects.save( elem, props );
14486
14487	elem
14488		.show()
14489		.css({
14490			backgroundImage: "none",
14491			backgroundColor: o.color || "#ffff99"
14492		})
14493		.animate( animation, {
14494			queue: false,
14495			duration: o.duration,
14496			easing: o.easing,
14497			complete: function() {
14498				if ( mode === "hide" ) {
14499					elem.hide();
14500				}
14501				$.effects.restore( elem, props );
14502				done();
14503			}
14504		});
14505};
14506
14507})(jQuery);
14508(function( $, undefined ) {
14509
14510$.effects.effect.pulsate = function( o, done ) {
14511	var elem = $( this ),
14512		mode = $.effects.setMode( elem, o.mode || "show" ),
14513		show = mode === "show",
14514		hide = mode === "hide",
14515		showhide = ( show || mode === "hide" ),
14516
14517		// showing or hiding leaves of the "last" animation
14518		anims = ( ( o.times || 5 ) * 2 ) + ( showhide ? 1 : 0 ),
14519		duration = o.duration / anims,
14520		animateTo = 0,
14521		queue = elem.queue(),
14522		queuelen = queue.length,
14523		i;
14524
14525	if ( show || !elem.is(":visible")) {
14526		elem.css( "opacity", 0 ).show();
14527		animateTo = 1;
14528	}
14529
14530	// anims - 1 opacity "toggles"
14531	for ( i = 1; i < anims; i++ ) {
14532		elem.animate({
14533			opacity: animateTo
14534		}, duration, o.easing );
14535		animateTo = 1 - animateTo;
14536	}
14537
14538	elem.animate({
14539		opacity: animateTo
14540	}, duration, o.easing);
14541
14542	elem.queue(function() {
14543		if ( hide ) {
14544			elem.hide();
14545		}
14546		done();
14547	});
14548
14549	// We just queued up "anims" animations, we need to put them next in the queue
14550	if ( queuelen > 1 ) {
14551		queue.splice.apply( queue,
14552			[ 1, 0 ].concat( queue.splice( queuelen, anims + 1 ) ) );
14553	}
14554	elem.dequeue();
14555};
14556
14557})(jQuery);
14558(function( $, undefined ) {
14559
14560$.effects.effect.puff = function( o, done ) {
14561	var elem = $( this ),
14562		mode = $.effects.setMode( elem, o.mode || "hide" ),
14563		hide = mode === "hide",
14564		percent = parseInt( o.percent, 10 ) || 150,
14565		factor = percent / 100,
14566		original = {
14567			height: elem.height(),
14568			width: elem.width(),
14569			outerHeight: elem.outerHeight(),
14570			outerWidth: elem.outerWidth()
14571		};
14572
14573	$.extend( o, {
14574		effect: "scale",
14575		queue: false,
14576		fade: true,
14577		mode: mode,
14578		complete: done,
14579		percent: hide ? percent : 100,
14580		from: hide ?
14581			original :
14582			{
14583				height: original.height * factor,
14584				width: original.width * factor,
14585				outerHeight: original.outerHeight * factor,
14586				outerWidth: original.outerWidth * factor
14587			}
14588	});
14589
14590	elem.effect( o );
14591};
14592
14593$.effects.effect.scale = function( o, done ) {
14594
14595	// Create element
14596	var el = $( this ),
14597		options = $.extend( true, {}, o ),
14598		mode = $.effects.setMode( el, o.mode || "effect" ),
14599		percent = parseInt( o.percent, 10 ) ||
14600			( parseInt( o.percent, 10 ) === 0 ? 0 : ( mode === "hide" ? 0 : 100 ) ),
14601		direction = o.direction || "both",
14602		origin = o.origin,
14603		original = {
14604			height: el.height(),
14605			width: el.width(),
14606			outerHeight: el.outerHeight(),
14607			outerWidth: el.outerWidth()
14608		},
14609		factor = {
14610			y: direction !== "horizontal" ? (percent / 100) : 1,
14611			x: direction !== "vertical" ? (percent / 100) : 1
14612		};
14613
14614	// We are going to pass this effect to the size effect:
14615	options.effect = "size";
14616	options.queue = false;
14617	options.complete = done;
14618
14619	// Set default origin and restore for show/hide
14620	if ( mode !== "effect" ) {
14621		options.origin = origin || ["middle","center"];
14622		options.restore = true;
14623	}
14624
14625	options.from = o.from || ( mode === "show" ? {
14626		height: 0,
14627		width: 0,
14628		outerHeight: 0,
14629		outerWidth: 0
14630	} : original );
14631	options.to = {
14632		height: original.height * factor.y,
14633		width: original.width * factor.x,
14634		outerHeight: original.outerHeight * factor.y,
14635		outerWidth: original.outerWidth * factor.x
14636	};
14637
14638	// Fade option to support puff
14639	if ( options.fade ) {
14640		if ( mode === "show" ) {
14641			options.from.opacity = 0;
14642			options.to.opacity = 1;
14643		}
14644		if ( mode === "hide" ) {
14645			options.from.opacity = 1;
14646			options.to.opacity = 0;
14647		}
14648	}
14649
14650	// Animate
14651	el.effect( options );
14652
14653};
14654
14655$.effects.effect.size = function( o, done ) {
14656
14657	// Create element
14658	var original, baseline, factor,
14659		el = $( this ),
14660		props0 = [ "position", "top", "bottom", "left", "right", "width", "height", "overflow", "opacity" ],
14661
14662		// Always restore
14663		props1 = [ "position", "top", "bottom", "left", "right", "overflow", "opacity" ],
14664
14665		// Copy for children
14666		props2 = [ "width", "height", "overflow" ],
14667		cProps = [ "fontSize" ],
14668		vProps = [ "borderTopWidth", "borderBottomWidth", "paddingTop", "paddingBottom" ],
14669		hProps = [ "borderLeftWidth", "borderRightWidth", "paddingLeft", "paddingRight" ],
14670
14671		// Set options
14672		mode = $.effects.setMode( el, o.mode || "effect" ),
14673		restore = o.restore || mode !== "effect",
14674		scale = o.scale || "both",
14675		origin = o.origin || [ "middle", "center" ],
14676		position = el.css( "position" ),
14677		props = restore ? props0 : props1,
14678		zero = {
14679			height: 0,
14680			width: 0,
14681			outerHeight: 0,
14682			outerWidth: 0
14683		};
14684
14685	if ( mode === "show" ) {
14686		el.show();
14687	}
14688	original = {
14689		height: el.height(),
14690		width: el.width(),
14691		outerHeight: el.outerHeight(),
14692		outerWidth: el.outerWidth()
14693	};
14694
14695	if ( o.mode === "toggle" && mode === "show" ) {
14696		el.from = o.to || zero;
14697		el.to = o.from || original;
14698	} else {
14699		el.from = o.from || ( mode === "show" ? zero : original );
14700		el.to = o.to || ( mode === "hide" ? zero : original );
14701	}
14702
14703	// Set scaling factor
14704	factor = {
14705		from: {
14706			y: el.from.height / original.height,
14707			x: el.from.width / original.width
14708		},
14709		to: {
14710			y: el.to.height / original.height,
14711			x: el.to.width / original.width
14712		}
14713	};
14714
14715	// Scale the css box
14716	if ( scale === "box" || scale === "both" ) {
14717
14718		// Vertical props scaling
14719		if ( factor.from.y !== factor.to.y ) {
14720			props = props.concat( vProps );
14721			el.from = $.effects.setTransition( el, vProps, factor.from.y, el.from );
14722			el.to = $.effects.setTransition( el, vProps, factor.to.y, el.to );
14723		}
14724
14725		// Horizontal props scaling
14726		if ( factor.from.x !== factor.to.x ) {
14727			props = props.concat( hProps );
14728			el.from = $.effects.setTransition( el, hProps, factor.from.x, el.from );
14729			el.to = $.effects.setTransition( el, hProps, factor.to.x, el.to );
14730		}
14731	}
14732
14733	// Scale the content
14734	if ( scale === "content" || scale === "both" ) {
14735
14736		// Vertical props scaling
14737		if ( factor.from.y !== factor.to.y ) {
14738			props = props.concat( cProps ).concat( props2 );
14739			el.from = $.effects.setTransition( el, cProps, factor.from.y, el.from );
14740			el.to = $.effects.setTransition( el, cProps, factor.to.y, el.to );
14741		}
14742	}
14743
14744	$.effects.save( el, props );
14745	el.show();
14746	$.effects.createWrapper( el );
14747	el.css( "overflow", "hidden" ).css( el.from );
14748
14749	// Adjust
14750	if (origin) { // Calculate baseline shifts
14751		baseline = $.effects.getBaseline( origin, original );
14752		el.from.top = ( original.outerHeight - el.outerHeight() ) * baseline.y;
14753		el.from.left = ( original.outerWidth - el.outerWidth() ) * baseline.x;
14754		el.to.top = ( original.outerHeight - el.to.outerHeight ) * baseline.y;
14755		el.to.left = ( original.outerWidth - el.to.outerWidth ) * baseline.x;
14756	}
14757	el.css( el.from ); // set top & left
14758
14759	// Animate
14760	if ( scale === "content" || scale === "both" ) { // Scale the children
14761
14762		// Add margins/font-size
14763		vProps = vProps.concat([ "marginTop", "marginBottom" ]).concat(cProps);
14764		hProps = hProps.concat([ "marginLeft", "marginRight" ]);
14765		props2 = props0.concat(vProps).concat(hProps);
14766
14767		el.find( "*[width]" ).each( function(){
14768			var child = $( this ),
14769				c_original = {
14770					height: child.height(),
14771					width: child.width(),
14772					outerHeight: child.outerHeight(),
14773					outerWidth: child.outerWidth()
14774				};
14775			if (restore) {
14776				$.effects.save(child, props2);
14777			}
14778
14779			child.from = {
14780				height: c_original.height * factor.from.y,
14781				width: c_original.width * factor.from.x,
14782				outerHeight: c_original.outerHeight * factor.from.y,
14783				outerWidth: c_original.outerWidth * factor.from.x
14784			};
14785			child.to = {
14786				height: c_original.height * factor.to.y,
14787				width: c_original.width * factor.to.x,
14788				outerHeight: c_original.height * factor.to.y,
14789				outerWidth: c_original.width * factor.to.x
14790			};
14791
14792			// Vertical props scaling
14793			if ( factor.from.y !== factor.to.y ) {
14794				child.from = $.effects.setTransition( child, vProps, factor.from.y, child.from );
14795				child.to = $.effects.setTransition( child, vProps, factor.to.y, child.to );
14796			}
14797
14798			// Horizontal props scaling
14799			if ( factor.from.x !== factor.to.x ) {
14800				child.from = $.effects.setTransition( child, hProps, factor.from.x, child.from );
14801				child.to = $.effects.setTransition( child, hProps, factor.to.x, child.to );
14802			}
14803
14804			// Animate children
14805			child.css( child.from );
14806			child.animate( child.to, o.duration, o.easing, function() {
14807
14808				// Restore children
14809				if ( restore ) {
14810					$.effects.restore( child, props2 );
14811				}
14812			});
14813		});
14814	}
14815
14816	// Animate
14817	el.animate( el.to, {
14818		queue: false,
14819		duration: o.duration,
14820		easing: o.easing,
14821		complete: function() {
14822			if ( el.to.opacity === 0 ) {
14823				el.css( "opacity", el.from.opacity );
14824			}
14825			if( mode === "hide" ) {
14826				el.hide();
14827			}
14828			$.effects.restore( el, props );
14829			if ( !restore ) {
14830
14831				// we need to calculate our new positioning based on the scaling
14832				if ( position === "static" ) {
14833					el.css({
14834						position: "relative",
14835						top: el.to.top,
14836						left: el.to.left
14837					});
14838				} else {
14839					$.each([ "top", "left" ], function( idx, pos ) {
14840						el.css( pos, function( _, str ) {
14841							var val = parseInt( str, 10 ),
14842								toRef = idx ? el.to.left : el.to.top;
14843
14844							// if original was "auto", recalculate the new value from wrapper
14845							if ( str === "auto" ) {
14846								return toRef + "px";
14847							}
14848
14849							return val + toRef + "px";
14850						});
14851					});
14852				}
14853			}
14854
14855			$.effects.removeWrapper( el );
14856			done();
14857		}
14858	});
14859
14860};
14861
14862})(jQuery);
14863(function( $, undefined ) {
14864
14865$.effects.effect.shake = function( o, done ) {
14866
14867	var el = $( this ),
14868		props = [ "position", "top", "bottom", "left", "right", "height", "width" ],
14869		mode = $.effects.setMode( el, o.mode || "effect" ),
14870		direction = o.direction || "left",
14871		distance = o.distance || 20,
14872		times = o.times || 3,
14873		anims = times * 2 + 1,
14874		speed = Math.round(o.duration/anims),
14875		ref = (direction === "up" || direction === "down") ? "top" : "left",
14876		positiveMotion = (direction === "up" || direction === "left"),
14877		animation = {},
14878		animation1 = {},
14879		animation2 = {},
14880		i,
14881
14882		// we will need to re-assemble the queue to stack our animations in place
14883		queue = el.queue(),
14884		queuelen = queue.length;
14885
14886	$.effects.save( el, props );
14887	el.show();
14888	$.effects.createWrapper( el );
14889
14890	// Animation
14891	animation[ ref ] = ( positiveMotion ? "-=" : "+=" ) + distance;
14892	animation1[ ref ] = ( positiveMotion ? "+=" : "-=" ) + distance * 2;
14893	animation2[ ref ] = ( positiveMotion ? "-=" : "+=" ) + distance * 2;
14894
14895	// Animate
14896	el.animate( animation, speed, o.easing );
14897
14898	// Shakes
14899	for ( i = 1; i < times; i++ ) {
14900		el.animate( animation1, speed, o.easing ).animate( animation2, speed, o.easing );
14901	}
14902	el
14903		.animate( animation1, speed, o.easing )
14904		.animate( animation, speed / 2, o.easing )
14905		.queue(function() {
14906			if ( mode === "hide" ) {
14907				el.hide();
14908			}
14909			$.effects.restore( el, props );
14910			$.effects.removeWrapper( el );
14911			done();
14912		});
14913
14914	// inject all the animations we just queued to be first in line (after "inprogress")
14915	if ( queuelen > 1) {
14916		queue.splice.apply( queue,
14917			[ 1, 0 ].concat( queue.splice( queuelen, anims + 1 ) ) );
14918	}
14919	el.dequeue();
14920
14921};
14922
14923})(jQuery);
14924(function( $, undefined ) {
14925
14926$.effects.effect.slide = function( o, done ) {
14927
14928	// Create element
14929	var el = $( this ),
14930		props = [ "position", "top", "bottom", "left", "right", "width", "height" ],
14931		mode = $.effects.setMode( el, o.mode || "show" ),
14932		show = mode === "show",
14933		direction = o.direction || "left",
14934		ref = (direction === "up" || direction === "down") ? "top" : "left",
14935		positiveMotion = (direction === "up" || direction === "left"),
14936		distance,
14937		animation = {};
14938
14939	// Adjust
14940	$.effects.save( el, props );
14941	el.show();
14942	distance = o.distance || el[ ref === "top" ? "outerHeight" : "outerWidth" ]( true );
14943
14944	$.effects.createWrapper( el ).css({
14945		overflow: "hidden"
14946	});
14947
14948	if ( show ) {
14949		el.css( ref, positiveMotion ? (isNaN(distance) ? "-" + distance : -distance) : distance );
14950	}
14951
14952	// Animation
14953	animation[ ref ] = ( show ?
14954		( positiveMotion ? "+=" : "-=") :
14955		( positiveMotion ? "-=" : "+=")) +
14956		distance;
14957
14958	// Animate
14959	el.animate( animation, {
14960		queue: false,
14961		duration: o.duration,
14962		easing: o.easing,
14963		complete: function() {
14964			if ( mode === "hide" ) {
14965				el.hide();
14966			}
14967			$.effects.restore( el, props );
14968			$.effects.removeWrapper( el );
14969			done();
14970		}
14971	});
14972};
14973
14974})(jQuery);
14975(function( $, undefined ) {
14976
14977$.effects.effect.transfer = function( o, done ) {
14978	var elem = $( this ),
14979		target = $( o.to ),
14980		targetFixed = target.css( "position" ) === "fixed",
14981		body = $("body"),
14982		fixTop = targetFixed ? body.scrollTop() : 0,
14983		fixLeft = targetFixed ? body.scrollLeft() : 0,
14984		endPosition = target.offset(),
14985		animation = {
14986			top: endPosition.top - fixTop ,
14987			left: endPosition.left - fixLeft ,
14988			height: target.innerHeight(),
14989			width: target.innerWidth()
14990		},
14991		startPosition = elem.offset(),
14992		transfer = $( "<div class='ui-effects-transfer'></div>" )
14993			.appendTo( document.body )
14994			.addClass( o.className )
14995			.css({
14996				top: startPosition.top - fixTop ,
14997				left: startPosition.left - fixLeft ,
14998				height: elem.innerHeight(),
14999				width: elem.innerWidth(),
15000				position: targetFixed ? "fixed" : "absolute"
15001			})
15002			.animate( animation, o.duration, o.easing, function() {
15003				transfer.remove();
15004				done();
15005			});
15006};
15007
15008})(jQuery);

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.