PageSourceSearch

https://datashine.org.uk/js/jquery-ui-1.10.4/ui/jquery-ui.js

js datashine.org.uk collected 2026-10-03 22:57:00 UTC 436,747 bytes, 15,040 lines download raw bytes

vendor: 8,543 bytes, lines 1-294
1/*! jQuery UI - v1.10.4 - 2014-01-17
2* http://jqueryui.com
3* Includes: jquery.ui.core.js, jquery.ui.widget.js, jquery.ui.mouse.js, jquery.ui.draggable.js, jquery.ui.droppable.js, jquery.ui.resizable.js, jquery.ui.selectable.js, jquery.ui.sortable.js, jquery.ui.effect.js, jquery.ui.accordion.js, jquery.ui.autocomplete.js, jquery.ui.button.js, jquery.ui.datepicker.js, jquery.ui.dialog.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, jquery.ui.menu.js, jquery.ui.position.js, jquery.ui.progressbar.js, jquery.ui.slider.js, jquery.ui.spinner.js, jquery.ui.tabs.js, jquery.ui.tooltip.js
4* Copyright 2014 jQuery Foundation and other contributors; Licensed MIT */
5(function( $, undefined ) {
6
7var uuid = 0,
8	runiqueId = /^ui-id-\d+$/;
9
10// $.ui might exist from components with no dependencies, e.g., $.ui.position
11$.ui = $.ui || {};
12
13$.extend( $.ui, {
14	version: "1.10.4",
15
16	keyCode: {
17		BACKSPACE: 8,
18		COMMA: 188,
19		DELETE: 46,
20		DOWN: 40,
21		END: 35,
22		ENTER: 13,
23		ESCAPE: 27,
24		HOME: 36,
25		LEFT: 37,
26		NUMPAD_ADD: 107,
27		NUMPAD_DECIMAL: 110,
28		NUMPAD_DIVIDE: 111,
29		NUMPAD_ENTER: 108,
30		NUMPAD_MULTIPLY: 106,
31		NUMPAD_SUBTRACT: 109,
32		PAGE_DOWN: 34,
33		PAGE_UP: 33,
34		PERIOD: 190,
35		RIGHT: 39,
36		SPACE: 32,
37		TAB: 9,
38		UP: 38
39	}
40});
41
42// plugins
43$.fn.extend({
44	focus: (function( orig ) {
45		return function( delay, fn ) {
46			return typeof delay === "number" ?
47				this.each(function() {
48					var elem = this;
49					setTimeout(function() {
50						$( elem ).focus();
51						if ( fn ) {
52							fn.call( elem );
53						}
54					}, delay );
55				}) :
56				orig.apply( this, arguments );
57		};
58	})( $.fn.focus ),
59
60	scrollParent: function() {
61		var scrollParent;
62		if (($.ui.ie && (/(static|relative)/).test(this.css("position"))) || (/absolute/).test(this.css("position"))) {
63			scrollParent = this.parents().filter(function() {
64				return (/(relative|absolute|fixed)/).test($.css(this,"position")) && (/(auto|scroll)/).test($.css(this,"overflow")+$.css(this,"overflow-y")+$.css(this,"overflow-x"));
65			}).eq(0);
66		} else {
67			scrollParent = this.parents().filter(function() {
68				return (/(auto|scroll)/).test($.css(this,"overflow")+$.css(this,"overflow-y")+$.css(this,"overflow-x"));
69			}).eq(0);
70		}
71
72		return (/fixed/).test(this.css("position")) || !scrollParent.length ? $(document) : scrollParent;
73	},
74
75	zIndex: function( zIndex ) {
76		if ( zIndex !== undefined ) {
77			return this.css( "zIndex", zIndex );
78		}
79
80		if ( this.length ) {
81			var elem = $( this[ 0 ] ), position, value;
82			while ( elem.length && elem[ 0 ] !== document ) {
83				// Ignore z-index if position is set to a value where z-index is ignored by the browser
84				// This makes behavior of this function consistent across browsers
85				// WebKit always returns auto if the element is positioned
86				position = elem.css( "position" );
87				if ( position === "absolute" || position === "relative" || position === "fixed" ) {
88					// IE returns 0 when zIndex is not specified
89					// other browsers return a string
90					// we ignore the case of nested elements with an explicit value of 0
91					// <div style="z-index: -10;"><div style="z-index: 0;"></div></div>
92					value = parseInt( elem.css( "zIndex" ), 10 );
93					if ( !isNaN( value ) && value !== 0 ) {
94						return value;
95					}
96				}
97				elem = elem.parent();
98			}
99		}
100
101		return 0;
102	},
103
104	uniqueId: function() {
105		return this.each(function() {
106			if ( !this.id ) {
107				this.id = "ui-id-" + (++uuid);
108			}
109		});
110	},
111
112	removeUniqueId: function() {
113		return this.each(function() {
114			if ( runiqueId.test( this.id ) ) {
115				$( this ).removeAttr( "id" );
116			}
117		});
118	}
119});
120
121// selectors
122function focusable( element, isTabIndexNotNaN ) {
123	var map, mapName, img,
124		nodeName = element.nodeName.toLowerCase();
125	if ( "area" === nodeName ) {
126		map = element.parentNode;
127		mapName = map.name;
128		if ( !element.href || !mapName || map.nodeName.toLowerCase() !== "map" ) {
129			return false;
130		}
131		img = $( "img[usemap=#" + mapName + "]" )[0];
132		return !!img && visible( img );
133	}
134	return ( /input|select|textarea|button|object/.test( nodeName ) ?
135		!element.disabled :
136		"a" === nodeName ?
137			element.href || isTabIndexNotNaN :
138			isTabIndexNotNaN) &&
139		// the element and all of its ancestors must be visible
140		visible( element );
141}
142
143function visible( element ) {
144	return $.expr.filters.visible( element ) &&
145		!$( element ).parents().addBack().filter(function() {
146			return $.css( this, "visibility" ) === "hidden";
147		}).length;
148}
149
150$.extend( $.expr[ ":" ], {
151	data: $.expr.createPseudo ?
152		$.expr.createPseudo(function( dataName ) {
153			return function( elem ) {
154				return !!$.data( elem, dataName );
155			};
156		}) :
157		// support: jQuery <1.8
158		function( elem, i, match ) {
159			return !!$.data( elem, match[ 3 ] );
160		},
161
162	focusable: function( element ) {
163		return focusable( element, !isNaN( $.attr( element, "tabindex" ) ) );
164	},
165
166	tabbable: function( element ) {
167		var tabIndex = $.attr( element, "tabindex" ),
168			isTabIndexNaN = isNaN( tabIndex );
169		return ( isTabIndexNaN || tabIndex >= 0 ) && focusable( element, !isTabIndexNaN );
170	}
171});
172
173// support: jQuery <1.8
174if ( !$( "<a>" ).outerWidth( 1 ).jquery ) {
175	$.each( [ "Width", "Height" ], function( i, name ) {
176		var side = name === "Width" ? [ "Left", "Right" ] : [ "Top", "Bottom" ],
177			type = name.toLowerCase(),
178			orig = {
179				innerWidth: $.fn.innerWidth,
180				innerHeight: $.fn.innerHeight,
181				outerWidth: $.fn.outerWidth,
182				outerHeight: $.fn.outerHeight
183			};
184
185		function reduce( elem, size, border, margin ) {
186			$.each( side, function() {
187				size -= parseFloat( $.css( elem, "padding" + this ) ) || 0;
188				if ( border ) {
189					size -= parseFloat( $.css( elem, "border" + this + "Width" ) ) || 0;
190				}
191				if ( margin ) {
192					size -= parseFloat( $.css( elem, "margin" + this ) ) || 0;
193				}
194			});
195			return size;
196		}
197
198		$.fn[ "inner" + name ] = function( size ) {
199			if ( size === undefined ) {
200				return orig[ "inner" + name ].call( this );
201			}
202
203			return this.each(function() {
204				$( this ).css( type, reduce( this, size ) + "px" );
205			});
206		};
207
208		$.fn[ "outer" + name] = function( size, margin ) {
209			if ( typeof size !== "number" ) {
210				return orig[ "outer" + name ].call( this, size );
211			}
212
213			return this.each(function() {
214				$( this).css( type, reduce( this, size, true, margin ) + "px" );
215			});
216		};
217	});
218}
219
220// support: jQuery <1.8
221if ( !$.fn.addBack ) {
222	$.fn.addBack = function( selector ) {
223		return this.add( selector == null ?
224			this.prevObject : this.prevObject.filter( selector )
225		);
226	};
227}
228
229// support: jQuery 1.6.1, 1.6.2 (http://bugs.jquery.com/ticket/9413)
230if ( $( "<a>" ).data( "a-b", "a" ).removeData( "a-b" ).data( "a-b" ) ) {
231	$.fn.removeData = (function( removeData ) {
232		return function( key ) {
233			if ( arguments.length ) {
234				return removeData.call( this, $.camelCase( key ) );
235			} else {
236				return removeData.call( this );
237			}
238		};
239	})( $.fn.removeData );
240}
241
242
243
244
245
246// deprecated
247$.ui.ie = !!/msie [\w.]+/.exec( navigator.userAgent.toLowerCase() );
248
249$.support.selectstart = "onselectstart" in document.createElement( "div" );
250$.fn.extend({
251	disableSelection: function() {
252		return this.bind( ( $.support.selectstart ? "selectstart" : "mousedown" ) +
253			".ui-disableSelection", function( event ) {
254				event.preventDefault();
255			});
256	},
257
258	enableSelection: function() {
259		return this.unbind( ".ui-disableSelection" );
260	}
261});
262
263$.extend( $.ui, {
264	// $.ui.plugin is deprecated. Use $.widget() extensions instead.
265	plugin: {
266		add: function( module, option, set ) {
267			var i,
268				proto = $.ui[ module ].prototype;
269			for ( i in set ) {
270				proto.plugins[ i ] = proto.plugins[ i ] || [];
271				proto.plugins[ i ].push( [ option, set[ i ] ] );
272			}
273		},
274		call: function( instance, name, args ) {
275			var i,
276				set = instance.plugins[ name ];
277			if ( !set || !instance.element[ 0 ].parentNode || instance.element[ 0 ].parentNode.nodeType === 11 ) {
278				return;
279			}
280
281			for ( i = 0; i < set.length; i++ ) {
282				if ( instance.options[ set[ i ][ 0 ] ] ) {
283					set[ i ][ 1 ].apply( instance.element, args );
284				}
285			}
286		}
287	},
288
289	// only used by resizable
290	hasScroll: function( el, a ) {
291
292		//If overflow is hidden, the element might have extra content, but the user wants to hide it
293		if ( $( el ).css( "overflow" ) === "hidden") {
294			return false;
vendor: 6,506 bytes, lines 295-498
295		}
296
297		var scroll = ( a && a === "left" ) ? "scrollLeft" : "scrollTop",
298			has = false;
299
300		if ( el[ scroll ] > 0 ) {
301			return true;
302		}
303
304		// TODO: determine which cases actually cause this to happen
305		// if the element doesn't have the scroll set, see if it's possible to
306		// set the scroll
307		el[ scroll ] = 1;
308		has = ( el[ scroll ] > 0 );
309		el[ scroll ] = 0;
310		return has;
311	}
312});
313
314})( jQuery );
315
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,807 bytes, lines 499-830
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
828(function( $, undefined ) {
829
830var mouseHandled = false;
vendor: 97,508 bytes, lines 831-4124
831$( document ).mouseup( function() {
832	mouseHandled = false;
833});
834
835$.widget("ui.mouse", {
836	version: "1.10.4",
837	options: {
838		cancel: "input,textarea,button,select,option",
839		distance: 1,
840		delay: 0
841	},
842	_mouseInit: function() {
843		var that = this;
844
845		this.element
846			.bind("mousedown."+this.widgetName, function(event) {
847				return that._mouseDown(event);
848			})
849			.bind("click."+this.widgetName, function(event) {
850				if (true === $.data(event.target, that.widgetName + ".preventClickEvent")) {
851					$.removeData(event.target, that.widgetName + ".preventClickEvent");
852					event.stopImmediatePropagation();
853					return false;
854				}
855			});
856
857		this.started = false;
858	},
859
860	// TODO: make sure destroying one instance of mouse doesn't mess with
861	// other instances of mouse
862	_mouseDestroy: function() {
863		this.element.unbind("."+this.widgetName);
864		if ( this._mouseMoveDelegate ) {
865			$(document)
866				.unbind("mousemove."+this.widgetName, this._mouseMoveDelegate)
867				.unbind("mouseup."+this.widgetName, this._mouseUpDelegate);
868		}
869	},
870
871	_mouseDown: function(event) {
872		// don't let more than one widget handle mouseStart
873		if( mouseHandled ) { return; }
874
875		// we may have missed mouseup (out of window)
876		(this._mouseStarted && this._mouseUp(event));
877
878		this._mouseDownEvent = event;
879
880		var that = this,
881			btnIsLeft = (event.which === 1),
882			// event.target.nodeName works around a bug in IE 8 with
883			// disabled inputs (#7620)
884			elIsCancel = (typeof this.options.cancel === "string" && event.target.nodeName ? $(event.target).closest(this.options.cancel).length : false);
885		if (!btnIsLeft || elIsCancel || !this._mouseCapture(event)) {
886			return true;
887		}
888
889		this.mouseDelayMet = !this.options.delay;
890		if (!this.mouseDelayMet) {
891			this._mouseDelayTimer = setTimeout(function() {
892				that.mouseDelayMet = true;
893			}, this.options.delay);
894		}
895
896		if (this._mouseDistanceMet(event) && this._mouseDelayMet(event)) {
897			this._mouseStarted = (this._mouseStart(event) !== false);
898			if (!this._mouseStarted) {
899				event.preventDefault();
900				return true;
901			}
902		}
903
904		// Click event may never have fired (Gecko & Opera)
905		if (true === $.data(event.target, this.widgetName + ".preventClickEvent")) {
906			$.removeData(event.target, this.widgetName + ".preventClickEvent");
907		}
908
909		// these delegates are required to keep context
910		this._mouseMoveDelegate = function(event) {
911			return that._mouseMove(event);
912		};
913		this._mouseUpDelegate = function(event) {
914			return that._mouseUp(event);
915		};
916		$(document)
917			.bind("mousemove."+this.widgetName, this._mouseMoveDelegate)
918			.bind("mouseup."+this.widgetName, this._mouseUpDelegate);
919
920		event.preventDefault();
921
922		mouseHandled = true;
923		return true;
924	},
925
926	_mouseMove: function(event) {
927		// IE mouseup check - mouseup happened when mouse was out of window
928		if ($.ui.ie && ( !document.documentMode || document.documentMode < 9 ) && !event.button) {
929			return this._mouseUp(event);
930		}
931
932		if (this._mouseStarted) {
933			this._mouseDrag(event);
934			return event.preventDefault();
935		}
936
937		if (this._mouseDistanceMet(event) && this._mouseDelayMet(event)) {
938			this._mouseStarted =
939				(this._mouseStart(this._mouseDownEvent, event) !== false);
940			(this._mouseStarted ? this._mouseDrag(event) : this._mouseUp(event));
941		}
942
943		return !this._mouseStarted;
944	},
945
946	_mouseUp: function(event) {
947		$(document)
948			.unbind("mousemove."+this.widgetName, this._mouseMoveDelegate)
949			.unbind("mouseup."+this.widgetName, this._mouseUpDelegate);
950
951		if (this._mouseStarted) {
952			this._mouseStarted = false;
953
954			if (event.target === this._mouseDownEvent.target) {
955				$.data(event.target, this.widgetName + ".preventClickEvent", true);
956			}
957
958			this._mouseStop(event);
959		}
960
961		return false;
962	},
963
964	_mouseDistanceMet: function(event) {
965		return (Math.max(
966				Math.abs(this._mouseDownEvent.pageX - event.pageX),
967				Math.abs(this._mouseDownEvent.pageY - event.pageY)
968			) >= this.options.distance
969		);
970	},
971
972	_mouseDelayMet: function(/* event */) {
973		return this.mouseDelayMet;
974	},
975
976	// These are placeholder methods, to be overriden by extending plugin
977	_mouseStart: function(/* event */) {},
978	_mouseDrag: function(/* event */) {},
979	_mouseStop: function(/* event */) {},
980	_mouseCapture: function(/* event */) { return true; }
981});
982
983})(jQuery);
984
985(function( $, undefined ) {
986
987$.widget("ui.draggable", $.ui.mouse, {
988	version: "1.10.4",
989	widgetEventPrefix: "drag",
990	options: {
991		addClasses: true,
992		appendTo: "parent",
993		axis: false,
994		connectToSortable: false,
995		containment: false,
996		cursor: "auto",
997		cursorAt: false,
998		grid: false,
999		handle: false,
1000		helper: "original",
1001		iframeFix: false,
1002		opacity: false,
1003		refreshPositions: false,
1004		revert: false,
1005		revertDuration: 500,
1006		scope: "default",
1007		scroll: true,
1008		scrollSensitivity: 20,
1009		scrollSpeed: 20,
1010		snap: false,
1011		snapMode: "both",
1012		snapTolerance: 20,
1013		stack: false,
1014		zIndex: false,
1015
1016		// callbacks
1017		drag: null,
1018		start: null,
1019		stop: null
1020	},
1021	_create: function() {
1022
1023		if (this.options.helper === "original" && !(/^(?:r|a|f)/).test(this.element.css("position"))) {
1024			this.element[0].style.position = "relative";
1025		}
1026		if (this.options.addClasses){
1027			this.element.addClass("ui-draggable");
1028		}
1029		if (this.options.disabled){
1030			this.element.addClass("ui-draggable-disabled");
1031		}
1032
1033		this._mouseInit();
1034
1035	},
1036
1037	_destroy: function() {
1038		this.element.removeClass( "ui-draggable ui-draggable-dragging ui-draggable-disabled" );
1039		this._mouseDestroy();
1040	},
1041
1042	_mouseCapture: function(event) {
1043
1044		var o = this.options;
1045
1046		// among others, prevent a drag on a resizable-handle
1047		if (this.helper || o.disabled || $(event.target).closest(".ui-resizable-handle").length > 0) {
1048			return false;
1049		}
1050
1051		//Quit if we're not on a valid handle
1052		this.handle = this._getHandle(event);
1053		if (!this.handle) {
1054			return false;
1055		}
1056
1057		$(o.iframeFix === true ? "iframe" : o.iframeFix).each(function() {
1058			$("<div class='ui-draggable-iframeFix' style='background: #fff;'></div>")
1059			.css({
1060				width: this.offsetWidth+"px", height: this.offsetHeight+"px",
1061				position: "absolute", opacity: "0.001", zIndex: 1000
1062			})
1063			.css($(this).offset())
1064			.appendTo("body");
1065		});
1066
1067		return true;
1068
1069	},
1070
1071	_mouseStart: function(event) {
1072
1073		var o = this.options;
1074
1075		//Create and append the visible helper
1076		this.helper = this._createHelper(event);
1077
1078		this.helper.addClass("ui-draggable-dragging");
1079
1080		//Cache the helper size
1081		this._cacheHelperProportions();
1082
1083		//If ddmanager is used for droppables, set the global draggable
1084		if($.ui.ddmanager) {
1085			$.ui.ddmanager.current = this;
1086		}
1087
1088		/*
1089		 * - Position generation -
1090		 * This block generates everything position related - it's the core of draggables.
1091		 */
1092
1093		//Cache the margins of the original element
1094		this._cacheMargins();
1095
1096		//Store the helper's css position
1097		this.cssPosition = this.helper.css( "position" );
1098		this.scrollParent = this.helper.scrollParent();
1099		this.offsetParent = this.helper.offsetParent();
1100		this.offsetParentCssPosition = this.offsetParent.css( "position" );
1101
1102		//The element's absolute position on the page minus margins
1103		this.offset = this.positionAbs = this.element.offset();
1104		this.offset = {
1105			top: this.offset.top - this.margins.top,
1106			left: this.offset.left - this.margins.left
1107		};
1108
1109		//Reset scroll cache
1110		this.offset.scroll = false;
1111
1112		$.extend(this.offset, {
1113			click: { //Where the click happened, relative to the element
1114				left: event.pageX - this.offset.left,
1115				top: event.pageY - this.offset.top
1116			},
1117			parent: this._getParentOffset(),
1118			relative: this._getRelativeOffset() //This is a relative to absolute position minus the actual position calculation - only used for relative positioned helper
1119		});
1120
1121		//Generate the original position
1122		this.originalPosition = this.position = this._generatePosition(event);
1123		this.originalPageX = event.pageX;
1124		this.originalPageY = event.pageY;
1125
1126		//Adjust the mouse offset relative to the helper if "cursorAt" is supplied
1127		(o.cursorAt && this._adjustOffsetFromHelper(o.cursorAt));
1128
1129		//Set a containment if given in the options
1130		this._setContainment();
1131
1132		//Trigger event + callbacks
1133		if(this._trigger("start", event) === false) {
1134			this._clear();
1135			return false;
1136		}
1137
1138		//Recache the helper size
1139		this._cacheHelperProportions();
1140
1141		//Prepare the droppable offsets
1142		if ($.ui.ddmanager && !o.dropBehaviour) {
1143			$.ui.ddmanager.prepareOffsets(this, event);
1144		}
1145
1146
1147		this._mouseDrag(event, true); //Execute the drag once - this causes the helper not to be visible before getting its correct position
1148
1149		//If the ddmanager is used for droppables, inform the manager that dragging has started (see #5003)
1150		if ( $.ui.ddmanager ) {
1151			$.ui.ddmanager.dragStart(this, event);
1152		}
1153
1154		return true;
1155	},
1156
1157	_mouseDrag: function(event, noPropagation) {
1158		// reset any necessary cached properties (see #5009)
1159		if ( this.offsetParentCssPosition === "fixed" ) {
1160			this.offset.parent = this._getParentOffset();
1161		}
1162
1163		//Compute the helpers position
1164		this.position = this._generatePosition(event);
1165		this.positionAbs = this._convertPositionTo("absolute");
1166
1167		//Call plugins and callbacks and use the resulting position if something is returned
1168		if (!noPropagation) {
1169			var ui = this._uiHash();
1170			if(this._trigger("drag", event, ui) === false) {
1171				this._mouseUp({});
1172				return false;
1173			}
1174			this.position = ui.position;
1175		}
1176
1177		if(!this.options.axis || this.options.axis !== "y") {
1178			this.helper[0].style.left = this.position.left+"px";
1179		}
1180		if(!this.options.axis || this.options.axis !== "x") {
1181			this.helper[0].style.top = this.position.top+"px";
1182		}
1183		if($.ui.ddmanager) {
1184			$.ui.ddmanager.drag(this, event);
1185		}
1186
1187		return false;
1188	},
1189
1190	_mouseStop: function(event) {
1191
1192		//If we are using droppables, inform the manager about the drop
1193		var that = this,
1194			dropped = false;
1195		if ($.ui.ddmanager && !this.options.dropBehaviour) {
1196			dropped = $.ui.ddmanager.drop(this, event);
1197		}
1198
1199		//if a drop comes from outside (a sortable)
1200		if(this.dropped) {
1201			dropped = this.dropped;
1202			this.dropped = false;
1203		}
1204
1205		//if the original element is no longer in the DOM don't bother to continue (see #8269)
1206		if ( this.options.helper === "original" && !$.contains( this.element[ 0 ].ownerDocument, this.element[ 0 ] ) ) {
1207			return false;
1208		}
1209
1210		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))) {
1211			$(this.helper).animate(this.originalPosition, parseInt(this.options.revertDuration, 10), function() {
1212				if(that._trigger("stop", event) !== false) {
1213					that._clear();
1214				}
1215			});
1216		} else {
1217			if(this._trigger("stop", event) !== false) {
1218				this._clear();
1219			}
1220		}
1221
1222		return false;
1223	},
1224
1225	_mouseUp: function(event) {
1226		//Remove frame helpers
1227		$("div.ui-draggable-iframeFix").each(function() {
1228			this.parentNode.removeChild(this);
1229		});
1230
1231		//If the ddmanager is used for droppables, inform the manager that dragging has stopped (see #5003)
1232		if( $.ui.ddmanager ) {
1233			$.ui.ddmanager.dragStop(this, event);
1234		}
1235
1236		return $.ui.mouse.prototype._mouseUp.call(this, event);
1237	},
1238
1239	cancel: function() {
1240
1241		if(this.helper.is(".ui-draggable-dragging")) {
1242			this._mouseUp({});
1243		} else {
1244			this._clear();
1245		}
1246
1247		return this;
1248
1249	},
1250
1251	_getHandle: function(event) {
1252		return this.options.handle ?
1253			!!$( event.target ).closest( this.element.find( this.options.handle ) ).length :
1254			true;
1255	},
1256
1257	_createHelper: function(event) {
1258
1259		var o = this.options,
1260			helper = $.isFunction(o.helper) ? $(o.helper.apply(this.element[0], [event])) : (o.helper === "clone" ? this.element.clone().removeAttr("id") : this.element);
1261
1262		if(!helper.parents("body").length) {
1263			helper.appendTo((o.appendTo === "parent" ? this.element[0].parentNode : o.appendTo));
1264		}
1265
1266		if(helper[0] !== this.element[0] && !(/(fixed|absolute)/).test(helper.css("position"))) {
1267			helper.css("position", "absolute");
1268		}
1269
1270		return helper;
1271
1272	},
1273
1274	_adjustOffsetFromHelper: function(obj) {
1275		if (typeof obj === "string") {
1276			obj = obj.split(" ");
1277		}
1278		if ($.isArray(obj)) {
1279			obj = {left: +obj[0], top: +obj[1] || 0};
1280		}
1281		if ("left" in obj) {
1282			this.offset.click.left = obj.left + this.margins.left;
1283		}
1284		if ("right" in obj) {
1285			this.offset.click.left = this.helperProportions.width - obj.right + this.margins.left;
1286		}
1287		if ("top" in obj) {
1288			this.offset.click.top = obj.top + this.margins.top;
1289		}
1290		if ("bottom" in obj) {
1291			this.offset.click.top = this.helperProportions.height - obj.bottom + this.margins.top;
1292		}
1293	},
1294
1295	_getParentOffset: function() {
1296
1297		//Get the offsetParent and cache its position
1298		var po = this.offsetParent.offset();
1299
1300		// This is a special case where we need to modify a offset calculated on start, since the following happened:
1301		// 1. The position of the helper is absolute, so it's position is calculated based on the next positioned parent
1302		// 2. The actual offset parent is a child of the scroll parent, and the scroll parent isn't the document, which means that
1303		//    the scroll is included in the initial calculation of the offset of the parent, and never recalculated upon drag
1304		if(this.cssPosition === "absolute" && this.scrollParent[0] !== document && $.contains(this.scrollParent[0], this.offsetParent[0])) {
1305			po.left += this.scrollParent.scrollLeft();
1306			po.top += this.scrollParent.scrollTop();
1307		}
1308
1309		//This needs to be actually done for all browsers, since pageX/pageY includes this information
1310		//Ugly IE fix
1311		if((this.offsetParent[0] === document.body) ||
1312			(this.offsetParent[0].tagName && this.offsetParent[0].tagName.toLowerCase() === "html" && $.ui.ie)) {
1313			po = { top: 0, left: 0 };
1314		}
1315
1316		return {
1317			top: po.top + (parseInt(this.offsetParent.css("borderTopWidth"),10) || 0),
1318			left: po.left + (parseInt(this.offsetParent.css("borderLeftWidth"),10) || 0)
1319		};
1320
1321	},
1322
1323	_getRelativeOffset: function() {
1324
1325		if(this.cssPosition === "relative") {
1326			var p = this.element.position();
1327			return {
1328				top: p.top - (parseInt(this.helper.css("top"),10) || 0) + this.scrollParent.scrollTop(),
1329				left: p.left - (parseInt(this.helper.css("left"),10) || 0) + this.scrollParent.scrollLeft()
1330			};
1331		} else {
1332			return { top: 0, left: 0 };
1333		}
1334
1335	},
1336
1337	_cacheMargins: function() {
1338		this.margins = {
1339			left: (parseInt(this.element.css("marginLeft"),10) || 0),
1340			top: (parseInt(this.element.css("marginTop"),10) || 0),
1341			right: (parseInt(this.element.css("marginRight"),10) || 0),
1342			bottom: (parseInt(this.element.css("marginBottom"),10) || 0)
1343		};
1344	},
1345
1346	_cacheHelperProportions: function() {
1347		this.helperProportions = {
1348			width: this.helper.outerWidth(),
1349			height: this.helper.outerHeight()
1350		};
1351	},
1352
1353	_setContainment: function() {
1354
1355		var over, c, ce,
1356			o = this.options;
1357
1358		if ( !o.containment ) {
1359			this.containment = null;
1360			return;
1361		}
1362
1363		if ( o.containment === "window" ) {
1364			this.containment = [
1365				$( window ).scrollLeft() - this.offset.relative.left - this.offset.parent.left,
1366				$( window ).scrollTop() - this.offset.relative.top - this.offset.parent.top,
1367				$( window ).scrollLeft() + $( window ).width() - this.helperProportions.width - this.margins.left,
1368				$( window ).scrollTop() + ( $( window ).height() || document.body.parentNode.scrollHeight ) - this.helperProportions.height - this.margins.top
1369			];
1370			return;
1371		}
1372
1373		if ( o.containment === "document") {
1374			this.containment = [
1375				0,
1376				0,
1377				$( document ).width() - this.helperProportions.width - this.margins.left,
1378				( $( document ).height() || document.body.parentNode.scrollHeight ) - this.helperProportions.height - this.margins.top
1379			];
1380			return;
1381		}
1382
1383		if ( o.containment.constructor === Array ) {
1384			this.containment = o.containment;
1385			return;
1386		}
1387
1388		if ( o.containment === "parent" ) {
1389			o.containment = this.helper[ 0 ].parentNode;
1390		}
1391
1392		c = $( o.containment );
1393		ce = c[ 0 ];
1394
1395		if( !ce ) {
1396			return;
1397		}
1398
1399		over = c.css( "overflow" ) !== "hidden";
1400
1401		this.containment = [
1402			( parseInt( c.css( "borderLeftWidth" ), 10 ) || 0 ) + ( parseInt( c.css( "paddingLeft" ), 10 ) || 0 ),
1403			( parseInt( c.css( "borderTopWidth" ), 10 ) || 0 ) + ( parseInt( c.css( "paddingTop" ), 10 ) || 0 ) ,
1404			( 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,
1405			( 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
1406		];
1407		this.relative_container = c;
1408	},
1409
1410	_convertPositionTo: function(d, pos) {
1411
1412		if(!pos) {
1413			pos = this.position;
1414		}
1415
1416		var mod = d === "absolute" ? 1 : -1,
1417			scroll = this.cssPosition === "absolute" && !( this.scrollParent[ 0 ] !== document && $.contains( this.scrollParent[ 0 ], this.offsetParent[ 0 ] ) ) ? this.offsetParent : this.scrollParent;
1418
1419		//Cache the scroll
1420		if (!this.offset.scroll) {
1421			this.offset.scroll = {top : scroll.scrollTop(), left : scroll.scrollLeft()};
1422		}
1423
1424		return {
1425			top: (
1426				pos.top	+																// The absolute mouse position
1427				this.offset.relative.top * mod +										// Only for relative positioned nodes: Relative offset from element to offset parent
1428				this.offset.parent.top * mod -										// The offsetParent's offset without borders (offset + border)
1429				( ( this.cssPosition === "fixed" ? -this.scrollParent.scrollTop() : this.offset.scroll.top ) * mod )
1430			),
1431			left: (
1432				pos.left +																// The absolute mouse position
1433				this.offset.relative.left * mod +										// Only for relative positioned nodes: Relative offset from element to offset parent
1434				this.offset.parent.left * mod	-										// The offsetParent's offset without borders (offset + border)
1435				( ( this.cssPosition === "fixed" ? -this.scrollParent.scrollLeft() : this.offset.scroll.left ) * mod )
1436			)
1437		};
1438
1439	},
1440
1441	_generatePosition: function(event) {
1442
1443		var containment, co, top, left,
1444			o = this.options,
1445			scroll = this.cssPosition === "absolute" && !( this.scrollParent[ 0 ] !== document && $.contains( this.scrollParent[ 0 ], this.offsetParent[ 0 ] ) ) ? this.offsetParent : this.scrollParent,
1446			pageX = event.pageX,
1447			pageY = event.pageY;
1448
1449		//Cache the scroll
1450		if (!this.offset.scroll) {
1451			this.offset.scroll = {top : scroll.scrollTop(), left : scroll.scrollLeft()};
1452		}
1453
1454		/*
1455		 * - Position constraining -
1456		 * Constrain the position to a mix of grid, containment.
1457		 */
1458
1459		// If we are not dragging yet, we won't check for options
1460		if ( this.originalPosition ) {
1461			if ( this.containment ) {
1462				if ( this.relative_container ){
1463					co = this.relative_container.offset();
1464					containment = [
1465						this.containment[ 0 ] + co.left,
1466						this.containment[ 1 ] + co.top,
1467						this.containment[ 2 ] + co.left,
1468						this.containment[ 3 ] + co.top
1469					];
1470				}
1471				else {
1472					containment = this.containment;
1473				}
1474
1475				if(event.pageX - this.offset.click.left < containment[0]) {
1476					pageX = containment[0] + this.offset.click.left;
1477				}
1478				if(event.pageY - this.offset.click.top < containment[1]) {
1479					pageY = containment[1] + this.offset.click.top;
1480				}
1481				if(event.pageX - this.offset.click.left > containment[2]) {
1482					pageX = containment[2] + this.offset.click.left;
1483				}
1484				if(event.pageY - this.offset.click.top > containment[3]) {
1485					pageY = containment[3] + this.offset.click.top;
1486				}
1487			}
1488
1489			if(o.grid) {
1490				//Check for grid elements set to 0 to prevent divide by 0 error causing invalid argument errors in IE (see ticket #6950)
1491				top = o.grid[1] ? this.originalPageY + Math.round((pageY - this.originalPageY) / o.grid[1]) * o.grid[1] : this.originalPageY;
1492				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;
1493
1494				left = o.grid[0] ? this.originalPageX + Math.round((pageX - this.originalPageX) / o.grid[0]) * o.grid[0] : this.originalPageX;
1495				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;
1496			}
1497
1498		}
1499
1500		return {
1501			top: (
1502				pageY -																	// The absolute mouse position
1503				this.offset.click.top	-												// Click offset (relative to the element)
1504				this.offset.relative.top -												// Only for relative positioned nodes: Relative offset from element to offset parent
1505				this.offset.parent.top +												// The offsetParent's offset without borders (offset + border)
1506				( this.cssPosition === "fixed" ? -this.scrollParent.scrollTop() : this.offset.scroll.top )
1507			),
1508			left: (
1509				pageX -																	// The absolute mouse position
1510				this.offset.click.left -												// Click offset (relative to the element)
1511				this.offset.relative.left -												// Only for relative positioned nodes: Relative offset from element to offset parent
1512				this.offset.parent.left +												// The offsetParent's offset without borders (offset + border)
1513				( this.cssPosition === "fixed" ? -this.scrollParent.scrollLeft() : this.offset.scroll.left )
1514			)
1515		};
1516
1517	},
1518
1519	_clear: function() {
1520		this.helper.removeClass("ui-draggable-dragging");
1521		if(this.helper[0] !== this.element[0] && !this.cancelHelperRemoval) {
1522			this.helper.remove();
1523		}
1524		this.helper = null;
1525		this.cancelHelperRemoval = false;
1526	},
1527
1528	// From now on bulk stuff - mainly helpers
1529
1530	_trigger: function(type, event, ui) {
1531		ui = ui || this._uiHash();
1532		$.ui.plugin.call(this, type, [event, ui]);
1533		//The absolute position has to be recalculated after plugins
1534		if(type === "drag") {
1535			this.positionAbs = this._convertPositionTo("absolute");
1536		}
1537		return $.Widget.prototype._trigger.call(this, type, event, ui);
1538	},
1539
1540	plugins: {},
1541
1542	_uiHash: function() {
1543		return {
1544			helper: this.helper,
1545			position: this.position,
1546			originalPosition: this.originalPosition,
1547			offset: this.positionAbs
1548		};
1549	}
1550
1551});
1552
1553$.ui.plugin.add("draggable", "connectToSortable", {
1554	start: function(event, ui) {
1555
1556		var inst = $(this).data("ui-draggable"), o = inst.options,
1557			uiSortable = $.extend({}, ui, { item: inst.element });
1558		inst.sortables = [];
1559		$(o.connectToSortable).each(function() {
1560			var sortable = $.data(this, "ui-sortable");
1561			if (sortable && !sortable.options.disabled) {
1562				inst.sortables.push({
1563					instance: sortable,
1564					shouldRevert: sortable.options.revert
1565				});
1566				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).
1567				sortable._trigger("activate", event, uiSortable);
1568			}
1569		});
1570
1571	},
1572	stop: function(event, ui) {
1573
1574		//If we are still over the sortable, we fake the stop event of the sortable, but also remove helper
1575		var inst = $(this).data("ui-draggable"),
1576			uiSortable = $.extend({}, ui, { item: inst.element });
1577
1578		$.each(inst.sortables, function() {
1579			if(this.instance.isOver) {
1580
1581				this.instance.isOver = 0;
1582
1583				inst.cancelHelperRemoval = true; //Don't remove the helper in the draggable instance
1584				this.instance.cancelHelperRemoval = false; //Remove it in the sortable instance (so sortable plugins like revert still work)
1585
1586				//The sortable revert is supported, and we have to set a temporary dropped variable on the draggable to support revert: "valid/invalid"
1587				if(this.shouldRevert) {
1588					this.instance.options.revert = this.shouldRevert;
1589				}
1590
1591				//Trigger the stop of the sortable
1592				this.instance._mouseStop(event);
1593
1594				this.instance.options.helper = this.instance.options._helper;
1595
1596				//If the helper has been the original item, restore properties in the sortable
1597				if(inst.options.helper === "original") {
1598					this.instance.currentItem.css({ top: "auto", left: "auto" });
1599				}
1600
1601			} else {
1602				this.instance.cancelHelperRemoval = false; //Remove the helper in the sortable instance
1603				this.instance._trigger("deactivate", event, uiSortable);
1604			}
1605
1606		});
1607
1608	},
1609	drag: function(event, ui) {
1610
1611		var inst = $(this).data("ui-draggable"), that = this;
1612
1613		$.each(inst.sortables, function() {
1614
1615			var innermostIntersecting = false,
1616				thisSortable = this;
1617
1618			//Copy over some variables to allow calling the sortable's native _intersectsWith
1619			this.instance.positionAbs = inst.positionAbs;
1620			this.instance.helperProportions = inst.helperProportions;
1621			this.instance.offset.click = inst.offset.click;
1622
1623			if(this.instance._intersectsWith(this.instance.containerCache)) {
1624				innermostIntersecting = true;
1625				$.each(inst.sortables, function () {
1626					this.instance.positionAbs = inst.positionAbs;
1627					this.instance.helperProportions = inst.helperProportions;
1628					this.instance.offset.click = inst.offset.click;
1629					if (this !== thisSortable &&
1630						this.instance._intersectsWith(this.instance.containerCache) &&
1631						$.contains(thisSortable.instance.element[0], this.instance.element[0])
1632					) {
1633						innermostIntersecting = false;
1634					}
1635					return innermostIntersecting;
1636				});
1637			}
1638
1639
1640			if(innermostIntersecting) {
1641				//If it intersects, we use a little isOver variable and set it once, so our move-in stuff gets fired only once
1642				if(!this.instance.isOver) {
1643
1644					this.instance.isOver = 1;
1645					//Now we fake the start of dragging for the sortable instance,
1646					//by cloning the list group item, appending it to the sortable and using it as inst.currentItem
1647					//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)
1648					this.instance.currentItem = $(that).clone().removeAttr("id").appendTo(this.instance.element).data("ui-sortable-item", true);
1649					this.instance.options._helper = this.instance.options.helper; //Store helper option to later restore it
1650					this.instance.options.helper = function() { return ui.helper[0]; };
1651
1652					event.target = this.instance.currentItem[0];
1653					this.instance._mouseCapture(event, true);
1654					this.instance._mouseStart(event, true, true);
1655
1656					//Because the browser event is way off the new appended portlet, we modify a couple of variables to reflect the changes
1657					this.instance.offset.click.top = inst.offset.click.top;
1658					this.instance.offset.click.left = inst.offset.click.left;
1659					this.instance.offset.parent.left -= inst.offset.parent.left - this.instance.offset.parent.left;
1660					this.instance.offset.parent.top -= inst.offset.parent.top - this.instance.offset.parent.top;
1661
1662					inst._trigger("toSortable", event);
1663					inst.dropped = this.instance.element; //draggable revert needs that
1664					//hack so receive/update callbacks work (mostly)
1665					inst.currentItem = inst.element;
1666					this.instance.fromOutside = inst;
1667
1668				}
1669
1670				//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
1671				if(this.instance.currentItem) {
1672					this.instance._mouseDrag(event);
1673				}
1674
1675			} else {
1676
1677				//If it doesn't intersect with the sortable, and it intersected before,
1678				//we fake the drag stop of the sortable, but make sure it doesn't remove the helper by using cancelHelperRemoval
1679				if(this.instance.isOver) {
1680
1681					this.instance.isOver = 0;
1682					this.instance.cancelHelperRemoval = true;
1683
1684					//Prevent reverting on this forced stop
1685					this.instance.options.revert = false;
1686
1687					// The out event needs to be triggered independently
1688					this.instance._trigger("out", event, this.instance._uiHash(this.instance));
1689
1690					this.instance._mouseStop(event, true);
1691					this.instance.options.helper = this.instance.options._helper;
1692
1693					//Now we remove our currentItem, the list group clone again, and the placeholder, and animate the helper back to it's original size
1694					this.instance.currentItem.remove();
1695					if(this.instance.placeholder) {
1696						this.instance.placeholder.remove();
1697					}
1698
1699					inst._trigger("fromSortable", event);
1700					inst.dropped = false; //draggable revert needs that
1701				}
1702
1703			}
1704
1705		});
1706
1707	}
1708});
1709
1710$.ui.plugin.add("draggable", "cursor", {
1711	start: function() {
1712		var t = $("body"), o = $(this).data("ui-draggable").options;
1713		if (t.css("cursor")) {
1714			o._cursor = t.css("cursor");
1715		}
1716		t.css("cursor", o.cursor);
1717	},
1718	stop: function() {
1719		var o = $(this).data("ui-draggable").options;
1720		if (o._cursor) {
1721			$("body").css("cursor", o._cursor);
1722		}
1723	}
1724});
1725
1726$.ui.plugin.add("draggable", "opacity", {
1727	start: function(event, ui) {
1728		var t = $(ui.helper), o = $(this).data("ui-draggable").options;
1729		if(t.css("opacity")) {
1730			o._opacity = t.css("opacity");
1731		}
1732		t.css("opacity", o.opacity);
1733	},
1734	stop: function(event, ui) {
1735		var o = $(this).data("ui-draggable").options;
1736		if(o._opacity) {
1737			$(ui.helper).css("opacity", o._opacity);
1738		}
1739	}
1740});
1741
1742$.ui.plugin.add("draggable", "scroll", {
1743	start: function() {
1744		var i = $(this).data("ui-draggable");
1745		if(i.scrollParent[0] !== document && i.scrollParent[0].tagName !== "HTML") {
1746			i.overflowOffset = i.scrollParent.offset();
1747		}
1748	},
1749	drag: function( event ) {
1750
1751		var i = $(this).data("ui-draggable"), o = i.options, scrolled = false;
1752
1753		if(i.scrollParent[0] !== document && i.scrollParent[0].tagName !== "HTML") {
1754
1755			if(!o.axis || o.axis !== "x") {
1756				if((i.overflowOffset.top + i.scrollParent[0].offsetHeight) - event.pageY < o.scrollSensitivity) {
1757					i.scrollParent[0].scrollTop = scrolled = i.scrollParent[0].scrollTop + o.scrollSpeed;
1758				} else if(event.pageY - i.overflowOffset.top < o.scrollSensitivity) {
1759					i.scrollParent[0].scrollTop = scrolled = i.scrollParent[0].scrollTop - o.scrollSpeed;
1760				}
1761			}
1762
1763			if(!o.axis || o.axis !== "y") {
1764				if((i.overflowOffset.left + i.scrollParent[0].offsetWidth) - event.pageX < o.scrollSensitivity) {
1765					i.scrollParent[0].scrollLeft = scrolled = i.scrollParent[0].scrollLeft + o.scrollSpeed;
1766				} else if(event.pageX - i.overflowOffset.left < o.scrollSensitivity) {
1767					i.scrollParent[0].scrollLeft = scrolled = i.scrollParent[0].scrollLeft - o.scrollSpeed;
1768				}
1769			}
1770
1771		} else {
1772
1773			if(!o.axis || o.axis !== "x") {
1774				if(event.pageY - $(document).scrollTop() < o.scrollSensitivity) {
1775					scrolled = $(document).scrollTop($(document).scrollTop() - o.scrollSpeed);
1776				} else if($(window).height() - (event.pageY - $(document).scrollTop()) < o.scrollSensitivity) {
1777					scrolled = $(document).scrollTop($(document).scrollTop() + o.scrollSpeed);
1778				}
1779			}
1780
1781			if(!o.axis || o.axis !== "y") {
1782				if(event.pageX - $(document).scrollLeft() < o.scrollSensitivity) {
1783					scrolled = $(document).scrollLeft($(document).scrollLeft() - o.scrollSpeed);
1784				} else if($(window).width() - (event.pageX - $(document).scrollLeft()) < o.scrollSensitivity) {
1785					scrolled = $(document).scrollLeft($(document).scrollLeft() + o.scrollSpeed);
1786				}
1787			}
1788
1789		}
1790
1791		if(scrolled !== false && $.ui.ddmanager && !o.dropBehaviour) {
1792			$.ui.ddmanager.prepareOffsets(i, event);
1793		}
1794
1795	}
1796});
1797
1798$.ui.plugin.add("draggable", "snap", {
1799	start: function() {
1800
1801		var i = $(this).data("ui-draggable"),
1802			o = i.options;
1803
1804		i.snapElements = [];
1805
1806		$(o.snap.constructor !== String ? ( o.snap.items || ":data(ui-draggable)" ) : o.snap).each(function() {
1807			var $t = $(this),
1808				$o = $t.offset();
1809			if(this !== i.element[0]) {
1810				i.snapElements.push({
1811					item: this,
1812					width: $t.outerWidth(), height: $t.outerHeight(),
1813					top: $o.top, left: $o.left
1814				});
1815			}
1816		});
1817
1818	},
1819	drag: function(event, ui) {
1820
1821		var ts, bs, ls, rs, l, r, t, b, i, first,
1822			inst = $(this).data("ui-draggable"),
1823			o = inst.options,
1824			d = o.snapTolerance,
1825			x1 = ui.offset.left, x2 = x1 + inst.helperProportions.width,
1826			y1 = ui.offset.top, y2 = y1 + inst.helperProportions.height;
1827
1828		for (i = inst.snapElements.length - 1; i >= 0; i--){
1829
1830			l = inst.snapElements[i].left;
1831			r = l + inst.snapElements[i].width;
1832			t = inst.snapElements[i].top;
1833			b = t + inst.snapElements[i].height;
1834
1835			if ( x2 < l - d || x1 > r + d || y2 < t - d || y1 > b + d || !$.contains( inst.snapElements[ i ].item.ownerDocument, inst.snapElements[ i ].item ) ) {
1836				if(inst.snapElements[i].snapping) {
1837					(inst.options.snap.release && inst.options.snap.release.call(inst.element, event, $.extend(inst._uiHash(), { snapItem: inst.snapElements[i].item })));
1838				}
1839				inst.snapElements[i].snapping = false;
1840				continue;
1841			}
1842
1843			if(o.snapMode !== "inner") {
1844				ts = Math.abs(t - y2) <= d;
1845				bs = Math.abs(b - y1) <= d;
1846				ls = Math.abs(l - x2) <= d;
1847				rs = Math.abs(r - x1) <= d;
1848				if(ts) {
1849					ui.position.top = inst._convertPositionTo("relative", { top: t - inst.helperProportions.height, left: 0 }).top - inst.margins.top;
1850				}
1851				if(bs) {
1852					ui.position.top = inst._convertPositionTo("relative", { top: b, left: 0 }).top - inst.margins.top;
1853				}
1854				if(ls) {
1855					ui.position.left = inst._convertPositionTo("relative", { top: 0, left: l - inst.helperProportions.width }).left - inst.margins.left;
1856				}
1857				if(rs) {
1858					ui.position.left = inst._convertPositionTo("relative", { top: 0, left: r }).left - inst.margins.left;
1859				}
1860			}
1861
1862			first = (ts || bs || ls || rs);
1863
1864			if(o.snapMode !== "outer") {
1865				ts = Math.abs(t - y1) <= d;
1866				bs = Math.abs(b - y2) <= d;
1867				ls = Math.abs(l - x1) <= d;
1868				rs = Math.abs(r - x2) <= d;
1869				if(ts) {
1870					ui.position.top = inst._convertPositionTo("relative", { top: t, left: 0 }).top - inst.margins.top;
1871				}
1872				if(bs) {
1873					ui.position.top = inst._convertPositionTo("relative", { top: b - inst.helperProportions.height, left: 0 }).top - inst.margins.top;
1874				}
1875				if(ls) {
1876					ui.position.left = inst._convertPositionTo("relative", { top: 0, left: l }).left - inst.margins.left;
1877				}
1878				if(rs) {
1879					ui.position.left = inst._convertPositionTo("relative", { top: 0, left: r - inst.helperProportions.width }).left - inst.margins.left;
1880				}
1881			}
1882
1883			if(!inst.snapElements[i].snapping && (ts || bs || ls || rs || first)) {
1884				(inst.options.snap.snap && inst.options.snap.snap.call(inst.element, event, $.extend(inst._uiHash(), { snapItem: inst.snapElements[i].item })));
1885			}
1886			inst.snapElements[i].snapping = (ts || bs || ls || rs || first);
1887
1888		}
1889
1890	}
1891});
1892
1893$.ui.plugin.add("draggable", "stack", {
1894	start: function() {
1895		var min,
1896			o = this.data("ui-draggable").options,
1897			group = $.makeArray($(o.stack)).sort(function(a,b) {
1898				return (parseInt($(a).css("zIndex"),10) || 0) - (parseInt($(b).css("zIndex"),10) || 0);
1899			});
1900
1901		if (!group.length) { return; }
1902
1903		min = parseInt($(group[0]).css("zIndex"), 10) || 0;
1904		$(group).each(function(i) {
1905			$(this).css("zIndex", min + i);
1906		});
1907		this.css("zIndex", (min + group.length));
1908	}
1909});
1910
1911$.ui.plugin.add("draggable", "zIndex", {
1912	start: function(event, ui) {
1913		var t = $(ui.helper), o = $(this).data("ui-draggable").options;
1914		if(t.css("zIndex")) {
1915			o._zIndex = t.css("zIndex");
1916		}
1917		t.css("zIndex", o.zIndex);
1918	},
1919	stop: function(event, ui) {
1920		var o = $(this).data("ui-draggable").options;
1921		if(o._zIndex) {
1922			$(ui.helper).css("zIndex", o._zIndex);
1923		}
1924	}
1925});
1926
1927})(jQuery);
1928
1929(function( $, undefined ) {
1930
1931function isOverAxis( x, reference, size ) {
1932	return ( x > reference ) && ( x < ( reference + size ) );
1933}
1934
1935$.widget("ui.droppable", {
1936	version: "1.10.4",
1937	widgetEventPrefix: "drop",
1938	options: {
1939		accept: "*",
1940		activeClass: false,
1941		addClasses: true,
1942		greedy: false,
1943		hoverClass: false,
1944		scope: "default",
1945		tolerance: "intersect",
1946
1947		// callbacks
1948		activate: null,
1949		deactivate: null,
1950		drop: null,
1951		out: null,
1952		over: null
1953	},
1954	_create: function() {
1955
1956		var proportions,
1957			o = this.options,
1958			accept = o.accept;
1959
1960		this.isover = false;
1961		this.isout = true;
1962
1963		this.accept = $.isFunction(accept) ? accept : function(d) {
1964			return d.is(accept);
1965		};
1966
1967		this.proportions = function( /* valueToWrite */ ) {
1968			if ( arguments.length ) {
1969				// Store the droppable's proportions
1970				proportions = arguments[ 0 ];
1971			} else {
1972				// Retrieve or derive the droppable's proportions
1973				return proportions ?
1974					proportions :
1975					proportions = {
1976						width: this.element[ 0 ].offsetWidth,
1977						height: this.element[ 0 ].offsetHeight
1978					};
1979			}
1980		};
1981
1982		// Add the reference and positions to the manager
1983		$.ui.ddmanager.droppables[o.scope] = $.ui.ddmanager.droppables[o.scope] || [];
1984		$.ui.ddmanager.droppables[o.scope].push(this);
1985
1986		(o.addClasses && this.element.addClass("ui-droppable"));
1987
1988	},
1989
1990	_destroy: function() {
1991		var i = 0,
1992			drop = $.ui.ddmanager.droppables[this.options.scope];
1993
1994		for ( ; i < drop.length; i++ ) {
1995			if ( drop[i] === this ) {
1996				drop.splice(i, 1);
1997			}
1998		}
1999
2000		this.element.removeClass("ui-droppable ui-droppable-disabled");
2001	},
2002
2003	_setOption: function(key, value) {
2004
2005		if(key === "accept") {
2006			this.accept = $.isFunction(value) ? value : function(d) {
2007				return d.is(value);
2008			};
2009		}
2010		$.Widget.prototype._setOption.apply(this, arguments);
2011	},
2012
2013	_activate: function(event) {
2014		var draggable = $.ui.ddmanager.current;
2015		if(this.options.activeClass) {
2016			this.element.addClass(this.options.activeClass);
2017		}
2018		if(draggable){
2019			this._trigger("activate", event, this.ui(draggable));
2020		}
2021	},
2022
2023	_deactivate: function(event) {
2024		var draggable = $.ui.ddmanager.current;
2025		if(this.options.activeClass) {
2026			this.element.removeClass(this.options.activeClass);
2027		}
2028		if(draggable){
2029			this._trigger("deactivate", event, this.ui(draggable));
2030		}
2031	},
2032
2033	_over: function(event) {
2034
2035		var draggable = $.ui.ddmanager.current;
2036
2037		// Bail if draggable and droppable are same element
2038		if (!draggable || (draggable.currentItem || draggable.element)[0] === this.element[0]) {
2039			return;
2040		}
2041
2042		if (this.accept.call(this.element[0],(draggable.currentItem || draggable.element))) {
2043			if(this.options.hoverClass) {
2044				this.element.addClass(this.options.hoverClass);
2045			}
2046			this._trigger("over", event, this.ui(draggable));
2047		}
2048
2049	},
2050
2051	_out: function(event) {
2052
2053		var draggable = $.ui.ddmanager.current;
2054
2055		// Bail if draggable and droppable are same element
2056		if (!draggable || (draggable.currentItem || draggable.element)[0] === this.element[0]) {
2057			return;
2058		}
2059
2060		if (this.accept.call(this.element[0],(draggable.currentItem || draggable.element))) {
2061			if(this.options.hoverClass) {
2062				this.element.removeClass(this.options.hoverClass);
2063			}
2064			this._trigger("out", event, this.ui(draggable));
2065		}
2066
2067	},
2068
2069	_drop: function(event,custom) {
2070
2071		var draggable = custom || $.ui.ddmanager.current,
2072			childrenIntersection = false;
2073
2074		// Bail if draggable and droppable are same element
2075		if (!draggable || (draggable.currentItem || draggable.element)[0] === this.element[0]) {
2076			return false;
2077		}
2078
2079		this.element.find(":data(ui-droppable)").not(".ui-draggable-dragging").each(function() {
2080			var inst = $.data(this, "ui-droppable");
2081			if(
2082				inst.options.greedy &&
2083				!inst.options.disabled &&
2084				inst.options.scope === draggable.options.scope &&
2085				inst.accept.call(inst.element[0], (draggable.currentItem || draggable.element)) &&
2086				$.ui.intersect(draggable, $.extend(inst, { offset: inst.element.offset() }), inst.options.tolerance)
2087			) { childrenIntersection = true; return false; }
2088		});
2089		if(childrenIntersection) {
2090			return false;
2091		}
2092
2093		if(this.accept.call(this.element[0],(draggable.currentItem || draggable.element))) {
2094			if(this.options.activeClass) {
2095				this.element.removeClass(this.options.activeClass);
2096			}
2097			if(this.options.hoverClass) {
2098				this.element.removeClass(this.options.hoverClass);
2099			}
2100			this._trigger("drop", event, this.ui(draggable));
2101			return this.element;
2102		}
2103
2104		return false;
2105
2106	},
2107
2108	ui: function(c) {
2109		return {
2110			draggable: (c.currentItem || c.element),
2111			helper: c.helper,
2112			position: c.position,
2113			offset: c.positionAbs
2114		};
2115	}
2116
2117});
2118
2119$.ui.intersect = function(draggable, droppable, toleranceMode) {
2120
2121	if (!droppable.offset) {
2122		return false;
2123	}
2124
2125	var draggableLeft, draggableTop,
2126		x1 = (draggable.positionAbs || draggable.position.absolute).left,
2127		y1 = (draggable.positionAbs || draggable.position.absolute).top,
2128		x2 = x1 + draggable.helperProportions.width,
2129		y2 = y1 + draggable.helperProportions.height,
2130		l = droppable.offset.left,
2131		t = droppable.offset.top,
2132		r = l + droppable.proportions().width,
2133		b = t + droppable.proportions().height;
2134
2135	switch (toleranceMode) {
2136		case "fit":
2137			return (l <= x1 && x2 <= r && t <= y1 && y2 <= b);
2138		case "intersect":
2139			return (l < x1 + (draggable.helperProportions.width / 2) && // Right Half
2140				x2 - (draggable.helperProportions.width / 2) < r && // Left Half
2141				t < y1 + (draggable.helperProportions.height / 2) && // Bottom Half
2142				y2 - (draggable.helperProportions.height / 2) < b ); // Top Half
2143		case "pointer":
2144			draggableLeft = ((draggable.positionAbs || draggable.position.absolute).left + (draggable.clickOffset || draggable.offset.click).left);
2145			draggableTop = ((draggable.positionAbs || draggable.position.absolute).top + (draggable.clickOffset || draggable.offset.click).top);
2146			return isOverAxis( draggableTop, t, droppable.proportions().height ) && isOverAxis( draggableLeft, l, droppable.proportions().width );
2147		case "touch":
2148			return (
2149				(y1 >= t && y1 <= b) ||	// Top edge touching
2150				(y2 >= t && y2 <= b) ||	// Bottom edge touching
2151				(y1 < t && y2 > b)		// Surrounded vertically
2152			) && (
2153				(x1 >= l && x1 <= r) ||	// Left edge touching
2154				(x2 >= l && x2 <= r) ||	// Right edge touching
2155				(x1 < l && x2 > r)		// Surrounded horizontally
2156			);
2157		default:
2158			return false;
2159		}
2160
2161};
2162
2163/*
2164	This manager tracks offsets of draggables and droppables
2165*/
2166$.ui.ddmanager = {
2167	current: null,
2168	droppables: { "default": [] },
2169	prepareOffsets: function(t, event) {
2170
2171		var i, j,
2172			m = $.ui.ddmanager.droppables[t.options.scope] || [],
2173			type = event ? event.type : null, // workaround for #2317
2174			list = (t.currentItem || t.element).find(":data(ui-droppable)").addBack();
2175
2176		droppablesLoop: for (i = 0; i < m.length; i++) {
2177
2178			//No disabled and non-accepted
2179			if(m[i].options.disabled || (t && !m[i].accept.call(m[i].element[0],(t.currentItem || t.element)))) {
2180				continue;
2181			}
2182
2183			// Filter out elements in the current dragged item
2184			for (j=0; j < list.length; j++) {
2185				if(list[j] === m[i].element[0]) {
2186					m[i].proportions().height = 0;
2187					continue droppablesLoop;
2188				}
2189			}
2190
2191			m[i].visible = m[i].element.css("display") !== "none";
2192			if(!m[i].visible) {
2193				continue;
2194			}
2195
2196			//Activate the droppable if used directly from draggables
2197			if(type === "mousedown") {
2198				m[i]._activate.call(m[i], event);
2199			}
2200
2201			m[ i ].offset = m[ i ].element.offset();
2202			m[ i ].proportions({ width: m[ i ].element[ 0 ].offsetWidth, height: m[ i ].element[ 0 ].offsetHeight });
2203
2204		}
2205
2206	},
2207	drop: function(draggable, event) {
2208
2209		var dropped = false;
2210		// Create a copy of the droppables in case the list changes during the drop (#9116)
2211		$.each(($.ui.ddmanager.droppables[draggable.options.scope] || []).slice(), function() {
2212
2213			if(!this.options) {
2214				return;
2215			}
2216			if (!this.options.disabled && this.visible && $.ui.intersect(draggable, this, this.options.tolerance)) {
2217				dropped = this._drop.call(this, event) || dropped;
2218			}
2219
2220			if (!this.options.disabled && this.visible && this.accept.call(this.element[0],(draggable.currentItem || draggable.element))) {
2221				this.isout = true;
2222				this.isover = false;
2223				this._deactivate.call(this, event);
2224			}
2225
2226		});
2227		return dropped;
2228
2229	},
2230	dragStart: function( draggable, event ) {
2231		//Listen for scrolling so that if the dragging causes scrolling the position of the droppables can be recalculated (see #5003)
2232		draggable.element.parentsUntil( "body" ).bind( "scroll.droppable", function() {
2233			if( !draggable.options.refreshPositions ) {
2234				$.ui.ddmanager.prepareOffsets( draggable, event );
2235			}
2236		});
2237	},
2238	drag: function(draggable, event) {
2239
2240		//If you have a highly dynamic page, you might try this option. It renders positions every time you move the mouse.
2241		if(draggable.options.refreshPositions) {
2242			$.ui.ddmanager.prepareOffsets(draggable, event);
2243		}
2244
2245		//Run through all droppables and check their positions based on specific tolerance options
2246		$.each($.ui.ddmanager.droppables[draggable.options.scope] || [], function() {
2247
2248			if(this.options.disabled || this.greedyChild || !this.visible) {
2249				return;
2250			}
2251
2252			var parentInstance, scope, parent,
2253				intersects = $.ui.intersect(draggable, this, this.options.tolerance),
2254				c = !intersects && this.isover ? "isout" : (intersects && !this.isover ? "isover" : null);
2255			if(!c) {
2256				return;
2257			}
2258
2259			if (this.options.greedy) {
2260				// find droppable parents with same scope
2261				scope = this.options.scope;
2262				parent = this.element.parents(":data(ui-droppable)").filter(function () {
2263					return $.data(this, "ui-droppable").options.scope === scope;
2264				});
2265
2266				if (parent.length) {
2267					parentInstance = $.data(parent[0], "ui-droppable");
2268					parentInstance.greedyChild = (c === "isover");
2269				}
2270			}
2271
2272			// we just moved into a greedy child
2273			if (parentInstance && c === "isover") {
2274				parentInstance.isover = false;
2275				parentInstance.isout = true;
2276				parentInstance._out.call(parentInstance, event);
2277			}
2278
2279			this[c] = true;
2280			this[c === "isout" ? "isover" : "isout"] = false;
2281			this[c === "isover" ? "_over" : "_out"].call(this, event);
2282
2283			// we just moved out of a greedy child
2284			if (parentInstance && c === "isout") {
2285				parentInstance.isout = false;
2286				parentInstance.isover = true;
2287				parentInstance._over.call(parentInstance, event);
2288			}
2289		});
2290
2291	},
2292	dragStop: function( draggable, event ) {
2293		draggable.element.parentsUntil( "body" ).unbind( "scroll.droppable" );
2294		//Call prepareOffsets one final time since IE does not fire return scroll events when overflow was caused by drag (see #5003)
2295		if( !draggable.options.refreshPositions ) {
2296			$.ui.ddmanager.prepareOffsets( draggable, event );
2297		}
2298	}
2299};
2300
2301})(jQuery);
2302
2303(function( $, undefined ) {
2304
2305function num(v) {
2306	return parseInt(v, 10) || 0;
2307}
2308
2309function isNumber(value) {
2310	return !isNaN(parseInt(value, 10));
2311}
2312
2313$.widget("ui.resizable", $.ui.mouse, {
2314	version: "1.10.4",
2315	widgetEventPrefix: "resize",
2316	options: {
2317		alsoResize: false,
2318		animate: false,
2319		animateDuration: "slow",
2320		animateEasing: "swing",
2321		aspectRatio: false,
2322		autoHide: false,
2323		containment: false,
2324		ghost: false,
2325		grid: false,
2326		handles: "e,s,se",
2327		helper: false,
2328		maxHeight: null,
2329		maxWidth: null,
2330		minHeight: 10,
2331		minWidth: 10,
2332		// See #7960
2333		zIndex: 90,
2334
2335		// callbacks
2336		resize: null,
2337		start: null,
2338		stop: null
2339	},
2340	_create: function() {
2341
2342		var n, i, handle, axis, hname,
2343			that = this,
2344			o = this.options;
2345		this.element.addClass("ui-resizable");
2346
2347		$.extend(this, {
2348			_aspectRatio: !!(o.aspectRatio),
2349			aspectRatio: o.aspectRatio,
2350			originalElement: this.element,
2351			_proportionallyResizeElements: [],
2352			_helper: o.helper || o.ghost || o.animate ? o.helper || "ui-resizable-helper" : null
2353		});
2354
2355		//Wrap the element if it cannot hold child nodes
2356		if(this.element[0].nodeName.match(/canvas|textarea|input|select|button|img/i)) {
2357
2358			//Create a wrapper element and set the wrapper to the new current internal element
2359			this.element.wrap(
2360				$("<div class='ui-wrapper' style='overflow: hidden;'></div>").css({
2361					position: this.element.css("position"),
2362					width: this.element.outerWidth(),
2363					height: this.element.outerHeight(),
2364					top: this.element.css("top"),
2365					left: this.element.css("left")
2366				})
2367			);
2368
2369			//Overwrite the original this.element
2370			this.element = this.element.parent().data(
2371				"ui-resizable", this.element.data("ui-resizable")
2372			);
2373
2374			this.elementIsWrapper = true;
2375
2376			//Move margins to the wrapper
2377			this.element.css({ marginLeft: this.originalElement.css("marginLeft"), marginTop: this.originalElement.css("marginTop"), marginRight: this.originalElement.css("marginRight"), marginBottom: this.originalElement.css("marginBottom") });
2378			this.originalElement.css({ marginLeft: 0, marginTop: 0, marginRight: 0, marginBottom: 0});
2379
2380			//Prevent Safari textarea resize
2381			this.originalResizeStyle = this.originalElement.css("resize");
2382			this.originalElement.css("resize", "none");
2383
2384			//Push the actual element to our proportionallyResize internal array
2385			this._proportionallyResizeElements.push(this.originalElement.css({ position: "static", zoom: 1, display: "block" }));
2386
2387			// avoid IE jump (hard set the margin)
2388			this.originalElement.css({ margin: this.originalElement.css("margin") });
2389
2390			// fix handlers offset
2391			this._proportionallyResize();
2392
2393		}
2394
2395		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" });
2396		if(this.handles.constructor === String) {
2397
2398			if ( this.handles === "all") {
2399				this.handles = "n,e,s,w,se,sw,ne,nw";
2400			}
2401
2402			n = this.handles.split(",");
2403			this.handles = {};
2404
2405			for(i = 0; i < n.length; i++) {
2406
2407				handle = $.trim(n[i]);
2408				hname = "ui-resizable-"+handle;
2409				axis = $("<div class='ui-resizable-handle " + hname + "'></div>");
2410
2411				// Apply zIndex to all handles - see #7960
2412				axis.css({ zIndex: o.zIndex });
2413
2414				//TODO : What's going on here?
2415				if ("se" === handle) {
2416					axis.addClass("ui-icon ui-icon-gripsmall-diagonal-se");
2417				}
2418
2419				//Insert into internal handles object and append to element
2420				this.handles[handle] = ".ui-resizable-"+handle;
2421				this.element.append(axis);
2422			}
2423
2424		}
2425
2426		this._renderAxis = function(target) {
2427
2428			var i, axis, padPos, padWrapper;
2429
2430			target = target || this.element;
2431
2432			for(i in this.handles) {
2433
2434				if(this.handles[i].constructor === String) {
2435					this.handles[i] = $(this.handles[i], this.element).show();
2436				}
2437
2438				//Apply pad to wrapper element, needed to fix axis position (textarea, inputs, scrolls)
2439				if (this.elementIsWrapper && this.originalElement[0].nodeName.match(/textarea|input|select|button/i)) {
2440
2441					axis = $(this.handles[i], this.element);
2442
2443					//Checking the correct pad and border
2444					padWrapper = /sw|ne|nw|se|n|s/.test(i) ? axis.outerHeight() : axis.outerWidth();
2445
2446					//The padding type i have to apply...
2447					padPos = [ "padding",
2448						/ne|nw|n/.test(i) ? "Top" :
2449						/se|sw|s/.test(i) ? "Bottom" :
2450						/^e$/.test(i) ? "Right" : "Left" ].join("");
2451
2452					target.css(padPos, padWrapper);
2453
2454					this._proportionallyResize();
2455
2456				}
2457
2458				//TODO: What's that good for? There's not anything to be executed left
2459				if(!$(this.handles[i]).length) {
2460					continue;
2461				}
2462			}
2463		};
2464
2465		//TODO: make renderAxis a prototype function
2466		this._renderAxis(this.element);
2467
2468		this._handles = $(".ui-resizable-handle", this.element)
2469			.disableSelection();
2470
2471		//Matching axis name
2472		this._handles.mouseover(function() {
2473			if (!that.resizing) {
2474				if (this.className) {
2475					axis = this.className.match(/ui-resizable-(se|sw|ne|nw|n|e|s|w)/i);
2476				}
2477				//Axis, default = se
2478				that.axis = axis && axis[1] ? axis[1] : "se";
2479			}
2480		});
2481
2482		//If we want to auto hide the elements
2483		if (o.autoHide) {
2484			this._handles.hide();
2485			$(this.element)
2486				.addClass("ui-resizable-autohide")
2487				.mouseenter(function() {
2488					if (o.disabled) {
2489						return;
2490					}
2491					$(this).removeClass("ui-resizable-autohide");
2492					that._handles.show();
2493				})
2494				.mouseleave(function(){
2495					if (o.disabled) {
2496						return;
2497					}
2498					if (!that.resizing) {
2499						$(this).addClass("ui-resizable-autohide");
2500						that._handles.hide();
2501					}
2502				});
2503		}
2504
2505		//Initialize the mouse interaction
2506		this._mouseInit();
2507
2508	},
2509
2510	_destroy: function() {
2511
2512		this._mouseDestroy();
2513
2514		var wrapper,
2515			_destroy = function(exp) {
2516				$(exp).removeClass("ui-resizable ui-resizable-disabled ui-resizable-resizing")
2517					.removeData("resizable").removeData("ui-resizable").unbind(".resizable").find(".ui-resizable-handle").remove();
2518			};
2519
2520		//TODO: Unwrap at same DOM position
2521		if (this.elementIsWrapper) {
2522			_destroy(this.element);
2523			wrapper = this.element;
2524			this.originalElement.css({
2525				position: wrapper.css("position"),
2526				width: wrapper.outerWidth(),
2527				height: wrapper.outerHeight(),
2528				top: wrapper.css("top"),
2529				left: wrapper.css("left")
2530			}).insertAfter( wrapper );
2531			wrapper.remove();
2532		}
2533
2534		this.originalElement.css("resize", this.originalResizeStyle);
2535		_destroy(this.originalElement);
2536
2537		return this;
2538	},
2539
2540	_mouseCapture: function(event) {
2541		var i, handle,
2542			capture = false;
2543
2544		for (i in this.handles) {
2545			handle = $(this.handles[i])[0];
2546			if (handle === event.target || $.contains(handle, event.target)) {
2547				capture = true;
2548			}
2549		}
2550
2551		return !this.options.disabled && capture;
2552	},
2553
2554	_mouseStart: function(event) {
2555
2556		var curleft, curtop, cursor,
2557			o = this.options,
2558			iniPos = this.element.position(),
2559			el = this.element;
2560
2561		this.resizing = true;
2562
2563		// bugfix for http://dev.jquery.com/ticket/1749
2564		if ( (/absolute/).test( el.css("position") ) ) {
2565			el.css({ position: "absolute", top: el.css("top"), left: el.css("left") });
2566		} else if (el.is(".ui-draggable")) {
2567			el.css({ position: "absolute", top: iniPos.top, left: iniPos.left });
2568		}
2569
2570		this._renderProxy();
2571
2572		curleft = num(this.helper.css("left"));
2573		curtop = num(this.helper.css("top"));
2574
2575		if (o.containment) {
2576			curleft += $(o.containment).scrollLeft() || 0;
2577			curtop += $(o.containment).scrollTop() || 0;
2578		}
2579
2580		//Store needed variables
2581		this.offset = this.helper.offset();
2582		this.position = { left: curleft, top: curtop };
2583		this.size = this._helper ? { width: this.helper.width(), height: this.helper.height() } : { width: el.width(), height: el.height() };
2584		this.originalSize = this._helper ? { width: el.outerWidth(), height: el.outerHeight() } : { width: el.width(), height: el.height() };
2585		this.originalPosition = { left: curleft, top: curtop };
2586		this.sizeDiff = { width: el.outerWidth() - el.width(), height: el.outerHeight() - el.height() };
2587		this.originalMousePosition = { left: event.pageX, top: event.pageY };
2588
2589		//Aspect Ratio
2590		this.aspectRatio = (typeof o.aspectRatio === "number") ? o.aspectRatio : ((this.originalSize.width / this.originalSize.height) || 1);
2591
2592		cursor = $(".ui-resizable-" + this.axis).css("cursor");
2593		$("body").css("cursor", cursor === "auto" ? this.axis + "-resize" : cursor);
2594
2595		el.addClass("ui-resizable-resizing");
2596		this._propagate("start", event);
2597		return true;
2598	},
2599
2600	_mouseDrag: function(event) {
2601
2602		//Increase performance, avoid regex
2603		var data,
2604			el = this.helper, props = {},
2605			smp = this.originalMousePosition,
2606			a = this.axis,
2607			prevTop = this.position.top,
2608			prevLeft = this.position.left,
2609			prevWidth = this.size.width,
2610			prevHeight = this.size.height,
2611			dx = (event.pageX-smp.left)||0,
2612			dy = (event.pageY-smp.top)||0,
2613			trigger = this._change[a];
2614
2615		if (!trigger) {
2616			return false;
2617		}
2618
2619		// Calculate the attrs that will be change
2620		data = trigger.apply(this, [event, dx, dy]);
2621
2622		// Put this in the mouseDrag handler since the user can start pressing shift while resizing
2623		this._updateVirtualBoundaries(event.shiftKey);
2624		if (this._aspectRatio || event.shiftKey) {
2625			data = this._updateRatio(data, event);
2626		}
2627
2628		data = this._respectSize(data, event);
2629
2630		this._updateCache(data);
2631
2632		// plugins callbacks need to be called first
2633		this._propagate("resize", event);
2634
2635		if (this.position.top !== prevTop) {
2636			props.top = this.position.top + "px";
2637		}
2638		if (this.position.left !== prevLeft) {
2639			props.left = this.position.left + "px";
2640		}
2641		if (this.size.width !== prevWidth) {
2642			props.width = this.size.width + "px";
2643		}
2644		if (this.size.height !== prevHeight) {
2645			props.height = this.size.height + "px";
2646		}
2647		el.css(props);
2648
2649		if (!this._helper && this._proportionallyResizeElements.length) {
2650			this._proportionallyResize();
2651		}
2652
2653		// Call the user callback if the element was resized
2654		if ( ! $.isEmptyObject(props) ) {
2655			this._trigger("resize", event, this.ui());
2656		}
2657
2658		return false;
2659	},
2660
2661	_mouseStop: function(event) {
2662
2663		this.resizing = false;
2664		var pr, ista, soffseth, soffsetw, s, left, top,
2665			o = this.options, that = this;
2666
2667		if(this._helper) {
2668
2669			pr = this._proportionallyResizeElements;
2670			ista = pr.length && (/textarea/i).test(pr[0].nodeName);
2671			soffseth = ista && $.ui.hasScroll(pr[0], "left") /* TODO - jump height */ ? 0 : that.sizeDiff.height;
2672			soffsetw = ista ? 0 : that.sizeDiff.width;
2673
2674			s = { width: (that.helper.width()  - soffsetw), height: (that.helper.height() - soffseth) };
2675			left = (parseInt(that.element.css("left"), 10) + (that.position.left - that.originalPosition.left)) || null;
2676			top = (parseInt(that.element.css("top"), 10) + (that.position.top - that.originalPosition.top)) || null;
2677
2678			if (!o.animate) {
2679				this.element.css($.extend(s, { top: top, left: left }));
2680			}
2681
2682			that.helper.height(that.size.height);
2683			that.helper.width(that.size.width);
2684
2685			if (this._helper && !o.animate) {
2686				this._proportionallyResize();
2687			}
2688		}
2689
2690		$("body").css("cursor", "auto");
2691
2692		this.element.removeClass("ui-resizable-resizing");
2693
2694		this._propagate("stop", event);
2695
2696		if (this._helper) {
2697			this.helper.remove();
2698		}
2699
2700		return false;
2701
2702	},
2703
2704	_updateVirtualBoundaries: function(forceAspectRatio) {
2705		var pMinWidth, pMaxWidth, pMinHeight, pMaxHeight, b,
2706			o = this.options;
2707
2708		b = {
2709			minWidth: isNumber(o.minWidth) ? o.minWidth : 0,
2710			maxWidth: isNumber(o.maxWidth) ? o.maxWidth : Infinity,
2711			minHeight: isNumber(o.minHeight) ? o.minHeight : 0,
2712			maxHeight: isNumber(o.maxHeight) ? o.maxHeight : Infinity
2713		};
2714
2715		if(this._aspectRatio || forceAspectRatio) {
2716			// We want to create an enclosing box whose aspect ration is the requested one
2717			// First, compute the "projected" size for each dimension based on the aspect ratio and other dimension
2718			pMinWidth = b.minHeight * this.aspectRatio;
2719			pMinHeight = b.minWidth / this.aspectRatio;
2720			pMaxWidth = b.maxHeight * this.aspectRatio;
2721			pMaxHeight = b.maxWidth / this.aspectRatio;
2722
2723			if(pMinWidth > b.minWidth) {
2724				b.minWidth = pMinWidth;
2725			}
2726			if(pMinHeight > b.minHeight) {
2727				b.minHeight = pMinHeight;
2728			}
2729			if(pMaxWidth < b.maxWidth) {
2730				b.maxWidth = pMaxWidth;
2731			}
2732			if(pMaxHeight < b.maxHeight) {
2733				b.maxHeight = pMaxHeight;
2734			}
2735		}
2736		this._vBoundaries = b;
2737	},
2738
2739	_updateCache: function(data) {
2740		this.offset = this.helper.offset();
2741		if (isNumber(data.left)) {
2742			this.position.left = data.left;
2743		}
2744		if (isNumber(data.top)) {
2745			this.position.top = data.top;
2746		}
2747		if (isNumber(data.height)) {
2748			this.size.height = data.height;
2749		}
2750		if (isNumber(data.width)) {
2751			this.size.width = data.width;
2752		}
2753	},
2754
2755	_updateRatio: function( data ) {
2756
2757		var cpos = this.position,
2758			csize = this.size,
2759			a = this.axis;
2760
2761		if (isNumber(data.height)) {
2762			data.width = (data.height * this.aspectRatio);
2763		} else if (isNumber(data.width)) {
2764			data.height = (data.width / this.aspectRatio);
2765		}
2766
2767		if (a === "sw") {
2768			data.left = cpos.left + (csize.width - data.width);
2769			data.top = null;
2770		}
2771		if (a === "nw") {
2772			data.top = cpos.top + (csize.height - data.height);
2773			data.left = cpos.left + (csize.width - data.width);
2774		}
2775
2776		return data;
2777	},
2778
2779	_respectSize: function( data ) {
2780
2781		var o = this._vBoundaries,
2782			a = this.axis,
2783			ismaxw = isNumber(data.width) && o.maxWidth && (o.maxWidth < data.width), ismaxh = isNumber(data.height) && o.maxHeight && (o.maxHeight < data.height),
2784			isminw = isNumber(data.width) && o.minWidth && (o.minWidth > data.width), isminh = isNumber(data.height) && o.minHeight && (o.minHeight > data.height),
2785			dw = this.originalPosition.left + this.originalSize.width,
2786			dh = this.position.top + this.size.height,
2787			cw = /sw|nw|w/.test(a), ch = /nw|ne|n/.test(a);
2788		if (isminw) {
2789			data.width = o.minWidth;
2790		}
2791		if (isminh) {
2792			data.height = o.minHeight;
2793		}
2794		if (ismaxw) {
2795			data.width = o.maxWidth;
2796		}
2797		if (ismaxh) {
2798			data.height = o.maxHeight;
2799		}
2800
2801		if (isminw && cw) {
2802			data.left = dw - o.minWidth;
2803		}
2804		if (ismaxw && cw) {
2805			data.left = dw - o.maxWidth;
2806		}
2807		if (isminh && ch) {
2808			data.top = dh - o.minHeight;
2809		}
2810		if (ismaxh && ch) {
2811			data.top = dh - o.maxHeight;
2812		}
2813
2814		// fixing jump error on top/left - bug #2330
2815		if (!data.width && !data.height && !data.left && data.top) {
2816			data.top = null;
2817		} else if (!data.width && !data.height && !data.top && data.left) {
2818			data.left = null;
2819		}
2820
2821		return data;
2822	},
2823
2824	_proportionallyResize: function() {
2825
2826		if (!this._proportionallyResizeElements.length) {
2827			return;
2828		}
2829
2830		var i, j, borders, paddings, prel,
2831			element = this.helper || this.element;
2832
2833		for ( i=0; i < this._proportionallyResizeElements.length; i++) {
2834
2835			prel = this._proportionallyResizeElements[i];
2836
2837			if (!this.borderDif) {
2838				this.borderDif = [];
2839				borders = [prel.css("borderTopWidth"), prel.css("borderRightWidth"), prel.css("borderBottomWidth"), prel.css("borderLeftWidth")];
2840				paddings = [prel.css("paddingTop"), prel.css("paddingRight"), prel.css("paddingBottom"), prel.css("paddingLeft")];
2841
2842				for ( j = 0; j < borders.length; j++ ) {
2843					this.borderDif[ j ] = ( parseInt( borders[ j ], 10 ) || 0 ) + ( parseInt( paddings[ j ], 10 ) || 0 );
2844				}
2845			}
2846
2847			prel.css({
2848				height: (element.height() - this.borderDif[0] - this.borderDif[2]) || 0,
2849				width: (element.width() - this.borderDif[1] - this.borderDif[3]) || 0
2850			});
2851
2852		}
2853
2854	},
2855
2856	_renderProxy: function() {
2857
2858		var el = this.element, o = this.options;
2859		this.elementOffset = el.offset();
2860
2861		if(this._helper) {
2862
2863			this.helper = this.helper || $("<div style='overflow:hidden;'></div>");
2864
2865			this.helper.addClass(this._helper).css({
2866				width: this.element.outerWidth() - 1,
2867				height: this.element.outerHeight() - 1,
2868				position: "absolute",
2869				left: this.elementOffset.left +"px",
2870				top: this.elementOffset.top +"px",
2871				zIndex: ++o.zIndex //TODO: Don't modify option
2872			});
2873
2874			this.helper
2875				.appendTo("body")
2876				.disableSelection();
2877
2878		} else {
2879			this.helper = this.element;
2880		}
2881
2882	},
2883
2884	_change: {
2885		e: function(event, dx) {
2886			return { width: this.originalSize.width + dx };
2887		},
2888		w: function(event, dx) {
2889			var cs = this.originalSize, sp = this.originalPosition;
2890			return { left: sp.left + dx, width: cs.width - dx };
2891		},
2892		n: function(event, dx, dy) {
2893			var cs = this.originalSize, sp = this.originalPosition;
2894			return { top: sp.top + dy, height: cs.height - dy };
2895		},
2896		s: function(event, dx, dy) {
2897			return { height: this.originalSize.height + dy };
2898		},
2899		se: function(event, dx, dy) {
2900			return $.extend(this._change.s.apply(this, arguments), this._change.e.apply(this, [event, dx, dy]));
2901		},
2902		sw: function(event, dx, dy) {
2903			return $.extend(this._change.s.apply(this, arguments), this._change.w.apply(this, [event, dx, dy]));
2904		},
2905		ne: function(event, dx, dy) {
2906			return $.extend(this._change.n.apply(this, arguments), this._change.e.apply(this, [event, dx, dy]));
2907		},
2908		nw: function(event, dx, dy) {
2909			return $.extend(this._change.n.apply(this, arguments), this._change.w.apply(this, [event, dx, dy]));
2910		}
2911	},
2912
2913	_propagate: function(n, event) {
2914		$.ui.plugin.call(this, n, [event, this.ui()]);
2915		(n !== "resize" && this._trigger(n, event, this.ui()));
2916	},
2917
2918	plugins: {},
2919
2920	ui: function() {
2921		return {
2922			originalElement: this.originalElement,
2923			element: this.element,
2924			helper: this.helper,
2925			position: this.position,
2926			size: this.size,
2927			originalSize: this.originalSize,
2928			originalPosition: this.originalPosition
2929		};
2930	}
2931
2932});
2933
2934/*
2935 * Resizable Extensions
2936 */
2937
2938$.ui.plugin.add("resizable", "animate", {
2939
2940	stop: function( event ) {
2941		var that = $(this).data("ui-resizable"),
2942			o = that.options,
2943			pr = that._proportionallyResizeElements,
2944			ista = pr.length && (/textarea/i).test(pr[0].nodeName),
2945			soffseth = ista && $.ui.hasScroll(pr[0], "left") /* TODO - jump height */ ? 0 : that.sizeDiff.height,
2946			soffsetw = ista ? 0 : that.sizeDiff.width,
2947			style = { width: (that.size.width - soffsetw), height: (that.size.height - soffseth) },
2948			left = (parseInt(that.element.css("left"), 10) + (that.position.left - that.originalPosition.left)) || null,
2949			top = (parseInt(that.element.css("top"), 10) + (that.position.top - that.originalPosition.top)) || null;
2950
2951		that.element.animate(
2952			$.extend(style, top && left ? { top: top, left: left } : {}), {
2953				duration: o.animateDuration,
2954				easing: o.animateEasing,
2955				step: function() {
2956
2957					var data = {
2958						width: parseInt(that.element.css("width"), 10),
2959						height: parseInt(that.element.css("height"), 10),
2960						top: parseInt(that.element.css("top"), 10),
2961						left: parseInt(that.element.css("left"), 10)
2962					};
2963
2964					if (pr && pr.length) {
2965						$(pr[0]).css({ width: data.width, height: data.height });
2966					}
2967
2968					// propagating resize, and updating values for each animation step
2969					that._updateCache(data);
2970					that._propagate("resize", event);
2971
2972				}
2973			}
2974		);
2975	}
2976
2977});
2978
2979$.ui.plugin.add("resizable", "containment", {
2980
2981	start: function() {
2982		var element, p, co, ch, cw, width, height,
2983			that = $(this).data("ui-resizable"),
2984			o = that.options,
2985			el = that.element,
2986			oc = o.containment,
2987			ce = (oc instanceof $) ? oc.get(0) : (/parent/.test(oc)) ? el.parent().get(0) : oc;
2988
2989		if (!ce) {
2990			return;
2991		}
2992
2993		that.containerElement = $(ce);
2994
2995		if (/document/.test(oc) || oc === document) {
2996			that.containerOffset = { left: 0, top: 0 };
2997			that.containerPosition = { left: 0, top: 0 };
2998
2999			that.parentData = {
3000				element: $(document), left: 0, top: 0,
3001				width: $(document).width(), height: $(document).height() || document.body.parentNode.scrollHeight
3002			};
3003		}
3004
3005		// i'm a node, so compute top, left, right, bottom
3006		else {
3007			element = $(ce);
3008			p = [];
3009			$([ "Top", "Right", "Left", "Bottom" ]).each(function(i, name) { p[i] = num(element.css("padding" + name)); });
3010
3011			that.containerOffset = element.offset();
3012			that.containerPosition = element.position();
3013			that.containerSize = { height: (element.innerHeight() - p[3]), width: (element.innerWidth() - p[1]) };
3014
3015			co = that.containerOffset;
3016			ch = that.containerSize.height;
3017			cw = that.containerSize.width;
3018			width = ($.ui.hasScroll(ce, "left") ? ce.scrollWidth : cw );
3019			height = ($.ui.hasScroll(ce) ? ce.scrollHeight : ch);
3020
3021			that.parentData = {
3022				element: ce, left: co.left, top: co.top, width: width, height: height
3023			};
3024		}
3025	},
3026
3027	resize: function( event ) {
3028		var woset, hoset, isParent, isOffsetRelative,
3029			that = $(this).data("ui-resizable"),
3030			o = that.options,
3031			co = that.containerOffset, cp = that.position,
3032			pRatio = that._aspectRatio || event.shiftKey,
3033			cop = { top:0, left:0 }, ce = that.containerElement;
3034
3035		if (ce[0] !== document && (/static/).test(ce.css("position"))) {
3036			cop = co;
3037		}
3038
3039		if (cp.left < (that._helper ? co.left : 0)) {
3040			that.size.width = that.size.width + (that._helper ? (that.position.left - co.left) : (that.position.left - cop.left));
3041			if (pRatio) {
3042				that.size.height = that.size.width / that.aspectRatio;
3043			}
3044			that.position.left = o.helper ? co.left : 0;
3045		}
3046
3047		if (cp.top < (that._helper ? co.top : 0)) {
3048			that.size.height = that.size.height + (that._helper ? (that.position.top - co.top) : that.position.top);
3049			if (pRatio) {
3050				that.size.width = that.size.height * that.aspectRatio;
3051			}
3052			that.position.top = that._helper ? co.top : 0;
3053		}
3054
3055		that.offset.left = that.parentData.left+that.position.left;
3056		that.offset.top = that.parentData.top+that.position.top;
3057
3058		woset = Math.abs( (that._helper ? that.offset.left - cop.left : (that.offset.left - cop.left)) + that.sizeDiff.width );
3059		hoset = Math.abs( (that._helper ? that.offset.top - cop.top : (that.offset.top - co.top)) + that.sizeDiff.height );
3060
3061		isParent = that.containerElement.get(0) === that.element.parent().get(0);
3062		isOffsetRelative = /relative|absolute/.test(that.containerElement.css("position"));
3063
3064		if ( isParent && isOffsetRelative ) {
3065			woset -= Math.abs( that.parentData.left );
3066		}
3067
3068		if (woset + that.size.width >= that.parentData.width) {
3069			that.size.width = that.parentData.width - woset;
3070			if (pRatio) {
3071				that.size.height = that.size.width / that.aspectRatio;
3072			}
3073		}
3074
3075		if (hoset + that.size.height >= that.parentData.height) {
3076			that.size.height = that.parentData.height - hoset;
3077			if (pRatio) {
3078				that.size.width = that.size.height * that.aspectRatio;
3079			}
3080		}
3081	},
3082
3083	stop: function(){
3084		var that = $(this).data("ui-resizable"),
3085			o = that.options,
3086			co = that.containerOffset,
3087			cop = that.containerPosition,
3088			ce = that.containerElement,
3089			helper = $(that.helper),
3090			ho = helper.offset(),
3091			w = helper.outerWidth() - that.sizeDiff.width,
3092			h = helper.outerHeight() - that.sizeDiff.height;
3093
3094		if (that._helper && !o.animate && (/relative/).test(ce.css("position"))) {
3095			$(this).css({ left: ho.left - cop.left - co.left, width: w, height: h });
3096		}
3097
3098		if (that._helper && !o.animate && (/static/).test(ce.css("position"))) {
3099			$(this).css({ left: ho.left - cop.left - co.left, width: w, height: h });
3100		}
3101
3102	}
3103});
3104
3105$.ui.plugin.add("resizable", "alsoResize", {
3106
3107	start: function () {
3108		var that = $(this).data("ui-resizable"),
3109			o = that.options,
3110			_store = function (exp) {
3111				$(exp).each(function() {
3112					var el = $(this);
3113					el.data("ui-resizable-alsoresize", {
3114						width: parseInt(el.width(), 10), height: parseInt(el.height(), 10),
3115						left: parseInt(el.css("left"), 10), top: parseInt(el.css("top"), 10)
3116					});
3117				});
3118			};
3119
3120		if (typeof(o.alsoResize) === "object" && !o.alsoResize.parentNode) {
3121			if (o.alsoResize.length) { o.alsoResize = o.alsoResize[0]; _store(o.alsoResize); }
3122			else { $.each(o.alsoResize, function (exp) { _store(exp); }); }
3123		}else{
3124			_store(o.alsoResize);
3125		}
3126	},
3127
3128	resize: function (event, ui) {
3129		var that = $(this).data("ui-resizable"),
3130			o = that.options,
3131			os = that.originalSize,
3132			op = that.originalPosition,
3133			delta = {
3134				height: (that.size.height - os.height) || 0, width: (that.size.width - os.width) || 0,
3135				top: (that.position.top - op.top) || 0, left: (that.position.left - op.left) || 0
3136			},
3137
3138			_alsoResize = function (exp, c) {
3139				$(exp).each(function() {
3140					var el = $(this), start = $(this).data("ui-resizable-alsoresize"), style = {},
3141						css = c && c.length ? c : el.parents(ui.originalElement[0]).length ? ["width", "height"] : ["width", "height", "top", "left"];
3142
3143					$.each(css, function (i, prop) {
3144						var sum = (start[prop]||0) + (delta[prop]||0);
3145						if (sum && sum >= 0) {
3146							style[prop] = sum || null;
3147						}
3148					});
3149
3150					el.css(style);
3151				});
3152			};
3153
3154		if (typeof(o.alsoResize) === "object" && !o.alsoResize.nodeType) {
3155			$.each(o.alsoResize, function (exp, c) { _alsoResize(exp, c); });
3156		}else{
3157			_alsoResize(o.alsoResize);
3158		}
3159	},
3160
3161	stop: function () {
3162		$(this).removeData("resizable-alsoresize");
3163	}
3164});
3165
3166$.ui.plugin.add("resizable", "ghost", {
3167
3168	start: function() {
3169
3170		var that = $(this).data("ui-resizable"), o = that.options, cs = that.size;
3171
3172		that.ghost = that.originalElement.clone();
3173		that.ghost
3174			.css({ opacity: 0.25, display: "block", position: "relative", height: cs.height, width: cs.width, margin: 0, left: 0, top: 0 })
3175			.addClass("ui-resizable-ghost")
3176			.addClass(typeof o.ghost === "string" ? o.ghost : "");
3177
3178		that.ghost.appendTo(that.helper);
3179
3180	},
3181
3182	resize: function(){
3183		var that = $(this).data("ui-resizable");
3184		if (that.ghost) {
3185			that.ghost.css({ position: "relative", height: that.size.height, width: that.size.width });
3186		}
3187	},
3188
3189	stop: function() {
3190		var that = $(this).data("ui-resizable");
3191		if (that.ghost && that.helper) {
3192			that.helper.get(0).removeChild(that.ghost.get(0));
3193		}
3194	}
3195
3196});
3197
3198$.ui.plugin.add("resizable", "grid", {
3199
3200	resize: function() {
3201		var that = $(this).data("ui-resizable"),
3202			o = that.options,
3203			cs = that.size,
3204			os = that.originalSize,
3205			op = that.originalPosition,
3206			a = that.axis,
3207			grid = typeof o.grid === "number" ? [o.grid, o.grid] : o.grid,
3208			gridX = (grid[0]||1),
3209			gridY = (grid[1]||1),
3210			ox = Math.round((cs.width - os.width) / gridX) * gridX,
3211			oy = Math.round((cs.height - os.height) / gridY) * gridY,
3212			newWidth = os.width + ox,
3213			newHeight = os.height + oy,
3214			isMaxWidth = o.maxWidth && (o.maxWidth < newWidth),
3215			isMaxHeight = o.maxHeight && (o.maxHeight < newHeight),
3216			isMinWidth = o.minWidth && (o.minWidth > newWidth),
3217			isMinHeight = o.minHeight && (o.minHeight > newHeight);
3218
3219		o.grid = grid;
3220
3221		if (isMinWidth) {
3222			newWidth = newWidth + gridX;
3223		}
3224		if (isMinHeight) {
3225			newHeight = newHeight + gridY;
3226		}
3227		if (isMaxWidth) {
3228			newWidth = newWidth - gridX;
3229		}
3230		if (isMaxHeight) {
3231			newHeight = newHeight - gridY;
3232		}
3233
3234		if (/^(se|s|e)$/.test(a)) {
3235			that.size.width = newWidth;
3236			that.size.height = newHeight;
3237		} else if (/^(ne)$/.test(a)) {
3238			that.size.width = newWidth;
3239			that.size.height = newHeight;
3240			that.position.top = op.top - oy;
3241		} else if (/^(sw)$/.test(a)) {
3242			that.size.width = newWidth;
3243			that.size.height = newHeight;
3244			that.position.left = op.left - ox;
3245		} else {
3246			if ( newHeight - gridY > 0 ) {
3247				that.size.height = newHeight;
3248				that.position.top = op.top - oy;
3249			} else {
3250				that.size.height = gridY;
3251				that.position.top = op.top + os.height - gridY;
3252			}
3253			if ( newWidth - gridX > 0 ) {
3254				that.size.width = newWidth;
3255				that.position.left = op.left - ox;
3256			} else {
3257				that.size.width = gridX;
3258				that.position.left = op.left + os.width - gridX;
3259			}
3260		}
3261	}
3262
3263});
3264
3265})(jQuery);
3266
3267(function( $, undefined ) {
3268
3269$.widget("ui.selectable", $.ui.mouse, {
3270	version: "1.10.4",
3271	options: {
3272		appendTo: "body",
3273		autoRefresh: true,
3274		distance: 0,
3275		filter: "*",
3276		tolerance: "touch",
3277
3278		// callbacks
3279		selected: null,
3280		selecting: null,
3281		start: null,
3282		stop: null,
3283		unselected: null,
3284		unselecting: null
3285	},
3286	_create: function() {
3287		var selectees,
3288			that = this;
3289
3290		this.element.addClass("ui-selectable");
3291
3292		this.dragged = false;
3293
3294		// cache selectee children based on filter
3295		this.refresh = function() {
3296			selectees = $(that.options.filter, that.element[0]);
3297			selectees.addClass("ui-selectee");
3298			selectees.each(function() {
3299				var $this = $(this),
3300					pos = $this.offset();
3301				$.data(this, "selectable-item", {
3302					element: this,
3303					$element: $this,
3304					left: pos.left,
3305					top: pos.top,
3306					right: pos.left + $this.outerWidth(),
3307					bottom: pos.top + $this.outerHeight(),
3308					startselected: false,
3309					selected: $this.hasClass("ui-selected"),
3310					selecting: $this.hasClass("ui-selecting"),
3311					unselecting: $this.hasClass("ui-unselecting")
3312				});
3313			});
3314		};
3315		this.refresh();
3316
3317		this.selectees = selectees.addClass("ui-selectee");
3318
3319		this._mouseInit();
3320
3321		this.helper = $("<div class='ui-selectable-helper'></div>");
3322	},
3323
3324	_destroy: function() {
3325		this.selectees
3326			.removeClass("ui-selectee")
3327			.removeData("selectable-item");
3328		this.element
3329			.removeClass("ui-selectable ui-selectable-disabled");
3330		this._mouseDestroy();
3331	},
3332
3333	_mouseStart: function(event) {
3334		var that = this,
3335			options = this.options;
3336
3337		this.opos = [event.pageX, event.pageY];
3338
3339		if (this.options.disabled) {
3340			return;
3341		}
3342
3343		this.selectees = $(options.filter, this.element[0]);
3344
3345		this._trigger("start", event);
3346
3347		$(options.appendTo).append(this.helper);
3348		// position helper (lasso)
3349		this.helper.css({
3350			"left": event.pageX,
3351			"top": event.pageY,
3352			"width": 0,
3353			"height": 0
3354		});
3355
3356		if (options.autoRefresh) {
3357			this.refresh();
3358		}
3359
3360		this.selectees.filter(".ui-selected").each(function() {
3361			var selectee = $.data(this, "selectable-item");
3362			selectee.startselected = true;
3363			if (!event.metaKey && !event.ctrlKey) {
3364				selectee.$element.removeClass("ui-selected");
3365				selectee.selected = false;
3366				selectee.$element.addClass("ui-unselecting");
3367				selectee.unselecting = true;
3368				// selectable UNSELECTING callback
3369				that._trigger("unselecting", event, {
3370					unselecting: selectee.element
3371				});
3372			}
3373		});
3374
3375		$(event.target).parents().addBack().each(function() {
3376			var doSelect,
3377				selectee = $.data(this, "selectable-item");
3378			if (selectee) {
3379				doSelect = (!event.metaKey && !event.ctrlKey) || !selectee.$element.hasClass("ui-selected");
3380				selectee.$element
3381					.removeClass(doSelect ? "ui-unselecting" : "ui-selected")
3382					.addClass(doSelect ? "ui-selecting" : "ui-unselecting");
3383				selectee.unselecting = !doSelect;
3384				selectee.selecting = doSelect;
3385				selectee.selected = doSelect;
3386				// selectable (UN)SELECTING callback
3387				if (doSelect) {
3388					that._trigger("selecting", event, {
3389						selecting: selectee.element
3390					});
3391				} else {
3392					that._trigger("unselecting", event, {
3393						unselecting: selectee.element
3394					});
3395				}
3396				return false;
3397			}
3398		});
3399
3400	},
3401
3402	_mouseDrag: function(event) {
3403
3404		this.dragged = true;
3405
3406		if (this.options.disabled) {
3407			return;
3408		}
3409
3410		var tmp,
3411			that = this,
3412			options = this.options,
3413			x1 = this.opos[0],
3414			y1 = this.opos[1],
3415			x2 = event.pageX,
3416			y2 = event.pageY;
3417
3418		if (x1 > x2) { tmp = x2; x2 = x1; x1 = tmp; }
3419		if (y1 > y2) { tmp = y2; y2 = y1; y1 = tmp; }
3420		this.helper.css({left: x1, top: y1, width: x2-x1, height: y2-y1});
3421
3422		this.selectees.each(function() {
3423			var selectee = $.data(this, "selectable-item"),
3424				hit = false;
3425
3426			//prevent helper from being selected if appendTo: selectable
3427			if (!selectee || selectee.element === that.element[0]) {
3428				return;
3429			}
3430
3431			if (options.tolerance === "touch") {
3432				hit = ( !(selectee.left > x2 || selectee.right < x1 || selectee.top > y2 || selectee.bottom < y1) );
3433			} else if (options.tolerance === "fit") {
3434				hit = (selectee.left > x1 && selectee.right < x2 && selectee.top > y1 && selectee.bottom < y2);
3435			}
3436
3437			if (hit) {
3438				// SELECT
3439				if (selectee.selected) {
3440					selectee.$element.removeClass("ui-selected");
3441					selectee.selected = false;
3442				}
3443				if (selectee.unselecting) {
3444					selectee.$element.removeClass("ui-unselecting");
3445					selectee.unselecting = false;
3446				}
3447				if (!selectee.selecting) {
3448					selectee.$element.addClass("ui-selecting");
3449					selectee.selecting = true;
3450					// selectable SELECTING callback
3451					that._trigger("selecting", event, {
3452						selecting: selectee.element
3453					});
3454				}
3455			} else {
3456				// UNSELECT
3457				if (selectee.selecting) {
3458					if ((event.metaKey || event.ctrlKey) && selectee.startselected) {
3459						selectee.$element.removeClass("ui-selecting");
3460						selectee.selecting = false;
3461						selectee.$element.addClass("ui-selected");
3462						selectee.selected = true;
3463					} else {
3464						selectee.$element.removeClass("ui-selecting");
3465						selectee.selecting = false;
3466						if (selectee.startselected) {
3467							selectee.$element.addClass("ui-unselecting");
3468							selectee.unselecting = true;
3469						}
3470						// selectable UNSELECTING callback
3471						that._trigger("unselecting", event, {
3472							unselecting: selectee.element
3473						});
3474					}
3475				}
3476				if (selectee.selected) {
3477					if (!event.metaKey && !event.ctrlKey && !selectee.startselected) {
3478						selectee.$element.removeClass("ui-selected");
3479						selectee.selected = false;
3480
3481						selectee.$element.addClass("ui-unselecting");
3482						selectee.unselecting = true;
3483						// selectable UNSELECTING callback
3484						that._trigger("unselecting", event, {
3485							unselecting: selectee.element
3486						});
3487					}
3488				}
3489			}
3490		});
3491
3492		return false;
3493	},
3494
3495	_mouseStop: function(event) {
3496		var that = this;
3497
3498		this.dragged = false;
3499
3500		$(".ui-unselecting", this.element[0]).each(function() {
3501			var selectee = $.data(this, "selectable-item");
3502			selectee.$element.removeClass("ui-unselecting");
3503			selectee.unselecting = false;
3504			selectee.startselected = false;
3505			that._trigger("unselected", event, {
3506				unselected: selectee.element
3507			});
3508		});
3509		$(".ui-selecting", this.element[0]).each(function() {
3510			var selectee = $.data(this, "selectable-item");
3511			selectee.$element.removeClass("ui-selecting").addClass("ui-selected");
3512			selectee.selecting = false;
3513			selectee.selected = true;
3514			selectee.startselected = true;
3515			that._trigger("selected", event, {
3516				selected: selectee.element
3517			});
3518		});
3519		this._trigger("stop", event);
3520
3521		this.helper.remove();
3522
3523		return false;
3524	}
3525
3526});
3527
3528})(jQuery);
3529
3530(function( $, undefined ) {
3531
3532function isOverAxis( x, reference, size ) {
3533	return ( x > reference ) && ( x < ( reference + size ) );
3534}
3535
3536function isFloating(item) {
3537	return (/left|right/).test(item.css("float")) || (/inline|table-cell/).test(item.css("display"));
3538}
3539
3540$.widget("ui.sortable", $.ui.mouse, {
3541	version: "1.10.4",
3542	widgetEventPrefix: "sort",
3543	ready: false,
3544	options: {
3545		appendTo: "parent",
3546		axis: false,
3547		connectWith: false,
3548		containment: false,
3549		cursor: "auto",
3550		cursorAt: false,
3551		dropOnEmpty: true,
3552		forcePlaceholderSize: false,
3553		forceHelperSize: false,
3554		grid: false,
3555		handle: false,
3556		helper: "original",
3557		items: "> *",
3558		opacity: false,
3559		placeholder: false,
3560		revert: false,
3561		scroll: true,
3562		scrollSensitivity: 20,
3563		scrollSpeed: 20,
3564		scope: "default",
3565		tolerance: "intersect",
3566		zIndex: 1000,
3567
3568		// callbacks
3569		activate: null,
3570		beforeStop: null,
3571		change: null,
3572		deactivate: null,
3573		out: null,
3574		over: null,
3575		receive: null,
3576		remove: null,
3577		sort: null,
3578		start: null,
3579		stop: null,
3580		update: null
3581	},
3582	_create: function() {
3583
3584		var o = this.options;
3585		this.containerCache = {};
3586		this.element.addClass("ui-sortable");
3587
3588		//Get the items
3589		this.refresh();
3590
3591		//Let's determine if the items are being displayed horizontally
3592		this.floating = this.items.length ? o.axis === "x" || isFloating(this.items[0].item) : false;
3593
3594		//Let's determine the parent's offset
3595		this.offset = this.element.offset();
3596
3597		//Initialize mouse events for interaction
3598		this._mouseInit();
3599
3600		//We're ready to go
3601		this.ready = true;
3602
3603	},
3604
3605	_destroy: function() {
3606		this.element
3607			.removeClass("ui-sortable ui-sortable-disabled");
3608		this._mouseDestroy();
3609
3610		for ( var i = this.items.length - 1; i >= 0; i-- ) {
3611			this.items[i].item.removeData(this.widgetName + "-item");
3612		}
3613
3614		return this;
3615	},
3616
3617	_setOption: function(key, value){
3618		if ( key === "disabled" ) {
3619			this.options[ key ] = value;
3620
3621			this.widget().toggleClass( "ui-sortable-disabled", !!value );
3622		} else {
3623			// Don't call widget base _setOption for disable as it adds ui-state-disabled class
3624			$.Widget.prototype._setOption.apply(this, arguments);
3625		}
3626	},
3627
3628	_mouseCapture: function(event, overrideHandle) {
3629		var currentItem = null,
3630			validHandle = false,
3631			that = this;
3632
3633		if (this.reverting) {
3634			return false;
3635		}
3636
3637		if(this.options.disabled || this.options.type === "static") {
3638			return false;
3639		}
3640
3641		//We have to refresh the items data once first
3642		this._refreshItems(event);
3643
3644		//Find out if the clicked node (or one of its parents) is a actual item in this.items
3645		$(event.target).parents().each(function() {
3646			if($.data(this, that.widgetName + "-item") === that) {
3647				currentItem = $(this);
3648				return false;
3649			}
3650		});
3651		if($.data(event.target, that.widgetName + "-item") === that) {
3652			currentItem = $(event.target);
3653		}
3654
3655		if(!currentItem) {
3656			return false;
3657		}
3658		if(this.options.handle && !overrideHandle) {
3659			$(this.options.handle, currentItem).find("*").addBack().each(function() {
3660				if(this === event.target) {
3661					validHandle = true;
3662				}
3663			});
3664			if(!validHandle) {
3665				return false;
3666			}
3667		}
3668
3669		this.currentItem = currentItem;
3670		this._removeCurrentsFromItems();
3671		return true;
3672
3673	},
3674
3675	_mouseStart: function(event, overrideHandle, noActivation) {
3676
3677		var i, body,
3678			o = this.options;
3679
3680		this.currentContainer = this;
3681
3682		//We only need to call refreshPositions, because the refreshItems call has been moved to mouseCapture
3683		this.refreshPositions();
3684
3685		//Create and append the visible helper
3686		this.helper = this._createHelper(event);
3687
3688		//Cache the helper size
3689		this._cacheHelperProportions();
3690
3691		/*
3692		 * - Position generation -
3693		 * This block generates everything position related - it's the core of draggables.
3694		 */
3695
3696		//Cache the margins of the original element
3697		this._cacheMargins();
3698
3699		//Get the next scrolling parent
3700		this.scrollParent = this.helper.scrollParent();
3701
3702		//The element's absolute position on the page minus margins
3703		this.offset = this.currentItem.offset();
3704		this.offset = {
3705			top: this.offset.top - this.margins.top,
3706			left: this.offset.left - this.margins.left
3707		};
3708
3709		$.extend(this.offset, {
3710			click: { //Where the click happened, relative to the element
3711				left: event.pageX - this.offset.left,
3712				top: event.pageY - this.offset.top
3713			},
3714			parent: this._getParentOffset(),
3715			relative: this._getRelativeOffset() //This is a relative to absolute position minus the actual position calculation - only used for relative positioned helper
3716		});
3717
3718		// Only after we got the offset, we can change the helper's position to absolute
3719		// TODO: Still need to figure out a way to make relative sorting possible
3720		this.helper.css("position", "absolute");
3721		this.cssPosition = this.helper.css("position");
3722
3723		//Generate the original position
3724		this.originalPosition = this._generatePosition(event);
3725		this.originalPageX = event.pageX;
3726		this.originalPageY = event.pageY;
3727
3728		//Adjust the mouse offset relative to the helper if "cursorAt" is supplied
3729		(o.cursorAt && this._adjustOffsetFromHelper(o.cursorAt));
3730
3731		//Cache the former DOM position
3732		this.domPosition = { prev: this.currentItem.prev()[0], parent: this.currentItem.parent()[0] };
3733
3734		//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
3735		if(this.helper[0] !== this.currentItem[0]) {
3736			this.currentItem.hide();
3737		}
3738
3739		//Create the placeholder
3740		this._createPlaceholder();
3741
3742		//Set a containment if given in the options
3743		if(o.containment) {
3744			this._setContainment();
3745		}
3746
3747		if( o.cursor && o.cursor !== "auto" ) { // cursor option
3748			body = this.document.find( "body" );
3749
3750			// support: IE
3751			this.storedCursor = body.css( "cursor" );
3752			body.css( "cursor", o.cursor );
3753
3754			this.storedStylesheet = $( "<style>*{ cursor: "+o.cursor+" !important; }</style>" ).appendTo( body );
3755		}
3756
3757		if(o.opacity) { // opacity option
3758			if (this.helper.css("opacity")) {
3759				this._storedOpacity = this.helper.css("opacity");
3760			}
3761			this.helper.css("opacity", o.opacity);
3762		}
3763
3764		if(o.zIndex) { // zIndex option
3765			if (this.helper.css("zIndex")) {
3766				this._storedZIndex = this.helper.css("zIndex");
3767			}
3768			this.helper.css("zIndex", o.zIndex);
3769		}
3770
3771		//Prepare scrolling
3772		if(this.scrollParent[0] !== document && this.scrollParent[0].tagName !== "HTML") {
3773			this.overflowOffset = this.scrollParent.offset();
3774		}
3775
3776		//Call callbacks
3777		this._trigger("start", event, this._uiHash());
3778
3779		//Recache the helper size
3780		if(!this._preserveHelperProportions) {
3781			this._cacheHelperProportions();
3782		}
3783
3784
3785		//Post "activate" events to possible containers
3786		if( !noActivation ) {
3787			for ( i = this.containers.length - 1; i >= 0; i-- ) {
3788				this.containers[ i ]._trigger( "activate", event, this._uiHash( this ) );
3789			}
3790		}
3791
3792		//Prepare possible droppables
3793		if($.ui.ddmanager) {
3794			$.ui.ddmanager.current = this;
3795		}
3796
3797		if ($.ui.ddmanager && !o.dropBehaviour) {
3798			$.ui.ddmanager.prepareOffsets(this, event);
3799		}
3800
3801		this.dragging = true;
3802
3803		this.helper.addClass("ui-sortable-helper");
3804		this._mouseDrag(event); //Execute the drag once - this causes the helper not to be visible before getting its correct position
3805		return true;
3806
3807	},
3808
3809	_mouseDrag: function(event) {
3810		var i, item, itemElement, intersection,
3811			o = this.options,
3812			scrolled = false;
3813
3814		//Compute the helpers position
3815		this.position = this._generatePosition(event);
3816		this.positionAbs = this._convertPositionTo("absolute");
3817
3818		if (!this.lastPositionAbs) {
3819			this.lastPositionAbs = this.positionAbs;
3820		}
3821
3822		//Do scrolling
3823		if(this.options.scroll) {
3824			if(this.scrollParent[0] !== document && this.scrollParent[0].tagName !== "HTML") {
3825
3826				if((this.overflowOffset.top + this.scrollParent[0].offsetHeight) - event.pageY < o.scrollSensitivity) {
3827					this.scrollParent[0].scrollTop = scrolled = this.scrollParent[0].scrollTop + o.scrollSpeed;
3828				} else if(event.pageY - this.overflowOffset.top < o.scrollSensitivity) {
3829					this.scrollParent[0].scrollTop = scrolled = this.scrollParent[0].scrollTop - o.scrollSpeed;
3830				}
3831
3832				if((this.overflowOffset.left + this.scrollParent[0].offsetWidth) - event.pageX < o.scrollSensitivity) {
3833					this.scrollParent[0].scrollLeft = scrolled = this.scrollParent[0].scrollLeft + o.scrollSpeed;
3834				} else if(event.pageX - this.overflowOffset.left < o.scrollSensitivity) {
3835					this.scrollParent[0].scrollLeft = scrolled = this.scrollParent[0].scrollLeft - o.scrollSpeed;
3836				}
3837
3838			} else {
3839
3840				if(event.pageY - $(document).scrollTop() < o.scrollSensitivity) {
3841					scrolled = $(document).scrollTop($(document).scrollTop() - o.scrollSpeed);
3842				} else if($(window).height() - (event.pageY - $(document).scrollTop()) < o.scrollSensitivity) {
3843					scrolled = $(document).scrollTop($(document).scrollTop() + o.scrollSpeed);
3844				}
3845
3846				if(event.pageX - $(document).scrollLeft() < o.scrollSensitivity) {
3847					scrolled = $(document).scrollLeft($(document).scrollLeft() - o.scrollSpeed);
3848				} else if($(window).width() - (event.pageX - $(document).scrollLeft()) < o.scrollSensitivity) {
3849					scrolled = $(document).scrollLeft($(document).scrollLeft() + o.scrollSpeed);
3850				}
3851
3852			}
3853
3854			if(scrolled !== false && $.ui.ddmanager && !o.dropBehaviour) {
3855				$.ui.ddmanager.prepareOffsets(this, event);
3856			}
3857		}
3858
3859		//Regenerate the absolute position used for position checks
3860		this.positionAbs = this._convertPositionTo("absolute");
3861
3862		//Set the helper position
3863		if(!this.options.axis || this.options.axis !== "y") {
3864			this.helper[0].style.left = this.position.left+"px";
3865		}
3866		if(!this.options.axis || this.options.axis !== "x") {
3867			this.helper[0].style.top = this.position.top+"px";
3868		}
3869
3870		//Rearrange
3871		for (i = this.items.length - 1; i >= 0; i--) {
3872
3873			//Cache variables and intersection, continue if no intersection
3874			item = this.items[i];
3875			itemElement = item.item[0];
3876			intersection = this._intersectsWithPointer(item);
3877			if (!intersection) {
3878				continue;
3879			}
3880
3881			// Only put the placeholder inside the current Container, skip all
3882			// items from other containers. This works because when moving
3883			// an item from one container to another the
3884			// currentContainer is switched before the placeholder is moved.
3885			//
3886			// Without this, moving items in "sub-sortables" can cause
3887			// the placeholder to jitter beetween the outer and inner container.
3888			if (item.instance !== this.currentContainer) {
3889				continue;
3890			}
3891
3892			// cannot intersect with itself
3893			// no useless actions that have been done before
3894			// no action if the item moved is the parent of the item checked
3895			if (itemElement !== this.currentItem[0] &&
3896				this.placeholder[intersection === 1 ? "next" : "prev"]()[0] !== itemElement &&
3897				!$.contains(this.placeholder[0], itemElement) &&
3898				(this.options.type === "semi-dynamic" ? !$.contains(this.element[0], itemElement) : true)
3899			) {
3900
3901				this.direction = intersection === 1 ? "down" : "up";
3902
3903				if (this.options.tolerance === "pointer" || this._intersectsWithSides(item)) {
3904					this._rearrange(event, item);
3905				} else {
3906					break;
3907				}
3908
3909				this._trigger("change", event, this._uiHash());
3910				break;
3911			}
3912		}
3913
3914		//Post events to containers
3915		this._contactContainers(event);
3916
3917		//Interconnect with droppables
3918		if($.ui.ddmanager) {
3919			$.ui.ddmanager.drag(this, event);
3920		}
3921
3922		//Call callbacks
3923		this._trigger("sort", event, this._uiHash());
3924
3925		this.lastPositionAbs = this.positionAbs;
3926		return false;
3927
3928	},
3929
3930	_mouseStop: function(event, noPropagation) {
3931
3932		if(!event) {
3933			return;
3934		}
3935
3936		//If we are using droppables, inform the manager about the drop
3937		if ($.ui.ddmanager && !this.options.dropBehaviour) {
3938			$.ui.ddmanager.drop(this, event);
3939		}
3940
3941		if(this.options.revert) {
3942			var that = this,
3943				cur = this.placeholder.offset(),
3944				axis = this.options.axis,
3945				animation = {};
3946
3947			if ( !axis || axis === "x" ) {
3948				animation.left = cur.left - this.offset.parent.left - this.margins.left + (this.offsetParent[0] === document.body ? 0 : this.offsetParent[0].scrollLeft);
3949			}
3950			if ( !axis || axis === "y" ) {
3951				animation.top = cur.top - this.offset.parent.top - this.margins.top + (this.offsetParent[0] === document.body ? 0 : this.offsetParent[0].scrollTop);
3952			}
3953			this.reverting = true;
3954			$(this.helper).animate( animation, parseInt(this.options.revert, 10) || 500, function() {
3955				that._clear(event);
3956			});
3957		} else {
3958			this._clear(event, noPropagation);
3959		}
3960
3961		return false;
3962
3963	},
3964
3965	cancel: function() {
3966
3967		if(this.dragging) {
3968
3969			this._mouseUp({ target: null });
3970
3971			if(this.options.helper === "original") {
3972				this.currentItem.css(this._storedCSS).removeClass("ui-sortable-helper");
3973			} else {
3974				this.currentItem.show();
3975			}
3976
3977			//Post deactivating events to containers
3978			for (var i = this.containers.length - 1; i >= 0; i--){
3979				this.containers[i]._trigger("deactivate", null, this._uiHash(this));
3980				if(this.containers[i].containerCache.over) {
3981					this.containers[i]._trigger("out", null, this._uiHash(this));
3982					this.containers[i].containerCache.over = 0;
3983				}
3984			}
3985
3986		}
3987
3988		if (this.placeholder) {
3989			//$(this.placeholder[0]).remove(); would have been the jQuery way - unfortunately, it unbinds ALL events from the original node!
3990			if(this.placeholder[0].parentNode) {
3991				this.placeholder[0].parentNode.removeChild(this.placeholder[0]);
3992			}
3993			if(this.options.helper !== "original" && this.helper && this.helper[0].parentNode) {
3994				this.helper.remove();
3995			}
3996
3997			$.extend(this, {
3998				helper: null,
3999				dragging: false,
4000				reverting: false,
4001				_noFinalSort: null
4002			});
4003
4004			if(this.domPosition.prev) {
4005				$(this.domPosition.prev).after(this.currentItem);
4006			} else {
4007				$(this.domPosition.parent).prepend(this.currentItem);
4008			}
4009		}
4010
4011		return this;
4012
4013	},
4014
4015	serialize: function(o) {
4016
4017		var items = this._getItemsAsjQuery(o && o.connected),
4018			str = [];
4019		o = o || {};
4020
4021		$(items).each(function() {
4022			var res = ($(o.item || this).attr(o.attribute || "id") || "").match(o.expression || (/(.+)[\-=_](.+)/));
4023			if (res) {
4024				str.push((o.key || res[1]+"[]")+"="+(o.key && o.expression ? res[1] : res[2]));
4025			}
4026		});
4027
4028		if(!str.length && o.key) {
4029			str.push(o.key + "=");
4030		}
4031
4032		return str.join("&");
4033
4034	},
4035
4036	toArray: function(o) {
4037
4038		var items = this._getItemsAsjQuery(o && o.connected),
4039			ret = [];
4040
4041		o = o || {};
4042
4043		items.each(function() { ret.push($(o.item || this).attr(o.attribute || "id") || ""); });
4044		return ret;
4045
4046	},
4047
4048	/* Be careful with the following core functions */
4049	_intersectsWith: function(item) {
4050
4051		var x1 = this.positionAbs.left,
4052			x2 = x1 + this.helperProportions.width,
4053			y1 = this.positionAbs.top,
4054			y2 = y1 + this.helperProportions.height,
4055			l = item.left,
4056			r = l + item.width,
4057			t = item.top,
4058			b = t + item.height,
4059			dyClick = this.offset.click.top,
4060			dxClick = this.offset.click.left,
4061			isOverElementHeight = ( this.options.axis === "x" ) || ( ( y1 + dyClick ) > t && ( y1 + dyClick ) < b ),
4062			isOverElementWidth = ( this.options.axis === "y" ) || ( ( x1 + dxClick ) > l && ( x1 + dxClick ) < r ),
4063			isOverElement = isOverElementHeight && isOverElementWidth;
4064
4065		if ( this.options.tolerance === "pointer" ||
4066			this.options.forcePointerForContainers ||
4067			(this.options.tolerance !== "pointer" && this.helperProportions[this.floating ? "width" : "height"] > item[this.floating ? "width" : "height"])
4068		) {
4069			return isOverElement;
4070		} else {
4071
4072			return (l < x1 + (this.helperProportions.width / 2) && // Right Half
4073				x2 - (this.helperProportions.width / 2) < r && // Left Half
4074				t < y1 + (this.helperProportions.height / 2) && // Bottom Half
4075				y2 - (this.helperProportions.height / 2) < b ); // Top Half
4076
4077		}
4078	},
4079
4080	_intersectsWithPointer: function(item) {
4081
4082		var isOverElementHeight = (this.options.axis === "x") || isOverAxis(this.positionAbs.top + this.offset.click.top, item.top, item.height),
4083			isOverElementWidth = (this.options.axis === "y") || isOverAxis(this.positionAbs.left + this.offset.click.left, item.left, item.width),
4084			isOverElement = isOverElementHeight && isOverElementWidth,
4085			verticalDirection = this._getDragVerticalDirection(),
4086			horizontalDirection = this._getDragHorizontalDirection();
4087
4088		if (!isOverElement) {
4089			return false;
4090		}
4091
4092		return this.floating ?
4093			( ((horizontalDirection && horizontalDirection === "right") || verticalDirection === "down") ? 2 : 1 )
4094			: ( verticalDirection && (verticalDirection === "down" ? 2 : 1) );
4095
4096	},
4097
4098	_intersectsWithSides: function(item) {
4099
4100		var isOverBottomHalf = isOverAxis(this.positionAbs.top + this.offset.click.top, item.top + (item.height/2), item.height),
4101			isOverRightHalf = isOverAxis(this.positionAbs.left + this.offset.click.left, item.left + (item.width/2), item.width),
4102			verticalDirection = this._getDragVerticalDirection(),
4103			horizontalDirection = this._getDragHorizontalDirection();
4104
4105		if (this.floating && horizontalDirection) {
4106			return ((horizontalDirection === "right" && isOverRightHalf) || (horizontalDirection === "left" && !isOverRightHalf));
4107		} else {
4108			return verticalDirection && ((verticalDirection === "down" && isOverBottomHalf) || (verticalDirection === "up" && !isOverBottomHalf));
4109		}
4110
4111	},
4112
4113	_getDragVerticalDirection: function() {
4114		var delta = this.positionAbs.top - this.lastPositionAbs.top;
4115		return delta !== 0 && (delta > 0 ? "down" : "up");
4116	},
4117
4118	_getDragHorizontalDirection: function() {
4119		var delta = this.positionAbs.left - this.lastPositionAbs.left;
4120		return delta !== 0 && (delta > 0 ? "right" : "left");
4121	},
4122
4123	refresh: function(event) {
4124		this._refreshItems(event
vendor: 4,154 bytes, lines 4124-4260
4124);
4125		this.refreshPositions();
4126		return this;
4127	},
4128
4129	_connectWith: function() {
4130		var options = this.options;
4131		return options.connectWith.constructor === String ? [options.connectWith] : options.connectWith;
4132	},
4133
4134	_getItemsAsjQuery: function(connected) {
4135
4136		var i, j, cur, inst,
4137			items = [],
4138			queries = [],
4139			connectWith = this._connectWith();
4140
4141		if(connectWith && connected) {
4142			for (i = connectWith.length - 1; i >= 0; i--){
4143				cur = $(connectWith[i]);
4144				for ( j = cur.length - 1; j >= 0; j--){
4145					inst = $.data(cur[j], this.widgetFullName);
4146					if(inst && inst !== this && !inst.options.disabled) {
4147						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]);
4148					}
4149				}
4150			}
4151		}
4152
4153		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]);
4154
4155		function addItems() {
4156			items.push( this );
4157		}
4158		for (i = queries.length - 1; i >= 0; i--){
4159			queries[i][0].each( addItems );
4160		}
4161
4162		return $(items);
4163
4164	},
4165
4166	_removeCurrentsFromItems: function() {
4167
4168		var list = this.currentItem.find(":data(" + this.widgetName + "-item)");
4169
4170		this.items = $.grep(this.items, function (item) {
4171			for (var j=0; j < list.length; j++) {
4172				if(list[j] === item.item[0]) {
4173					return false;
4174				}
4175			}
4176			return true;
4177		});
4178
4179	},
4180
4181	_refreshItems: function(event) {
4182
4183		this.items = [];
4184		this.containers = [this];
4185
4186		var i, j, cur, inst, targetData, _queries, item, queriesLength,
4187			items = this.items,
4188			queries = [[$.isFunction(this.options.items) ? this.options.items.call(this.element[0], event, { item: this.currentItem }) : $(this.options.items, this.element), this]],
4189			connectWith = this._connectWith();
4190
4191		if(connectWith && this.ready) { //Shouldn't be run the first time through due to massive slow-down
4192			for (i = connectWith.length - 1; i >= 0; i--){
4193				cur = $(connectWith[i]);
4194				for (j = cur.length - 1; j >= 0; j--){
4195					inst = $.data(cur[j], this.widgetFullName);
4196					if(inst && inst !== this && !inst.options.disabled) {
4197						queries.push([$.isFunction(inst.options.items) ? inst.options.items.call(inst.element[0], event, { item: this.currentItem }) : $(inst.options.items, inst.element), inst]);
4198						this.containers.push(inst);
4199					}
4200				}
4201			}
4202		}
4203
4204		for (i = queries.length - 1; i >= 0; i--) {
4205			targetData = queries[i][1];
4206			_queries = queries[i][0];
4207
4208			for (j=0, queriesLength = _queries.length; j < queriesLength; j++) {
4209				item = $(_queries[j]);
4210
4211				item.data(this.widgetName + "-item", targetData); // Data for target checking (mouse manager)
4212
4213				items.push({
4214					item: item,
4215					instance: targetData,
4216					width: 0, height: 0,
4217					left: 0, top: 0
4218				});
4219			}
4220		}
4221
4222	},
4223
4224	refreshPositions: function(fast) {
4225
4226		//This has to be redone because due to the item being moved out/into the offsetParent, the offsetParent's position will change
4227		if(this.offsetParent && this.helper) {
4228			this.offset.parent = this._getParentOffset();
4229		}
4230
4231		var i, item, t, p;
4232
4233		for (i = this.items.length - 1; i >= 0; i--){
4234			item = this.items[i];
4235
4236			//We ignore calculating positions of all connected containers when we're not over them
4237			if(item.instance !== this.currentContainer && this.currentContainer && item.item[0] !== this.currentItem[0]) {
4238				continue;
4239			}
4240
4241			t = this.options.toleranceElement ? $(this.options.toleranceElement, item.item) : item.item;
4242
4243			if (!fast) {
4244				item.width = t.outerWidth();
4245				item.height = t.outerHeight();
4246			}
4247
4248			p = t.offset();
4249			item.left = p.left;
4250			item.top = p.top;
4251		}
4252
4253		if(this.options.custom && this.options.custom.refreshContainers) {
4254			this.options.custom.refreshContainers.call(this);
4255		} else {
4256			for (i = this.containers.length - 1; i >= 0; i--){
4257				p = this.containers[i].element.offset();
4258				this.containers[i].containerCache.left = p.left;
4259				this.containers[i].containerCache.top = p.top;
4260				this.containers[i].containerCache.width
vendor: 1,591 bytes, lines 4260-4307
4260	= this.containers[i].element.outerWidth();
4261				this.containers[i].containerCache.height = this.containers[i].element.outerHeight();
4262			}
4263		}
4264
4265		return this;
4266	},
4267
4268	_createPlaceholder: function(that) {
4269		that = that || this;
4270		var className,
4271			o = that.options;
4272
4273		if(!o.placeholder || o.placeholder.constructor === String) {
4274			className = o.placeholder;
4275			o.placeholder = {
4276				element: function() {
4277
4278					var nodeName = that.currentItem[0].nodeName.toLowerCase(),
4279						element = $( "<" + nodeName + ">", that.document[0] )
4280							.addClass(className || that.currentItem[0].className+" ui-sortable-placeholder")
4281							.removeClass("ui-sortable-helper");
4282
4283					if ( nodeName === "tr" ) {
4284						that.currentItem.children().each(function() {
4285							$( "<td>&#160;</td>", that.document[0] )
4286								.attr( "colspan", $( this ).attr( "colspan" ) || 1 )
4287								.appendTo( element );
4288						});
4289					} else if ( nodeName === "img" ) {
4290						element.attr( "src", that.currentItem.attr( "src" ) );
4291					}
4292
4293					if ( !className ) {
4294						element.css( "visibility", "hidden" );
4295					}
4296
4297					return element;
4298				},
4299				update: function(container, p) {
4300
4301					// 1. If a className is set as 'placeholder option, we don't force sizes - the class is responsible for that
4302					// 2. The option 'forcePlaceholderSize can be enabled to force it even if a class name is specified
4303					if(className && !o.forcePlaceholderSize) {
4304						return;
4305					}
4306
4307					//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
4308					if(!p.height()) { p.height(that.currentItem.innerHeight() - parseInt(that.currentItem.css("paddingTop")||0, 10) - parseInt(that.currentItem.css("paddingBottom")||0, 10)); }
4309					if(!p.width()) { p.width(that.currentItem.innerWidth() - parseInt(that.currentItem.css("paddingLeft")||0, 10) - parseInt(that.currentItem.css("paddingRight")||0, 10)); }
4310				}
4311			};
4312		}
4313
4314		//Create the placeholder
4315		that.placeholder = $(o.placeholder.element.call(that.element, that.currentItem));
4316
4317		//Append it after the actual current item
4318		that.currentItem.after(that.placeholder);
4319
4320		//Update the size of the placeholder (TODO: Logic to fuzzy, see line 316/317)
4321		o.placeholder.update(that, that.placeholder);
4322
4323	},
4324
4325	_contactContainers: function(event) {
4326		var i, j, dist, itemWithLeastDistance, posProperty, sizeProperty, base, cur, nearBottom, floating,
4327			innermostContainer = null,
4328			innermostIndex = null;
4329
4330		// get innermost container that intersects with item
4331		for (i = this.containers.length - 1; i >= 0; i--) {
4332
4333			// never consider a container that's located within the item itself
4334			if($.contains(this.currentItem[0], this.containers[i].element[0])) {
4335				continue;
4336			}
4337
4338			if(this._intersectsWith(this.containers[i].containerCache)) {
4339
4340				// if we've already found a container and it's more "inner" than this, then continue
4341				if(innermostContainer && $.contains(this.containers[i].element[0], innermostContainer.element[0])) {
4342					continue;
4343				}
4344
4345				innermostContainer = this.containers[i];
4346				innermostIndex = i;
4347
4348			} else {
4349				// container doesn't intersect. trigger "out" event if necessary
4350				if(this.containers[i].containerCache.over) {
4351					this.containers[i]._trigger("out", event, this._uiHash(this));
4352					this.containers[i].containerCache.over = 0;
4353				}
4354			}
4355
4356		}
4357
4358		// if no intersecting containers found, return
4359		if(!innermostContainer) {
4360			return;
4361		}
4362
4363		// move the item into the container if it's not there already
4364		if(this.containers.length === 1) {
4365			if (!this.containers[innermostIndex].containerCache.over) {
4366				this.containers[innermostIndex]._trigger("over", event, this._uiHash(this));
4367				this.containers[innermostIndex].containerCache.over = 1;
4368			}
4369		} else {
4370
4371			//When entering a new container, we will find the item with the least distance and append our item near it
4372			dist = 10000;
4373			itemWithLeastDistance = null;
4374			floating = innermostContainer.floating || isFloating(this.currentItem);
4375			posProperty = floating ? "left" : "top";
4376			sizeProperty = floating ? "width" : "height";
4377			base = this.positionAbs[posProperty] + this.offset.click[posProperty];
4378			for (j = this.items.length - 1; j >= 0; j--) {
4379				if(!$.contains(this.containers[innermostIndex].element[0], this.items[j].item[0])) {
4380					continue;
4381				}
4382				if(this.items[j].item[0] === this.currentItem[0]) {
4383					continue;
4384				}
4385				if (floating && !isOverAxis(this.positionAbs.top + this.offset.click.top, this.items[j].top, this.items[j].height)) {
4386					continue;
4387				}
4388				cur = this.items[j].item.offset()[posProperty];
4389				nearBottom = false;
4390				if(Math.abs(cur - base) > Math.abs(cur + this.items[j][sizeProperty] - base)){
4391					nearBottom = true;
4392					cur += this.items[j][sizeProperty];
4393				}
4394
4395				if(Math.abs(cur - base) < dist) {
4396					dist = Math.abs(cur - base); itemWithLeastDistance = this.items[j
vendor: 15,870 bytes, lines 4396-4802
4396];
4397					this.direction = nearBottom ? "up": "down";
4398				}
4399			}
4400
4401			//Check if dropOnEmpty is enabled
4402			if(!itemWithLeastDistance && !this.options.dropOnEmpty) {
4403				return;
4404			}
4405
4406			if(this.currentContainer === this.containers[innermostIndex]) {
4407				return;
4408			}
4409
4410			itemWithLeastDistance ? this._rearrange(event, itemWithLeastDistance, null, true) : this._rearrange(event, null, this.containers[innermostIndex].element, true);
4411			this._trigger("change", event, this._uiHash());
4412			this.containers[innermostIndex]._trigger("change", event, this._uiHash(this));
4413			this.currentContainer = this.containers[innermostIndex];
4414
4415			//Update the placeholder
4416			this.options.placeholder.update(this.currentContainer, this.placeholder);
4417
4418			this.containers[innermostIndex]._trigger("over", event, this._uiHash(this));
4419			this.containers[innermostIndex].containerCache.over = 1;
4420		}
4421
4422
4423	},
4424
4425	_createHelper: function(event) {
4426
4427		var o = this.options,
4428			helper = $.isFunction(o.helper) ? $(o.helper.apply(this.element[0], [event, this.currentItem])) : (o.helper === "clone" ? this.currentItem.clone() : this.currentItem);
4429
4430		//Add the helper to the DOM if that didn't happen already
4431		if(!helper.parents("body").length) {
4432			$(o.appendTo !== "parent" ? o.appendTo : this.currentItem[0].parentNode)[0].appendChild(helper[0]);
4433		}
4434
4435		if(helper[0] === this.currentItem[0]) {
4436			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") };
4437		}
4438
4439		if(!helper[0].style.width || o.forceHelperSize) {
4440			helper.width(this.currentItem.width());
4441		}
4442		if(!helper[0].style.height || o.forceHelperSize) {
4443			helper.height(this.currentItem.height());
4444		}
4445
4446		return helper;
4447
4448	},
4449
4450	_adjustOffsetFromHelper: function(obj) {
4451		if (typeof obj === "string") {
4452			obj = obj.split(" ");
4453		}
4454		if ($.isArray(obj)) {
4455			obj = {left: +obj[0], top: +obj[1] || 0};
4456		}
4457		if ("left" in obj) {
4458			this.offset.click.left = obj.left + this.margins.left;
4459		}
4460		if ("right" in obj) {
4461			this.offset.click.left = this.helperProportions.width - obj.right + this.margins.left;
4462		}
4463		if ("top" in obj) {
4464			this.offset.click.top = obj.top + this.margins.top;
4465		}
4466		if ("bottom" in obj) {
4467			this.offset.click.top = this.helperProportions.height - obj.bottom + this.margins.top;
4468		}
4469	},
4470
4471	_getParentOffset: function() {
4472
4473
4474		//Get the offsetParent and cache its position
4475		this.offsetParent = this.helper.offsetParent();
4476		var po = this.offsetParent.offset();
4477
4478		// This is a special case where we need to modify a offset calculated on start, since the following happened:
4479		// 1. The position of the helper is absolute, so it's position is calculated based on the next positioned parent
4480		// 2. The actual offset parent is a child of the scroll parent, and the scroll parent isn't the document, which means that
4481		//    the scroll is included in the initial calculation of the offset of the parent, and never recalculated upon drag
4482		if(this.cssPosition === "absolute" && this.scrollParent[0] !== document && $.contains(this.scrollParent[0], this.offsetParent[0])) {
4483			po.left += this.scrollParent.scrollLeft();
4484			po.top += this.scrollParent.scrollTop();
4485		}
4486
4487		// This needs to be actually done for all browsers, since pageX/pageY includes this information
4488		// with an ugly IE fix
4489		if( this.offsetParent[0] === document.body || (this.offsetParent[0].tagName && this.offsetParent[0].tagName.toLowerCase() === "html" && $.ui.ie)) {
4490			po = { top: 0, left: 0 };
4491		}
4492
4493		return {
4494			top: po.top + (parseInt(this.offsetParent.css("borderTopWidth"),10) || 0),
4495			left: po.left + (parseInt(this.offsetParent.css("borderLeftWidth"),10) || 0)
4496		};
4497
4498	},
4499
4500	_getRelativeOffset: function() {
4501
4502		if(this.cssPosition === "relative") {
4503			var p = this.currentItem.position();
4504			return {
4505				top: p.top - (parseInt(this.helper.css("top"),10) || 0) + this.scrollParent.scrollTop(),
4506				left: p.left - (parseInt(this.helper.css("left"),10) || 0) + this.scrollParent.scrollLeft()
4507			};
4508		} else {
4509			return { top: 0, left: 0 };
4510		}
4511
4512	},
4513
4514	_cacheMargins: function() {
4515		this.margins = {
4516			left: (parseInt(this.currentItem.css("marginLeft"),10) || 0),
4517			top: (parseInt(this.currentItem.css("marginTop"),10) || 0)
4518		};
4519	},
4520
4521	_cacheHelperProportions: function() {
4522		this.helperProportions = {
4523			width: this.helper.outerWidth(),
4524			height: this.helper.outerHeight()
4525		};
4526	},
4527
4528	_setContainment: function() {
4529
4530		var ce, co, over,
4531			o = this.options;
4532		if(o.containment === "parent") {
4533			o.containment = this.helper[0].parentNode;
4534		}
4535		if(o.containment === "document" || o.containment === "window") {
4536			this.containment = [
4537				0 - this.offset.relative.left - this.offset.parent.left,
4538				0 - this.offset.relative.top - this.offset.parent.top,
4539				$(o.containment === "document" ? document : window).width() - this.helperProportions.width - this.margins.left,
4540				($(o.containment === "document" ? document : window).height() || document.body.parentNode.scrollHeight) - this.helperProportions.height - this.margins.top
4541			];
4542		}
4543
4544		if(!(/^(document|window|parent)$/).test(o.containment)) {
4545			ce = $(o.containment)[0];
4546			co = $(o.containment).offset();
4547			over = ($(ce).css("overflow") !== "hidden");
4548
4549			this.containment = [
4550				co.left + (parseInt($(ce).css("borderLeftWidth"),10) || 0) + (parseInt($(ce).css("paddingLeft"),10) || 0) - this.margins.left,
4551				co.top + (parseInt($(ce).css("borderTopWidth"),10) || 0) + (parseInt($(ce).css("paddingTop"),10) || 0) - this.margins.top,
4552				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,
4553				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
4554			];
4555		}
4556
4557	},
4558
4559	_convertPositionTo: function(d, pos) {
4560
4561		if(!pos) {
4562			pos = this.position;
4563		}
4564		var mod = d === "absolute" ? 1 : -1,
4565			scroll = this.cssPosition === "absolute" && !(this.scrollParent[0] !== document && $.contains(this.scrollParent[0], this.offsetParent[0])) ? this.offsetParent : this.scrollParent,
4566			scrollIsRootNode = (/(html|body)/i).test(scroll[0].tagName);
4567
4568		return {
4569			top: (
4570				pos.top	+																// The absolute mouse position
4571				this.offset.relative.top * mod +										// Only for relative positioned nodes: Relative offset from element to offset parent
4572				this.offset.parent.top * mod -											// The offsetParent's offset without borders (offset + border)
4573				( ( this.cssPosition === "fixed" ? -this.scrollParent.scrollTop() : ( scrollIsRootNode ? 0 : scroll.scrollTop() ) ) * mod)
4574			),
4575			left: (
4576				pos.left +																// The absolute mouse position
4577				this.offset.relative.left * mod +										// Only for relative positioned nodes: Relative offset from element to offset parent
4578				this.offset.parent.left * mod	-										// The offsetParent's offset without borders (offset + border)
4579				( ( this.cssPosition === "fixed" ? -this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 : scroll.scrollLeft() ) * mod)
4580			)
4581		};
4582
4583	},
4584
4585	_generatePosition: function(event) {
4586
4587		var top, left,
4588			o = this.options,
4589			pageX = event.pageX,
4590			pageY = event.pageY,
4591			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);
4592
4593		// This is another very weird special case that only happens for relative elements:
4594		// 1. If the css position is relative
4595		// 2. and the scroll parent is the document or similar to the offset parent
4596		// we have to refresh the relative offset during the scroll so there are no jumps
4597		if(this.cssPosition === "relative" && !(this.scrollParent[0] !== document && this.scrollParent[0] !== this.offsetParent[0])) {
4598			this.offset.relative = this._getRelativeOffset();
4599		}
4600
4601		/*
4602		 * - Position constraining -
4603		 * Constrain the position to a mix of grid, containment.
4604		 */
4605
4606		if(this.originalPosition) { //If we are not dragging yet, we won't check for options
4607
4608			if(this.containment) {
4609				if(event.pageX - this.offset.click.left < this.containment[0]) {
4610					pageX = this.containment[0] + this.offset.click.left;
4611				}
4612				if(event.pageY - this.offset.click.top < this.containment[1]) {
4613					pageY = this.containment[1] + this.offset.click.top;
4614				}
4615				if(event.pageX - this.offset.click.left > this.containment[2]) {
4616					pageX = this.containment[2] + this.offset.click.left;
4617				}
4618				if(event.pageY - this.offset.click.top > this.containment[3]) {
4619					pageY = this.containment[3] + this.offset.click.top;
4620				}
4621			}
4622
4623			if(o.grid) {
4624				top = this.originalPageY + Math.round((pageY - this.originalPageY) / o.grid[1]) * o.grid[1];
4625				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;
4626
4627				left = this.originalPageX + Math.round((pageX - this.originalPageX) / o.grid[0]) * o.grid[0];
4628				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;
4629			}
4630
4631		}
4632
4633		return {
4634			top: (
4635				pageY -																// The absolute mouse position
4636				this.offset.click.top -													// Click offset (relative to the element)
4637				this.offset.relative.top	-											// Only for relative positioned nodes: Relative offset from element to offset parent
4638				this.offset.parent.top +												// The offsetParent's offset without borders (offset + border)
4639				( ( this.cssPosition === "fixed" ? -this.scrollParent.scrollTop() : ( scrollIsRootNode ? 0 : scroll.scrollTop() ) ))
4640			),
4641			left: (
4642				pageX -																// The absolute mouse position
4643				this.offset.click.left -												// Click offset (relative to the element)
4644				this.offset.relative.left	-											// Only for relative positioned nodes: Relative offset from element to offset parent
4645				this.offset.parent.left +												// The offsetParent's offset without borders (offset + border)
4646				( ( this.cssPosition === "fixed" ? -this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 : scroll.scrollLeft() ))
4647			)
4648		};
4649
4650	},
4651
4652	_rearrange: function(event, i, a, hardRefresh) {
4653
4654		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));
4655
4656		//Various things done here to improve the performance:
4657		// 1. we create a setTimeout, that calls refreshPositions
4658		// 2. on the instance, we have a counter variable, that get's higher after every append
4659		// 3. on the local scope, we copy the counter variable, and check in the timeout, if it's still the same
4660		// 4. this lets only the last addition to the timeout stack through
4661		this.counter = this.counter ? ++this.counter : 1;
4662		var counter = this.counter;
4663
4664		this._delay(function() {
4665			if(counter === this.counter) {
4666				this.refreshPositions(!hardRefresh); //Precompute after each DOM insertion, NOT on mousemove
4667			}
4668		});
4669
4670	},
4671
4672	_clear: function(event, noPropagation) {
4673
4674		this.reverting = false;
4675		// We delay all events that have to be triggered to after the point where the placeholder has been removed and
4676		// everything else normalized again
4677		var i,
4678			delayedTriggers = [];
4679
4680		// We first have to update the dom position of the actual currentItem
4681		// Note: don't do it if the current item is already removed (by a user), or it gets reappended (see #4088)
4682		if(!this._noFinalSort && this.currentItem.parent().length) {
4683			this.placeholder.before(this.currentItem);
4684		}
4685		this._noFinalSort = null;
4686
4687		if(this.helper[0] === this.currentItem[0]) {
4688			for(i in this._storedCSS) {
4689				if(this._storedCSS[i] === "auto" || this._storedCSS[i] === "static") {
4690					this._storedCSS[i] = "";
4691				}
4692			}
4693			this.currentItem.css(this._storedCSS).removeClass("ui-sortable-helper");
4694		} else {
4695			this.currentItem.show();
4696		}
4697
4698		if(this.fromOutside && !noPropagation) {
4699			delayedTriggers.push(function(event) { this._trigger("receive", event, this._uiHash(this.fromOutside)); });
4700		}
4701		if((this.fromOutside || this.domPosition.prev !== this.currentItem.prev().not(".ui-sortable-helper")[0] || this.domPosition.parent !== this.currentItem.parent()[0]) && !noPropagation) {
4702			delayedTriggers.push(function(event) { this._trigger("update", event, this._uiHash()); }); //Trigger update callback if the DOM position has changed
4703		}
4704
4705		// Check if the items Container has Changed and trigger appropriate
4706		// events.
4707		if (this !== this.currentContainer) {
4708			if(!noPropagation) {
4709				delayedTriggers.push(function(event) { this._trigger("remove", event, this._uiHash()); });
4710				delayedTriggers.push((function(c) { return function(event) { c._trigger("receive", event, this._uiHash(this)); };  }).call(this, this.currentContainer));
4711				delayedTriggers.push((function(c) { return function(event) { c._trigger("update", event, this._uiHash(this));  }; }).call(this, this.currentContainer));
4712			}
4713		}
4714
4715
4716		//Post events to containers
4717		function delayEvent( type, instance, container ) {
4718			return function( event ) {
4719				container._trigger( type, event, instance._uiHash( instance ) );
4720			};
4721		}
4722		for (i = this.containers.length - 1; i >= 0; i--){
4723			if (!noPropagation) {
4724				delayedTriggers.push( delayEvent( "deactivate", this, this.containers[ i ] ) );
4725			}
4726			if(this.containers[i].containerCache.over) {
4727				delayedTriggers.push( delayEvent( "out", this, this.containers[ i ] ) );
4728				this.containers[i].containerCache.over = 0;
4729			}
4730		}
4731
4732		//Do what was originally in plugins
4733		if ( this.storedCursor ) {
4734			this.document.find( "body" ).css( "cursor", this.storedCursor );
4735			this.storedStylesheet.remove();
4736		}
4737		if(this._storedOpacity) {
4738			this.helper.css("opacity", this._storedOpacity);
4739		}
4740		if(this._storedZIndex) {
4741			this.helper.css("zIndex", this._storedZIndex === "auto" ? "" : this._storedZIndex);
4742		}
4743
4744		this.dragging = false;
4745		if(this.cancelHelperRemoval) {
4746			if(!noPropagation) {
4747				this._trigger("beforeStop", event, this._uiHash());
4748				for (i=0; i < delayedTriggers.length; i++) {
4749					delayedTriggers[i].call(this, event);
4750				} //Trigger all delayed events
4751				this._trigger("stop", event, this._uiHash());
4752			}
4753
4754			this.fromOutside = false;
4755			return false;
4756		}
4757
4758		if(!noPropagation) {
4759			this._trigger("beforeStop", event, this._uiHash());
4760		}
4761
4762		//$(this.placeholder[0]).remove(); would have been the jQuery way - unfortunately, it unbinds ALL events from the original node!
4763		this.placeholder[0].parentNode.removeChild(this.placeholder[0]);
4764
4765		if(this.helper[0] !== this.currentItem[0]) {
4766			this.helper.remove();
4767		}
4768		this.helper = null;
4769
4770		if(!noPropagation) {
4771			for (i=0; i < delayedTriggers.length; i++) {
4772				delayedTriggers[i].call(this, event);
4773			} //Trigger all delayed events
4774			this._trigger("stop", event, this._uiHash());
4775		}
4776
4777		this.fromOutside = false;
4778		return true;
4779
4780	},
4781
4782	_trigger: function() {
4783		if ($.Widget.prototype._trigger.apply(this, arguments) === false) {
4784			this.cancel();
4785		}
4786	},
4787
4788	_uiHash: function(_inst) {
4789		var inst = _inst || this;
4790		return {
4791			helper: inst.helper,
4792			placeholder: inst.placeholder || $([]),
4793			position: inst.position,
4794			originalPosition: inst.originalPosition,
4795			offset: inst.positionAbs,
4796			item: inst.currentItem,
4797			sender: _inst ? _inst.element : null
4798		};
4799	}
4800
4801});
4802
vendor: 70,403 bytes, lines 4803-7526
4803})(jQuery);
4804
4805(function($, undefined) {
4806
4807var dataSpace = "ui-effects-";
4808
4809$.effects = {
4810	effect: {}
4811};
4812
4813/*!
4814 * jQuery Color Animations v2.1.2
4815 * https://github.com/jquery/jquery-color
4816 *
4817 * Copyright 2013 jQuery Foundation and other contributors
4818 * Released under the MIT license.
4819 * http://jquery.org/license
4820 *
4821 * Date: Wed Jan 16 08:47:09 2013 -0600
4822 */
4823(function( jQuery, undefined ) {
4824
4825	var stepHooks = "backgroundColor borderBottomColor borderLeftColor borderRightColor borderTopColor color columnRuleColor outlineColor textDecorationColor textEmphasisColor",
4826
4827	// plusequals test for += 100 -= 100
4828	rplusequals = /^([\-+])=\s*(\d+\.?\d*)/,
4829	// a set of RE's that can match strings and generate color tuples.
4830	stringParsers = [{
4831			re: /rgba?\(\s*(\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(\d{1,3})\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/,
4832			parse: function( execResult ) {
4833				return [
4834					execResult[ 1 ],
4835					execResult[ 2 ],
4836					execResult[ 3 ],
4837					execResult[ 4 ]
4838				];
4839			}
4840		}, {
4841			re: /rgba?\(\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/,
4842			parse: function( execResult ) {
4843				return [
4844					execResult[ 1 ] * 2.55,
4845					execResult[ 2 ] * 2.55,
4846					execResult[ 3 ] * 2.55,
4847					execResult[ 4 ]
4848				];
4849			}
4850		}, {
4851			// this regex ignores A-F because it's compared against an already lowercased string
4852			re: /#([a-f0-9]{2})([a-f0-9]{2})([a-f0-9]{2})/,
4853			parse: function( execResult ) {
4854				return [
4855					parseInt( execResult[ 1 ], 16 ),
4856					parseInt( execResult[ 2 ], 16 ),
4857					parseInt( execResult[ 3 ], 16 )
4858				];
4859			}
4860		}, {
4861			// this regex ignores A-F because it's compared against an already lowercased string
4862			re: /#([a-f0-9])([a-f0-9])([a-f0-9])/,
4863			parse: function( execResult ) {
4864				return [
4865					parseInt( execResult[ 1 ] + execResult[ 1 ], 16 ),
4866					parseInt( execResult[ 2 ] + execResult[ 2 ], 16 ),
4867					parseInt( execResult[ 3 ] + execResult[ 3 ], 16 )
4868				];
4869			}
4870		}, {
4871			re: /hsla?\(\s*(\d+(?:\.\d+)?)\s*,\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/,
4872			space: "hsla",
4873			parse: function( execResult ) {
4874				return [
4875					execResult[ 1 ],
4876					execResult[ 2 ] / 100,
4877					execResult[ 3 ] / 100,
4878					execResult[ 4 ]
4879				];
4880			}
4881		}],
4882
4883	// jQuery.Color( )
4884	color = jQuery.Color = function( color, green, blue, alpha ) {
4885		return new jQuery.Color.fn.parse( color, green, blue, alpha );
4886	},
4887	spaces = {
4888		rgba: {
4889			props: {
4890				red: {
4891					idx: 0,
4892					type: "byte"
4893				},
4894				green: {
4895					idx: 1,
4896					type: "byte"
4897				},
4898				blue: {
4899					idx: 2,
4900					type: "byte"
4901				}
4902			}
4903		},
4904
4905		hsla: {
4906			props: {
4907				hue: {
4908					idx: 0,
4909					type: "degrees"
4910				},
4911				saturation: {
4912					idx: 1,
4913					type: "percent"
4914				},
4915				lightness: {
4916					idx: 2,
4917					type: "percent"
4918				}
4919			}
4920		}
4921	},
4922	propTypes = {
4923		"byte": {
4924			floor: true,
4925			max: 255
4926		},
4927		"percent": {
4928			max: 1
4929		},
4930		"degrees": {
4931			mod: 360,
4932			floor: true
4933		}
4934	},
4935	support = color.support = {},
4936
4937	// element for support tests
4938	supportElem = jQuery( "<p>" )[ 0 ],
4939
4940	// colors = jQuery.Color.names
4941	colors,
4942
4943	// local aliases of functions called often
4944	each = jQuery.each;
4945
4946// determine rgba support immediately
4947supportElem.style.cssText = "background-color:rgba(1,1,1,.5)";
4948support.rgba = supportElem.style.backgroundColor.indexOf( "rgba" ) > -1;
4949
4950// define cache name and alpha properties
4951// for rgba and hsla spaces
4952each( spaces, function( spaceName, space ) {
4953	space.cache = "_" + spaceName;
4954	space.props.alpha = {
4955		idx: 3,
4956		type: "percent",
4957		def: 1
4958	};
4959});
4960
4961function clamp( value, prop, allowEmpty ) {
4962	var type = propTypes[ prop.type ] || {};
4963
4964	if ( value == null ) {
4965		return (allowEmpty || !prop.def) ? null : prop.def;
4966	}
4967
4968	// ~~ is an short way of doing floor for positive numbers
4969	value = type.floor ? ~~value : parseFloat( value );
4970
4971	// IE will pass in empty strings as value for alpha,
4972	// which will hit this case
4973	if ( isNaN( value ) ) {
4974		return prop.def;
4975	}
4976
4977	if ( type.mod ) {
4978		// we add mod before modding to make sure that negatives values
4979		// get converted properly: -10 -> 350
4980		return (value + type.mod) % type.mod;
4981	}
4982
4983	// for now all property types without mod have min and max
4984	return 0 > value ? 0 : type.max < value ? type.max : value;
4985}
4986
4987function stringParse( string ) {
4988	var inst = color(),
4989		rgba = inst._rgba = [];
4990
4991	string = string.toLowerCase();
4992
4993	each( stringParsers, function( i, parser ) {
4994		var parsed,
4995			match = parser.re.exec( string ),
4996			values = match && parser.parse( match ),
4997			spaceName = parser.space || "rgba";
4998
4999		if ( values ) {
5000			parsed = inst[ spaceName ]( values );
5001
5002			// if this was an rgba parse the assignment might happen twice
5003			// oh well....
5004			inst[ spaces[ spaceName ].cache ] = parsed[ spaces[ spaceName ].cache ];
5005			rgba = inst._rgba = parsed._rgba;
5006
5007			// exit each( stringParsers ) here because we matched
5008			return false;
5009		}
5010	});
5011
5012	// Found a stringParser that handled it
5013	if ( rgba.length ) {
5014
5015		// if this came from a parsed string, force "transparent" when alpha is 0
5016		// chrome, (and maybe others) return "transparent" as rgba(0,0,0,0)
5017		if ( rgba.join() === "0,0,0,0" ) {
5018			jQuery.extend( rgba, colors.transparent );
5019		}
5020		return inst;
5021	}
5022
5023	// named colors
5024	return colors[ string ];
5025}
5026
5027color.fn = jQuery.extend( color.prototype, {
5028	parse: function( red, green, blue, alpha ) {
5029		if ( red === undefined ) {
5030			this._rgba = [ null, null, null, null ];
5031			return this;
5032		}
5033		if ( red.jquery || red.nodeType ) {
5034			red = jQuery( red ).css( green );
5035			green = undefined;
5036		}
5037
5038		var inst = this,
5039			type = jQuery.type( red ),
5040			rgba = this._rgba = [];
5041
5042		// more than 1 argument specified - assume ( red, green, blue, alpha )
5043		if ( green !== undefined ) {
5044			red = [ red, green, blue, alpha ];
5045			type = "array";
5046		}
5047
5048		if ( type === "string" ) {
5049			return this.parse( stringParse( red ) || colors._default );
5050		}
5051
5052		if ( type === "array" ) {
5053			each( spaces.rgba.props, function( key, prop ) {
5054				rgba[ prop.idx ] = clamp( red[ prop.idx ], prop );
5055			});
5056			return this;
5057		}
5058
5059		if ( type === "object" ) {
5060			if ( red instanceof color ) {
5061				each( spaces, function( spaceName, space ) {
5062					if ( red[ space.cache ] ) {
5063						inst[ space.cache ] = red[ space.cache ].slice();
5064					}
5065				});
5066			} else {
5067				each( spaces, function( spaceName, space ) {
5068					var cache = space.cache;
5069					each( space.props, function( key, prop ) {
5070
5071						// if the cache doesn't exist, and we know how to convert
5072						if ( !inst[ cache ] && space.to ) {
5073
5074							// if the value was null, we don't need to copy it
5075							// if the key was alpha, we don't need to copy it either
5076							if ( key === "alpha" || red[ key ] == null ) {
5077								return;
5078							}
5079							inst[ cache ] = space.to( inst._rgba );
5080						}
5081
5082						// this is the only case where we allow nulls for ALL properties.
5083						// call clamp with alwaysAllowEmpty
5084						inst[ cache ][ prop.idx ] = clamp( red[ key ], prop, true );
5085					});
5086
5087					// everything defined but alpha?
5088					if ( inst[ cache ] && jQuery.inArray( null, inst[ cache ].slice( 0, 3 ) ) < 0 ) {
5089						// use the default of 1
5090						inst[ cache ][ 3 ] = 1;
5091						if ( space.from ) {
5092							inst._rgba = space.from( inst[ cache ] );
5093						}
5094					}
5095				});
5096			}
5097			return this;
5098		}
5099	},
5100	is: function( compare ) {
5101		var is = color( compare ),
5102			same = true,
5103			inst = this;
5104
5105		each( spaces, function( _, space ) {
5106			var localCache,
5107				isCache = is[ space.cache ];
5108			if (isCache) {
5109				localCache = inst[ space.cache ] || space.to && space.to( inst._rgba ) || [];
5110				each( space.props, function( _, prop ) {
5111					if ( isCache[ prop.idx ] != null ) {
5112						same = ( isCache[ prop.idx ] === localCache[ prop.idx ] );
5113						return same;
5114					}
5115				});
5116			}
5117			return same;
5118		});
5119		return same;
5120	},
5121	_space: function() {
5122		var used = [],
5123			inst = this;
5124		each( spaces, function( spaceName, space ) {
5125			if ( inst[ space.cache ] ) {
5126				used.push( spaceName );
5127			}
5128		});
5129		return used.pop();
5130	},
5131	transition: function( other, distance ) {
5132		var end = color( other ),
5133			spaceName = end._space(),
5134			space = spaces[ spaceName ],
5135			startColor = this.alpha() === 0 ? color( "transparent" ) : this,
5136			start = startColor[ space.cache ] || space.to( startColor._rgba ),
5137			result = start.slice();
5138
5139		end = end[ space.cache ];
5140		each( space.props, function( key, prop ) {
5141			var index = prop.idx,
5142				startValue = start[ index ],
5143				endValue = end[ index ],
5144				type = propTypes[ prop.type ] || {};
5145
5146			// if null, don't override start value
5147			if ( endValue === null ) {
5148				return;
5149			}
5150			// if null - use end
5151			if ( startValue === null ) {
5152				result[ index ] = endValue;
5153			} else {
5154				if ( type.mod ) {
5155					if ( endValue - startValue > type.mod / 2 ) {
5156						startValue += type.mod;
5157					} else if ( startValue - endValue > type.mod / 2 ) {
5158						startValue -= type.mod;
5159					}
5160				}
5161				result[ index ] = clamp( ( endValue - startValue ) * distance + startValue, prop );
5162			}
5163		});
5164		return this[ spaceName ]( result );
5165	},
5166	blend: function( opaque ) {
5167		// if we are already opaque - return ourself
5168		if ( this._rgba[ 3 ] === 1 ) {
5169			return this;
5170		}
5171
5172		var rgb = this._rgba.slice(),
5173			a = rgb.pop(),
5174			blend = color( opaque )._rgba;
5175
5176		return color( jQuery.map( rgb, function( v, i ) {
5177			return ( 1 - a ) * blend[ i ] + a * v;
5178		}));
5179	},
5180	toRgbaString: function() {
5181		var prefix = "rgba(",
5182			rgba = jQuery.map( this._rgba, function( v, i ) {
5183				return v == null ? ( i > 2 ? 1 : 0 ) : v;
5184			});
5185
5186		if ( rgba[ 3 ] === 1 ) {
5187			rgba.pop();
5188			prefix = "rgb(";
5189		}
5190
5191		return prefix + rgba.join() + ")";
5192	},
5193	toHslaString: function() {
5194		var prefix = "hsla(",
5195			hsla = jQuery.map( this.hsla(), function( v, i ) {
5196				if ( v == null ) {
5197					v = i > 2 ? 1 : 0;
5198				}
5199
5200				// catch 1 and 2
5201				if ( i && i < 3 ) {
5202					v = Math.round( v * 100 ) + "%";
5203				}
5204				return v;
5205			});
5206
5207		if ( hsla[ 3 ] === 1 ) {
5208			hsla.pop();
5209			prefix = "hsl(";
5210		}
5211		return prefix + hsla.join() + ")";
5212	},
5213	toHexString: function( includeAlpha ) {
5214		var rgba = this._rgba.slice(),
5215			alpha = rgba.pop();
5216
5217		if ( includeAlpha ) {
5218			rgba.push( ~~( alpha * 255 ) );
5219		}
5220
5221		return "#" + jQuery.map( rgba, function( v ) {
5222
5223			// default to 0 when nulls exist
5224			v = ( v || 0 ).toString( 16 );
5225			return v.length === 1 ? "0" + v : v;
5226		}).join("");
5227	},
5228	toString: function() {
5229		return this._rgba[ 3 ] === 0 ? "transparent" : this.toRgbaString();
5230	}
5231});
5232color.fn.parse.prototype = color.fn;
5233
5234// hsla conversions adapted from:
5235// https://code.google.com/p/maashaack/source/browse/packages/graphics/trunk/src/graphics/colors/HUE2RGB.as?r=5021
5236
5237function hue2rgb( p, q, h ) {
5238	h = ( h + 1 ) % 1;
5239	if ( h * 6 < 1 ) {
5240		return p + (q - p) * h * 6;
5241	}
5242	if ( h * 2 < 1) {
5243		return q;
5244	}
5245	if ( h * 3 < 2 ) {
5246		return p + (q - p) * ((2/3) - h) * 6;
5247	}
5248	return p;
5249}
5250
5251spaces.hsla.to = function ( rgba ) {
5252	if ( rgba[ 0 ] == null || rgba[ 1 ] == null || rgba[ 2 ] == null ) {
5253		return [ null, null, null, rgba[ 3 ] ];
5254	}
5255	var r = rgba[ 0 ] / 255,
5256		g = rgba[ 1 ] / 255,
5257		b = rgba[ 2 ] / 255,
5258		a = rgba[ 3 ],
5259		max = Math.max( r, g, b ),
5260		min = Math.min( r, g, b ),
5261		diff = max - min,
5262		add = max + min,
5263		l = add * 0.5,
5264		h, s;
5265
5266	if ( min === max ) {
5267		h = 0;
5268	} else if ( r === max ) {
5269		h = ( 60 * ( g - b ) / diff ) + 360;
5270	} else if ( g === max ) {
5271		h = ( 60 * ( b - r ) / diff ) + 120;
5272	} else {
5273		h = ( 60 * ( r - g ) / diff ) + 240;
5274	}
5275
5276	// chroma (diff) == 0 means greyscale which, by definition, saturation = 0%
5277	// otherwise, saturation is based on the ratio of chroma (diff) to lightness (add)
5278	if ( diff === 0 ) {
5279		s = 0;
5280	} else if ( l <= 0.5 ) {
5281		s = diff / add;
5282	} else {
5283		s = diff / ( 2 - add );
5284	}
5285	return [ Math.round(h) % 360, s, l, a == null ? 1 : a ];
5286};
5287
5288spaces.hsla.from = function ( hsla ) {
5289	if ( hsla[ 0 ] == null || hsla[ 1 ] == null || hsla[ 2 ] == null ) {
5290		return [ null, null, null, hsla[ 3 ] ];
5291	}
5292	var h = hsla[ 0 ] / 360,
5293		s = hsla[ 1 ],
5294		l = hsla[ 2 ],
5295		a = hsla[ 3 ],
5296		q = l <= 0.5 ? l * ( 1 + s ) : l + s - l * s,
5297		p = 2 * l - q;
5298
5299	return [
5300		Math.round( hue2rgb( p, q, h + ( 1 / 3 ) ) * 255 ),
5301		Math.round( hue2rgb( p, q, h ) * 255 ),
5302		Math.round( hue2rgb( p, q, h - ( 1 / 3 ) ) * 255 ),
5303		a
5304	];
5305};
5306
5307
5308each( spaces, function( spaceName, space ) {
5309	var props = space.props,
5310		cache = space.cache,
5311		to = space.to,
5312		from = space.from;
5313
5314	// makes rgba() and hsla()
5315	color.fn[ spaceName ] = function( value ) {
5316
5317		// generate a cache for this space if it doesn't exist
5318		if ( to && !this[ cache ] ) {
5319			this[ cache ] = to( this._rgba );
5320		}
5321		if ( value === undefined ) {
5322			return this[ cache ].slice();
5323		}
5324
5325		var ret,
5326			type = jQuery.type( value ),
5327			arr = ( type === "array" || type === "object" ) ? value : arguments,
5328			local = this[ cache ].slice();
5329
5330		each( props, function( key, prop ) {
5331			var val = arr[ type === "object" ? key : prop.idx ];
5332			if ( val == null ) {
5333				val = local[ prop.idx ];
5334			}
5335			local[ prop.idx ] = clamp( val, prop );
5336		});
5337
5338		if ( from ) {
5339			ret = color( from( local ) );
5340			ret[ cache ] = local;
5341			return ret;
5342		} else {
5343			return color( local );
5344		}
5345	};
5346
5347	// makes red() green() blue() alpha() hue() saturation() lightness()
5348	each( props, function( key, prop ) {
5349		// alpha is included in more than one space
5350		if ( color.fn[ key ] ) {
5351			return;
5352		}
5353		color.fn[ key ] = function( value ) {
5354			var vtype = jQuery.type( value ),
5355				fn = ( key === "alpha" ? ( this._hsla ? "hsla" : "rgba" ) : spaceName ),
5356				local = this[ fn ](),
5357				cur = local[ prop.idx ],
5358				match;
5359
5360			if ( vtype === "undefined" ) {
5361				return cur;
5362			}
5363
5364			if ( vtype === "function" ) {
5365				value = value.call( this, cur );
5366				vtype = jQuery.type( value );
5367			}
5368			if ( value == null && prop.empty ) {
5369				return this;
5370			}
5371			if ( vtype === "string" ) {
5372				match = rplusequals.exec( value );
5373				if ( match ) {
5374					value = cur + parseFloat( match[ 2 ] ) * ( match[ 1 ] === "+" ? 1 : -1 );
5375				}
5376			}
5377			local[ prop.idx ] = value;
5378			return this[ fn ]( local );
5379		};
5380	});
5381});
5382
5383// add cssHook and .fx.step function for each named hook.
5384// accept a space separated string of properties
5385color.hook = function( hook ) {
5386	var hooks = hook.split( " " );
5387	each( hooks, function( i, hook ) {
5388		jQuery.cssHooks[ hook ] = {
5389			set: function( elem, value ) {
5390				var parsed, curElem,
5391					backgroundColor = "";
5392
5393				if ( value !== "transparent" && ( jQuery.type( value ) !== "string" || ( parsed = stringParse( value ) ) ) ) {
5394					value = color( parsed || value );
5395					if ( !support.rgba && value._rgba[ 3 ] !== 1 ) {
5396						curElem = hook === "backgroundColor" ? elem.parentNode : elem;
5397						while (
5398							(backgroundColor === "" || backgroundColor === "transparent") &&
5399							curElem && curElem.style
5400						) {
5401							try {
5402								backgroundColor = jQuery.css( curElem, "backgroundColor" );
5403								curElem = curElem.parentNode;
5404							} catch ( e ) {
5405							}
5406						}
5407
5408						value = value.blend( backgroundColor && backgroundColor !== "transparent" ?
5409							backgroundColor :
5410							"_default" );
5411					}
5412
5413					value = value.toRgbaString();
5414				}
5415				try {
5416					elem.style[ hook ] = value;
5417				} catch( e ) {
5418					// wrapped to prevent IE from throwing errors on "invalid" values like 'auto' or 'inherit'
5419				}
5420			}
5421		};
5422		jQuery.fx.step[ hook ] = function( fx ) {
5423			if ( !fx.colorInit ) {
5424				fx.start = color( fx.elem, hook );
5425				fx.end = color( fx.end );
5426				fx.colorInit = true;
5427			}
5428			jQuery.cssHooks[ hook ].set( fx.elem, fx.start.transition( fx.end, fx.pos ) );
5429		};
5430	});
5431
5432};
5433
5434color.hook( stepHooks );
5435
5436jQuery.cssHooks.borderColor = {
5437	expand: function( value ) {
5438		var expanded = {};
5439
5440		each( [ "Top", "Right", "Bottom", "Left" ], function( i, part ) {
5441			expanded[ "border" + part + "Color" ] = value;
5442		});
5443		return expanded;
5444	}
5445};
5446
5447// Basic color names only.
5448// Usage of any of the other color names requires adding yourself or including
5449// jquery.color.svg-names.js.
5450colors = jQuery.Color.names = {
5451	// 4.1. Basic color keywords
5452	aqua: "#00ffff",
5453	black: "#000000",
5454	blue: "#0000ff",
5455	fuchsia: "#ff00ff",
5456	gray: "#808080",
5457	green: "#008000",
5458	lime: "#00ff00",
5459	maroon: "#800000",
5460	navy: "#000080",
5461	olive: "#808000",
5462	purple: "#800080",
5463	red: "#ff0000",
5464	silver: "#c0c0c0",
5465	teal: "#008080",
5466	white: "#ffffff",
5467	yellow: "#ffff00",
5468
5469	// 4.2.3. "transparent" color keyword
5470	transparent: [ null, null, null, 0 ],
5471
5472	_default: "#ffffff"
5473};
5474
5475})( jQuery );
5476
5477
5478/******************************************************************************/
5479/****************************** CLASS ANIMATIONS ******************************/
5480/******************************************************************************/
5481(function() {
5482
5483var classAnimationActions = [ "add", "remove", "toggle" ],
5484	shorthandStyles = {
5485		border: 1,
5486		borderBottom: 1,
5487		borderColor: 1,
5488		borderLeft: 1,
5489		borderRight: 1,
5490		borderTop: 1,
5491		borderWidth: 1,
5492		margin: 1,
5493		padding: 1
5494	};
5495
5496$.each([ "borderLeftStyle", "borderRightStyle", "borderBottomStyle", "borderTopStyle" ], function( _, prop ) {
5497	$.fx.step[ prop ] = function( fx ) {
5498		if ( fx.end !== "none" && !fx.setAttr || fx.pos === 1 && !fx.setAttr ) {
5499			jQuery.style( fx.elem, prop, fx.end );
5500			fx.setAttr = true;
5501		}
5502	};
5503});
5504
5505function getElementStyles( elem ) {
5506	var key, len,
5507		style = elem.ownerDocument.defaultView ?
5508			elem.ownerDocument.defaultView.getComputedStyle( elem, null ) :
5509			elem.currentStyle,
5510		styles = {};
5511
5512	if ( style && style.length && style[ 0 ] && style[ style[ 0 ] ] ) {
5513		len = style.length;
5514		while ( len-- ) {
5515			key = style[ len ];
5516			if ( typeof style[ key ] === "string" ) {
5517				styles[ $.camelCase( key ) ] = style[ key ];
5518			}
5519		}
5520	// support: Opera, IE <9
5521	} else {
5522		for ( key in style ) {
5523			if ( typeof style[ key ] === "string" ) {
5524				styles[ key ] = style[ key ];
5525			}
5526		}
5527	}
5528
5529	return styles;
5530}
5531
5532
5533function styleDifference( oldStyle, newStyle ) {
5534	var diff = {},
5535		name, value;
5536
5537	for ( name in newStyle ) {
5538		value = newStyle[ name ];
5539		if ( oldStyle[ name ] !== value ) {
5540			if ( !shorthandStyles[ name ] ) {
5541				if ( $.fx.step[ name ] || !isNaN( parseFloat( value ) ) ) {
5542					diff[ name ] = value;
5543				}
5544			}
5545		}
5546	}
5547
5548	return diff;
5549}
5550
5551// support: jQuery <1.8
5552if ( !$.fn.addBack ) {
5553	$.fn.addBack = function( selector ) {
5554		return this.add( selector == null ?
5555			this.prevObject : this.prevObject.filter( selector )
5556		);
5557	};
5558}
5559
5560$.effects.animateClass = function( value, duration, easing, callback ) {
5561	var o = $.speed( duration, easing, callback );
5562
5563	return this.queue( function() {
5564		var animated = $( this ),
5565			baseClass = animated.attr( "class" ) || "",
5566			applyClassChange,
5567			allAnimations = o.children ? animated.find( "*" ).addBack() : animated;
5568
5569		// map the animated objects to store the original styles.
5570		allAnimations = allAnimations.map(function() {
5571			var el = $( this );
5572			return {
5573				el: el,
5574				start: getElementStyles( this )
5575			};
5576		});
5577
5578		// apply class change
5579		applyClassChange = function() {
5580			$.each( classAnimationActions, function(i, action) {
5581				if ( value[ action ] ) {
5582					animated[ action + "Class" ]( value[ action ] );
5583				}
5584			});
5585		};
5586		applyClassChange();
5587
5588		// map all animated objects again - calculate new styles and diff
5589		allAnimations = allAnimations.map(function() {
5590			this.end = getElementStyles( this.el[ 0 ] );
5591			this.diff = styleDifference( this.start, this.end );
5592			return this;
5593		});
5594
5595		// apply original class
5596		animated.attr( "class", baseClass );
5597
5598		// map all animated objects again - this time collecting a promise
5599		allAnimations = allAnimations.map(function() {
5600			var styleInfo = this,
5601				dfd = $.Deferred(),
5602				opts = $.extend({}, o, {
5603					queue: false,
5604					complete: function() {
5605						dfd.resolve( styleInfo );
5606					}
5607				});
5608
5609			this.el.animate( this.diff, opts );
5610			return dfd.promise();
5611		});
5612
5613		// once all animations have completed:
5614		$.when.apply( $, allAnimations.get() ).done(function() {
5615
5616			// set the final class
5617			applyClassChange();
5618
5619			// for each animated element,
5620			// clear all css properties that were animated
5621			$.each( arguments, function() {
5622				var el = this.el;
5623				$.each( this.diff, function(key) {
5624					el.css( key, "" );
5625				});
5626			});
5627
5628			// this is guarnteed to be there if you use jQuery.speed()
5629			// it also handles dequeuing the next anim...
5630			o.complete.call( animated[ 0 ] );
5631		});
5632	});
5633};
5634
5635$.fn.extend({
5636	addClass: (function( orig ) {
5637		return function( classNames, speed, easing, callback ) {
5638			return speed ?
5639				$.effects.animateClass.call( this,
5640					{ add: classNames }, speed, easing, callback ) :
5641				orig.apply( this, arguments );
5642		};
5643	})( $.fn.addClass ),
5644
5645	removeClass: (function( orig ) {
5646		return function( classNames, speed, easing, callback ) {
5647			return arguments.length > 1 ?
5648				$.effects.animateClass.call( this,
5649					{ remove: classNames }, speed, easing, callback ) :
5650				orig.apply( this, arguments );
5651		};
5652	})( $.fn.removeClass ),
5653
5654	toggleClass: (function( orig ) {
5655		return function( classNames, force, speed, easing, callback ) {
5656			if ( typeof force === "boolean" || force === undefined ) {
5657				if ( !speed ) {
5658					// without speed parameter
5659					return orig.apply( this, arguments );
5660				} else {
5661					return $.effects.animateClass.call( this,
5662						(force ? { add: classNames } : { remove: classNames }),
5663						speed, easing, callback );
5664				}
5665			} else {
5666				// without force parameter
5667				return $.effects.animateClass.call( this,
5668					{ toggle: classNames }, force, speed, easing );
5669			}
5670		};
5671	})( $.fn.toggleClass ),
5672
5673	switchClass: function( remove, add, speed, easing, callback) {
5674		return $.effects.animateClass.call( this, {
5675			add: add,
5676			remove: remove
5677		}, speed, easing, callback );
5678	}
5679});
5680
5681})();
5682
5683/******************************************************************************/
5684/*********************************** EFFECTS **********************************/
5685/******************************************************************************/
5686
5687(function() {
5688
5689$.extend( $.effects, {
5690	version: "1.10.4",
5691
5692	// Saves a set of properties in a data storage
5693	save: function( element, set ) {
5694		for( var i=0; i < set.length; i++ ) {
5695			if ( set[ i ] !== null ) {
5696				element.data( dataSpace + set[ i ], element[ 0 ].style[ set[ i ] ] );
5697			}
5698		}
5699	},
5700
5701	// Restores a set of previously saved properties from a data storage
5702	restore: function( element, set ) {
5703		var val, i;
5704		for( i=0; i < set.length; i++ ) {
5705			if ( set[ i ] !== null ) {
5706				val = element.data( dataSpace + set[ i ] );
5707				// support: jQuery 1.6.2
5708				// http://bugs.jquery.com/ticket/9917
5709				// jQuery 1.6.2 incorrectly returns undefined for any falsy value.
5710				// We can't differentiate between "" and 0 here, so we just assume
5711				// empty string since it's likely to be a more common value...
5712				if ( val === undefined ) {
5713					val = "";
5714				}
5715				element.css( set[ i ], val );
5716			}
5717		}
5718	},
5719
5720	setMode: function( el, mode ) {
5721		if (mode === "toggle") {
5722			mode = el.is( ":hidden" ) ? "show" : "hide";
5723		}
5724		return mode;
5725	},
5726
5727	// Translates a [top,left] array into a baseline value
5728	// this should be a little more flexible in the future to handle a string & hash
5729	getBaseline: function( origin, original ) {
5730		var y, x;
5731		switch ( origin[ 0 ] ) {
5732			case "top": y = 0; break;
5733			case "middle": y = 0.5; break;
5734			case "bottom": y = 1; break;
5735			default: y = origin[ 0 ] / original.height;
5736		}
5737		switch ( origin[ 1 ] ) {
5738			case "left": x = 0; break;
5739			case "center": x = 0.5; break;
5740			case "right": x = 1; break;
5741			default: x = origin[ 1 ] / original.width;
5742		}
5743		return {
5744			x: x,
5745			y: y
5746		};
5747	},
5748
5749	// Wraps the element around a wrapper that copies position properties
5750	createWrapper: function( element ) {
5751
5752		// if the element is already wrapped, return it
5753		if ( element.parent().is( ".ui-effects-wrapper" )) {
5754			return element.parent();
5755		}
5756
5757		// wrap the element
5758		var props = {
5759				width: element.outerWidth(true),
5760				height: element.outerHeight(true),
5761				"float": element.css( "float" )
5762			},
5763			wrapper = $( "<div></div>" )
5764				.addClass( "ui-effects-wrapper" )
5765				.css({
5766					fontSize: "100%",
5767					background: "transparent",
5768					border: "none",
5769					margin: 0,
5770					padding: 0
5771				}),
5772			// Store the size in case width/height are defined in % - Fixes #5245
5773			size = {
5774				width: element.width(),
5775				height: element.height()
5776			},
5777			active = document.activeElement;
5778
5779		// support: Firefox
5780		// Firefox incorrectly exposes anonymous content
5781		// https://bugzilla.mozilla.org/show_bug.cgi?id=561664
5782		try {
5783			active.id;
5784		} catch( e ) {
5785			active = document.body;
5786		}
5787
5788		element.wrap( wrapper );
5789
5790		// Fixes #7595 - Elements lose focus when wrapped.
5791		if ( element[ 0 ] === active || $.contains( element[ 0 ], active ) ) {
5792			$( active ).focus();
5793		}
5794
5795		wrapper = element.parent(); //Hotfix for jQuery 1.4 since some change in wrap() seems to actually lose the reference to the wrapped element
5796
5797		// transfer positioning properties to the wrapper
5798		if ( element.css( "position" ) === "static" ) {
5799			wrapper.css({ position: "relative" });
5800			element.css({ position: "relative" });
5801		} else {
5802			$.extend( props, {
5803				position: element.css( "position" ),
5804				zIndex: element.css( "z-index" )
5805			});
5806			$.each([ "top", "left", "bottom", "right" ], function(i, pos) {
5807				props[ pos ] = element.css( pos );
5808				if ( isNaN( parseInt( props[ pos ], 10 ) ) ) {
5809					props[ pos ] = "auto";
5810				}
5811			});
5812			element.css({
5813				position: "relative",
5814				top: 0,
5815				left: 0,
5816				right: "auto",
5817				bottom: "auto"
5818			});
5819		}
5820		element.css(size);
5821
5822		return wrapper.css( props ).show();
5823	},
5824
5825	removeWrapper: function( element ) {
5826		var active = document.activeElement;
5827
5828		if ( element.parent().is( ".ui-effects-wrapper" ) ) {
5829			element.parent().replaceWith( element );
5830
5831			// Fixes #7595 - Elements lose focus when wrapped.
5832			if ( element[ 0 ] === active || $.contains( element[ 0 ], active ) ) {
5833				$( active ).focus();
5834			}
5835		}
5836
5837
5838		return element;
5839	},
5840
5841	setTransition: function( element, list, factor, value ) {
5842		value = value || {};
5843		$.each( list, function( i, x ) {
5844			var unit = element.cssUnit( x );
5845			if ( unit[ 0 ] > 0 ) {
5846				value[ x ] = unit[ 0 ] * factor + unit[ 1 ];
5847			}
5848		});
5849		return value;
5850	}
5851});
5852
5853// return an effect options object for the given parameters:
5854function _normalizeArguments( effect, options, speed, callback ) {
5855
5856	// allow passing all options as the first parameter
5857	if ( $.isPlainObject( effect ) ) {
5858		options = effect;
5859		effect = effect.effect;
5860	}
5861
5862	// convert to an object
5863	effect = { effect: effect };
5864
5865	// catch (effect, null, ...)
5866	if ( options == null ) {
5867		options = {};
5868	}
5869
5870	// catch (effect, callback)
5871	if ( $.isFunction( options ) ) {
5872		callback = options;
5873		speed = null;
5874		options = {};
5875	}
5876
5877	// catch (effect, speed, ?)
5878	if ( typeof options === "number" || $.fx.speeds[ options ] ) {
5879		callback = speed;
5880		speed = options;
5881		options = {};
5882	}
5883
5884	// catch (effect, options, callback)
5885	if ( $.isFunction( speed ) ) {
5886		callback = speed;
5887		speed = null;
5888	}
5889
5890	// add options to effect
5891	if ( options ) {
5892		$.extend( effect, options );
5893	}
5894
5895	speed = speed || options.duration;
5896	effect.duration = $.fx.off ? 0 :
5897		typeof speed === "number" ? speed :
5898		speed in $.fx.speeds ? $.fx.speeds[ speed ] :
5899		$.fx.speeds._default;
5900
5901	effect.complete = callback || options.complete;
5902
5903	return effect;
5904}
5905
5906function standardAnimationOption( option ) {
5907	// Valid standard speeds (nothing, number, named speed)
5908	if ( !option || typeof option === "number" || $.fx.speeds[ option ] ) {
5909		return true;
5910	}
5911
5912	// Invalid strings - treat as "normal" speed
5913	if ( typeof option === "string" && !$.effects.effect[ option ] ) {
5914		return true;
5915	}
5916
5917	// Complete callback
5918	if ( $.isFunction( option ) ) {
5919		return true;
5920	}
5921
5922	// Options hash (but not naming an effect)
5923	if ( typeof option === "object" && !option.effect ) {
5924		return true;
5925	}
5926
5927	// Didn't match any standard API
5928	return false;
5929}
5930
5931$.fn.extend({
5932	effect: function( /* effect, options, speed, callback */ ) {
5933		var args = _normalizeArguments.apply( this, arguments ),
5934			mode = args.mode,
5935			queue = args.queue,
5936			effectMethod = $.effects.effect[ args.effect ];
5937
5938		if ( $.fx.off || !effectMethod ) {
5939			// delegate to the original method (e.g., .show()) if possible
5940			if ( mode ) {
5941				return this[ mode ]( args.duration, args.complete );
5942			} else {
5943				return this.each( function() {
5944					if ( args.complete ) {
5945						args.complete.call( this );
5946					}
5947				});
5948			}
5949		}
5950
5951		function run( next ) {
5952			var elem = $( this ),
5953				complete = args.complete,
5954				mode = args.mode;
5955
5956			function done() {
5957				if ( $.isFunction( complete ) ) {
5958					complete.call( elem[0] );
5959				}
5960				if ( $.isFunction( next ) ) {
5961					next();
5962				}
5963			}
5964
5965			// If the element already has the correct final state, delegate to
5966			// the core methods so the internal tracking of "olddisplay" works.
5967			if ( elem.is( ":hidden" ) ? mode === "hide" : mode === "show" ) {
5968				elem[ mode ]();
5969				done();
5970			} else {
5971				effectMethod.call( elem[0], args, done );
5972			}
5973		}
5974
5975		return queue === false ? this.each( run ) : this.queue( queue || "fx", run );
5976	},
5977
5978	show: (function( orig ) {
5979		return function( option ) {
5980			if ( standardAnimationOption( option ) ) {
5981				return orig.apply( this, arguments );
5982			} else {
5983				var args = _normalizeArguments.apply( this, arguments );
5984				args.mode = "show";
5985				return this.effect.call( this, args );
5986			}
5987		};
5988	})( $.fn.show ),
5989
5990	hide: (function( orig ) {
5991		return function( option ) {
5992			if ( standardAnimationOption( option ) ) {
5993				return orig.apply( this, arguments );
5994			} else {
5995				var args = _normalizeArguments.apply( this, arguments );
5996				args.mode = "hide";
5997				return this.effect.call( this, args );
5998			}
5999		};
6000	})( $.fn.hide ),
6001
6002	toggle: (function( orig ) {
6003		return function( option ) {
6004			if ( standardAnimationOption( option ) || typeof option === "boolean" ) {
6005				return orig.apply( this, arguments );
6006			} else {
6007				var args = _normalizeArguments.apply( this, arguments );
6008				args.mode = "toggle";
6009				return this.effect.call( this, args );
6010			}
6011		};
6012	})( $.fn.toggle ),
6013
6014	// helper functions
6015	cssUnit: function(key) {
6016		var style = this.css( key ),
6017			val = [];
6018
6019		$.each( [ "em", "px", "%", "pt" ], function( i, unit ) {
6020			if ( style.indexOf( unit ) > 0 ) {
6021				val = [ parseFloat( style ), unit ];
6022			}
6023		});
6024		return val;
6025	}
6026});
6027
6028})();
6029
6030/******************************************************************************/
6031/*********************************** EASING ***********************************/
6032/******************************************************************************/
6033
6034(function() {
6035
6036// based on easing equations from Robert Penner (http://www.robertpenner.com/easing)
6037
6038var baseEasings = {};
6039
6040$.each( [ "Quad", "Cubic", "Quart", "Quint", "Expo" ], function( i, name ) {
6041	baseEasings[ name ] = function( p ) {
6042		return Math.pow( p, i + 2 );
6043	};
6044});
6045
6046$.extend( baseEasings, {
6047	Sine: function ( p ) {
6048		return 1 - Math.cos( p * Math.PI / 2 );
6049	},
6050	Circ: function ( p ) {
6051		return 1 - Math.sqrt( 1 - p * p );
6052	},
6053	Elastic: function( p ) {
6054		return p === 0 || p === 1 ? p :
6055			-Math.pow( 2, 8 * (p - 1) ) * Math.sin( ( (p - 1) * 80 - 7.5 ) * Math.PI / 15 );
6056	},
6057	Back: function( p ) {
6058		return p * p * ( 3 * p - 2 );
6059	},
6060	Bounce: function ( p ) {
6061		var pow2,
6062			bounce = 4;
6063
6064		while ( p < ( ( pow2 = Math.pow( 2, --bounce ) ) - 1 ) / 11 ) {}
6065		return 1 / Math.pow( 4, 3 - bounce ) - 7.5625 * Math.pow( ( pow2 * 3 - 2 ) / 22 - p, 2 );
6066	}
6067});
6068
6069$.each( baseEasings, function( name, easeIn ) {
6070	$.easing[ "easeIn" + name ] = easeIn;
6071	$.easing[ "easeOut" + name ] = function( p ) {
6072		return 1 - easeIn( 1 - p );
6073	};
6074	$.easing[ "easeInOut" + name ] = function( p ) {
6075		return p < 0.5 ?
6076			easeIn( p * 2 ) / 2 :
6077			1 - easeIn( p * -2 + 2 ) / 2;
6078	};
6079});
6080
6081})();
6082
6083})(jQuery);
6084
6085(function( $, undefined ) {
6086
6087var uid = 0,
6088	hideProps = {},
6089	showProps = {};
6090
6091hideProps.height = hideProps.paddingTop = hideProps.paddingBottom =
6092	hideProps.borderTopWidth = hideProps.borderBottomWidth = "hide";
6093showProps.height = showProps.paddingTop = showProps.paddingBottom =
6094	showProps.borderTopWidth = showProps.borderBottomWidth = "show";
6095
6096$.widget( "ui.accordion", {
6097	version: "1.10.4",
6098	options: {
6099		active: 0,
6100		animate: {},
6101		collapsible: false,
6102		event: "click",
6103		header: "> li > :first-child,> :not(li):even",
6104		heightStyle: "auto",
6105		icons: {
6106			activeHeader: "ui-icon-triangle-1-s",
6107			header: "ui-icon-triangle-1-e"
6108		},
6109
6110		// callbacks
6111		activate: null,
6112		beforeActivate: null
6113	},
6114
6115	_create: function() {
6116		var options = this.options;
6117		this.prevShow = this.prevHide = $();
6118		this.element.addClass( "ui-accordion ui-widget ui-helper-reset" )
6119			// ARIA
6120			.attr( "role", "tablist" );
6121
6122		// don't allow collapsible: false and active: false / null
6123		if ( !options.collapsible && (options.active === false || options.active == null) ) {
6124			options.active = 0;
6125		}
6126
6127		this._processPanels();
6128		// handle negative values
6129		if ( options.active < 0 ) {
6130			options.active += this.headers.length;
6131		}
6132		this._refresh();
6133	},
6134
6135	_getCreateEventData: function() {
6136		return {
6137			header: this.active,
6138			panel: !this.active.length ? $() : this.active.next(),
6139			content: !this.active.length ? $() : this.active.next()
6140		};
6141	},
6142
6143	_createIcons: function() {
6144		var icons = this.options.icons;
6145		if ( icons ) {
6146			$( "<span>" )
6147				.addClass( "ui-accordion-header-icon ui-icon " + icons.header )
6148				.prependTo( this.headers );
6149			this.active.children( ".ui-accordion-header-icon" )
6150				.removeClass( icons.header )
6151				.addClass( icons.activeHeader );
6152			this.headers.addClass( "ui-accordion-icons" );
6153		}
6154	},
6155
6156	_destroyIcons: function() {
6157		this.headers
6158			.removeClass( "ui-accordion-icons" )
6159			.children( ".ui-accordion-header-icon" )
6160				.remove();
6161	},
6162
6163	_destroy: function() {
6164		var contents;
6165
6166		// clean up main element
6167		this.element
6168			.removeClass( "ui-accordion ui-widget ui-helper-reset" )
6169			.removeAttr( "role" );
6170
6171		// clean up headers
6172		this.headers
6173			.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" )
6174			.removeAttr( "role" )
6175			.removeAttr( "aria-expanded" )
6176			.removeAttr( "aria-selected" )
6177			.removeAttr( "aria-controls" )
6178			.removeAttr( "tabIndex" )
6179			.each(function() {
6180				if ( /^ui-accordion/.test( this.id ) ) {
6181					this.removeAttribute( "id" );
6182				}
6183			});
6184		this._destroyIcons();
6185
6186		// clean up content panels
6187		contents = this.headers.next()
6188			.css( "display", "" )
6189			.removeAttr( "role" )
6190			.removeAttr( "aria-hidden" )
6191			.removeAttr( "aria-labelledby" )
6192			.removeClass( "ui-helper-reset ui-widget-content ui-corner-bottom ui-accordion-content ui-accordion-content-active ui-state-disabled" )
6193			.each(function() {
6194				if ( /^ui-accordion/.test( this.id ) ) {
6195					this.removeAttribute( "id" );
6196				}
6197			});
6198		if ( this.options.heightStyle !== "content" ) {
6199			contents.css( "height", "" );
6200		}
6201	},
6202
6203	_setOption: function( key, value ) {
6204		if ( key === "active" ) {
6205			// _activate() will handle invalid values and update this.options
6206			this._activate( value );
6207			return;
6208		}
6209
6210		if ( key === "event" ) {
6211			if ( this.options.event ) {
6212				this._off( this.headers, this.options.event );
6213			}
6214			this._setupEvents( value );
6215		}
6216
6217		this._super( key, value );
6218
6219		// setting collapsible: false while collapsed; open first panel
6220		if ( key === "collapsible" && !value && this.options.active === false ) {
6221			this._activate( 0 );
6222		}
6223
6224		if ( key === "icons" ) {
6225			this._destroyIcons();
6226			if ( value ) {
6227				this._createIcons();
6228			}
6229		}
6230
6231		// #5332 - opacity doesn't cascade to positioned elements in IE
6232		// so we need to add the disabled class to the headers and panels
6233		if ( key === "disabled" ) {
6234			this.headers.add( this.headers.next() )
6235				.toggleClass( "ui-state-disabled", !!value );
6236		}
6237	},
6238
6239	_keydown: function( event ) {
6240		if ( event.altKey || event.ctrlKey ) {
6241			return;
6242		}
6243
6244		var keyCode = $.ui.keyCode,
6245			length = this.headers.length,
6246			currentIndex = this.headers.index( event.target ),
6247			toFocus = false;
6248
6249		switch ( event.keyCode ) {
6250			case keyCode.RIGHT:
6251			case keyCode.DOWN:
6252				toFocus = this.headers[ ( currentIndex + 1 ) % length ];
6253				break;
6254			case keyCode.LEFT:
6255			case keyCode.UP:
6256				toFocus = this.headers[ ( currentIndex - 1 + length ) % length ];
6257				break;
6258			case keyCode.SPACE:
6259			case keyCode.ENTER:
6260				this._eventHandler( event );
6261				break;
6262			case keyCode.HOME:
6263				toFocus = this.headers[ 0 ];
6264				break;
6265			case keyCode.END:
6266				toFocus = this.headers[ length - 1 ];
6267				break;
6268		}
6269
6270		if ( toFocus ) {
6271			$( event.target ).attr( "tabIndex", -1 );
6272			$( toFocus ).attr( "tabIndex", 0 );
6273			toFocus.focus();
6274			event.preventDefault();
6275		}
6276	},
6277
6278	_panelKeyDown : function( event ) {
6279		if ( event.keyCode === $.ui.keyCode.UP && event.ctrlKey ) {
6280			$( event.currentTarget ).prev().focus();
6281		}
6282	},
6283
6284	refresh: function() {
6285		var options = this.options;
6286		this._processPanels();
6287
6288		// was collapsed or no panel
6289		if ( ( options.active === false && options.collapsible === true ) || !this.headers.length ) {
6290			options.active = false;
6291			this.active = $();
6292		// active false only when collapsible is true
6293		} else if ( options.active === false ) {
6294			this._activate( 0 );
6295		// was active, but active panel is gone
6296		} else if ( this.active.length && !$.contains( this.element[ 0 ], this.active[ 0 ] ) ) {
6297			// all remaining panel are disabled
6298			if ( this.headers.length === this.headers.find(".ui-state-disabled").length ) {
6299				options.active = false;
6300				this.active = $();
6301			// activate previous panel
6302			} else {
6303				this._activate( Math.max( 0, options.active - 1 ) );
6304			}
6305		// was active, active panel still exists
6306		} else {
6307			// make sure active index is correct
6308			options.active = this.headers.index( this.active );
6309		}
6310
6311		this._destroyIcons();
6312
6313		this._refresh();
6314	},
6315
6316	_processPanels: function() {
6317		this.headers = this.element.find( this.options.header )
6318			.addClass( "ui-accordion-header ui-helper-reset ui-state-default ui-corner-all" );
6319
6320		this.headers.next()
6321			.addClass( "ui-accordion-content ui-helper-reset ui-widget-content ui-corner-bottom" )
6322			.filter(":not(.ui-accordion-content-active)")
6323			.hide();
6324	},
6325
6326	_refresh: function() {
6327		var maxHeight,
6328			options = this.options,
6329			heightStyle = options.heightStyle,
6330			parent = this.element.parent(),
6331			accordionId = this.accordionId = "ui-accordion-" +
6332				(this.element.attr( "id" ) || ++uid);
6333
6334		this.active = this._findActive( options.active )
6335			.addClass( "ui-accordion-header-active ui-state-active ui-corner-top" )
6336			.removeClass( "ui-corner-all" );
6337		this.active.next()
6338			.addClass( "ui-accordion-content-active" )
6339			.show();
6340
6341		this.headers
6342			.attr( "role", "tab" )
6343			.each(function( i ) {
6344				var header = $( this ),
6345					headerId = header.attr( "id" ),
6346					panel = header.next(),
6347					panelId = panel.attr( "id" );
6348				if ( !headerId ) {
6349					headerId = accordionId + "-header-" + i;
6350					header.attr( "id", headerId );
6351				}
6352				if ( !panelId ) {
6353					panelId = accordionId + "-panel-" + i;
6354					panel.attr( "id", panelId );
6355				}
6356				header.attr( "aria-controls", panelId );
6357				panel.attr( "aria-labelledby", headerId );
6358			})
6359			.next()
6360				.attr( "role", "tabpanel" );
6361
6362		this.headers
6363			.not( this.active )
6364			.attr({
6365				"aria-selected": "false",
6366				"aria-expanded": "false",
6367				tabIndex: -1
6368			})
6369			.next()
6370				.attr({
6371					"aria-hidden": "true"
6372				})
6373				.hide();
6374
6375		// make sure at least one header is in the tab order
6376		if ( !this.active.length ) {
6377			this.headers.eq( 0 ).attr( "tabIndex", 0 );
6378		} else {
6379			this.active.attr({
6380				"aria-selected": "true",
6381				"aria-expanded": "true",
6382				tabIndex: 0
6383			})
6384			.next()
6385				.attr({
6386					"aria-hidden": "false"
6387				});
6388		}
6389
6390		this._createIcons();
6391
6392		this._setupEvents( options.event );
6393
6394		if ( heightStyle === "fill" ) {
6395			maxHeight = parent.height();
6396			this.element.siblings( ":visible" ).each(function() {
6397				var elem = $( this ),
6398					position = elem.css( "position" );
6399
6400				if ( position === "absolute" || position === "fixed" ) {
6401					return;
6402				}
6403				maxHeight -= elem.outerHeight( true );
6404			});
6405
6406			this.headers.each(function() {
6407				maxHeight -= $( this ).outerHeight( true );
6408			});
6409
6410			this.headers.next()
6411				.each(function() {
6412					$( this ).height( Math.max( 0, maxHeight -
6413						$( this ).innerHeight() + $( this ).height() ) );
6414				})
6415				.css( "overflow", "auto" );
6416		} else if ( heightStyle === "auto" ) {
6417			maxHeight = 0;
6418			this.headers.next()
6419				.each(function() {
6420					maxHeight = Math.max( maxHeight, $( this ).css( "height", "" ).height() );
6421				})
6422				.height( maxHeight );
6423		}
6424	},
6425
6426	_activate: function( index ) {
6427		var active = this._findActive( index )[ 0 ];
6428
6429		// trying to activate the already active panel
6430		if ( active === this.active[ 0 ] ) {
6431			return;
6432		}
6433
6434		// trying to collapse, simulate a click on the currently active header
6435		active = active || this.active[ 0 ];
6436
6437		this._eventHandler({
6438			target: active,
6439			currentTarget: active,
6440			preventDefault: $.noop
6441		});
6442	},
6443
6444	_findActive: function( selector ) {
6445		return typeof selector === "number" ? this.headers.eq( selector ) : $();
6446	},
6447
6448	_setupEvents: function( event ) {
6449		var events = {
6450			keydown: "_keydown"
6451		};
6452		if ( event ) {
6453			$.each( event.split(" "), function( index, eventName ) {
6454				events[ eventName ] = "_eventHandler";
6455			});
6456		}
6457
6458		this._off( this.headers.add( this.headers.next() ) );
6459		this._on( this.headers, events );
6460		this._on( this.headers.next(), { keydown: "_panelKeyDown" });
6461		this._hoverable( this.headers );
6462		this._focusable( this.headers );
6463	},
6464
6465	_eventHandler: function( event ) {
6466		var options = this.options,
6467			active = this.active,
6468			clicked = $( event.currentTarget ),
6469			clickedIsActive = clicked[ 0 ] === active[ 0 ],
6470			collapsing = clickedIsActive && options.collapsible,
6471			toShow = collapsing ? $() : clicked.next(),
6472			toHide = active.next(),
6473			eventData = {
6474				oldHeader: active,
6475				oldPanel: toHide,
6476				newHeader: collapsing ? $() : clicked,
6477				newPanel: toShow
6478			};
6479
6480		event.preventDefault();
6481
6482		if (
6483				// click on active header, but not collapsible
6484				( clickedIsActive && !options.collapsible ) ||
6485				// allow canceling activation
6486				( this._trigger( "beforeActivate", event, eventData ) === false ) ) {
6487			return;
6488		}
6489
6490		options.active = collapsing ? false : this.headers.index( clicked );
6491
6492		// when the call to ._toggle() comes after the class changes
6493		// it causes a very odd bug in IE 8 (see #6720)
6494		this.active = clickedIsActive ? $() : clicked;
6495		this._toggle( eventData );
6496
6497		// switch classes
6498		// corner classes on the previously active header stay after the animation
6499		active.removeClass( "ui-accordion-header-active ui-state-active" );
6500		if ( options.icons ) {
6501			active.children( ".ui-accordion-header-icon" )
6502				.removeClass( options.icons.activeHeader )
6503				.addClass( options.icons.header );
6504		}
6505
6506		if ( !clickedIsActive ) {
6507			clicked
6508				.removeClass( "ui-corner-all" )
6509				.addClass( "ui-accordion-header-active ui-state-active ui-corner-top" );
6510			if ( options.icons ) {
6511				clicked.children( ".ui-accordion-header-icon" )
6512					.removeClass( options.icons.header )
6513					.addClass( options.icons.activeHeader );
6514			}
6515
6516			clicked
6517				.next()
6518				.addClass( "ui-accordion-content-active" );
6519		}
6520	},
6521
6522	_toggle: function( data ) {
6523		var toShow = data.newPanel,
6524			toHide = this.prevShow.length ? this.prevShow : data.oldPanel;
6525
6526		// handle activating a panel during the animation for another activation
6527		this.prevShow.add( this.prevHide ).stop( true, true );
6528		this.prevShow = toShow;
6529		this.prevHide = toHide;
6530
6531		if ( this.options.animate ) {
6532			this._animate( toShow, toHide, data );
6533		} else {
6534			toHide.hide();
6535			toShow.show();
6536			this._toggleComplete( data );
6537		}
6538
6539		toHide.attr({
6540			"aria-hidden": "true"
6541		});
6542		toHide.prev().attr( "aria-selected", "false" );
6543		// if we're switching panels, remove the old header from the tab order
6544		// if we're opening from collapsed state, remove the previous header from the tab order
6545		// if we're collapsing, then keep the collapsing header in the tab order
6546		if ( toShow.length && toHide.length ) {
6547			toHide.prev().attr({
6548				"tabIndex": -1,
6549				"aria-expanded": "false"
6550			});
6551		} else if ( toShow.length ) {
6552			this.headers.filter(function() {
6553				return $( this ).attr( "tabIndex" ) === 0;
6554			})
6555			.attr( "tabIndex", -1 );
6556		}
6557
6558		toShow
6559			.attr( "aria-hidden", "false" )
6560			.prev()
6561				.attr({
6562					"aria-selected": "true",
6563					tabIndex: 0,
6564					"aria-expanded": "true"
6565				});
6566	},
6567
6568	_animate: function( toShow, toHide, data ) {
6569		var total, easing, duration,
6570			that = this,
6571			adjust = 0,
6572			down = toShow.length &&
6573				( !toHide.length || ( toShow.index() < toHide.index() ) ),
6574			animate = this.options.animate || {},
6575			options = down && animate.down || animate,
6576			complete = function() {
6577				that._toggleComplete( data );
6578			};
6579
6580		if ( typeof options === "number" ) {
6581			duration = options;
6582		}
6583		if ( typeof options === "string" ) {
6584			easing = options;
6585		}
6586		// fall back from options to animation in case of partial down settings
6587		easing = easing || options.easing || animate.easing;
6588		duration = duration || options.duration || animate.duration;
6589
6590		if ( !toHide.length ) {
6591			return toShow.animate( showProps, duration, easing, complete );
6592		}
6593		if ( !toShow.length ) {
6594			return toHide.animate( hideProps, duration, easing, complete );
6595		}
6596
6597		total = toShow.show().outerHeight();
6598		toHide.animate( hideProps, {
6599			duration: duration,
6600			easing: easing,
6601			step: function( now, fx ) {
6602				fx.now = Math.round( now );
6603			}
6604		});
6605		toShow
6606			.hide()
6607			.animate( showProps, {
6608				duration: duration,
6609				easing: easing,
6610				complete: complete,
6611				step: function( now, fx ) {
6612					fx.now = Math.round( now );
6613					if ( fx.prop !== "height" ) {
6614						adjust += fx.now;
6615					} else if ( that.options.heightStyle !== "content" ) {
6616						fx.now = Math.round( total - toHide.outerHeight() - adjust );
6617						adjust = 0;
6618					}
6619				}
6620			});
6621	},
6622
6623	_toggleComplete: function( data ) {
6624		var toHide = data.oldPanel;
6625
6626		toHide
6627			.removeClass( "ui-accordion-content-active" )
6628			.prev()
6629				.removeClass( "ui-corner-top" )
6630				.addClass( "ui-corner-all" );
6631
6632		// Work around for rendering bug in IE (#5421)
6633		if ( toHide.length ) {
6634			toHide.parent()[0].className = toHide.parent()[0].className;
6635		}
6636		this._trigger( "activate", null, data );
6637	}
6638});
6639
6640})( jQuery );
6641
6642(function( $, undefined ) {
6643
6644$.widget( "ui.autocomplete", {
6645	version: "1.10.4",
6646	defaultElement: "<input>",
6647	options: {
6648		appendTo: null,
6649		autoFocus: false,
6650		delay: 300,
6651		minLength: 1,
6652		position: {
6653			my: "left top",
6654			at: "left bottom",
6655			collision: "none"
6656		},
6657		source: null,
6658
6659		// callbacks
6660		change: null,
6661		close: null,
6662		focus: null,
6663		open: null,
6664		response: null,
6665		search: null,
6666		select: null
6667	},
6668
6669	requestIndex: 0,
6670	pending: 0,
6671
6672	_create: function() {
6673		// Some browsers only repeat keydown events, not keypress events,
6674		// so we use the suppressKeyPress flag to determine if we've already
6675		// handled the keydown event. #7269
6676		// Unfortunately the code for & in keypress is the same as the up arrow,
6677		// so we use the suppressKeyPressRepeat flag to avoid handling keypress
6678		// events when we know the keydown event was used to modify the
6679		// search term. #7799
6680		var suppressKeyPress, suppressKeyPressRepeat, suppressInput,
6681			nodeName = this.element[0].nodeName.toLowerCase(),
6682			isTextarea = nodeName === "textarea",
6683			isInput = nodeName === "input";
6684
6685		this.isMultiLine =
6686			// Textareas are always multi-line
6687			isTextarea ? true :
6688			// Inputs are always single-line, even if inside a contentEditable element
6689			// IE also treats inputs as contentEditable
6690			isInput ? false :
6691			// All other element types are determined by whether or not they're contentEditable
6692			this.element.prop( "isContentEditable" );
6693
6694		this.valueMethod = this.element[ isTextarea || isInput ? "val" : "text" ];
6695		this.isNewMenu = true;
6696
6697		this.element
6698			.addClass( "ui-autocomplete-input" )
6699			.attr( "autocomplete", "off" );
6700
6701		this._on( this.element, {
6702			keydown: function( event ) {
6703				if ( this.element.prop( "readOnly" ) ) {
6704					suppressKeyPress = true;
6705					suppressInput = true;
6706					suppressKeyPressRepeat = true;
6707					return;
6708				}
6709
6710				suppressKeyPress = false;
6711				suppressInput = false;
6712				suppressKeyPressRepeat = false;
6713				var keyCode = $.ui.keyCode;
6714				switch( event.keyCode ) {
6715				case keyCode.PAGE_UP:
6716					suppressKeyPress = true;
6717					this._move( "previousPage", event );
6718					break;
6719				case keyCode.PAGE_DOWN:
6720					suppressKeyPress = true;
6721					this._move( "nextPage", event );
6722					break;
6723				case keyCode.UP:
6724					suppressKeyPress = true;
6725					this._keyEvent( "previous", event );
6726					break;
6727				case keyCode.DOWN:
6728					suppressKeyPress = true;
6729					this._keyEvent( "next", event );
6730					break;
6731				case keyCode.ENTER:
6732				case keyCode.NUMPAD_ENTER:
6733					// when menu is open and has focus
6734					if ( this.menu.active ) {
6735						// #6055 - Opera still allows the keypress to occur
6736						// which causes forms to submit
6737						suppressKeyPress = true;
6738						event.preventDefault();
6739						this.menu.select( event );
6740					}
6741					break;
6742				case keyCode.TAB:
6743					if ( this.menu.active ) {
6744						this.menu.select( event );
6745					}
6746					break;
6747				case keyCode.ESCAPE:
6748					if ( this.menu.element.is( ":visible" ) ) {
6749						this._value( this.term );
6750						this.close( event );
6751						// Different browsers have different default behavior for escape
6752						// Single press can mean undo or clear
6753						// Double press in IE means clear the whole form
6754						event.preventDefault();
6755					}
6756					break;
6757				default:
6758					suppressKeyPressRepeat = true;
6759					// search timeout should be triggered before the input value is changed
6760					this._searchTimeout( event );
6761					break;
6762				}
6763			},
6764			keypress: function( event ) {
6765				if ( suppressKeyPress ) {
6766					suppressKeyPress = false;
6767					if ( !this.isMultiLine || this.menu.element.is( ":visible" ) ) {
6768						event.preventDefault();
6769					}
6770					return;
6771				}
6772				if ( suppressKeyPressRepeat ) {
6773					return;
6774				}
6775
6776				// replicate some key handlers to allow them to repeat in Firefox and Opera
6777				var keyCode = $.ui.keyCode;
6778				switch( event.keyCode ) {
6779				case keyCode.PAGE_UP:
6780					this._move( "previousPage", event );
6781					break;
6782				case keyCode.PAGE_DOWN:
6783					this._move( "nextPage", event );
6784					break;
6785				case keyCode.UP:
6786					this._keyEvent( "previous", event );
6787					break;
6788				case keyCode.DOWN:
6789					this._keyEvent( "next", event );
6790					break;
6791				}
6792			},
6793			input: function( event ) {
6794				if ( suppressInput ) {
6795					suppressInput = false;
6796					event.preventDefault();
6797					return;
6798				}
6799				this._searchTimeout( event );
6800			},
6801			focus: function() {
6802				this.selectedItem = null;
6803				this.previous = this._value();
6804			},
6805			blur: function( event ) {
6806				if ( this.cancelBlur ) {
6807					delete this.cancelBlur;
6808					return;
6809				}
6810
6811				clearTimeout( this.searching );
6812				this.close( event );
6813				this._change( event );
6814			}
6815		});
6816
6817		this._initSource();
6818		this.menu = $( "<ul>" )
6819			.addClass( "ui-autocomplete ui-front" )
6820			.appendTo( this._appendTo() )
6821			.menu({
6822				// disable ARIA support, the live region takes care of that
6823				role: null
6824			})
6825			.hide()
6826			.data( "ui-menu" );
6827
6828		this._on( this.menu.element, {
6829			mousedown: function( event ) {
6830				// prevent moving focus out of the text field
6831				event.preventDefault();
6832
6833				// IE doesn't prevent moving focus even with event.preventDefault()
6834				// so we set a flag to know when we should ignore the blur event
6835				this.cancelBlur = true;
6836				this._delay(function() {
6837					delete this.cancelBlur;
6838				});
6839
6840				// clicking on the scrollbar causes focus to shift to the body
6841				// but we can't detect a mouseup or a click immediately afterward
6842				// so we have to track the next mousedown and close the menu if
6843				// the user clicks somewhere outside of the autocomplete
6844				var menuElement = this.menu.element[ 0 ];
6845				if ( !$( event.target ).closest( ".ui-menu-item" ).length ) {
6846					this._delay(function() {
6847						var that = this;
6848						this.document.one( "mousedown", function( event ) {
6849							if ( event.target !== that.element[ 0 ] &&
6850									event.target !== menuElement &&
6851									!$.contains( menuElement, event.target ) ) {
6852								that.close();
6853							}
6854						});
6855					});
6856				}
6857			},
6858			menufocus: function( event, ui ) {
6859				// support: Firefox
6860				// Prevent accidental activation of menu items in Firefox (#7024 #9118)
6861				if ( this.isNewMenu ) {
6862					this.isNewMenu = false;
6863					if ( event.originalEvent && /^mouse/.test( event.originalEvent.type ) ) {
6864						this.menu.blur();
6865
6866						this.document.one( "mousemove", function() {
6867							$( event.target ).trigger( event.originalEvent );
6868						});
6869
6870						return;
6871					}
6872				}
6873
6874				var item = ui.item.data( "ui-autocomplete-item" );
6875				if ( false !== this._trigger( "focus", event, { item: item } ) ) {
6876					// use value to match what will end up in the input, if it was a key event
6877					if ( event.originalEvent && /^key/.test( event.originalEvent.type ) ) {
6878						this._value( item.value );
6879					}
6880				} else {
6881					// Normally the input is populated with the item's value as the
6882					// menu is navigated, causing screen readers to notice a change and
6883					// announce the item. Since the focus event was canceled, this doesn't
6884					// happen, so we update the live region so that screen readers can
6885					// still notice the change and announce it.
6886					this.liveRegion.text( item.value );
6887				}
6888			},
6889			menuselect: function( event, ui ) {
6890				var item = ui.item.data( "ui-autocomplete-item" ),
6891					previous = this.previous;
6892
6893				// only trigger when focus was lost (click on menu)
6894				if ( this.element[0] !== this.document[0].activeElement ) {
6895					this.element.focus();
6896					this.previous = previous;
6897					// #6109 - IE triggers two focus events and the second
6898					// is asynchronous, so we need to reset the previous
6899					// term synchronously and asynchronously :-(
6900					this._delay(function() {
6901						this.previous = previous;
6902						this.selectedItem = item;
6903					});
6904				}
6905
6906				if ( false !== this._trigger( "select", event, { item: item } ) ) {
6907					this._value( item.value );
6908				}
6909				// reset the term after the select event
6910				// this allows custom select handling to work properly
6911				this.term = this._value();
6912
6913				this.close( event );
6914				this.selectedItem = item;
6915			}
6916		});
6917
6918		this.liveRegion = $( "<span>", {
6919				role: "status",
6920				"aria-live": "polite"
6921			})
6922			.addClass( "ui-helper-hidden-accessible" )
6923			.insertBefore( this.element );
6924
6925		// turning off autocomplete prevents the browser from remembering the
6926		// value when navigating through history, so we re-enable autocomplete
6927		// if the page is unloaded before the widget is destroyed. #7790
6928		this._on( this.window, {
6929			beforeunload: function() {
6930				this.element.removeAttr( "autocomplete" );
6931			}
6932		});
6933	},
6934
6935	_destroy: function() {
6936		clearTimeout( this.searching );
6937		this.element
6938			.removeClass( "ui-autocomplete-input" )
6939			.removeAttr( "autocomplete" );
6940		this.menu.element.remove();
6941		this.liveRegion.remove();
6942	},
6943
6944	_setOption: function( key, value ) {
6945		this._super( key, value );
6946		if ( key === "source" ) {
6947			this._initSource();
6948		}
6949		if ( key === "appendTo" ) {
6950			this.menu.element.appendTo( this._appendTo() );
6951		}
6952		if ( key === "disabled" && value && this.xhr ) {
6953			this.xhr.abort();
6954		}
6955	},
6956
6957	_appendTo: function() {
6958		var element = this.options.appendTo;
6959
6960		if ( element ) {
6961			element = element.jquery || element.nodeType ?
6962				$( element ) :
6963				this.document.find( element ).eq( 0 );
6964		}
6965
6966		if ( !element ) {
6967			element = this.element.closest( ".ui-front" );
6968		}
6969
6970		if ( !element.length ) {
6971			element = this.document[0].body;
6972		}
6973
6974		return element;
6975	},
6976
6977	_initSource: function() {
6978		var array, url,
6979			that = this;
6980		if ( $.isArray(this.options.source) ) {
6981			array = this.options.source;
6982			this.source = function( request, response ) {
6983				response( $.ui.autocomplete.filter( array, request.term ) );
6984			};
6985		} else if ( typeof this.options.source === "string" ) {
6986			url = this.options.source;
6987			this.source = function( request, response ) {
6988				if ( that.xhr ) {
6989					that.xhr.abort();
6990				}
6991				that.xhr = $.ajax({
6992					url: url,
6993					data: request,
6994					dataType: "json",
6995					success: function( data ) {
6996						response( data );
6997					},
6998					error: function() {
6999						response( [] );
7000					}
7001				});
7002			};
7003		} else {
7004			this.source = this.options.source;
7005		}
7006	},
7007
7008	_searchTimeout: function( event ) {
7009		clearTimeout( this.searching );
7010		this.searching = this._delay(function() {
7011			// only search if the value has changed
7012			if ( this.term !== this._value() ) {
7013				this.selectedItem = null;
7014				this.search( null, event );
7015			}
7016		}, this.options.delay );
7017	},
7018
7019	search: function( value, event ) {
7020		value = value != null ? value : this._value();
7021
7022		// always save the actual value, not the one passed as an argument
7023		this.term = this._value();
7024
7025		if ( value.length < this.options.minLength ) {
7026			return this.close( event );
7027		}
7028
7029		if ( this._trigger( "search", event ) === false ) {
7030			return;
7031		}
7032
7033		return this._search( value );
7034	},
7035
7036	_search: function( value ) {
7037		this.pending++;
7038		this.element.addClass( "ui-autocomplete-loading" );
7039		this.cancelSearch = false;
7040
7041		this.source( { term: value }, this._response() );
7042	},
7043
7044	_response: function() {
7045		var index = ++this.requestIndex;
7046
7047		return $.proxy(function( content ) {
7048			if ( index === this.requestIndex ) {
7049				this.__response( content );
7050			}
7051
7052			this.pending--;
7053			if ( !this.pending ) {
7054				this.element.removeClass( "ui-autocomplete-loading" );
7055			}
7056		}, this );
7057	},
7058
7059	__response: function( content ) {
7060		if ( content ) {
7061			content = this._normalize( content );
7062		}
7063		this._trigger( "response", null, { content: content } );
7064		if ( !this.options.disabled && content && content.length && !this.cancelSearch ) {
7065			this._suggest( content );
7066			this._trigger( "open" );
7067		} else {
7068			// use ._close() instead of .close() so we don't cancel future searches
7069			this._close();
7070		}
7071	},
7072
7073	close: function( event ) {
7074		this.cancelSearch = true;
7075		this._close( event );
7076	},
7077
7078	_close: function( event ) {
7079		if ( this.menu.element.is( ":visible" ) ) {
7080			this.menu.element.hide();
7081			this.menu.blur();
7082			this.isNewMenu = true;
7083			this._trigger( "close", event );
7084		}
7085	},
7086
7087	_change: function( event ) {
7088		if ( this.previous !== this._value() ) {
7089			this._trigger( "change", event, { item: this.selectedItem } );
7090		}
7091	},
7092
7093	_normalize: function( items ) {
7094		// assume all items have the right format when the first item is complete
7095		if ( items.length && items[0].label && items[0].value ) {
7096			return items;
7097		}
7098		return $.map( items, function( item ) {
7099			if ( typeof item === "string" ) {
7100				return {
7101					label: item,
7102					value: item
7103				};
7104			}
7105			return $.extend({
7106				label: item.label || item.value,
7107				value: item.value || item.label
7108			}, item );
7109		});
7110	},
7111
7112	_suggest: function( items ) {
7113		var ul = this.menu.element.empty();
7114		this._renderMenu( ul, items );
7115		this.isNewMenu = true;
7116		this.menu.refresh();
7117
7118		// size and position menu
7119		ul.show();
7120		this._resizeMenu();
7121		ul.position( $.extend({
7122			of: this.element
7123		}, this.options.position ));
7124
7125		if ( this.options.autoFocus ) {
7126			this.menu.next();
7127		}
7128	},
7129
7130	_resizeMenu: function() {
7131		var ul = this.menu.element;
7132		ul.outerWidth( Math.max(
7133			// Firefox wraps long text (possibly a rounding bug)
7134			// so we add 1px to avoid the wrapping (#7513)
7135			ul.width( "" ).outerWidth() + 1,
7136			this.element.outerWidth()
7137		) );
7138	},
7139
7140	_renderMenu: function( ul, items ) {
7141		var that = this;
7142		$.each( items, function( index, item ) {
7143			that._renderItemData( ul, item );
7144		});
7145	},
7146
7147	_renderItemData: function( ul, item ) {
7148		return this._renderItem( ul, item ).data( "ui-autocomplete-item", item );
7149	},
7150
7151	_renderItem: function( ul, item ) {
7152		return $( "<li>" )
7153			.append( $( "<a>" ).text( item.label ) )
7154			.appendTo( ul );
7155	},
7156
7157	_move: function( direction, event ) {
7158		if ( !this.menu.element.is( ":visible" ) ) {
7159			this.search( null, event );
7160			return;
7161		}
7162		if ( this.menu.isFirstItem() && /^previous/.test( direction ) ||
7163				this.menu.isLastItem() && /^next/.test( direction ) ) {
7164			this._value( this.term );
7165			this.menu.blur();
7166			return;
7167		}
7168		this.menu[ direction ]( event );
7169	},
7170
7171	widget: function() {
7172		return this.menu.element;
7173	},
7174
7175	_value: function() {
7176		return this.valueMethod.apply( this.element, arguments );
7177	},
7178
7179	_keyEvent: function( keyEvent, event ) {
7180		if ( !this.isMultiLine || this.menu.element.is( ":visible" ) ) {
7181			this._move( keyEvent, event );
7182
7183			// prevents moving cursor to beginning/end of the text field in some browsers
7184			event.preventDefault();
7185		}
7186	}
7187});
7188
7189$.extend( $.ui.autocomplete, {
7190	escapeRegex: function( value ) {
7191		return value.replace(/[\-\[\]{}()*+?.,\\\^$|#\s]/g, "\\$&");
7192	},
7193	filter: function(array, term) {
7194		var matcher = new RegExp( $.ui.autocomplete.escapeRegex(term), "i" );
7195		return $.grep( array, function(value) {
7196			return matcher.test( value.label || value.value || value );
7197		});
7198	}
7199});
7200
7201
7202// live region extension, adding a `messages` option
7203// NOTE: This is an experimental API. We are still investigating
7204// a full solution for string manipulation and internationalization.
7205$.widget( "ui.autocomplete", $.ui.autocomplete, {
7206	options: {
7207		messages: {
7208			noResults: "No search results.",
7209			results: function( amount ) {
7210				return amount + ( amount > 1 ? " results are" : " result is" ) +
7211					" available, use up and down arrow keys to navigate.";
7212			}
7213		}
7214	},
7215
7216	__response: function( content ) {
7217		var message;
7218		this._superApply( arguments );
7219		if ( this.options.disabled || this.cancelSearch ) {
7220			return;
7221		}
7222		if ( content && content.length ) {
7223			message = this.options.messages.results( content.length );
7224		} else {
7225			message = this.options.messages.noResults;
7226		}
7227		this.liveRegion.text( message );
7228	}
7229});
7230
7231}( jQuery ));
7232
7233(function( $, undefined ) {
7234
7235var lastActive,
7236	baseClasses = "ui-button ui-widget ui-state-default ui-corner-all",
7237	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",
7238	formResetHandler = function() {
7239		var form = $( this );
7240		setTimeout(function() {
7241			form.find( ":ui-button" ).button( "refresh" );
7242		}, 1 );
7243	},
7244	radioGroup = function( radio ) {
7245		var name = radio.name,
7246			form = radio.form,
7247			radios = $( [] );
7248		if ( name ) {
7249			name = name.replace( /'/g, "\\'" );
7250			if ( form ) {
7251				radios = $( form ).find( "[name='" + name + "']" );
7252			} else {
7253				radios = $( "[name='" + name + "']", radio.ownerDocument )
7254					.filter(function() {
7255						return !this.form;
7256					});
7257			}
7258		}
7259		return radios;
7260	};
7261
7262$.widget( "ui.button", {
7263	version: "1.10.4",
7264	defaultElement: "<button>",
7265	options: {
7266		disabled: null,
7267		text: true,
7268		label: null,
7269		icons: {
7270			primary: null,
7271			secondary: null
7272		}
7273	},
7274	_create: function() {
7275		this.element.closest( "form" )
7276			.unbind( "reset" + this.eventNamespace )
7277			.bind( "reset" + this.eventNamespace, formResetHandler );
7278
7279		if ( typeof this.options.disabled !== "boolean" ) {
7280			this.options.disabled = !!this.element.prop( "disabled" );
7281		} else {
7282			this.element.prop( "disabled", this.options.disabled );
7283		}
7284
7285		this._determineButtonType();
7286		this.hasTitle = !!this.buttonElement.attr( "title" );
7287
7288		var that = this,
7289			options = this.options,
7290			toggleButton = this.type === "checkbox" || this.type === "radio",
7291			activeClass = !toggleButton ? "ui-state-active" : "";
7292
7293		if ( options.label === null ) {
7294			options.label = (this.type === "input" ? this.buttonElement.val() : this.buttonElement.html());
7295		}
7296
7297		this._hoverable( this.buttonElement );
7298
7299		this.buttonElement
7300			.addClass( baseClasses )
7301			.attr( "role", "button" )
7302			.bind( "mouseenter" + this.eventNamespace, function() {
7303				if ( options.disabled ) {
7304					return;
7305				}
7306				if ( this === lastActive ) {
7307					$( this ).addClass( "ui-state-active" );
7308				}
7309			})
7310			.bind( "mouseleave" + this.eventNamespace, function() {
7311				if ( options.disabled ) {
7312					return;
7313				}
7314				$( this ).removeClass( activeClass );
7315			})
7316			.bind( "click" + this.eventNamespace, function( event ) {
7317				if ( options.disabled ) {
7318					event.preventDefault();
7319					event.stopImmediatePropagation();
7320				}
7321			});
7322
7323		// Can't use _focusable() because the element that receives focus
7324		// and the element that gets the ui-state-focus class are different
7325		this._on({
7326			focus: function() {
7327				this.buttonElement.addClass( "ui-state-focus" );
7328			},
7329			blur: function() {
7330				this.buttonElement.removeClass( "ui-state-focus" );
7331			}
7332		});
7333
7334		if ( toggleButton ) {
7335			this.element.bind( "change" + this.eventNamespace, function() {
7336				that.refresh();
7337			});
7338		}
7339
7340		if ( this.type === "checkbox" ) {
7341			this.buttonElement.bind( "click" + this.eventNamespace, function() {
7342				if ( options.disabled ) {
7343					return false;
7344				}
7345			});
7346		} else if ( this.type === "radio" ) {
7347			this.buttonElement.bind( "click" + this.eventNamespace, function() {
7348				if ( options.disabled ) {
7349					return false;
7350				}
7351				$( this ).addClass( "ui-state-active" );
7352				that.buttonElement.attr( "aria-pressed", "true" );
7353
7354				var radio = that.element[ 0 ];
7355				radioGroup( radio )
7356					.not( radio )
7357					.map(function() {
7358						return $( this ).button( "widget" )[ 0 ];
7359					})
7360					.removeClass( "ui-state-active" )
7361					.attr( "aria-pressed", "false" );
7362			});
7363		} else {
7364			this.buttonElement
7365				.bind( "mousedown" + this.eventNamespace, function() {
7366					if ( options.disabled ) {
7367						return false;
7368					}
7369					$( this ).addClass( "ui-state-active" );
7370					lastActive = this;
7371					that.document.one( "mouseup", function() {
7372						lastActive = null;
7373					});
7374				})
7375				.bind( "mouseup" + this.eventNamespace, function() {
7376					if ( options.disabled ) {
7377						return false;
7378					}
7379					$( this ).removeClass( "ui-state-active" );
7380				})
7381				.bind( "keydown" + this.eventNamespace, function(event) {
7382					if ( options.disabled ) {
7383						return false;
7384					}
7385					if ( event.keyCode === $.ui.keyCode.SPACE || event.keyCode === $.ui.keyCode.ENTER ) {
7386						$( this ).addClass( "ui-state-active" );
7387					}
7388				})
7389				// see #8559, we bind to blur here in case the button element loses
7390				// focus between keydown and keyup, it would be left in an "active" state
7391				.bind( "keyup" + this.eventNamespace + " blur" + this.eventNamespace, function() {
7392					$( this ).removeClass( "ui-state-active" );
7393				});
7394
7395			if ( this.buttonElement.is("a") ) {
7396				this.buttonElement.keyup(function(event) {
7397					if ( event.keyCode === $.ui.keyCode.SPACE ) {
7398						// TODO pass through original event correctly (just as 2nd argument doesn't work)
7399						$( this ).click();
7400					}
7401				});
7402			}
7403		}
7404
7405		// TODO: pull out $.Widget's handling for the disabled option into
7406		// $.Widget.prototype._setOptionDisabled so it's easy to proxy and can
7407		// be overridden by individual plugins
7408		this._setOption( "disabled", options.disabled );
7409		this._resetButton();
7410	},
7411
7412	_determineButtonType: function() {
7413		var ancestor, labelSelector, checked;
7414
7415		if ( this.element.is("[type=checkbox]") ) {
7416			this.type = "checkbox";
7417		} else if ( this.element.is("[type=radio]") ) {
7418			this.type = "radio";
7419		} else if ( this.element.is("input") ) {
7420			this.type = "input";
7421		} else {
7422			this.type = "button";
7423		}
7424
7425		if ( this.type === "checkbox" || this.type === "radio" ) {
7426			// we don't search against the document in case the element
7427			// is disconnected from the DOM
7428			ancestor = this.element.parents().last();
7429			labelSelector = "label[for='" + this.element.attr("id") + "']";
7430			this.buttonElement = ancestor.find( labelSelector );
7431			if ( !this.buttonElement.length ) {
7432				ancestor = ancestor.length ? ancestor.siblings() : this.element.siblings();
7433				this.buttonElement = ancestor.filter( labelSelector );
7434				if ( !this.buttonElement.length ) {
7435					this.buttonElement = ancestor.find( labelSelector );
7436				}
7437			}
7438			this.element.addClass( "ui-helper-hidden-accessible" );
7439
7440			checked = this.element.is( ":checked" );
7441			if ( checked ) {
7442				this.buttonElement.addClass( "ui-state-active" );
7443			}
7444			this.buttonElement.prop( "aria-pressed", checked );
7445		} else {
7446			this.buttonElement = this.element;
7447		}
7448	},
7449
7450	widget: function() {
7451		return this.buttonElement;
7452	},
7453
7454	_destroy: function() {
7455		this.element
7456			.removeClass( "ui-helper-hidden-accessible" );
7457		this.buttonElement
7458			.removeClass( baseClasses + " ui-state-active " + typeClasses )
7459			.removeAttr( "role" )
7460			.removeAttr( "aria-pressed" )
7461			.html( this.buttonElement.find(".ui-button-text").html() );
7462
7463		if ( !this.hasTitle ) {
7464			this.buttonElement.removeAttr( "title" );
7465		}
7466	},
7467
7468	_setOption: function( key, value ) {
7469		this._super( key, value );
7470		if ( key === "disabled" ) {
7471			this.element.prop( "disabled", !!value );
7472			if ( value ) {
7473				this.buttonElement.removeClass( "ui-state-focus" );
7474			}
7475			return;
7476		}
7477		this._resetButton();
7478	},
7479
7480	refresh: function() {
7481		//See #8237 & #8828
7482		var isDisabled = this.element.is( "input, button" ) ? this.element.is( ":disabled" ) : this.element.hasClass( "ui-button-disabled" );
7483
7484		if ( isDisabled !== this.options.disabled ) {
7485			this._setOption( "disabled", isDisabled );
7486		}
7487		if ( this.type === "radio" ) {
7488			radioGroup( this.element[0] ).each(function() {
7489				if ( $( this ).is( ":checked" ) ) {
7490					$( this ).button( "widget" )
7491						.addClass( "ui-state-active" )
7492						.attr( "aria-pressed", "true" );
7493				} else {
7494					$( this ).button( "widget" )
7495						.removeClass( "ui-state-active" )
7496						.attr( "aria-pressed", "false" );
7497				}
7498			});
7499		} else if ( this.type === "checkbox" ) {
7500			if ( this.element.is( ":checked" ) ) {
7501				this.buttonElement
7502					.addClass( "ui-state-active" )
7503					.attr( "aria-pressed", "true" );
7504			} else {
7505				this.buttonElement
7506					.removeClass( "ui-state-active" )
7507					.attr( "aria-pressed", "false" );
7508			}
7509		}
7510	},
7511
7512	_resetButton: function() {
7513		if ( this.type === "input" ) {
7514			if ( this.options.label ) {
7515				this.element.val( this.options.label );
7516			}
7517			return;
7518		}
7519		var buttonElement = this.buttonElement.removeClass( typeClasses ),
7520			buttonText = $( "<span></span>", this.document[0] )
7521				.addClass( "ui-button-text" )
7522				.html( this.options.label )
7523				.appendTo( buttonElement.empty() )
7524				.text(),
7525			icons = this.options.icons,
7526			multipleIcons = icons.primary && icons.secondary,
vendor: 2,268 bytes, lines 7527-7617
7527			buttonClasses = [];
7528
7529		if ( icons.primary || icons.secondary ) {
7530			if ( this.options.text ) {
7531				buttonClasses.push( "ui-button-text-icon" + ( multipleIcons ? "s" : ( icons.primary ? "-primary" : "-secondary" ) ) );
7532			}
7533
7534			if ( icons.primary ) {
7535				buttonElement.prepend( "<span class='ui-button-icon-primary ui-icon " + icons.primary + "'></span>" );
7536			}
7537
7538			if ( icons.secondary ) {
7539				buttonElement.append( "<span class='ui-button-icon-secondary ui-icon " + icons.secondary + "'></span>" );
7540			}
7541
7542			if ( !this.options.text ) {
7543				buttonClasses.push( multipleIcons ? "ui-button-icons-only" : "ui-button-icon-only" );
7544
7545				if ( !this.hasTitle ) {
7546					buttonElement.attr( "title", $.trim( buttonText ) );
7547				}
7548			}
7549		} else {
7550			buttonClasses.push( "ui-button-text-only" );
7551		}
7552		buttonElement.addClass( buttonClasses.join( " " ) );
7553	}
7554});
7555
7556$.widget( "ui.buttonset", {
7557	version: "1.10.4",
7558	options: {
7559		items: "button, input[type=button], input[type=submit], input[type=reset], input[type=checkbox], input[type=radio], a, :data(ui-button)"
7560	},
7561
7562	_create: function() {
7563		this.element.addClass( "ui-buttonset" );
7564	},
7565
7566	_init: function() {
7567		this.refresh();
7568	},
7569
7570	_setOption: function( key, value ) {
7571		if ( key === "disabled" ) {
7572			this.buttons.button( "option", key, value );
7573		}
7574
7575		this._super( key, value );
7576	},
7577
7578	refresh: function() {
7579		var rtl = this.element.css( "direction" ) === "rtl";
7580
7581		this.buttons = this.element.find( this.options.items )
7582			.filter( ":ui-button" )
7583				.button( "refresh" )
7584			.end()
7585			.not( ":ui-button" )
7586				.button()
7587			.end()
7588			.map(function() {
7589				return $( this ).button( "widget" )[ 0 ];
7590			})
7591				.removeClass( "ui-corner-all ui-corner-left ui-corner-right" )
7592				.filter( ":first" )
7593					.addClass( rtl ? "ui-corner-right" : "ui-corner-left" )
7594				.end()
7595				.filter( ":last" )
7596					.addClass( rtl ? "ui-corner-left" : "ui-corner-right" )
7597				.end()
7598			.end();
7599	},
7600
7601	_destroy: function() {
7602		this.element.removeClass( "ui-buttonset" );
7603		this.buttons
7604			.map(function() {
7605				return $( this ).button( "widget" )[ 0 ];
7606			})
7607				.removeClass( "ui-corner-left ui-corner-right" )
7608			.end()
7609			.button( "destroy" );
7610	}
7611});
7612
7613}( jQuery ) );
7614
7615(function( $, undefined ) {
7616
7617$.extend($.ui, { datepicker: { version: "1.10.4
vendor: 75,965 bytes, lines 7617-9637
7617" } });
7618
7619var PROP_NAME = "datepicker",
7620	instActive;
7621
7622/* Date picker manager.
7623   Use the singleton instance of this class, $.datepicker, to interact with the date picker.
7624   Settings for (groups of) date pickers are maintained in an instance object,
7625   allowing multiple different settings on the same page. */
7626
7627function Datepicker() {
7628	this._curInst = null; // The current instance in use
7629	this._keyEvent = false; // If the last event was a key event
7630	this._disabledInputs = []; // List of date picker inputs that have been disabled
7631	this._datepickerShowing = false; // True if the popup picker is showing , false if not
7632	this._inDialog = false; // True if showing within a "dialog", false if not
7633	this._mainDivId = "ui-datepicker-div"; // The ID of the main datepicker division
7634	this._inlineClass = "ui-datepicker-inline"; // The name of the inline marker class
7635	this._appendClass = "ui-datepicker-append"; // The name of the append marker class
7636	this._triggerClass = "ui-datepicker-trigger"; // The name of the trigger marker class
7637	this._dialogClass = "ui-datepicker-dialog"; // The name of the dialog marker class
7638	this._disableClass = "ui-datepicker-disabled"; // The name of the disabled covering marker class
7639	this._unselectableClass = "ui-datepicker-unselectable"; // The name of the unselectable cell marker class
7640	this._currentClass = "ui-datepicker-current-day"; // The name of the current day marker class
7641	this._dayOverClass = "ui-datepicker-days-cell-over"; // The name of the day hover marker class
7642	this.regional = []; // Available regional settings, indexed by language code
7643	this.regional[""] = { // Default regional settings
7644		closeText: "Done", // Display text for close link
7645		prevText: "Prev", // Display text for previous month link
7646		nextText: "Next", // Display text for next month link
7647		currentText: "Today", // Display text for current month link
7648		monthNames: ["January","February","March","April","May","June",
7649			"July","August","September","October","November","December"], // Names of months for drop-down and formatting
7650		monthNamesShort: ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"], // For formatting
7651		dayNames: ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"], // For formatting
7652		dayNamesShort: ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"], // For formatting
7653		dayNamesMin: ["Su","Mo","Tu","We","Th","Fr","Sa"], // Column headings for days starting at Sunday
7654		weekHeader: "Wk", // Column header for week of the year
7655		dateFormat: "mm/dd/yy", // See format options on parseDate
7656		firstDay: 0, // The first day of the week, Sun = 0, Mon = 1, ...
7657		isRTL: false, // True if right-to-left language, false if left-to-right
7658		showMonthAfterYear: false, // True if the year select precedes month, false for month then year
7659		yearSuffix: "" // Additional text to append to the year in the month headers
7660	};
7661	this._defaults = { // Global defaults for all the date picker instances
7662		showOn: "focus", // "focus" for popup on focus,
7663			// "button" for trigger button, or "both" for either
7664		showAnim: "fadeIn", // Name of jQuery animation for popup
7665		showOptions: {}, // Options for enhanced animations
7666		defaultDate: null, // Used when field is blank: actual date,
7667			// +/-number for offset from today, null for today
7668		appendText: "", // Display text following the input box, e.g. showing the format
7669		buttonText: "...", // Text for trigger button
7670		buttonImage: "", // URL for trigger button image
7671		buttonImageOnly: false, // True if the image appears alone, false if it appears on a button
7672		hideIfNoPrevNext: false, // True to hide next/previous month links
7673			// if not applicable, false to just disable them
7674		navigationAsDateFormat: false, // True if date formatting applied to prev/today/next links
7675		gotoCurrent: false, // True if today link goes back to current selection instead
7676		changeMonth: false, // True if month can be selected directly, false if only prev/next
7677		changeYear: false, // True if year can be selected directly, false if only prev/next
7678		yearRange: "c-10:c+10", // Range of years to display in drop-down,
7679			// either relative to today's year (-nn:+nn), relative to currently displayed year
7680			// (c-nn:c+nn), absolute (nnnn:nnnn), or a combination of the above (nnnn:-n)
7681		showOtherMonths: false, // True to show dates in other months, false to leave blank
7682		selectOtherMonths: false, // True to allow selection of dates in other months, false for unselectable
7683		showWeek: false, // True to show week of the year, false to not show it
7684		calculateWeek: this.iso8601Week, // How to calculate the week of the year,
7685			// takes a Date and returns the number of the week for it
7686		shortYearCutoff: "+10", // Short year values < this are in the current century,
7687			// > this are in the previous century,
7688			// string value starting with "+" for current year + value
7689		minDate: null, // The earliest selectable date, or null for no limit
7690		maxDate: null, // The latest selectable date, or null for no limit
7691		duration: "fast", // Duration of display/closure
7692		beforeShowDay: null, // Function that takes a date and returns an array with
7693			// [0] = true if selectable, false if not, [1] = custom CSS class name(s) or "",
7694			// [2] = cell title (optional), e.g. $.datepicker.noWeekends
7695		beforeShow: null, // Function that takes an input field and
7696			// returns a set of custom settings for the date picker
7697		onSelect: null, // Define a callback function when a date is selected
7698		onChangeMonthYear: null, // Define a callback function when the month or year is changed
7699		onClose: null, // Define a callback function when the datepicker is closed
7700		numberOfMonths: 1, // Number of months to show at a time
7701		showCurrentAtPos: 0, // The position in multipe months at which to show the current month (starting at 0)
7702		stepMonths: 1, // Number of months to step back/forward
7703		stepBigMonths: 12, // Number of months to step back/forward for the big links
7704		altField: "", // Selector for an alternate field to store selected dates into
7705		altFormat: "", // The date format to use for the alternate field
7706		constrainInput: true, // The input is constrained by the current date format
7707		showButtonPanel: false, // True to show button panel, false to not show it
7708		autoSize: false, // True to size the input for the date format, false to leave as is
7709		disabled: false // The initial disabled state
7710	};
7711	$.extend(this._defaults, this.regional[""]);
7712	this.dpDiv = bindHover($("<div id='" + this._mainDivId + "' class='ui-datepicker ui-widget ui-widget-content ui-helper-clearfix ui-corner-all'></div>"));
7713}
7714
7715$.extend(Datepicker.prototype, {
7716	/* Class name added to elements to indicate already configured with a date picker. */
7717	markerClassName: "hasDatepicker",
7718
7719	//Keep track of the maximum number of rows displayed (see #7043)
7720	maxRows: 4,
7721
7722	// TODO rename to "widget" when switching to widget factory
7723	_widgetDatepicker: function() {
7724		return this.dpDiv;
7725	},
7726
7727	/* Override the default settings for all instances of the date picker.
7728	 * @param  settings  object - the new settings to use as defaults (anonymous object)
7729	 * @return the manager object
7730	 */
7731	setDefaults: function(settings) {
7732		extendRemove(this._defaults, settings || {});
7733		return this;
7734	},
7735
7736	/* Attach the date picker to a jQuery selection.
7737	 * @param  target	element - the target input field or division or span
7738	 * @param  settings  object - the new settings to use for this date picker instance (anonymous)
7739	 */
7740	_attachDatepicker: function(target, settings) {
7741		var nodeName, inline, inst;
7742		nodeName = target.nodeName.toLowerCase();
7743		inline = (nodeName === "div" || nodeName === "span");
7744		if (!target.id) {
7745			this.uuid += 1;
7746			target.id = "dp" + this.uuid;
7747		}
7748		inst = this._newInst($(target), inline);
7749		inst.settings = $.extend({}, settings || {});
7750		if (nodeName === "input") {
7751			this._connectDatepicker(target, inst);
7752		} else if (inline) {
7753			this._inlineDatepicker(target, inst);
7754		}
7755	},
7756
7757	/* Create a new instance object. */
7758	_newInst: function(target, inline) {
7759		var id = target[0].id.replace(/([^A-Za-z0-9_\-])/g, "\\\\$1"); // escape jQuery meta chars
7760		return {id: id, input: target, // associated target
7761			selectedDay: 0, selectedMonth: 0, selectedYear: 0, // current selection
7762			drawMonth: 0, drawYear: 0, // month being drawn
7763			inline: inline, // is datepicker inline or not
7764			dpDiv: (!inline ? this.dpDiv : // presentation div
7765			bindHover($("<div class='" + this._inlineClass + " ui-datepicker ui-widget ui-widget-content ui-helper-clearfix ui-corner-all'></div>")))};
7766	},
7767
7768	/* Attach the date picker to an input field. */
7769	_connectDatepicker: function(target, inst) {
7770		var input = $(target);
7771		inst.append = $([]);
7772		inst.trigger = $([]);
7773		if (input.hasClass(this.markerClassName)) {
7774			return;
7775		}
7776		this._attachments(input, inst);
7777		input.addClass(this.markerClassName).keydown(this._doKeyDown).
7778			keypress(this._doKeyPress).keyup(this._doKeyUp);
7779		this._autoSize(inst);
7780		$.data(target, PROP_NAME, inst);
7781		//If disabled option is true, disable the datepicker once it has been attached to the input (see ticket #5665)
7782		if( inst.settings.disabled ) {
7783			this._disableDatepicker( target );
7784		}
7785	},
7786
7787	/* Make attachments based on settings. */
7788	_attachments: function(input, inst) {
7789		var showOn, buttonText, buttonImage,
7790			appendText = this._get(inst, "appendText"),
7791			isRTL = this._get(inst, "isRTL");
7792
7793		if (inst.append) {
7794			inst.append.remove();
7795		}
7796		if (appendText) {
7797			inst.append = $("<span class='" + this._appendClass + "'>" + appendText + "</span>");
7798			input[isRTL ? "before" : "after"](inst.append);
7799		}
7800
7801		input.unbind("focus", this._showDatepicker);
7802
7803		if (inst.trigger) {
7804			inst.trigger.remove();
7805		}
7806
7807		showOn = this._get(inst, "showOn");
7808		if (showOn === "focus" || showOn === "both") { // pop-up date picker when in the marked field
7809			input.focus(this._showDatepicker);
7810		}
7811		if (showOn === "button" || showOn === "both") { // pop-up date picker when button clicked
7812			buttonText = this._get(inst, "buttonText");
7813			buttonImage = this._get(inst, "buttonImage");
7814			inst.trigger = $(this._get(inst, "buttonImageOnly") ?
7815				$("<img/>").addClass(this._triggerClass).
7816					attr({ src: buttonImage, alt: buttonText, title: buttonText }) :
7817				$("<button type='button'></button>").addClass(this._triggerClass).
7818					html(!buttonImage ? buttonText : $("<img/>").attr(
7819					{ src:buttonImage, alt:buttonText, title:buttonText })));
7820			input[isRTL ? "before" : "after"](inst.trigger);
7821			inst.trigger.click(function() {
7822				if ($.datepicker._datepickerShowing && $.datepicker._lastInput === input[0]) {
7823					$.datepicker._hideDatepicker();
7824				} else if ($.datepicker._datepickerShowing && $.datepicker._lastInput !== input[0]) {
7825					$.datepicker._hideDatepicker();
7826					$.datepicker._showDatepicker(input[0]);
7827				} else {
7828					$.datepicker._showDatepicker(input[0]);
7829				}
7830				return false;
7831			});
7832		}
7833	},
7834
7835	/* Apply the maximum length for the date format. */
7836	_autoSize: function(inst) {
7837		if (this._get(inst, "autoSize") && !inst.inline) {
7838			var findMax, max, maxI, i,
7839				date = new Date(2009, 12 - 1, 20), // Ensure double digits
7840				dateFormat = this._get(inst, "dateFormat");
7841
7842			if (dateFormat.match(/[DM]/)) {
7843				findMax = function(names) {
7844					max = 0;
7845					maxI = 0;
7846					for (i = 0; i < names.length; i++) {
7847						if (names[i].length > max) {
7848							max = names[i].length;
7849							maxI = i;
7850						}
7851					}
7852					return maxI;
7853				};
7854				date.setMonth(findMax(this._get(inst, (dateFormat.match(/MM/) ?
7855					"monthNames" : "monthNamesShort"))));
7856				date.setDate(findMax(this._get(inst, (dateFormat.match(/DD/) ?
7857					"dayNames" : "dayNamesShort"))) + 20 - date.getDay());
7858			}
7859			inst.input.attr("size", this._formatDate(inst, date).length);
7860		}
7861	},
7862
7863	/* Attach an inline date picker to a div. */
7864	_inlineDatepicker: function(target, inst) {
7865		var divSpan = $(target);
7866		if (divSpan.hasClass(this.markerClassName)) {
7867			return;
7868		}
7869		divSpan.addClass(this.markerClassName).append(inst.dpDiv);
7870		$.data(target, PROP_NAME, inst);
7871		this._setDate(inst, this._getDefaultDate(inst), true);
7872		this._updateDatepicker(inst);
7873		this._updateAlternate(inst);
7874		//If disabled option is true, disable the datepicker before showing it (see ticket #5665)
7875		if( inst.settings.disabled ) {
7876			this._disableDatepicker( target );
7877		}
7878		// Set display:block in place of inst.dpDiv.show() which won't work on disconnected elements
7879		// http://bugs.jqueryui.com/ticket/7552 - A Datepicker created on a detached div has zero height
7880		inst.dpDiv.css( "display", "block" );
7881	},
7882
7883	/* Pop-up the date picker in a "dialog" box.
7884	 * @param  input element - ignored
7885	 * @param  date	string or Date - the initial date to display
7886	 * @param  onSelect  function - the function to call when a date is selected
7887	 * @param  settings  object - update the dialog date picker instance's settings (anonymous object)
7888	 * @param  pos int[2] - coordinates for the dialog's position within the screen or
7889	 *					event - with x/y coordinates or
7890	 *					leave empty for default (screen centre)
7891	 * @return the manager object
7892	 */
7893	_dialogDatepicker: function(input, date, onSelect, settings, pos) {
7894		var id, browserWidth, browserHeight, scrollX, scrollY,
7895			inst = this._dialogInst; // internal instance
7896
7897		if (!inst) {
7898			this.uuid += 1;
7899			id = "dp" + this.uuid;
7900			this._dialogInput = $("<input type='text' id='" + id +
7901				"' style='position: absolute; top: -100px; width: 0px;'/>");
7902			this._dialogInput.keydown(this._doKeyDown);
7903			$("body").append(this._dialogInput);
7904			inst = this._dialogInst = this._newInst(this._dialogInput, false);
7905			inst.settings = {};
7906			$.data(this._dialogInput[0], PROP_NAME, inst);
7907		}
7908		extendRemove(inst.settings, settings || {});
7909		date = (date && date.constructor === Date ? this._formatDate(inst, date) : date);
7910		this._dialogInput.val(date);
7911
7912		this._pos = (pos ? (pos.length ? pos : [pos.pageX, pos.pageY]) : null);
7913		if (!this._pos) {
7914			browserWidth = document.documentElement.clientWidth;
7915			browserHeight = document.documentElement.clientHeight;
7916			scrollX = document.documentElement.scrollLeft || document.body.scrollLeft;
7917			scrollY = document.documentElement.scrollTop || document.body.scrollTop;
7918			this._pos = // should use actual width/height below
7919				[(browserWidth / 2) - 100 + scrollX, (browserHeight / 2) - 150 + scrollY];
7920		}
7921
7922		// move input on screen for focus, but hidden behind dialog
7923		this._dialogInput.css("left", (this._pos[0] + 20) + "px").css("top", this._pos[1] + "px");
7924		inst.settings.onSelect = onSelect;
7925		this._inDialog = true;
7926		this.dpDiv.addClass(this._dialogClass);
7927		this._showDatepicker(this._dialogInput[0]);
7928		if ($.blockUI) {
7929			$.blockUI(this.dpDiv);
7930		}
7931		$.data(this._dialogInput[0], PROP_NAME, inst);
7932		return this;
7933	},
7934
7935	/* Detach a datepicker from its control.
7936	 * @param  target	element - the target input field or division or span
7937	 */
7938	_destroyDatepicker: function(target) {
7939		var nodeName,
7940			$target = $(target),
7941			inst = $.data(target, PROP_NAME);
7942
7943		if (!$target.hasClass(this.markerClassName)) {
7944			return;
7945		}
7946
7947		nodeName = target.nodeName.toLowerCase();
7948		$.removeData(target, PROP_NAME);
7949		if (nodeName === "input") {
7950			inst.append.remove();
7951			inst.trigger.remove();
7952			$target.removeClass(this.markerClassName).
7953				unbind("focus", this._showDatepicker).
7954				unbind("keydown", this._doKeyDown).
7955				unbind("keypress", this._doKeyPress).
7956				unbind("keyup", this._doKeyUp);
7957		} else if (nodeName === "div" || nodeName === "span") {
7958			$target.removeClass(this.markerClassName).empty();
7959		}
7960	},
7961
7962	/* Enable the date picker to a jQuery selection.
7963	 * @param  target	element - the target input field or division or span
7964	 */
7965	_enableDatepicker: function(target) {
7966		var nodeName, inline,
7967			$target = $(target),
7968			inst = $.data(target, PROP_NAME);
7969
7970		if (!$target.hasClass(this.markerClassName)) {
7971			return;
7972		}
7973
7974		nodeName = target.nodeName.toLowerCase();
7975		if (nodeName === "input") {
7976			target.disabled = false;
7977			inst.trigger.filter("button").
7978				each(function() { this.disabled = false; }).end().
7979				filter("img").css({opacity: "1.0", cursor: ""});
7980		} else if (nodeName === "div" || nodeName === "span") {
7981			inline = $target.children("." + this._inlineClass);
7982			inline.children().removeClass("ui-state-disabled");
7983			inline.find("select.ui-datepicker-month, select.ui-datepicker-year").
7984				prop("disabled", false);
7985		}
7986		this._disabledInputs = $.map(this._disabledInputs,
7987			function(value) { return (value === target ? null : value); }); // delete entry
7988	},
7989
7990	/* Disable the date picker to a jQuery selection.
7991	 * @param  target	element - the target input field or division or span
7992	 */
7993	_disableDatepicker: function(target) {
7994		var nodeName, inline,
7995			$target = $(target),
7996			inst = $.data(target, PROP_NAME);
7997
7998		if (!$target.hasClass(this.markerClassName)) {
7999			return;
8000		}
8001
8002		nodeName = target.nodeName.toLowerCase();
8003		if (nodeName === "input") {
8004			target.disabled = true;
8005			inst.trigger.filter("button").
8006				each(function() { this.disabled = true; }).end().
8007				filter("img").css({opacity: "0.5", cursor: "default"});
8008		} else if (nodeName === "div" || nodeName === "span") {
8009			inline = $target.children("." + this._inlineClass);
8010			inline.children().addClass("ui-state-disabled");
8011			inline.find("select.ui-datepicker-month, select.ui-datepicker-year").
8012				prop("disabled", true);
8013		}
8014		this._disabledInputs = $.map(this._disabledInputs,
8015			function(value) { return (value === target ? null : value); }); // delete entry
8016		this._disabledInputs[this._disabledInputs.length] = target;
8017	},
8018
8019	/* Is the first field in a jQuery collection disabled as a datepicker?
8020	 * @param  target	element - the target input field or division or span
8021	 * @return boolean - true if disabled, false if enabled
8022	 */
8023	_isDisabledDatepicker: function(target) {
8024		if (!target) {
8025			return false;
8026		}
8027		for (var i = 0; i < this._disabledInputs.length; i++) {
8028			if (this._disabledInputs[i] === target) {
8029				return true;
8030			}
8031		}
8032		return false;
8033	},
8034
8035	/* Retrieve the instance data for the target control.
8036	 * @param  target  element - the target input field or division or span
8037	 * @return  object - the associated instance data
8038	 * @throws  error if a jQuery problem getting data
8039	 */
8040	_getInst: function(target) {
8041		try {
8042			return $.data(target, PROP_NAME);
8043		}
8044		catch (err) {
8045			throw "Missing instance data for this datepicker";
8046		}
8047	},
8048
8049	/* Update or retrieve the settings for a date picker attached to an input field or division.
8050	 * @param  target  element - the target input field or division or span
8051	 * @param  name	object - the new settings to update or
8052	 *				string - the name of the setting to change or retrieve,
8053	 *				when retrieving also "all" for all instance settings or
8054	 *				"defaults" for all global defaults
8055	 * @param  value   any - the new value for the setting
8056	 *				(omit if above is an object or to retrieve a value)
8057	 */
8058	_optionDatepicker: function(target, name, value) {
8059		var settings, date, minDate, maxDate,
8060			inst = this._getInst(target);
8061
8062		if (arguments.length === 2 && typeof name === "string") {
8063			return (name === "defaults" ? $.extend({}, $.datepicker._defaults) :
8064				(inst ? (name === "all" ? $.extend({}, inst.settings) :
8065				this._get(inst, name)) : null));
8066		}
8067
8068		settings = name || {};
8069		if (typeof name === "string") {
8070			settings = {};
8071			settings[name] = value;
8072		}
8073
8074		if (inst) {
8075			if (this._curInst === inst) {
8076				this._hideDatepicker();
8077			}
8078
8079			date = this._getDateDatepicker(target, true);
8080			minDate = this._getMinMaxDate(inst, "min");
8081			maxDate = this._getMinMaxDate(inst, "max");
8082			extendRemove(inst.settings, settings);
8083			// reformat the old minDate/maxDate values if dateFormat changes and a new minDate/maxDate isn't provided
8084			if (minDate !== null && settings.dateFormat !== undefined && settings.minDate === undefined) {
8085				inst.settings.minDate = this._formatDate(inst, minDate);
8086			}
8087			if (maxDate !== null && settings.dateFormat !== undefined && settings.maxDate === undefined) {
8088				inst.settings.maxDate = this._formatDate(inst, maxDate);
8089			}
8090			if ( "disabled" in settings ) {
8091				if ( settings.disabled ) {
8092					this._disableDatepicker(target);
8093				} else {
8094					this._enableDatepicker(target);
8095				}
8096			}
8097			this._attachments($(target), inst);
8098			this._autoSize(inst);
8099			this._setDate(inst, date);
8100			this._updateAlternate(inst);
8101			this._updateDatepicker(inst);
8102		}
8103	},
8104
8105	// change method deprecated
8106	_changeDatepicker: function(target, name, value) {
8107		this._optionDatepicker(target, name, value);
8108	},
8109
8110	/* Redraw the date picker attached to an input field or division.
8111	 * @param  target  element - the target input field or division or span
8112	 */
8113	_refreshDatepicker: function(target) {
8114		var inst = this._getInst(target);
8115		if (inst) {
8116			this._updateDatepicker(inst);
8117		}
8118	},
8119
8120	/* Set the dates for a jQuery selection.
8121	 * @param  target element - the target input field or division or span
8122	 * @param  date	Date - the new date
8123	 */
8124	_setDateDatepicker: function(target, date) {
8125		var inst = this._getInst(target);
8126		if (inst) {
8127			this._setDate(inst, date);
8128			this._updateDatepicker(inst);
8129			this._updateAlternate(inst);
8130		}
8131	},
8132
8133	/* Get the date(s) for the first entry in a jQuery selection.
8134	 * @param  target element - the target input field or division or span
8135	 * @param  noDefault boolean - true if no default date is to be used
8136	 * @return Date - the current date
8137	 */
8138	_getDateDatepicker: function(target, noDefault) {
8139		var inst = this._getInst(target);
8140		if (inst && !inst.inline) {
8141			this._setDateFromField(inst, noDefault);
8142		}
8143		return (inst ? this._getDate(inst) : null);
8144	},
8145
8146	/* Handle keystrokes. */
8147	_doKeyDown: function(event) {
8148		var onSelect, dateStr, sel,
8149			inst = $.datepicker._getInst(event.target),
8150			handled = true,
8151			isRTL = inst.dpDiv.is(".ui-datepicker-rtl");
8152
8153		inst._keyEvent = true;
8154		if ($.datepicker._datepickerShowing) {
8155			switch (event.keyCode) {
8156				case 9: $.datepicker._hideDatepicker();
8157						handled = false;
8158						break; // hide on tab out
8159				case 13: sel = $("td." + $.datepicker._dayOverClass + ":not(." +
8160									$.datepicker._currentClass + ")", inst.dpDiv);
8161						if (sel[0]) {
8162							$.datepicker._selectDay(event.target, inst.selectedMonth, inst.selectedYear, sel[0]);
8163						}
8164
8165						onSelect = $.datepicker._get(inst, "onSelect");
8166						if (onSelect) {
8167							dateStr = $.datepicker._formatDate(inst);
8168
8169							// trigger custom callback
8170							onSelect.apply((inst.input ? inst.input[0] : null), [dateStr, inst]);
8171						} else {
8172							$.datepicker._hideDatepicker();
8173						}
8174
8175						return false; // don't submit the form
8176				case 27: $.datepicker._hideDatepicker();
8177						break; // hide on escape
8178				case 33: $.datepicker._adjustDate(event.target, (event.ctrlKey ?
8179							-$.datepicker._get(inst, "stepBigMonths") :
8180							-$.datepicker._get(inst, "stepMonths")), "M");
8181						break; // previous month/year on page up/+ ctrl
8182				case 34: $.datepicker._adjustDate(event.target, (event.ctrlKey ?
8183							+$.datepicker._get(inst, "stepBigMonths") :
8184							+$.datepicker._get(inst, "stepMonths")), "M");
8185						break; // next month/year on page down/+ ctrl
8186				case 35: if (event.ctrlKey || event.metaKey) {
8187							$.datepicker._clearDate(event.target);
8188						}
8189						handled = event.ctrlKey || event.metaKey;
8190						break; // clear on ctrl or command +end
8191				case 36: if (event.ctrlKey || event.metaKey) {
8192							$.datepicker._gotoToday(event.target);
8193						}
8194						handled = event.ctrlKey || event.metaKey;
8195						break; // current on ctrl or command +home
8196				case 37: if (event.ctrlKey || event.metaKey) {
8197							$.datepicker._adjustDate(event.target, (isRTL ? +1 : -1), "D");
8198						}
8199						handled = event.ctrlKey || event.metaKey;
8200						// -1 day on ctrl or command +left
8201						if (event.originalEvent.altKey) {
8202							$.datepicker._adjustDate(event.target, (event.ctrlKey ?
8203								-$.datepicker._get(inst, "stepBigMonths") :
8204								-$.datepicker._get(inst, "stepMonths")), "M");
8205						}
8206						// next month/year on alt +left on Mac
8207						break;
8208				case 38: if (event.ctrlKey || event.metaKey) {
8209							$.datepicker._adjustDate(event.target, -7, "D");
8210						}
8211						handled = event.ctrlKey || event.metaKey;
8212						break; // -1 week on ctrl or command +up
8213				case 39: if (event.ctrlKey || event.metaKey) {
8214							$.datepicker._adjustDate(event.target, (isRTL ? -1 : +1), "D");
8215						}
8216						handled = event.ctrlKey || event.metaKey;
8217						// +1 day on ctrl or command +right
8218						if (event.originalEvent.altKey) {
8219							$.datepicker._adjustDate(event.target, (event.ctrlKey ?
8220								+$.datepicker._get(inst, "stepBigMonths") :
8221								+$.datepicker._get(inst, "stepMonths")), "M");
8222						}
8223						// next month/year on alt +right
8224						break;
8225				case 40: if (event.ctrlKey || event.metaKey) {
8226							$.datepicker._adjustDate(event.target, +7, "D");
8227						}
8228						handled = event.ctrlKey || event.metaKey;
8229						break; // +1 week on ctrl or command +down
8230				default: handled = false;
8231			}
8232		} else if (event.keyCode === 36 && event.ctrlKey) { // display the date picker on ctrl+home
8233			$.datepicker._showDatepicker(this);
8234		} else {
8235			handled = false;
8236		}
8237
8238		if (handled) {
8239			event.preventDefault();
8240			event.stopPropagation();
8241		}
8242	},
8243
8244	/* Filter entered characters - based on date format. */
8245	_doKeyPress: function(event) {
8246		var chars, chr,
8247			inst = $.datepicker._getInst(event.target);
8248
8249		if ($.datepicker._get(inst, "constrainInput")) {
8250			chars = $.datepicker._possibleChars($.datepicker._get(inst, "dateFormat"));
8251			chr = String.fromCharCode(event.charCode == null ? event.keyCode : event.charCode);
8252			return event.ctrlKey || event.metaKey || (chr < " " || !chars || chars.indexOf(chr) > -1);
8253		}
8254	},
8255
8256	/* Synchronise manual entry and field/alternate field. */
8257	_doKeyUp: function(event) {
8258		var date,
8259			inst = $.datepicker._getInst(event.target);
8260
8261		if (inst.input.val() !== inst.lastVal) {
8262			try {
8263				date = $.datepicker.parseDate($.datepicker._get(inst, "dateFormat"),
8264					(inst.input ? inst.input.val() : null),
8265					$.datepicker._getFormatConfig(inst));
8266
8267				if (date) { // only if valid
8268					$.datepicker._setDateFromField(inst);
8269					$.datepicker._updateAlternate(inst);
8270					$.datepicker._updateDatepicker(inst);
8271				}
8272			}
8273			catch (err) {
8274			}
8275		}
8276		return true;
8277	},
8278
8279	/* Pop-up the date picker for a given input field.
8280	 * If false returned from beforeShow event handler do not show.
8281	 * @param  input  element - the input field attached to the date picker or
8282	 *					event - if triggered by focus
8283	 */
8284	_showDatepicker: function(input) {
8285		input = input.target || input;
8286		if (input.nodeName.toLowerCase() !== "input") { // find from button/image trigger
8287			input = $("input", input.parentNode)[0];
8288		}
8289
8290		if ($.datepicker._isDisabledDatepicker(input) || $.datepicker._lastInput === input) { // already here
8291			return;
8292		}
8293
8294		var inst, beforeShow, beforeShowSettings, isFixed,
8295			offset, showAnim, duration;
8296
8297		inst = $.datepicker._getInst(input);
8298		if ($.datepicker._curInst && $.datepicker._curInst !== inst) {
8299			$.datepicker._curInst.dpDiv.stop(true, true);
8300			if ( inst && $.datepicker._datepickerShowing ) {
8301				$.datepicker._hideDatepicker( $.datepicker._curInst.input[0] );
8302			}
8303		}
8304
8305		beforeShow = $.datepicker._get(inst, "beforeShow");
8306		beforeShowSettings = beforeShow ? beforeShow.apply(input, [input, inst]) : {};
8307		if(beforeShowSettings === false){
8308			return;
8309		}
8310		extendRemove(inst.settings, beforeShowSettings);
8311
8312		inst.lastVal = null;
8313		$.datepicker._lastInput = input;
8314		$.datepicker._setDateFromField(inst);
8315
8316		if ($.datepicker._inDialog) { // hide cursor
8317			input.value = "";
8318		}
8319		if (!$.datepicker._pos) { // position below input
8320			$.datepicker._pos = $.datepicker._findPos(input);
8321			$.datepicker._pos[1] += input.offsetHeight; // add the height
8322		}
8323
8324		isFixed = false;
8325		$(input).parents().each(function() {
8326			isFixed |= $(this).css("position") === "fixed";
8327			return !isFixed;
8328		});
8329
8330		offset = {left: $.datepicker._pos[0], top: $.datepicker._pos[1]};
8331		$.datepicker._pos = null;
8332		//to avoid flashes on Firefox
8333		inst.dpDiv.empty();
8334		// determine sizing offscreen
8335		inst.dpDiv.css({position: "absolute", display: "block", top: "-1000px"});
8336		$.datepicker._updateDatepicker(inst);
8337		// fix width for dynamic number of date pickers
8338		// and adjust position before showing
8339		offset = $.datepicker._checkOffset(inst, offset, isFixed);
8340		inst.dpDiv.css({position: ($.datepicker._inDialog && $.blockUI ?
8341			"static" : (isFixed ? "fixed" : "absolute")), display: "none",
8342			left: offset.left + "px", top: offset.top + "px"});
8343
8344		if (!inst.inline) {
8345			showAnim = $.datepicker._get(inst, "showAnim");
8346			duration = $.datepicker._get(inst, "duration");
8347			inst.dpDiv.zIndex($(input).zIndex()+1);
8348			$.datepicker._datepickerShowing = true;
8349
8350			if ( $.effects && $.effects.effect[ showAnim ] ) {
8351				inst.dpDiv.show(showAnim, $.datepicker._get(inst, "showOptions"), duration);
8352			} else {
8353				inst.dpDiv[showAnim || "show"](showAnim ? duration : null);
8354			}
8355
8356			if ( $.datepicker._shouldFocusInput( inst ) ) {
8357				inst.input.focus();
8358			}
8359
8360			$.datepicker._curInst = inst;
8361		}
8362	},
8363
8364	/* Generate the date picker content. */
8365	_updateDatepicker: function(inst) {
8366		this.maxRows = 4; //Reset the max number of rows being displayed (see #7043)
8367		instActive = inst; // for delegate hover events
8368		inst.dpDiv.empty().append(this._generateHTML(inst));
8369		this._attachHandlers(inst);
8370		inst.dpDiv.find("." + this._dayOverClass + " a").mouseover();
8371
8372		var origyearshtml,
8373			numMonths = this._getNumberOfMonths(inst),
8374			cols = numMonths[1],
8375			width = 17;
8376
8377		inst.dpDiv.removeClass("ui-datepicker-multi-2 ui-datepicker-multi-3 ui-datepicker-multi-4").width("");
8378		if (cols > 1) {
8379			inst.dpDiv.addClass("ui-datepicker-multi-" + cols).css("width", (width * cols) + "em");
8380		}
8381		inst.dpDiv[(numMonths[0] !== 1 || numMonths[1] !== 1 ? "add" : "remove") +
8382			"Class"]("ui-datepicker-multi");
8383		inst.dpDiv[(this._get(inst, "isRTL") ? "add" : "remove") +
8384			"Class"]("ui-datepicker-rtl");
8385
8386		if (inst === $.datepicker._curInst && $.datepicker._datepickerShowing && $.datepicker._shouldFocusInput( inst ) ) {
8387			inst.input.focus();
8388		}
8389
8390		// deffered render of the years select (to avoid flashes on Firefox)
8391		if( inst.yearshtml ){
8392			origyearshtml = inst.yearshtml;
8393			setTimeout(function(){
8394				//assure that inst.yearshtml didn't change.
8395				if( origyearshtml === inst.yearshtml && inst.yearshtml ){
8396					inst.dpDiv.find("select.ui-datepicker-year:first").replaceWith(inst.yearshtml);
8397				}
8398				origyearshtml = inst.yearshtml = null;
8399			}, 0);
8400		}
8401	},
8402
8403	// #6694 - don't focus the input if it's already focused
8404	// this breaks the change event in IE
8405	// Support: IE and jQuery <1.9
8406	_shouldFocusInput: function( inst ) {
8407		return inst.input && inst.input.is( ":visible" ) && !inst.input.is( ":disabled" ) && !inst.input.is( ":focus" );
8408	},
8409
8410	/* Check positioning to remain on screen. */
8411	_checkOffset: function(inst, offset, isFixed) {
8412		var dpWidth = inst.dpDiv.outerWidth(),
8413			dpHeight = inst.dpDiv.outerHeight(),
8414			inputWidth = inst.input ? inst.input.outerWidth() : 0,
8415			inputHeight = inst.input ? inst.input.outerHeight() : 0,
8416			viewWidth = document.documentElement.clientWidth + (isFixed ? 0 : $(document).scrollLeft()),
8417			viewHeight = document.documentElement.clientHeight + (isFixed ? 0 : $(document).scrollTop());
8418
8419		offset.left -= (this._get(inst, "isRTL") ? (dpWidth - inputWidth) : 0);
8420		offset.left -= (isFixed && offset.left === inst.input.offset().left) ? $(document).scrollLeft() : 0;
8421		offset.top -= (isFixed && offset.top === (inst.input.offset().top + inputHeight)) ? $(document).scrollTop() : 0;
8422
8423		// now check if datepicker is showing outside window viewport - move to a better place if so.
8424		offset.left -= Math.min(offset.left, (offset.left + dpWidth > viewWidth && viewWidth > dpWidth) ?
8425			Math.abs(offset.left + dpWidth - viewWidth) : 0);
8426		offset.top -= Math.min(offset.top, (offset.top + dpHeight > viewHeight && viewHeight > dpHeight) ?
8427			Math.abs(dpHeight + inputHeight) : 0);
8428
8429		return offset;
8430	},
8431
8432	/* Find an object's position on the screen. */
8433	_findPos: function(obj) {
8434		var position,
8435			inst = this._getInst(obj),
8436			isRTL = this._get(inst, "isRTL");
8437
8438		while (obj && (obj.type === "hidden" || obj.nodeType !== 1 || $.expr.filters.hidden(obj))) {
8439			obj = obj[isRTL ? "previousSibling" : "nextSibling"];
8440		}
8441
8442		position = $(obj).offset();
8443		return [position.left, position.top];
8444	},
8445
8446	/* Hide the date picker from view.
8447	 * @param  input  element - the input field attached to the date picker
8448	 */
8449	_hideDatepicker: function(input) {
8450		var showAnim, duration, postProcess, onClose,
8451			inst = this._curInst;
8452
8453		if (!inst || (input && inst !== $.data(input, PROP_NAME))) {
8454			return;
8455		}
8456
8457		if (this._datepickerShowing) {
8458			showAnim = this._get(inst, "showAnim");
8459			duration = this._get(inst, "duration");
8460			postProcess = function() {
8461				$.datepicker._tidyDialog(inst);
8462			};
8463
8464			// DEPRECATED: after BC for 1.8.x $.effects[ showAnim ] is not needed
8465			if ( $.effects && ( $.effects.effect[ showAnim ] || $.effects[ showAnim ] ) ) {
8466				inst.dpDiv.hide(showAnim, $.datepicker._get(inst, "showOptions"), duration, postProcess);
8467			} else {
8468				inst.dpDiv[(showAnim === "slideDown" ? "slideUp" :
8469					(showAnim === "fadeIn" ? "fadeOut" : "hide"))]((showAnim ? duration : null), postProcess);
8470			}
8471
8472			if (!showAnim) {
8473				postProcess();
8474			}
8475			this._datepickerShowing = false;
8476
8477			onClose = this._get(inst, "onClose");
8478			if (onClose) {
8479				onClose.apply((inst.input ? inst.input[0] : null), [(inst.input ? inst.input.val() : ""), inst]);
8480			}
8481
8482			this._lastInput = null;
8483			if (this._inDialog) {
8484				this._dialogInput.css({ position: "absolute", left: "0", top: "-100px" });
8485				if ($.blockUI) {
8486					$.unblockUI();
8487					$("body").append(this.dpDiv);
8488				}
8489			}
8490			this._inDialog = false;
8491		}
8492	},
8493
8494	/* Tidy up after a dialog display. */
8495	_tidyDialog: function(inst) {
8496		inst.dpDiv.removeClass(this._dialogClass).unbind(".ui-datepicker-calendar");
8497	},
8498
8499	/* Close date picker if clicked elsewhere. */
8500	_checkExternalClick: function(event) {
8501		if (!$.datepicker._curInst) {
8502			return;
8503		}
8504
8505		var $target = $(event.target),
8506			inst = $.datepicker._getInst($target[0]);
8507
8508		if ( ( ( $target[0].id !== $.datepicker._mainDivId &&
8509				$target.parents("#" + $.datepicker._mainDivId).length === 0 &&
8510				!$target.hasClass($.datepicker.markerClassName) &&
8511				!$target.closest("." + $.datepicker._triggerClass).length &&
8512				$.datepicker._datepickerShowing && !($.datepicker._inDialog && $.blockUI) ) ) ||
8513			( $target.hasClass($.datepicker.markerClassName) && $.datepicker._curInst !== inst ) ) {
8514				$.datepicker._hideDatepicker();
8515		}
8516	},
8517
8518	/* Adjust one of the date sub-fields. */
8519	_adjustDate: function(id, offset, period) {
8520		var target = $(id),
8521			inst = this._getInst(target[0]);
8522
8523		if (this._isDisabledDatepicker(target[0])) {
8524			return;
8525		}
8526		this._adjustInstDate(inst, offset +
8527			(period === "M" ? this._get(inst, "showCurrentAtPos") : 0), // undo positioning
8528			period);
8529		this._updateDatepicker(inst);
8530	},
8531
8532	/* Action for current link. */
8533	_gotoToday: function(id) {
8534		var date,
8535			target = $(id),
8536			inst = this._getInst(target[0]);
8537
8538		if (this._get(inst, "gotoCurrent") && inst.currentDay) {
8539			inst.selectedDay = inst.currentDay;
8540			inst.drawMonth = inst.selectedMonth = inst.currentMonth;
8541			inst.drawYear = inst.selectedYear = inst.currentYear;
8542		} else {
8543			date = new Date();
8544			inst.selectedDay = date.getDate();
8545			inst.drawMonth = inst.selectedMonth = date.getMonth();
8546			inst.drawYear = inst.selectedYear = date.getFullYear();
8547		}
8548		this._notifyChange(inst);
8549		this._adjustDate(target);
8550	},
8551
8552	/* Action for selecting a new month/year. */
8553	_selectMonthYear: function(id, select, period) {
8554		var target = $(id),
8555			inst = this._getInst(target[0]);
8556
8557		inst["selected" + (period === "M" ? "Month" : "Year")] =
8558		inst["draw" + (period === "M" ? "Month" : "Year")] =
8559			parseInt(select.options[select.selectedIndex].value,10);
8560
8561		this._notifyChange(inst);
8562		this._adjustDate(target);
8563	},
8564
8565	/* Action for selecting a day. */
8566	_selectDay: function(id, month, year, td) {
8567		var inst,
8568			target = $(id);
8569
8570		if ($(td).hasClass(this._unselectableClass) || this._isDisabledDatepicker(target[0])) {
8571			return;
8572		}
8573
8574		inst = this._getInst(target[0]);
8575		inst.selectedDay = inst.currentDay = $("a", td).html();
8576		inst.selectedMonth = inst.currentMonth = month;
8577		inst.selectedYear = inst.currentYear = year;
8578		this._selectDate(id, this._formatDate(inst,
8579			inst.currentDay, inst.currentMonth, inst.currentYear));
8580	},
8581
8582	/* Erase the input field and hide the date picker. */
8583	_clearDate: function(id) {
8584		var target = $(id);
8585		this._selectDate(target, "");
8586	},
8587
8588	/* Update the input field with the selected date. */
8589	_selectDate: function(id, dateStr) {
8590		var onSelect,
8591			target = $(id),
8592			inst = this._getInst(target[0]);
8593
8594		dateStr = (dateStr != null ? dateStr : this._formatDate(inst));
8595		if (inst.input) {
8596			inst.input.val(dateStr);
8597		}
8598		this._updateAlternate(inst);
8599
8600		onSelect = this._get(inst, "onSelect");
8601		if (onSelect) {
8602			onSelect.apply((inst.input ? inst.input[0] : null), [dateStr, inst]);  // trigger custom callback
8603		} else if (inst.input) {
8604			inst.input.trigger("change"); // fire the change event
8605		}
8606
8607		if (inst.inline){
8608			this._updateDatepicker(inst);
8609		} else {
8610			this._hideDatepicker();
8611			this._lastInput = inst.input[0];
8612			if (typeof(inst.input[0]) !== "object") {
8613				inst.input.focus(); // restore focus
8614			}
8615			this._lastInput = null;
8616		}
8617	},
8618
8619	/* Update any alternate field to synchronise with the main field. */
8620	_updateAlternate: function(inst) {
8621		var altFormat, date, dateStr,
8622			altField = this._get(inst, "altField");
8623
8624		if (altField) { // update alternate field too
8625			altFormat = this._get(inst, "altFormat") || this._get(inst, "dateFormat");
8626			date = this._getDate(inst);
8627			dateStr = this.formatDate(altFormat, date, this._getFormatConfig(inst));
8628			$(altField).each(function() { $(this).val(dateStr); });
8629		}
8630	},
8631
8632	/* Set as beforeShowDay function to prevent selection of weekends.
8633	 * @param  date  Date - the date to customise
8634	 * @return [boolean, string] - is this date selectable?, what is its CSS class?
8635	 */
8636	noWeekends: function(date) {
8637		var day = date.getDay();
8638		return [(day > 0 && day < 6), ""];
8639	},
8640
8641	/* Set as calculateWeek to determine the week of the year based on the ISO 8601 definition.
8642	 * @param  date  Date - the date to get the week for
8643	 * @return  number - the number of the week within the year that contains this date
8644	 */
8645	iso8601Week: function(date) {
8646		var time,
8647			checkDate = new Date(date.getTime());
8648
8649		// Find Thursday of this week starting on Monday
8650		checkDate.setDate(checkDate.getDate() + 4 - (checkDate.getDay() || 7));
8651
8652		time = checkDate.getTime();
8653		checkDate.setMonth(0); // Compare with Jan 1
8654		checkDate.setDate(1);
8655		return Math.floor(Math.round((time - checkDate) / 86400000) / 7) + 1;
8656	},
8657
8658	/* Parse a string value into a date object.
8659	 * See formatDate below for the possible formats.
8660	 *
8661	 * @param  format string - the expected format of the date
8662	 * @param  value string - the date in the above format
8663	 * @param  settings Object - attributes include:
8664	 *					shortYearCutoff  number - the cutoff year for determining the century (optional)
8665	 *					dayNamesShort	string[7] - abbreviated names of the days from Sunday (optional)
8666	 *					dayNames		string[7] - names of the days from Sunday (optional)
8667	 *					monthNamesShort string[12] - abbreviated names of the months (optional)
8668	 *					monthNames		string[12] - names of the months (optional)
8669	 * @return  Date - the extracted date value or null if value is blank
8670	 */
8671	parseDate: function (format, value, settings) {
8672		if (format == null || value == null) {
8673			throw "Invalid arguments";
8674		}
8675
8676		value = (typeof value === "object" ? value.toString() : value + "");
8677		if (value === "") {
8678			return null;
8679		}
8680
8681		var iFormat, dim, extra,
8682			iValue = 0,
8683			shortYearCutoffTemp = (settings ? settings.shortYearCutoff : null) || this._defaults.shortYearCutoff,
8684			shortYearCutoff = (typeof shortYearCutoffTemp !== "string" ? shortYearCutoffTemp :
8685				new Date().getFullYear() % 100 + parseInt(shortYearCutoffTemp, 10)),
8686			dayNamesShort = (settings ? settings.dayNamesShort : null) || this._defaults.dayNamesShort,
8687			dayNames = (settings ? settings.dayNames : null) || this._defaults.dayNames,
8688			monthNamesShort = (settings ? settings.monthNamesShort : null) || this._defaults.monthNamesShort,
8689			monthNames = (settings ? settings.monthNames : null) || this._defaults.monthNames,
8690			year = -1,
8691			month = -1,
8692			day = -1,
8693			doy = -1,
8694			literal = false,
8695			date,
8696			// Check whether a format character is doubled
8697			lookAhead = function(match) {
8698				var matches = (iFormat + 1 < format.length && format.charAt(iFormat + 1) === match);
8699				if (matches) {
8700					iFormat++;
8701				}
8702				return matches;
8703			},
8704			// Extract a number from the string value
8705			getNumber = function(match) {
8706				var isDoubled = lookAhead(match),
8707					size = (match === "@" ? 14 : (match === "!" ? 20 :
8708					(match === "y" && isDoubled ? 4 : (match === "o" ? 3 : 2)))),
8709					digits = new RegExp("^\\d{1," + size + "}"),
8710					num = value.substring(iValue).match(digits);
8711				if (!num) {
8712					throw "Missing number at position " + iValue;
8713				}
8714				iValue += num[0].length;
8715				return parseInt(num[0], 10);
8716			},
8717			// Extract a name from the string value and convert to an index
8718			getName = function(match, shortNames, longNames) {
8719				var index = -1,
8720					names = $.map(lookAhead(match) ? longNames : shortNames, function (v, k) {
8721						return [ [k, v] ];
8722					}).sort(function (a, b) {
8723						return -(a[1].length - b[1].length);
8724					});
8725
8726				$.each(names, function (i, pair) {
8727					var name = pair[1];
8728					if (value.substr(iValue, name.length).toLowerCase() === name.toLowerCase()) {
8729						index = pair[0];
8730						iValue += name.length;
8731						return false;
8732					}
8733				});
8734				if (index !== -1) {
8735					return index + 1;
8736				} else {
8737					throw "Unknown name at position " + iValue;
8738				}
8739			},
8740			// Confirm that a literal character matches the string value
8741			checkLiteral = function() {
8742				if (value.charAt(iValue) !== format.charAt(iFormat)) {
8743					throw "Unexpected literal at position " + iValue;
8744				}
8745				iValue++;
8746			};
8747
8748		for (iFormat = 0; iFormat < format.length; iFormat++) {
8749			if (literal) {
8750				if (format.charAt(iFormat) === "'" && !lookAhead("'")) {
8751					literal = false;
8752				} else {
8753					checkLiteral();
8754				}
8755			} else {
8756				switch (format.charAt(iFormat)) {
8757					case "d":
8758						day = getNumber("d");
8759						break;
8760					case "D":
8761						getName("D", dayNamesShort, dayNames);
8762						break;
8763					case "o":
8764						doy = getNumber("o");
8765						break;
8766					case "m":
8767						month = getNumber("m");
8768						break;
8769					case "M":
8770						month = getName("M", monthNamesShort, monthNames);
8771						break;
8772					case "y":
8773						year = getNumber("y");
8774						break;
8775					case "@":
8776						date = new Date(getNumber("@"));
8777						year = date.getFullYear();
8778						month = date.getMonth() + 1;
8779						day = date.getDate();
8780						break;
8781					case "!":
8782						date = new Date((getNumber("!") - this._ticksTo1970) / 10000);
8783						year = date.getFullYear();
8784						month = date.getMonth() + 1;
8785						day = date.getDate();
8786						break;
8787					case "'":
8788						if (lookAhead("'")){
8789							checkLiteral();
8790						} else {
8791							literal = true;
8792						}
8793						break;
8794					default:
8795						checkLiteral();
8796				}
8797			}
8798		}
8799
8800		if (iValue < value.length){
8801			extra = value.substr(iValue);
8802			if (!/^\s+/.test(extra)) {
8803				throw "Extra/unparsed characters found in date: " + extra;
8804			}
8805		}
8806
8807		if (year === -1) {
8808			year = new Date().getFullYear();
8809		} else if (year < 100) {
8810			year += new Date().getFullYear() - new Date().getFullYear() % 100 +
8811				(year <= shortYearCutoff ? 0 : -100);
8812		}
8813
8814		if (doy > -1) {
8815			month = 1;
8816			day = doy;
8817			do {
8818				dim = this._getDaysInMonth(year, month - 1);
8819				if (day <= dim) {
8820					break;
8821				}
8822				month++;
8823				day -= dim;
8824			} while (true);
8825		}
8826
8827		date = this._daylightSavingAdjust(new Date(year, month - 1, day));
8828		if (date.getFullYear() !== year || date.getMonth() + 1 !== month || date.getDate() !== day) {
8829			throw "Invalid date"; // E.g. 31/02/00
8830		}
8831		return date;
8832	},
8833
8834	/* Standard date formats. */
8835	ATOM: "yy-mm-dd", // RFC 3339 (ISO 8601)
8836	COOKIE: "D, dd M yy",
8837	ISO_8601: "yy-mm-dd",
8838	RFC_822: "D, d M y",
8839	RFC_850: "DD, dd-M-y",
8840	RFC_1036: "D, d M y",
8841	RFC_1123: "D, d M yy",
8842	RFC_2822: "D, d M yy",
8843	RSS: "D, d M y", // RFC 822
8844	TICKS: "!",
8845	TIMESTAMP: "@",
8846	W3C: "yy-mm-dd", // ISO 8601
8847
8848	_ticksTo1970: (((1970 - 1) * 365 + Math.floor(1970 / 4) - Math.floor(1970 / 100) +
8849		Math.floor(1970 / 400)) * 24 * 60 * 60 * 10000000),
8850
8851	/* Format a date object into a string value.
8852	 * The format can be combinations of the following:
8853	 * d  - day of month (no leading zero)
8854	 * dd - day of month (two digit)
8855	 * o  - day of year (no leading zeros)
8856	 * oo - day of year (three digit)
8857	 * D  - day name short
8858	 * DD - day name long
8859	 * m  - month of year (no leading zero)
8860	 * mm - month of year (two digit)
8861	 * M  - month name short
8862	 * MM - month name long
8863	 * y  - year (two digit)
8864	 * yy - year (four digit)
8865	 * @ - Unix timestamp (ms since 01/01/1970)
8866	 * ! - Windows ticks (100ns since 01/01/0001)
8867	 * "..." - literal text
8868	 * '' - single quote
8869	 *
8870	 * @param  format string - the desired format of the date
8871	 * @param  date Date - the date value to format
8872	 * @param  settings Object - attributes include:
8873	 *					dayNamesShort	string[7] - abbreviated names of the days from Sunday (optional)
8874	 *					dayNames		string[7] - names of the days from Sunday (optional)
8875	 *					monthNamesShort string[12] - abbreviated names of the months (optional)
8876	 *					monthNames		string[12] - names of the months (optional)
8877	 * @return  string - the date in the above format
8878	 */
8879	formatDate: function (format, date, settings) {
8880		if (!date) {
8881			return "";
8882		}
8883
8884		var iFormat,
8885			dayNamesShort = (settings ? settings.dayNamesShort : null) || this._defaults.dayNamesShort,
8886			dayNames = (settings ? settings.dayNames : null) || this._defaults.dayNames,
8887			monthNamesShort = (settings ? settings.monthNamesShort : null) || this._defaults.monthNamesShort,
8888			monthNames = (settings ? settings.monthNames : null) || this._defaults.monthNames,
8889			// Check whether a format character is doubled
8890			lookAhead = function(match) {
8891				var matches = (iFormat + 1 < format.length && format.charAt(iFormat + 1) === match);
8892				if (matches) {
8893					iFormat++;
8894				}
8895				return matches;
8896			},
8897			// Format a number, with leading zero if necessary
8898			formatNumber = function(match, value, len) {
8899				var num = "" + value;
8900				if (lookAhead(match)) {
8901					while (num.length < len) {
8902						num = "0" + num;
8903					}
8904				}
8905				return num;
8906			},
8907			// Format a name, short or long as requested
8908			formatName = function(match, value, shortNames, longNames) {
8909				return (lookAhead(match) ? longNames[value] : shortNames[value]);
8910			},
8911			output = "",
8912			literal = false;
8913
8914		if (date) {
8915			for (iFormat = 0; iFormat < format.length; iFormat++) {
8916				if (literal) {
8917					if (format.charAt(iFormat) === "'" && !lookAhead("'")) {
8918						literal = false;
8919					} else {
8920						output += format.charAt(iFormat);
8921					}
8922				} else {
8923					switch (format.charAt(iFormat)) {
8924						case "d":
8925							output += formatNumber("d", date.getDate(), 2);
8926							break;
8927						case "D":
8928							output += formatName("D", date.getDay(), dayNamesShort, dayNames);
8929							break;
8930						case "o":
8931							output += formatNumber("o",
8932								Math.round((new Date(date.getFullYear(), date.getMonth(), date.getDate()).getTime() - new Date(date.getFullYear(), 0, 0).getTime()) / 86400000), 3);
8933							break;
8934						case "m":
8935							output += formatNumber("m", date.getMonth() + 1, 2);
8936							break;
8937						case "M":
8938							output += formatName("M", date.getMonth(), monthNamesShort, monthNames);
8939							break;
8940						case "y":
8941							output += (lookAhead("y") ? date.getFullYear() :
8942								(date.getYear() % 100 < 10 ? "0" : "") + date.getYear() % 100);
8943							break;
8944						case "@":
8945							output += date.getTime();
8946							break;
8947						case "!":
8948							output += date.getTime() * 10000 + this._ticksTo1970;
8949							break;
8950						case "'":
8951							if (lookAhead("'")) {
8952								output += "'";
8953							} else {
8954								literal = true;
8955							}
8956							break;
8957						default:
8958							output += format.charAt(iFormat);
8959					}
8960				}
8961			}
8962		}
8963		return output;
8964	},
8965
8966	/* Extract all possible characters from the date format. */
8967	_possibleChars: function (format) {
8968		var iFormat,
8969			chars = "",
8970			literal = false,
8971			// Check whether a format character is doubled
8972			lookAhead = function(match) {
8973				var matches = (iFormat + 1 < format.length && format.charAt(iFormat + 1) === match);
8974				if (matches) {
8975					iFormat++;
8976				}
8977				return matches;
8978			};
8979
8980		for (iFormat = 0; iFormat < format.length; iFormat++) {
8981			if (literal) {
8982				if (format.charAt(iFormat) === "'" && !lookAhead("'")) {
8983					literal = false;
8984				} else {
8985					chars += format.charAt(iFormat);
8986				}
8987			} else {
8988				switch (format.charAt(iFormat)) {
8989					case "d": case "m": case "y": case "@":
8990						chars += "0123456789";
8991						break;
8992					case "D": case "M":
8993						return null; // Accept anything
8994					case "'":
8995						if (lookAhead("'")) {
8996							chars += "'";
8997						} else {
8998							literal = true;
8999						}
9000						break;
9001					default:
9002						chars += format.charAt(iFormat);
9003				}
9004			}
9005		}
9006		return chars;
9007	},
9008
9009	/* Get a setting value, defaulting if necessary. */
9010	_get: function(inst, name) {
9011		return inst.settings[name] !== undefined ?
9012			inst.settings[name] : this._defaults[name];
9013	},
9014
9015	/* Parse existing date and initialise date picker. */
9016	_setDateFromField: function(inst, noDefault) {
9017		if (inst.input.val() === inst.lastVal) {
9018			return;
9019		}
9020
9021		var dateFormat = this._get(inst, "dateFormat"),
9022			dates = inst.lastVal = inst.input ? inst.input.val() : null,
9023			defaultDate = this._getDefaultDate(inst),
9024			date = defaultDate,
9025			settings = this._getFormatConfig(inst);
9026
9027		try {
9028			date = this.parseDate(dateFormat, dates, settings) || defaultDate;
9029		} catch (event) {
9030			dates = (noDefault ? "" : dates);
9031		}
9032		inst.selectedDay = date.getDate();
9033		inst.drawMonth = inst.selectedMonth = date.getMonth();
9034		inst.drawYear = inst.selectedYear = date.getFullYear();
9035		inst.currentDay = (dates ? date.getDate() : 0);
9036		inst.currentMonth = (dates ? date.getMonth() : 0);
9037		inst.currentYear = (dates ? date.getFullYear() : 0);
9038		this._adjustInstDate(inst);
9039	},
9040
9041	/* Retrieve the default date shown on opening. */
9042	_getDefaultDate: function(inst) {
9043		return this._restrictMinMax(inst,
9044			this._determineDate(inst, this._get(inst, "defaultDate"), new Date()));
9045	},
9046
9047	/* A date may be specified as an exact value or a relative one. */
9048	_determineDate: function(inst, date, defaultDate) {
9049		var offsetNumeric = function(offset) {
9050				var date = new Date();
9051				date.setDate(date.getDate() + offset);
9052				return date;
9053			},
9054			offsetString = function(offset) {
9055				try {
9056					return $.datepicker.parseDate($.datepicker._get(inst, "dateFormat"),
9057						offset, $.datepicker._getFormatConfig(inst));
9058				}
9059				catch (e) {
9060					// Ignore
9061				}
9062
9063				var date = (offset.toLowerCase().match(/^c/) ?
9064					$.datepicker._getDate(inst) : null) || new Date(),
9065					year = date.getFullYear(),
9066					month = date.getMonth(),
9067					day = date.getDate(),
9068					pattern = /([+\-]?[0-9]+)\s*(d|D|w|W|m|M|y|Y)?/g,
9069					matches = pattern.exec(offset);
9070
9071				while (matches) {
9072					switch (matches[2] || "d") {
9073						case "d" : case "D" :
9074							day += parseInt(matches[1],10); break;
9075						case "w" : case "W" :
9076							day += parseInt(matches[1],10) * 7; break;
9077						case "m" : case "M" :
9078							month += parseInt(matches[1],10);
9079							day = Math.min(day, $.datepicker._getDaysInMonth(year, month));
9080							break;
9081						case "y": case "Y" :
9082							year += parseInt(matches[1],10);
9083							day = Math.min(day, $.datepicker._getDaysInMonth(year, month));
9084							break;
9085					}
9086					matches = pattern.exec(offset);
9087				}
9088				return new Date(year, month, day);
9089			},
9090			newDate = (date == null || date === "" ? defaultDate : (typeof date === "string" ? offsetString(date) :
9091				(typeof date === "number" ? (isNaN(date) ? defaultDate : offsetNumeric(date)) : new Date(date.getTime()))));
9092
9093		newDate = (newDate && newDate.toString() === "Invalid Date" ? defaultDate : newDate);
9094		if (newDate) {
9095			newDate.setHours(0);
9096			newDate.setMinutes(0);
9097			newDate.setSeconds(0);
9098			newDate.setMilliseconds(0);
9099		}
9100		return this._daylightSavingAdjust(newDate);
9101	},
9102
9103	/* Handle switch to/from daylight saving.
9104	 * Hours may be non-zero on daylight saving cut-over:
9105	 * > 12 when midnight changeover, but then cannot generate
9106	 * midnight datetime, so jump to 1AM, otherwise reset.
9107	 * @param  date  (Date) the date to check
9108	 * @return  (Date) the corrected date
9109	 */
9110	_daylightSavingAdjust: function(date) {
9111		if (!date) {
9112			return null;
9113		}
9114		date.setHours(date.getHours() > 12 ? date.getHours() + 2 : 0);
9115		return date;
9116	},
9117
9118	/* Set the date(s) directly. */
9119	_setDate: function(inst, date, noChange) {
9120		var clear = !date,
9121			origMonth = inst.selectedMonth,
9122			origYear = inst.selectedYear,
9123			newDate = this._restrictMinMax(inst, this._determineDate(inst, date, new Date()));
9124
9125		inst.selectedDay = inst.currentDay = newDate.getDate();
9126		inst.drawMonth = inst.selectedMonth = inst.currentMonth = newDate.getMonth();
9127		inst.drawYear = inst.selectedYear = inst.currentYear = newDate.getFullYear();
9128		if ((origMonth !== inst.selectedMonth || origYear !== inst.selectedYear) && !noChange) {
9129			this._notifyChange(inst);
9130		}
9131		this._adjustInstDate(inst);
9132		if (inst.input) {
9133			inst.input.val(clear ? "" : this._formatDate(inst));
9134		}
9135	},
9136
9137	/* Retrieve the date(s) directly. */
9138	_getDate: function(inst) {
9139		var startDate = (!inst.currentYear || (inst.input && inst.input.val() === "") ? null :
9140			this._daylightSavingAdjust(new Date(
9141			inst.currentYear, inst.currentMonth, inst.currentDay)));
9142			return startDate;
9143	},
9144
9145	/* Attach the onxxx handlers.  These are declared statically so
9146	 * they work with static code transformers like Caja.
9147	 */
9148	_attachHandlers: function(inst) {
9149		var stepMonths = this._get(inst, "stepMonths"),
9150			id = "#" + inst.id.replace( /\\\\/g, "\\" );
9151		inst.dpDiv.find("[data-handler]").map(function () {
9152			var handler = {
9153				prev: function () {
9154					$.datepicker._adjustDate(id, -stepMonths, "M");
9155				},
9156				next: function () {
9157					$.datepicker._adjustDate(id, +stepMonths, "M");
9158				},
9159				hide: function () {
9160					$.datepicker._hideDatepicker();
9161				},
9162				today: function () {
9163					$.datepicker._gotoToday(id);
9164				},
9165				selectDay: function () {
9166					$.datepicker._selectDay(id, +this.getAttribute("data-month"), +this.getAttribute("data-year"), this);
9167					return false;
9168				},
9169				selectMonth: function () {
9170					$.datepicker._selectMonthYear(id, this, "M");
9171					return false;
9172				},
9173				selectYear: function () {
9174					$.datepicker._selectMonthYear(id, this, "Y");
9175					return false;
9176				}
9177			};
9178			$(this).bind(this.getAttribute("data-event"), handler[this.getAttribute("data-handler")]);
9179		});
9180	},
9181
9182	/* Generate the HTML for the current state of the date picker. */
9183	_generateHTML: function(inst) {
9184		var maxDraw, prevText, prev, nextText, next, currentText, gotoDate,
9185			controls, buttonPanel, firstDay, showWeek, dayNames, dayNamesMin,
9186			monthNames, monthNamesShort, beforeShowDay, showOtherMonths,
9187			selectOtherMonths, defaultDate, html, dow, row, group, col, selectedDate,
9188			cornerClass, calender, thead, day, daysInMonth, leadDays, curRows, numRows,
9189			printDate, dRow, tbody, daySettings, otherMonth, unselectable,
9190			tempDate = new Date(),
9191			today = this._daylightSavingAdjust(
9192				new Date(tempDate.getFullYear(), tempDate.getMonth(), tempDate.getDate())), // clear time
9193			isRTL = this._get(inst, "isRTL"),
9194			showButtonPanel = this._get(inst, "showButtonPanel"),
9195			hideIfNoPrevNext = this._get(inst, "hideIfNoPrevNext"),
9196			navigationAsDateFormat = this._get(inst, "navigationAsDateFormat"),
9197			numMonths = this._getNumberOfMonths(inst),
9198			showCurrentAtPos = this._get(inst, "showCurrentAtPos"),
9199			stepMonths = this._get(inst, "stepMonths"),
9200			isMultiMonth = (numMonths[0] !== 1 || numMonths[1] !== 1),
9201			currentDate = this._daylightSavingAdjust((!inst.currentDay ? new Date(9999, 9, 9) :
9202				new Date(inst.currentYear, inst.currentMonth, inst.currentDay))),
9203			minDate = this._getMinMaxDate(inst, "min"),
9204			maxDate = this._getMinMaxDate(inst, "max"),
9205			drawMonth = inst.drawMonth - showCurrentAtPos,
9206			drawYear = inst.drawYear;
9207
9208		if (drawMonth < 0) {
9209			drawMonth += 12;
9210			drawYear--;
9211		}
9212		if (maxDate) {
9213			maxDraw = this._daylightSavingAdjust(new Date(maxDate.getFullYear(),
9214				maxDate.getMonth() - (numMonths[0] * numMonths[1]) + 1, maxDate.getDate()));
9215			maxDraw = (minDate && maxDraw < minDate ? minDate : maxDraw);
9216			while (this._daylightSavingAdjust(new Date(drawYear, drawMonth, 1)) > maxDraw) {
9217				drawMonth--;
9218				if (drawMonth < 0) {
9219					drawMonth = 11;
9220					drawYear--;
9221				}
9222			}
9223		}
9224		inst.drawMonth = drawMonth;
9225		inst.drawYear = drawYear;
9226
9227		prevText = this._get(inst, "prevText");
9228		prevText = (!navigationAsDateFormat ? prevText : this.formatDate(prevText,
9229			this._daylightSavingAdjust(new Date(drawYear, drawMonth - stepMonths, 1)),
9230			this._getFormatConfig(inst)));
9231
9232		prev = (this._canAdjustMonth(inst, -1, drawYear, drawMonth) ?
9233			"<a class='ui-datepicker-prev ui-corner-all' data-handler='prev' data-event='click'" +
9234			" title='" + prevText + "'><span class='ui-icon ui-icon-circle-triangle-" + ( isRTL ? "e" : "w") + "'>" + prevText + "</span></a>" :
9235			(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>"));
9236
9237		nextText = this._get(inst, "nextText");
9238		nextText = (!navigationAsDateFormat ? nextText : this.formatDate(nextText,
9239			this._daylightSavingAdjust(new Date(drawYear, drawMonth + stepMonths, 1)),
9240			this._getFormatConfig(inst)));
9241
9242		next = (this._canAdjustMonth(inst, +1, drawYear, drawMonth) ?
9243			"<a class='ui-datepicker-next ui-corner-all' data-handler='next' data-event='click'" +
9244			" title='" + nextText + "'><span class='ui-icon ui-icon-circle-triangle-" + ( isRTL ? "w" : "e") + "'>" + nextText + "</span></a>" :
9245			(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>"));
9246
9247		currentText = this._get(inst, "currentText");
9248		gotoDate = (this._get(inst, "gotoCurrent") && inst.currentDay ? currentDate : today);
9249		currentText = (!navigationAsDateFormat ? currentText :
9250			this.formatDate(currentText, gotoDate, this._getFormatConfig(inst)));
9251
9252		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'>" +
9253			this._get(inst, "closeText") + "</button>" : "");
9254
9255		buttonPanel = (showButtonPanel) ? "<div class='ui-datepicker-buttonpane ui-widget-content'>" + (isRTL ? controls : "") +
9256			(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'" +
9257			">" + currentText + "</button>" : "") + (isRTL ? "" : controls) + "</div>" : "";
9258
9259		firstDay = parseInt(this._get(inst, "firstDay"),10);
9260		firstDay = (isNaN(firstDay) ? 0 : firstDay);
9261
9262		showWeek = this._get(inst, "showWeek");
9263		dayNames = this._get(inst, "dayNames");
9264		dayNamesMin = this._get(inst, "dayNamesMin");
9265		monthNames = this._get(inst, "monthNames");
9266		monthNamesShort = this._get(inst, "monthNamesShort");
9267		beforeShowDay = this._get(inst, "beforeShowDay");
9268		showOtherMonths = this._get(inst, "showOtherMonths");
9269		selectOtherMonths = this._get(inst, "selectOtherMonths");
9270		defaultDate = this._getDefaultDate(inst);
9271		html = "";
9272		dow;
9273		for (row = 0; row < numMonths[0]; row++) {
9274			group = "";
9275			this.maxRows = 4;
9276			for (col = 0; col < numMonths[1]; col++) {
9277				selectedDate = this._daylightSavingAdjust(new Date(drawYear, drawMonth, inst.selectedDay));
9278				cornerClass = " ui-corner-all";
9279				calender = "";
9280				if (isMultiMonth) {
9281					calender += "<div class='ui-datepicker-group";
9282					if (numMonths[1] > 1) {
9283						switch (col) {
9284							case 0: calender += " ui-datepicker-group-first";
9285								cornerClass = " ui-corner-" + (isRTL ? "right" : "left"); break;
9286							case numMonths[1]-1: calender += " ui-datepicker-group-last";
9287								cornerClass = " ui-corner-" + (isRTL ? "left" : "right"); break;
9288							default: calender += " ui-datepicker-group-middle"; cornerClass = ""; break;
9289						}
9290					}
9291					calender += "'>";
9292				}
9293				calender += "<div class='ui-datepicker-header ui-widget-header ui-helper-clearfix" + cornerClass + "'>" +
9294					(/all|left/.test(cornerClass) && row === 0 ? (isRTL ? next : prev) : "") +
9295					(/all|right/.test(cornerClass) && row === 0 ? (isRTL ? prev : next) : "") +
9296					this._generateMonthYearHeader(inst, drawMonth, drawYear, minDate, maxDate,
9297					row > 0 || col > 0, monthNames, monthNamesShort) + // draw month headers
9298					"</div><table class='ui-datepicker-calendar'><thead>" +
9299					"<tr>";
9300				thead = (showWeek ? "<th class='ui-datepicker-week-col'>" + this._get(inst, "weekHeader") + "</th>" : "");
9301				for (dow = 0; dow < 7; dow++) { // days of the week
9302					day = (dow + firstDay) % 7;
9303					thead += "<th" + ((dow + firstDay + 6) % 7 >= 5 ? " class='ui-datepicker-week-end'" : "") + ">" +
9304						"<span title='" + dayNames[day] + "'>" + dayNamesMin[day] + "</span></th>";
9305				}
9306				calender += thead + "</tr></thead><tbody>";
9307				daysInMonth = this._getDaysInMonth(drawYear, drawMonth);
9308				if (drawYear === inst.selectedYear && drawMonth === inst.selectedMonth) {
9309					inst.selectedDay = Math.min(inst.selectedDay, daysInMonth);
9310				}
9311				leadDays = (this._getFirstDayOfMonth(drawYear, drawMonth) - firstDay + 7) % 7;
9312				curRows = Math.ceil((leadDays + daysInMonth) / 7); // calculate the number of rows to generate
9313				numRows = (isMultiMonth ? this.maxRows > curRows ? this.maxRows : curRows : curRows); //If multiple months, use the higher number of rows (see #7043)
9314				this.maxRows = numRows;
9315				printDate = this._daylightSavingAdjust(new Date(drawYear, drawMonth, 1 - leadDays));
9316				for (dRow = 0; dRow < numRows; dRow++) { // create date picker rows
9317					calender += "<tr>";
9318					tbody = (!showWeek ? "" : "<td class='ui-datepicker-week-col'>" +
9319						this._get(inst, "calculateWeek")(printDate) + "</td>");
9320					for (dow = 0; dow < 7; dow++) { // create date picker days
9321						daySettings = (beforeShowDay ?
9322							beforeShowDay.apply((inst.input ? inst.input[0] : null), [printDate]) : [true, ""]);
9323						otherMonth = (printDate.getMonth() !== drawMonth);
9324						unselectable = (otherMonth && !selectOtherMonths) || !daySettings[0] ||
9325							(minDate && printDate < minDate) || (maxDate && printDate > maxDate);
9326						tbody += "<td class='" +
9327							((dow + firstDay + 6) % 7 >= 5 ? " ui-datepicker-week-end" : "") + // highlight weekends
9328							(otherMonth ? " ui-datepicker-other-month" : "") + // highlight days from other months
9329							((printDate.getTime() === selectedDate.getTime() && drawMonth === inst.selectedMonth && inst._keyEvent) || // user pressed key
9330							(defaultDate.getTime() === printDate.getTime() && defaultDate.getTime() === selectedDate.getTime()) ?
9331							// or defaultDate is current printedDate and defaultDate is selectedDate
9332							" " + this._dayOverClass : "") + // highlight selected day
9333							(unselectable ? " " + this._unselectableClass + " ui-state-disabled": "") +  // highlight unselectable days
9334							(otherMonth && !showOtherMonths ? "" : " " + daySettings[1] + // highlight custom dates
9335							(printDate.getTime() === currentDate.getTime() ? " " + this._currentClass : "") + // highlight selected day
9336							(printDate.getTime() === today.getTime() ? " ui-datepicker-today" : "")) + "'" + // highlight today (if different)
9337							((!otherMonth || showOtherMonths) && daySettings[2] ? " title='" + daySettings[2].replace(/'/g, "&#39;") + "'" : "") + // cell title
9338							(unselectable ? "" : " data-handler='selectDay' data-event='click' data-month='" + printDate.getMonth() + "' data-year='" + printDate.getFullYear() + "'") + ">" + // actions
9339							(otherMonth && !showOtherMonths ? "&#xa0;" : // display for other months
9340							(unselectable ? "<span class='ui-state-default'>" + printDate.getDate() + "</span>" : "<a class='ui-state-default" +
9341							(printDate.getTime() === today.getTime() ? " ui-state-highlight" : "") +
9342							(printDate.getTime() === currentDate.getTime() ? " ui-state-active" : "") + // highlight selected day
9343							(otherMonth ? " ui-priority-secondary" : "") + // distinguish dates from other months
9344							"' href='#'>" + printDate.getDate() + "</a>")) + "</td>"; // display selectable date
9345						printDate.setDate(printDate.getDate() + 1);
9346						printDate = this._daylightSavingAdjust(printDate);
9347					}
9348					calender += tbody + "</tr>";
9349				}
9350				drawMonth++;
9351				if (drawMonth > 11) {
9352					drawMonth = 0;
9353					drawYear++;
9354				}
9355				calender += "</tbody></table>" + (isMultiMonth ? "</div>" +
9356							((numMonths[0] > 0 && col === numMonths[1]-1) ? "<div class='ui-datepicker-row-break'></div>" : "") : "");
9357				group += calender;
9358			}
9359			html += group;
9360		}
9361		html += buttonPanel;
9362		inst._keyEvent = false;
9363		return html;
9364	},
9365
9366	/* Generate the month and year header. */
9367	_generateMonthYearHeader: function(inst, drawMonth, drawYear, minDate, maxDate,
9368			secondary, monthNames, monthNamesShort) {
9369
9370		var inMinYear, inMaxYear, month, years, thisYear, determineYear, year, endYear,
9371			changeMonth = this._get(inst, "changeMonth"),
9372			changeYear = this._get(inst, "changeYear"),
9373			showMonthAfterYear = this._get(inst, "showMonthAfterYear"),
9374			html = "<div class='ui-datepicker-title'>",
9375			monthHtml = "";
9376
9377		// month selection
9378		if (secondary || !changeMonth) {
9379			monthHtml += "<span class='ui-datepicker-month'>" + monthNames[drawMonth] + "</span>";
9380		} else {
9381			inMinYear = (minDate && minDate.getFullYear() === drawYear);
9382			inMaxYear = (maxDate && maxDate.getFullYear() === drawYear);
9383			monthHtml += "<select class='ui-datepicker-month' data-handler='selectMonth' data-event='change'>";
9384			for ( month = 0; month < 12; month++) {
9385				if ((!inMinYear || month >= minDate.getMonth()) && (!inMaxYear || month <= maxDate.getMonth())) {
9386					monthHtml += "<option value='" + month + "'" +
9387						(month === drawMonth ? " selected='selected'" : "") +
9388						">" + monthNamesShort[month] + "</option>";
9389				}
9390			}
9391			monthHtml += "</select>";
9392		}
9393
9394		if (!showMonthAfterYear) {
9395			html += monthHtml + (secondary || !(changeMonth && changeYear) ? "&#xa0;" : "");
9396		}
9397
9398		// year selection
9399		if ( !inst.yearshtml ) {
9400			inst.yearshtml = "";
9401			if (secondary || !changeYear) {
9402				html += "<span class='ui-datepicker-year'>" + drawYear + "</span>";
9403			} else {
9404				// determine range of years to display
9405				years = this._get(inst, "yearRange").split(":");
9406				thisYear = new Date().getFullYear();
9407				determineYear = function(value) {
9408					var year = (value.match(/c[+\-].*/) ? drawYear + parseInt(value.substring(1), 10) :
9409						(value.match(/[+\-].*/) ? thisYear + parseInt(value, 10) :
9410						parseInt(value, 10)));
9411					return (isNaN(year) ? thisYear : year);
9412				};
9413				year = determineYear(years[0]);
9414				endYear = Math.max(year, determineYear(years[1] || ""));
9415				year = (minDate ? Math.max(year, minDate.getFullYear()) : year);
9416				endYear = (maxDate ? Math.min(endYear, maxDate.getFullYear()) : endYear);
9417				inst.yearshtml += "<select class='ui-datepicker-year' data-handler='selectYear' data-event='change'>";
9418				for (; year <= endYear; year++) {
9419					inst.yearshtml += "<option value='" + year + "'" +
9420						(year === drawYear ? " selected='selected'" : "") +
9421						">" + year + "</option>";
9422				}
9423				inst.yearshtml += "</select>";
9424
9425				html += inst.yearshtml;
9426				inst.yearshtml = null;
9427			}
9428		}
9429
9430		html += this._get(inst, "yearSuffix");
9431		if (showMonthAfterYear) {
9432			html += (secondary || !(changeMonth && changeYear) ? "&#xa0;" : "") + monthHtml;
9433		}
9434		html += "</div>"; // Close datepicker_header
9435		return html;
9436	},
9437
9438	/* Adjust one of the date sub-fields. */
9439	_adjustInstDate: function(inst, offset, period) {
9440		var year = inst.drawYear + (period === "Y" ? offset : 0),
9441			month = inst.drawMonth + (period === "M" ? offset : 0),
9442			day = Math.min(inst.selectedDay, this._getDaysInMonth(year, month)) + (period === "D" ? offset : 0),
9443			date = this._restrictMinMax(inst, this._daylightSavingAdjust(new Date(year, month, day)));
9444
9445		inst.selectedDay = date.getDate();
9446		inst.drawMonth = inst.selectedMonth = date.getMonth();
9447		inst.drawYear = inst.selectedYear = date.getFullYear();
9448		if (period === "M" || period === "Y") {
9449			this._notifyChange(inst);
9450		}
9451	},
9452
9453	/* Ensure a date is within any min/max bounds. */
9454	_restrictMinMax: function(inst, date) {
9455		var minDate = this._getMinMaxDate(inst, "min"),
9456			maxDate = this._getMinMaxDate(inst, "max"),
9457			newDate = (minDate && date < minDate ? minDate : date);
9458		return (maxDate && newDate > maxDate ? maxDate : newDate);
9459	},
9460
9461	/* Notify change of month/year. */
9462	_notifyChange: function(inst) {
9463		var onChange = this._get(inst, "onChangeMonthYear");
9464		if (onChange) {
9465			onChange.apply((inst.input ? inst.input[0] : null),
9466				[inst.selectedYear, inst.selectedMonth + 1, inst]);
9467		}
9468	},
9469
9470	/* Determine the number of months to show. */
9471	_getNumberOfMonths: function(inst) {
9472		var numMonths = this._get(inst, "numberOfMonths");
9473		return (numMonths == null ? [1, 1] : (typeof numMonths === "number" ? [1, numMonths] : numMonths));
9474	},
9475
9476	/* Determine the current maximum date - ensure no time components are set. */
9477	_getMinMaxDate: function(inst, minMax) {
9478		return this._determineDate(inst, this._get(inst, minMax + "Date"), null);
9479	},
9480
9481	/* Find the number of days in a given month. */
9482	_getDaysInMonth: function(year, month) {
9483		return 32 - this._daylightSavingAdjust(new Date(year, month, 32)).getDate();
9484	},
9485
9486	/* Find the day of the week of the first of a month. */
9487	_getFirstDayOfMonth: function(year, month) {
9488		return new Date(year, month, 1).getDay();
9489	},
9490
9491	/* Determines if we should allow a "next/prev" month display change. */
9492	_canAdjustMonth: function(inst, offset, curYear, curMonth) {
9493		var numMonths = this._getNumberOfMonths(inst),
9494			date = this._daylightSavingAdjust(new Date(curYear,
9495			curMonth + (offset < 0 ? offset : numMonths[0] * numMonths[1]), 1));
9496
9497		if (offset < 0) {
9498			date.setDate(this._getDaysInMonth(date.getFullYear(), date.getMonth()));
9499		}
9500		return this._isInRange(inst, date);
9501	},
9502
9503	/* Is the given date in the accepted range? */
9504	_isInRange: function(inst, date) {
9505		var yearSplit, currentYear,
9506			minDate = this._getMinMaxDate(inst, "min"),
9507			maxDate = this._getMinMaxDate(inst, "max"),
9508			minYear = null,
9509			maxYear = null,
9510			years = this._get(inst, "yearRange");
9511			if (years){
9512				yearSplit = years.split(":");
9513				currentYear = new Date().getFullYear();
9514				minYear = parseInt(yearSplit[0], 10);
9515				maxYear = parseInt(yearSplit[1], 10);
9516				if ( yearSplit[0].match(/[+\-].*/) ) {
9517					minYear += currentYear;
9518				}
9519				if ( yearSplit[1].match(/[+\-].*/) ) {
9520					maxYear += currentYear;
9521				}
9522			}
9523
9524		return ((!minDate || date.getTime() >= minDate.getTime()) &&
9525			(!maxDate || date.getTime() <= maxDate.getTime()) &&
9526			(!minYear || date.getFullYear() >= minYear) &&
9527			(!maxYear || date.getFullYear() <= maxYear));
9528	},
9529
9530	/* Provide the configuration settings for formatting/parsing. */
9531	_getFormatConfig: function(inst) {
9532		var shortYearCutoff = this._get(inst, "shortYearCutoff");
9533		shortYearCutoff = (typeof shortYearCutoff !== "string" ? shortYearCutoff :
9534			new Date().getFullYear() % 100 + parseInt(shortYearCutoff, 10));
9535		return {shortYearCutoff: shortYearCutoff,
9536			dayNamesShort: this._get(inst, "dayNamesShort"), dayNames: this._get(inst, "dayNames"),
9537			monthNamesShort: this._get(inst, "monthNamesShort"), monthNames: this._get(inst, "monthNames")};
9538	},
9539
9540	/* Format the given date for display. */
9541	_formatDate: function(inst, day, month, year) {
9542		if (!day) {
9543			inst.currentDay = inst.selectedDay;
9544			inst.currentMonth = inst.selectedMonth;
9545			inst.currentYear = inst.selectedYear;
9546		}
9547		var date = (day ? (typeof day === "object" ? day :
9548			this._daylightSavingAdjust(new Date(year, month, day))) :
9549			this._daylightSavingAdjust(new Date(inst.currentYear, inst.currentMonth, inst.currentDay)));
9550		return this.formatDate(this._get(inst, "dateFormat"), date, this._getFormatConfig(inst));
9551	}
9552});
9553
9554/*
9555 * Bind hover events for datepicker elements.
9556 * Done via delegate so the binding only occurs once in the lifetime of the parent div.
9557 * Global instActive, set by _updateDatepicker allows the handlers to find their way back to the active picker.
9558 */
9559function bindHover(dpDiv) {
9560	var selector = "button, .ui-datepicker-prev, .ui-datepicker-next, .ui-datepicker-calendar td a";
9561	return dpDiv.delegate(selector, "mouseout", function() {
9562			$(this).removeClass("ui-state-hover");
9563			if (this.className.indexOf("ui-datepicker-prev") !== -1) {
9564				$(this).removeClass("ui-datepicker-prev-hover");
9565			}
9566			if (this.className.indexOf("ui-datepicker-next") !== -1) {
9567				$(this).removeClass("ui-datepicker-next-hover");
9568			}
9569		})
9570		.delegate(selector, "mouseover", function(){
9571			if (!$.datepicker._isDisabledDatepicker( instActive.inline ? dpDiv.parent()[0] : instActive.input[0])) {
9572				$(this).parents(".ui-datepicker-calendar").find("a").removeClass("ui-state-hover");
9573				$(this).addClass("ui-state-hover");
9574				if (this.className.indexOf("ui-datepicker-prev") !== -1) {
9575					$(this).addClass("ui-datepicker-prev-hover");
9576				}
9577				if (this.className.indexOf("ui-datepicker-next") !== -1) {
9578					$(this).addClass("ui-datepicker-next-hover");
9579				}
9580			}
9581		});
9582}
9583
9584/* jQuery extend now ignores nulls! */
9585function extendRemove(target, props) {
9586	$.extend(target, props);
9587	for (var name in props) {
9588		if (props[name] == null) {
9589			target[name] = props[name];
9590		}
9591	}
9592	return target;
9593}
9594
9595/* Invoke the datepicker functionality.
9596   @param  options  string - a command, optionally followed by additional parameters or
9597					Object - settings for attaching new datepicker functionality
9598   @return  jQuery object */
9599$.fn.datepicker = function(options){
9600
9601	/* Verify an empty collection wasn't passed - Fixes #6976 */
9602	if ( !this.length ) {
9603		return this;
9604	}
9605
9606	/* Initialise the date picker. */
9607	if (!$.datepicker.initialized) {
9608		$(document).mousedown($.datepicker._checkExternalClick);
9609		$.datepicker.initialized = true;
9610	}
9611
9612	/* Append datepicker main container to body if not exist. */
9613	if ($("#"+$.datepicker._mainDivId).length === 0) {
9614		$("body").append($.datepicker.dpDiv);
9615	}
9616
9617	var otherArgs = Array.prototype.slice.call(arguments, 1);
9618	if (typeof options === "string" && (options === "isDisabled" || options === "getDate" || options === "widget")) {
9619		return $.datepicker["_" + options + "Datepicker"].
9620			apply($.datepicker, [this[0]].concat(otherArgs));
9621	}
9622	if (options === "option" && arguments.length === 2 && typeof arguments[1] === "string") {
9623		return $.datepicker["_" + options + "Datepicker"].
9624			apply($.datepicker, [this[0]].concat(otherArgs));
9625	}
9626	return this.each(function() {
9627		typeof options === "string" ?
9628			$.datepicker["_" + options + "Datepicker"].
9629				apply($.datepicker, [this].concat(otherArgs)) :
9630			$.datepicker._attachDatepicker(this, options);
9631	});
9632};
9633
9634$.datepicker = new Datepicker(); // singleton instance
9635$.datepicker.initialized = false;
9636$.datepicker.uuid = new Date().getTime();
9637$.datepicker.version = "1.10.
vendor: 18,168 bytes, lines 9637-10365
96374";
9638
9639})(jQuery);
9640
9641(function( $, undefined ) {
9642
9643var sizeRelatedOptions = {
9644		buttons: true,
9645		height: true,
9646		maxHeight: true,
9647		maxWidth: true,
9648		minHeight: true,
9649		minWidth: true,
9650		width: true
9651	},
9652	resizableRelatedOptions = {
9653		maxHeight: true,
9654		maxWidth: true,
9655		minHeight: true,
9656		minWidth: true
9657	};
9658
9659$.widget( "ui.dialog", {
9660	version: "1.10.4",
9661	options: {
9662		appendTo: "body",
9663		autoOpen: true,
9664		buttons: [],
9665		closeOnEscape: true,
9666		closeText: "close",
9667		dialogClass: "",
9668		draggable: true,
9669		hide: null,
9670		height: "auto",
9671		maxHeight: null,
9672		maxWidth: null,
9673		minHeight: 150,
9674		minWidth: 150,
9675		modal: false,
9676		position: {
9677			my: "center",
9678			at: "center",
9679			of: window,
9680			collision: "fit",
9681			// Ensure the titlebar is always visible
9682			using: function( pos ) {
9683				var topOffset = $( this ).css( pos ).offset().top;
9684				if ( topOffset < 0 ) {
9685					$( this ).css( "top", pos.top - topOffset );
9686				}
9687			}
9688		},
9689		resizable: true,
9690		show: null,
9691		title: null,
9692		width: 300,
9693
9694		// callbacks
9695		beforeClose: null,
9696		close: null,
9697		drag: null,
9698		dragStart: null,
9699		dragStop: null,
9700		focus: null,
9701		open: null,
9702		resize: null,
9703		resizeStart: null,
9704		resizeStop: null
9705	},
9706
9707	_create: function() {
9708		this.originalCss = {
9709			display: this.element[0].style.display,
9710			width: this.element[0].style.width,
9711			minHeight: this.element[0].style.minHeight,
9712			maxHeight: this.element[0].style.maxHeight,
9713			height: this.element[0].style.height
9714		};
9715		this.originalPosition = {
9716			parent: this.element.parent(),
9717			index: this.element.parent().children().index( this.element )
9718		};
9719		this.originalTitle = this.element.attr("title");
9720		this.options.title = this.options.title || this.originalTitle;
9721
9722		this._createWrapper();
9723
9724		this.element
9725			.show()
9726			.removeAttr("title")
9727			.addClass("ui-dialog-content ui-widget-content")
9728			.appendTo( this.uiDialog );
9729
9730		this._createTitlebar();
9731		this._createButtonPane();
9732
9733		if ( this.options.draggable && $.fn.draggable ) {
9734			this._makeDraggable();
9735		}
9736		if ( this.options.resizable && $.fn.resizable ) {
9737			this._makeResizable();
9738		}
9739
9740		this._isOpen = false;
9741	},
9742
9743	_init: function() {
9744		if ( this.options.autoOpen ) {
9745			this.open();
9746		}
9747	},
9748
9749	_appendTo: function() {
9750		var element = this.options.appendTo;
9751		if ( element && (element.jquery || element.nodeType) ) {
9752			return $( element );
9753		}
9754		return this.document.find( element || "body" ).eq( 0 );
9755	},
9756
9757	_destroy: function() {
9758		var next,
9759			originalPosition = this.originalPosition;
9760
9761		this._destroyOverlay();
9762
9763		this.element
9764			.removeUniqueId()
9765			.removeClass("ui-dialog-content ui-widget-content")
9766			.css( this.originalCss )
9767			// Without detaching first, the following becomes really slow
9768			.detach();
9769
9770		this.uiDialog.stop( true, true ).remove();
9771
9772		if ( this.originalTitle ) {
9773			this.element.attr( "title", this.originalTitle );
9774		}
9775
9776		next = originalPosition.parent.children().eq( originalPosition.index );
9777		// Don't try to place the dialog next to itself (#8613)
9778		if ( next.length && next[0] !== this.element[0] ) {
9779			next.before( this.element );
9780		} else {
9781			originalPosition.parent.append( this.element );
9782		}
9783	},
9784
9785	widget: function() {
9786		return this.uiDialog;
9787	},
9788
9789	disable: $.noop,
9790	enable: $.noop,
9791
9792	close: function( event ) {
9793		var activeElement,
9794			that = this;
9795
9796		if ( !this._isOpen || this._trigger( "beforeClose", event ) === false ) {
9797			return;
9798		}
9799
9800		this._isOpen = false;
9801		this._destroyOverlay();
9802
9803		if ( !this.opener.filter(":focusable").focus().length ) {
9804
9805			// support: IE9
9806			// IE9 throws an "Unspecified error" accessing document.activeElement from an <iframe>
9807			try {
9808				activeElement = this.document[ 0 ].activeElement;
9809
9810				// Support: IE9, IE10
9811				// If the <body> is blurred, IE will switch windows, see #4520
9812				if ( activeElement && activeElement.nodeName.toLowerCase() !== "body" ) {
9813
9814					// Hiding a focused element doesn't trigger blur in WebKit
9815					// so in case we have nothing to focus on, explicitly blur the active element
9816					// https://bugs.webkit.org/show_bug.cgi?id=47182
9817					$( activeElement ).blur();
9818				}
9819			} catch ( error ) {}
9820		}
9821
9822		this._hide( this.uiDialog, this.options.hide, function() {
9823			that._trigger( "close", event );
9824		});
9825	},
9826
9827	isOpen: function() {
9828		return this._isOpen;
9829	},
9830
9831	moveToTop: function() {
9832		this._moveToTop();
9833	},
9834
9835	_moveToTop: function( event, silent ) {
9836		var moved = !!this.uiDialog.nextAll(":visible").insertBefore( this.uiDialog ).length;
9837		if ( moved && !silent ) {
9838			this._trigger( "focus", event );
9839		}
9840		return moved;
9841	},
9842
9843	open: function() {
9844		var that = this;
9845		if ( this._isOpen ) {
9846			if ( this._moveToTop() ) {
9847				this._focusTabbable();
9848			}
9849			return;
9850		}
9851
9852		this._isOpen = true;
9853		this.opener = $( this.document[0].activeElement );
9854
9855		this._size();
9856		this._position();
9857		this._createOverlay();
9858		this._moveToTop( null, true );
9859		this._show( this.uiDialog, this.options.show, function() {
9860			that._focusTabbable();
9861			that._trigger("focus");
9862		});
9863
9864		this._trigger("open");
9865	},
9866
9867	_focusTabbable: function() {
9868		// Set focus to the first match:
9869		// 1. First element inside the dialog matching [autofocus]
9870		// 2. Tabbable element inside the content element
9871		// 3. Tabbable element inside the buttonpane
9872		// 4. The close button
9873		// 5. The dialog itself
9874		var hasFocus = this.element.find("[autofocus]");
9875		if ( !hasFocus.length ) {
9876			hasFocus = this.element.find(":tabbable");
9877		}
9878		if ( !hasFocus.length ) {
9879			hasFocus = this.uiDialogButtonPane.find(":tabbable");
9880		}
9881		if ( !hasFocus.length ) {
9882			hasFocus = this.uiDialogTitlebarClose.filter(":tabbable");
9883		}
9884		if ( !hasFocus.length ) {
9885			hasFocus = this.uiDialog;
9886		}
9887		hasFocus.eq( 0 ).focus();
9888	},
9889
9890	_keepFocus: function( event ) {
9891		function checkFocus() {
9892			var activeElement = this.document[0].activeElement,
9893				isActive = this.uiDialog[0] === activeElement ||
9894					$.contains( this.uiDialog[0], activeElement );
9895			if ( !isActive ) {
9896				this._focusTabbable();
9897			}
9898		}
9899		event.preventDefault();
9900		checkFocus.call( this );
9901		// support: IE
9902		// IE <= 8 doesn't prevent moving focus even with event.preventDefault()
9903		// so we check again later
9904		this._delay( checkFocus );
9905	},
9906
9907	_createWrapper: function() {
9908		this.uiDialog = $("<div>")
9909			.addClass( "ui-dialog ui-widget ui-widget-content ui-corner-all ui-front " +
9910				this.options.dialogClass )
9911			.hide()
9912			.attr({
9913				// Setting tabIndex makes the div focusable
9914				tabIndex: -1,
9915				role: "dialog"
9916			})
9917			.appendTo( this._appendTo() );
9918
9919		this._on( this.uiDialog, {
9920			keydown: function( event ) {
9921				if ( this.options.closeOnEscape && !event.isDefaultPrevented() && event.keyCode &&
9922						event.keyCode === $.ui.keyCode.ESCAPE ) {
9923					event.preventDefault();
9924					this.close( event );
9925					return;
9926				}
9927
9928				// prevent tabbing out of dialogs
9929				if ( event.keyCode !== $.ui.keyCode.TAB ) {
9930					return;
9931				}
9932				var tabbables = this.uiDialog.find(":tabbable"),
9933					first = tabbables.filter(":first"),
9934					last  = tabbables.filter(":last");
9935
9936				if ( ( event.target === last[0] || event.target === this.uiDialog[0] ) && !event.shiftKey ) {
9937					first.focus( 1 );
9938					event.preventDefault();
9939				} else if ( ( event.target === first[0] || event.target === this.uiDialog[0] ) && event.shiftKey ) {
9940					last.focus( 1 );
9941					event.preventDefault();
9942				}
9943			},
9944			mousedown: function( event ) {
9945				if ( this._moveToTop( event ) ) {
9946					this._focusTabbable();
9947				}
9948			}
9949		});
9950
9951		// We assume that any existing aria-describedby attribute means
9952		// that the dialog content is marked up properly
9953		// otherwise we brute force the content as the description
9954		if ( !this.element.find("[aria-describedby]").length ) {
9955			this.uiDialog.attr({
9956				"aria-describedby": this.element.uniqueId().attr("id")
9957			});
9958		}
9959	},
9960
9961	_createTitlebar: function() {
9962		var uiDialogTitle;
9963
9964		this.uiDialogTitlebar = $("<div>")
9965			.addClass("ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix")
9966			.prependTo( this.uiDialog );
9967		this._on( this.uiDialogTitlebar, {
9968			mousedown: function( event ) {
9969				// Don't prevent click on close button (#8838)
9970				// Focusing a dialog that is partially scrolled out of view
9971				// causes the browser to scroll it into view, preventing the click event
9972				if ( !$( event.target ).closest(".ui-dialog-titlebar-close") ) {
9973					// Dialog isn't getting focus when dragging (#8063)
9974					this.uiDialog.focus();
9975				}
9976			}
9977		});
9978
9979		// support: IE
9980		// Use type="button" to prevent enter keypresses in textboxes from closing the
9981		// dialog in IE (#9312)
9982		this.uiDialogTitlebarClose = $( "<button type='button'></button>" )
9983			.button({
9984				label: this.options.closeText,
9985				icons: {
9986					primary: "ui-icon-closethick"
9987				},
9988				text: false
9989			})
9990			.addClass("ui-dialog-titlebar-close")
9991			.appendTo( this.uiDialogTitlebar );
9992		this._on( this.uiDialogTitlebarClose, {
9993			click: function( event ) {
9994				event.preventDefault();
9995				this.close( event );
9996			}
9997		});
9998
9999		uiDialogTitle = $("<span>")
10000			.uniqueId()
10001			.addClass("ui-dialog-title")
10002			.prependTo( this.uiDialogTitlebar );
10003		this._title( uiDialogTitle );
10004
10005		this.uiDialog.attr({
10006			"aria-labelledby": uiDialogTitle.attr("id")
10007		});
10008	},
10009
10010	_title: function( title ) {
10011		if ( !this.options.title ) {
10012			title.html("&#160;");
10013		}
10014		title.text( this.options.title );
10015	},
10016
10017	_createButtonPane: function() {
10018		this.uiDialogButtonPane = $("<div>")
10019			.addClass("ui-dialog-buttonpane ui-widget-content ui-helper-clearfix");
10020
10021		this.uiButtonSet = $("<div>")
10022			.addClass("ui-dialog-buttonset")
10023			.appendTo( this.uiDialogButtonPane );
10024
10025		this._createButtons();
10026	},
10027
10028	_createButtons: function() {
10029		var that = this,
10030			buttons = this.options.buttons;
10031
10032		// if we already have a button pane, remove it
10033		this.uiDialogButtonPane.remove();
10034		this.uiButtonSet.empty();
10035
10036		if ( $.isEmptyObject( buttons ) || ($.isArray( buttons ) && !buttons.length) ) {
10037			this.uiDialog.removeClass("ui-dialog-buttons");
10038			return;
10039		}
10040
10041		$.each( buttons, function( name, props ) {
10042			var click, buttonOptions;
10043			props = $.isFunction( props ) ?
10044				{ click: props, text: name } :
10045				props;
10046			// Default to a non-submitting button
10047			props = $.extend( { type: "button" }, props );
10048			// Change the context for the click callback to be the main element
10049			click = props.click;
10050			props.click = function() {
10051				click.apply( that.element[0], arguments );
10052			};
10053			buttonOptions = {
10054				icons: props.icons,
10055				text: props.showText
10056			};
10057			delete props.icons;
10058			delete props.showText;
10059			$( "<button></button>", props )
10060				.button( buttonOptions )
10061				.appendTo( that.uiButtonSet );
10062		});
10063		this.uiDialog.addClass("ui-dialog-buttons");
10064		this.uiDialogButtonPane.appendTo( this.uiDialog );
10065	},
10066
10067	_makeDraggable: function() {
10068		var that = this,
10069			options = this.options;
10070
10071		function filteredUi( ui ) {
10072			return {
10073				position: ui.position,
10074				offset: ui.offset
10075			};
10076		}
10077
10078		this.uiDialog.draggable({
10079			cancel: ".ui-dialog-content, .ui-dialog-titlebar-close",
10080			handle: ".ui-dialog-titlebar",
10081			containment: "document",
10082			start: function( event, ui ) {
10083				$( this ).addClass("ui-dialog-dragging");
10084				that._blockFrames();
10085				that._trigger( "dragStart", event, filteredUi( ui ) );
10086			},
10087			drag: function( event, ui ) {
10088				that._trigger( "drag", event, filteredUi( ui ) );
10089			},
10090			stop: function( event, ui ) {
10091				options.position = [
10092					ui.position.left - that.document.scrollLeft(),
10093					ui.position.top - that.document.scrollTop()
10094				];
10095				$( this ).removeClass("ui-dialog-dragging");
10096				that._unblockFrames();
10097				that._trigger( "dragStop", event, filteredUi( ui ) );
10098			}
10099		});
10100	},
10101
10102	_makeResizable: function() {
10103		var that = this,
10104			options = this.options,
10105			handles = options.resizable,
10106			// .ui-resizable has position: relative defined in the stylesheet
10107			// but dialogs have to use absolute or fixed positioning
10108			position = this.uiDialog.css("position"),
10109			resizeHandles = typeof handles === "string" ?
10110				handles	:
10111				"n,e,s,w,se,sw,ne,nw";
10112
10113		function filteredUi( ui ) {
10114			return {
10115				originalPosition: ui.originalPosition,
10116				originalSize: ui.originalSize,
10117				position: ui.position,
10118				size: ui.size
10119			};
10120		}
10121
10122		this.uiDialog.resizable({
10123			cancel: ".ui-dialog-content",
10124			containment: "document",
10125			alsoResize: this.element,
10126			maxWidth: options.maxWidth,
10127			maxHeight: options.maxHeight,
10128			minWidth: options.minWidth,
10129			minHeight: this._minHeight(),
10130			handles: resizeHandles,
10131			start: function( event, ui ) {
10132				$( this ).addClass("ui-dialog-resizing");
10133				that._blockFrames();
10134				that._trigger( "resizeStart", event, filteredUi( ui ) );
10135			},
10136			resize: function( event, ui ) {
10137				that._trigger( "resize", event, filteredUi( ui ) );
10138			},
10139			stop: function( event, ui ) {
10140				options.height = $( this ).height();
10141				options.width = $( this ).width();
10142				$( this ).removeClass("ui-dialog-resizing");
10143				that._unblockFrames();
10144				that._trigger( "resizeStop", event, filteredUi( ui ) );
10145			}
10146		})
10147		.css( "position", position );
10148	},
10149
10150	_minHeight: function() {
10151		var options = this.options;
10152
10153		return options.height === "auto" ?
10154			options.minHeight :
10155			Math.min( options.minHeight, options.height );
10156	},
10157
10158	_position: function() {
10159		// Need to show the dialog to get the actual offset in the position plugin
10160		var isVisible = this.uiDialog.is(":visible");
10161		if ( !isVisible ) {
10162			this.uiDialog.show();
10163		}
10164		this.uiDialog.position( this.options.position );
10165		if ( !isVisible ) {
10166			this.uiDialog.hide();
10167		}
10168	},
10169
10170	_setOptions: function( options ) {
10171		var that = this,
10172			resize = false,
10173			resizableOptions = {};
10174
10175		$.each( options, function( key, value ) {
10176			that._setOption( key, value );
10177
10178			if ( key in sizeRelatedOptions ) {
10179				resize = true;
10180			}
10181			if ( key in resizableRelatedOptions ) {
10182				resizableOptions[ key ] = value;
10183			}
10184		});
10185
10186		if ( resize ) {
10187			this._size();
10188			this._position();
10189		}
10190		if ( this.uiDialog.is(":data(ui-resizable)") ) {
10191			this.uiDialog.resizable( "option", resizableOptions );
10192		}
10193	},
10194
10195	_setOption: function( key, value ) {
10196		var isDraggable, isResizable,
10197			uiDialog = this.uiDialog;
10198
10199		if ( key === "dialogClass" ) {
10200			uiDialog
10201				.removeClass( this.options.dialogClass )
10202				.addClass( value );
10203		}
10204
10205		if ( key === "disabled" ) {
10206			return;
10207		}
10208
10209		this._super( key, value );
10210
10211		if ( key === "appendTo" ) {
10212			this.uiDialog.appendTo( this._appendTo() );
10213		}
10214
10215		if ( key === "buttons" ) {
10216			this._createButtons();
10217		}
10218
10219		if ( key === "closeText" ) {
10220			this.uiDialogTitlebarClose.button({
10221				// Ensure that we always pass a string
10222				label: "" + value
10223			});
10224		}
10225
10226		if ( key === "draggable" ) {
10227			isDraggable = uiDialog.is(":data(ui-draggable)");
10228			if ( isDraggable && !value ) {
10229				uiDialog.draggable("destroy");
10230			}
10231
10232			if ( !isDraggable && value ) {
10233				this._makeDraggable();
10234			}
10235		}
10236
10237		if ( key === "position" ) {
10238			this._position();
10239		}
10240
10241		if ( key === "resizable" ) {
10242			// currently resizable, becoming non-resizable
10243			isResizable = uiDialog.is(":data(ui-resizable)");
10244			if ( isResizable && !value ) {
10245				uiDialog.resizable("destroy");
10246			}
10247
10248			// currently resizable, changing handles
10249			if ( isResizable && typeof value === "string" ) {
10250				uiDialog.resizable( "option", "handles", value );
10251			}
10252
10253			// currently non-resizable, becoming resizable
10254			if ( !isResizable && value !== false ) {
10255				this._makeResizable();
10256			}
10257		}
10258
10259		if ( key === "title" ) {
10260			this._title( this.uiDialogTitlebar.find(".ui-dialog-title") );
10261		}
10262	},
10263
10264	_size: function() {
10265		// If the user has resized the dialog, the .ui-dialog and .ui-dialog-content
10266		// divs will both have width and height set, so we need to reset them
10267		var nonContentHeight, minContentHeight, maxContentHeight,
10268			options = this.options;
10269
10270		// Reset content sizing
10271		this.element.show().css({
10272			width: "auto",
10273			minHeight: 0,
10274			maxHeight: "none",
10275			height: 0
10276		});
10277
10278		if ( options.minWidth > options.width ) {
10279			options.width = options.minWidth;
10280		}
10281
10282		// reset wrapper sizing
10283		// determine the height of all the non-content elements
10284		nonContentHeight = this.uiDialog.css({
10285				height: "auto",
10286				width: options.width
10287			})
10288			.outerHeight();
10289		minContentHeight = Math.max( 0, options.minHeight - nonContentHeight );
10290		maxContentHeight = typeof options.maxHeight === "number" ?
10291			Math.max( 0, options.maxHeight - nonContentHeight ) :
10292			"none";
10293
10294		if ( options.height === "auto" ) {
10295			this.element.css({
10296				minHeight: minContentHeight,
10297				maxHeight: maxContentHeight,
10298				height: "auto"
10299			});
10300		} else {
10301			this.element.height( Math.max( 0, options.height - nonContentHeight ) );
10302		}
10303
10304		if (this.uiDialog.is(":data(ui-resizable)") ) {
10305			this.uiDialog.resizable( "option", "minHeight", this._minHeight() );
10306		}
10307	},
10308
10309	_blockFrames: function() {
10310		this.iframeBlocks = this.document.find( "iframe" ).map(function() {
10311			var iframe = $( this );
10312
10313			return $( "<div>" )
10314				.css({
10315					position: "absolute",
10316					width: iframe.outerWidth(),
10317					height: iframe.outerHeight()
10318				})
10319				.appendTo( iframe.parent() )
10320				.offset( iframe.offset() )[0];
10321		});
10322	},
10323
10324	_unblockFrames: function() {
10325		if ( this.iframeBlocks ) {
10326			this.iframeBlocks.remove();
10327			delete this.iframeBlocks;
10328		}
10329	},
10330
10331	_allowInteraction: function( event ) {
10332		if ( $( event.target ).closest(".ui-dialog").length ) {
10333			return true;
10334		}
10335
10336		// TODO: Remove hack when datepicker implements
10337		// the .ui-front logic (#8989)
10338		return !!$( event.target ).closest(".ui-datepicker").length;
10339	},
10340
10341	_createOverlay: function() {
10342		if ( !this.options.modal ) {
10343			return;
10344		}
10345
10346		var that = this,
10347			widgetFullName = this.widgetFullName;
10348		if ( !$.ui.dialog.overlayInstances ) {
10349			// Prevent use of anchors and inputs.
10350			// We use a delay in case the overlay is created from an
10351			// event that we're going to be cancelling. (#2804)
10352			this._delay(function() {
10353				// Handle .dialog().dialog("close") (#4065)
10354				if ( $.ui.dialog.overlayInstances ) {
10355					this.document.bind( "focusin.dialog", function( event ) {
10356						if ( !that._allowInteraction( event ) ) {
10357							event.preventDefault();
10358							$(".ui-dialog:visible:last .ui-dialog-content")
10359								.data( widgetFullName )._focusTabbable();
10360						}
10361					});
10362				}
10363			});
10364		}
10365
vendor: 7,122 bytes, lines 10366-10657
10366		this.overlay = $("<div>")
10367			.addClass("ui-widget-overlay ui-front")
10368			.appendTo( this._appendTo() );
10369		this._on( this.overlay, {
10370			mousedown: "_keepFocus"
10371		});
10372		$.ui.dialog.overlayInstances++;
10373	},
10374
10375	_destroyOverlay: function() {
10376		if ( !this.options.modal ) {
10377			return;
10378		}
10379
10380		if ( this.overlay ) {
10381			$.ui.dialog.overlayInstances--;
10382
10383			if ( !$.ui.dialog.overlayInstances ) {
10384				this.document.unbind( "focusin.dialog" );
10385			}
10386			this.overlay.remove();
10387			this.overlay = null;
10388		}
10389	}
10390});
10391
10392$.ui.dialog.overlayInstances = 0;
10393
10394// DEPRECATED
10395if ( $.uiBackCompat !== false ) {
10396	// position option with array notation
10397	// just override with old implementation
10398	$.widget( "ui.dialog", $.ui.dialog, {
10399		_position: function() {
10400			var position = this.options.position,
10401				myAt = [],
10402				offset = [ 0, 0 ],
10403				isVisible;
10404
10405			if ( position ) {
10406				if ( typeof position === "string" || (typeof position === "object" && "0" in position ) ) {
10407					myAt = position.split ? position.split(" ") : [ position[0], position[1] ];
10408					if ( myAt.length === 1 ) {
10409						myAt[1] = myAt[0];
10410					}
10411
10412					$.each( [ "left", "top" ], function( i, offsetPosition ) {
10413						if ( +myAt[ i ] === myAt[ i ] ) {
10414							offset[ i ] = myAt[ i ];
10415							myAt[ i ] = offsetPosition;
10416						}
10417					});
10418
10419					position = {
10420						my: myAt[0] + (offset[0] < 0 ? offset[0] : "+" + offset[0]) + " " +
10421							myAt[1] + (offset[1] < 0 ? offset[1] : "+" + offset[1]),
10422						at: myAt.join(" ")
10423					};
10424				}
10425
10426				position = $.extend( {}, $.ui.dialog.prototype.options.position, position );
10427			} else {
10428				position = $.ui.dialog.prototype.options.position;
10429			}
10430
10431			// need to show the dialog to get the actual offset in the position plugin
10432			isVisible = this.uiDialog.is(":visible");
10433			if ( !isVisible ) {
10434				this.uiDialog.show();
10435			}
10436			this.uiDialog.position( position );
10437			if ( !isVisible ) {
10438				this.uiDialog.hide();
10439			}
10440		}
10441	});
10442}
10443
10444}( jQuery ) );
10445
10446(function( $, undefined ) {
10447
10448var rvertical = /up|down|vertical/,
10449	rpositivemotion = /up|left|vertical|horizontal/;
10450
10451$.effects.effect.blind = function( o, done ) {
10452	// Create element
10453	var el = $( this ),
10454		props = [ "position", "top", "bottom", "left", "right", "height", "width" ],
10455		mode = $.effects.setMode( el, o.mode || "hide" ),
10456		direction = o.direction || "up",
10457		vertical = rvertical.test( direction ),
10458		ref = vertical ? "height" : "width",
10459		ref2 = vertical ? "top" : "left",
10460		motion = rpositivemotion.test( direction ),
10461		animation = {},
10462		show = mode === "show",
10463		wrapper, distance, margin;
10464
10465	// if already wrapped, the wrapper's properties are my property. #6245
10466	if ( el.parent().is( ".ui-effects-wrapper" ) ) {
10467		$.effects.save( el.parent(), props );
10468	} else {
10469		$.effects.save( el, props );
10470	}
10471	el.show();
10472	wrapper = $.effects.createWrapper( el ).css({
10473		overflow: "hidden"
10474	});
10475
10476	distance = wrapper[ ref ]();
10477	margin = parseFloat( wrapper.css( ref2 ) ) || 0;
10478
10479	animation[ ref ] = show ? distance : 0;
10480	if ( !motion ) {
10481		el
10482			.css( vertical ? "bottom" : "right", 0 )
10483			.css( vertical ? "top" : "left", "auto" )
10484			.css({ position: "absolute" });
10485
10486		animation[ ref2 ] = show ? margin : distance + margin;
10487	}
10488
10489	// start at 0 if we are showing
10490	if ( show ) {
10491		wrapper.css( ref, 0 );
10492		if ( ! motion ) {
10493			wrapper.css( ref2, margin + distance );
10494		}
10495	}
10496
10497	// Animate
10498	wrapper.animate( animation, {
10499		duration: o.duration,
10500		easing: o.easing,
10501		queue: false,
10502		complete: function() {
10503			if ( mode === "hide" ) {
10504				el.hide();
10505			}
10506			$.effects.restore( el, props );
10507			$.effects.removeWrapper( el );
10508			done();
10509		}
10510	});
10511
10512};
10513
10514})(jQuery);
10515
10516(function( $, undefined ) {
10517
10518$.effects.effect.bounce = function( o, done ) {
10519	var el = $( this ),
10520		props = [ "position", "top", "bottom", "left", "right", "height", "width" ],
10521
10522		// defaults:
10523		mode = $.effects.setMode( el, o.mode || "effect" ),
10524		hide = mode === "hide",
10525		show = mode === "show",
10526		direction = o.direction || "up",
10527		distance = o.distance,
10528		times = o.times || 5,
10529
10530		// number of internal animations
10531		anims = times * 2 + ( show || hide ? 1 : 0 ),
10532		speed = o.duration / anims,
10533		easing = o.easing,
10534
10535		// utility:
10536		ref = ( direction === "up" || direction === "down" ) ? "top" : "left",
10537		motion = ( direction === "up" || direction === "left" ),
10538		i,
10539		upAnim,
10540		downAnim,
10541
10542		// we will need to re-assemble the queue to stack our animations in place
10543		queue = el.queue(),
10544		queuelen = queue.length;
10545
10546	// Avoid touching opacity to prevent clearType and PNG issues in IE
10547	if ( show || hide ) {
10548		props.push( "opacity" );
10549	}
10550
10551	$.effects.save( el, props );
10552	el.show();
10553	$.effects.createWrapper( el ); // Create Wrapper
10554
10555	// default distance for the BIGGEST bounce is the outer Distance / 3
10556	if ( !distance ) {
10557		distance = el[ ref === "top" ? "outerHeight" : "outerWidth" ]() / 3;
10558	}
10559
10560	if ( show ) {
10561		downAnim = { opacity: 1 };
10562		downAnim[ ref ] = 0;
10563
10564		// if we are showing, force opacity 0 and set the initial position
10565		// then do the "first" animation
10566		el.css( "opacity", 0 )
10567			.css( ref, motion ? -distance * 2 : distance * 2 )
10568			.animate( downAnim, speed, easing );
10569	}
10570
10571	// start at the smallest distance if we are hiding
10572	if ( hide ) {
10573		distance = distance / Math.pow( 2, times - 1 );
10574	}
10575
10576	downAnim = {};
10577	downAnim[ ref ] = 0;
10578	// Bounces up/down/left/right then back to 0 -- times * 2 animations happen here
10579	for ( i = 0; i < times; i++ ) {
10580		upAnim = {};
10581		upAnim[ ref ] = ( motion ? "-=" : "+=" ) + distance;
10582
10583		el.animate( upAnim, speed, easing )
10584			.animate( downAnim, speed, easing );
10585
10586		distance = hide ? distance * 2 : distance / 2;
10587	}
10588
10589	// Last Bounce when Hiding
10590	if ( hide ) {
10591		upAnim = { opacity: 0 };
10592		upAnim[ ref ] = ( motion ? "-=" : "+=" ) + distance;
10593
10594		el.animate( upAnim, speed, easing );
10595	}
10596
10597	el.queue(function() {
10598		if ( hide ) {
10599			el.hide();
10600		}
10601		$.effects.restore( el, props );
10602		$.effects.removeWrapper( el );
10603		done();
10604	});
10605
10606	// inject all the animations we just queued to be first in line (after "inprogress")
10607	if ( queuelen > 1) {
10608		queue.splice.apply( queue,
10609			[ 1, 0 ].concat( queue.splice( queuelen, anims + 1 ) ) );
10610	}
10611	el.dequeue();
10612
10613};
10614
10615})(jQuery);
10616
10617(function( $, undefined ) {
10618
10619$.effects.effect.clip = function( o, done ) {
10620	// Create element
10621	var el = $( this ),
10622		props = [ "position", "top", "bottom", "left", "right", "height", "width" ],
10623		mode = $.effects.setMode( el, o.mode || "hide" ),
10624		show = mode === "show",
10625		direction = o.direction || "vertical",
10626		vert = direction === "vertical",
10627		size = vert ? "height" : "width",
10628		position = vert ? "top" : "left",
10629		animation = {},
10630		wrapper, animate, distance;
10631
10632	// Save & Show
10633	$.effects.save( el, props );
10634	el.show();
10635
10636	// Create Wrapper
10637	wrapper = $.effects.createWrapper( el ).css({
10638		overflow: "hidden"
10639	});
10640	animate = ( el[0].tagName === "IMG" ) ? wrapper : el;
10641	distance = animate[ size ]();
10642
10643	// Shift
10644	if ( show ) {
10645		animate.css( size, 0 );
10646		animate.css( position, distance / 2 );
10647	}
10648
10649	// Create Animation Object:
10650	animation[ size ] = show ? distance : 0;
10651	animation[ position ] = show ? 0 : distance / 2;
10652
10653	// Animate
10654	animate.animate( animation, {
10655		queue: false,
10656		duration: o.duration,
10657		easing: o.easing,
vendor: 116,514 bytes, lines 10658-15040
10658		complete: function() {
10659			if ( !show ) {
10660				el.hide();
10661			}
10662			$.effects.restore( el, props );
10663			$.effects.removeWrapper( el );
10664			done();
10665		}
10666	});
10667
10668};
10669
10670})(jQuery);
10671
10672(function( $, undefined ) {
10673
10674$.effects.effect.drop = function( o, done ) {
10675
10676	var el = $( this ),
10677		props = [ "position", "top", "bottom", "left", "right", "opacity", "height", "width" ],
10678		mode = $.effects.setMode( el, o.mode || "hide" ),
10679		show = mode === "show",
10680		direction = o.direction || "left",
10681		ref = ( direction === "up" || direction === "down" ) ? "top" : "left",
10682		motion = ( direction === "up" || direction === "left" ) ? "pos" : "neg",
10683		animation = {
10684			opacity: show ? 1 : 0
10685		},
10686		distance;
10687
10688	// Adjust
10689	$.effects.save( el, props );
10690	el.show();
10691	$.effects.createWrapper( el );
10692
10693	distance = o.distance || el[ ref === "top" ? "outerHeight": "outerWidth" ]( true ) / 2;
10694
10695	if ( show ) {
10696		el
10697			.css( "opacity", 0 )
10698			.css( ref, motion === "pos" ? -distance : distance );
10699	}
10700
10701	// Animation
10702	animation[ ref ] = ( show ?
10703		( motion === "pos" ? "+=" : "-=" ) :
10704		( motion === "pos" ? "-=" : "+=" ) ) +
10705		distance;
10706
10707	// Animate
10708	el.animate( animation, {
10709		queue: false,
10710		duration: o.duration,
10711		easing: o.easing,
10712		complete: function() {
10713			if ( mode === "hide" ) {
10714				el.hide();
10715			}
10716			$.effects.restore( el, props );
10717			$.effects.removeWrapper( el );
10718			done();
10719		}
10720	});
10721};
10722
10723})(jQuery);
10724
10725(function( $, undefined ) {
10726
10727$.effects.effect.explode = function( o, done ) {
10728
10729	var rows = o.pieces ? Math.round( Math.sqrt( o.pieces ) ) : 3,
10730		cells = rows,
10731		el = $( this ),
10732		mode = $.effects.setMode( el, o.mode || "hide" ),
10733		show = mode === "show",
10734
10735		// show and then visibility:hidden the element before calculating offset
10736		offset = el.show().css( "visibility", "hidden" ).offset(),
10737
10738		// width and height of a piece
10739		width = Math.ceil( el.outerWidth() / cells ),
10740		height = Math.ceil( el.outerHeight() / rows ),
10741		pieces = [],
10742
10743		// loop
10744		i, j, left, top, mx, my;
10745
10746	// children animate complete:
10747	function childComplete() {
10748		pieces.push( this );
10749		if ( pieces.length === rows * cells ) {
10750			animComplete();
10751		}
10752	}
10753
10754	// clone the element for each row and cell.
10755	for( i = 0; i < rows ; i++ ) { // ===>
10756		top = offset.top + i * height;
10757		my = i - ( rows - 1 ) / 2 ;
10758
10759		for( j = 0; j < cells ; j++ ) { // |||
10760			left = offset.left + j * width;
10761			mx = j - ( cells - 1 ) / 2 ;
10762
10763			// Create a clone of the now hidden main element that will be absolute positioned
10764			// within a wrapper div off the -left and -top equal to size of our pieces
10765			el
10766				.clone()
10767				.appendTo( "body" )
10768				.wrap( "<div></div>" )
10769				.css({
10770					position: "absolute",
10771					visibility: "visible",
10772					left: -j * width,
10773					top: -i * height
10774				})
10775
10776			// select the wrapper - make it overflow: hidden and absolute positioned based on
10777			// where the original was located +left and +top equal to the size of pieces
10778				.parent()
10779				.addClass( "ui-effects-explode" )
10780				.css({
10781					position: "absolute",
10782					overflow: "hidden",
10783					width: width,
10784					height: height,
10785					left: left + ( show ? mx * width : 0 ),
10786					top: top + ( show ? my * height : 0 ),
10787					opacity: show ? 0 : 1
10788				}).animate({
10789					left: left + ( show ? 0 : mx * width ),
10790					top: top + ( show ? 0 : my * height ),
10791					opacity: show ? 1 : 0
10792				}, o.duration || 500, o.easing, childComplete );
10793		}
10794	}
10795
10796	function animComplete() {
10797		el.css({
10798			visibility: "visible"
10799		});
10800		$( pieces ).remove();
10801		if ( !show ) {
10802			el.hide();
10803		}
10804		done();
10805	}
10806};
10807
10808})(jQuery);
10809
10810(function( $, undefined ) {
10811
10812$.effects.effect.fade = function( o, done ) {
10813	var el = $( this ),
10814		mode = $.effects.setMode( el, o.mode || "toggle" );
10815
10816	el.animate({
10817		opacity: mode
10818	}, {
10819		queue: false,
10820		duration: o.duration,
10821		easing: o.easing,
10822		complete: done
10823	});
10824};
10825
10826})( jQuery );
10827
10828(function( $, undefined ) {
10829
10830$.effects.effect.fold = function( o, done ) {
10831
10832	// Create element
10833	var el = $( this ),
10834		props = [ "position", "top", "bottom", "left", "right", "height", "width" ],
10835		mode = $.effects.setMode( el, o.mode || "hide" ),
10836		show = mode === "show",
10837		hide = mode === "hide",
10838		size = o.size || 15,
10839		percent = /([0-9]+)%/.exec( size ),
10840		horizFirst = !!o.horizFirst,
10841		widthFirst = show !== horizFirst,
10842		ref = widthFirst ? [ "width", "height" ] : [ "height", "width" ],
10843		duration = o.duration / 2,
10844		wrapper, distance,
10845		animation1 = {},
10846		animation2 = {};
10847
10848	$.effects.save( el, props );
10849	el.show();
10850
10851	// Create Wrapper
10852	wrapper = $.effects.createWrapper( el ).css({
10853		overflow: "hidden"
10854	});
10855	distance = widthFirst ?
10856		[ wrapper.width(), wrapper.height() ] :
10857		[ wrapper.height(), wrapper.width() ];
10858
10859	if ( percent ) {
10860		size = parseInt( percent[ 1 ], 10 ) / 100 * distance[ hide ? 0 : 1 ];
10861	}
10862	if ( show ) {
10863		wrapper.css( horizFirst ? {
10864			height: 0,
10865			width: size
10866		} : {
10867			height: size,
10868			width: 0
10869		});
10870	}
10871
10872	// Animation
10873	animation1[ ref[ 0 ] ] = show ? distance[ 0 ] : size;
10874	animation2[ ref[ 1 ] ] = show ? distance[ 1 ] : 0;
10875
10876	// Animate
10877	wrapper
10878		.animate( animation1, duration, o.easing )
10879		.animate( animation2, duration, o.easing, function() {
10880			if ( hide ) {
10881				el.hide();
10882			}
10883			$.effects.restore( el, props );
10884			$.effects.removeWrapper( el );
10885			done();
10886		});
10887
10888};
10889
10890})(jQuery);
10891
10892(function( $, undefined ) {
10893
10894$.effects.effect.highlight = function( o, done ) {
10895	var elem = $( this ),
10896		props = [ "backgroundImage", "backgroundColor", "opacity" ],
10897		mode = $.effects.setMode( elem, o.mode || "show" ),
10898		animation = {
10899			backgroundColor: elem.css( "backgroundColor" )
10900		};
10901
10902	if (mode === "hide") {
10903		animation.opacity = 0;
10904	}
10905
10906	$.effects.save( elem, props );
10907
10908	elem
10909		.show()
10910		.css({
10911			backgroundImage: "none",
10912			backgroundColor: o.color || "#ffff99"
10913		})
10914		.animate( animation, {
10915			queue: false,
10916			duration: o.duration,
10917			easing: o.easing,
10918			complete: function() {
10919				if ( mode === "hide" ) {
10920					elem.hide();
10921				}
10922				$.effects.restore( elem, props );
10923				done();
10924			}
10925		});
10926};
10927
10928})(jQuery);
10929
10930(function( $, undefined ) {
10931
10932$.effects.effect.pulsate = function( o, done ) {
10933	var elem = $( this ),
10934		mode = $.effects.setMode( elem, o.mode || "show" ),
10935		show = mode === "show",
10936		hide = mode === "hide",
10937		showhide = ( show || mode === "hide" ),
10938
10939		// showing or hiding leaves of the "last" animation
10940		anims = ( ( o.times || 5 ) * 2 ) + ( showhide ? 1 : 0 ),
10941		duration = o.duration / anims,
10942		animateTo = 0,
10943		queue = elem.queue(),
10944		queuelen = queue.length,
10945		i;
10946
10947	if ( show || !elem.is(":visible")) {
10948		elem.css( "opacity", 0 ).show();
10949		animateTo = 1;
10950	}
10951
10952	// anims - 1 opacity "toggles"
10953	for ( i = 1; i < anims; i++ ) {
10954		elem.animate({
10955			opacity: animateTo
10956		}, duration, o.easing );
10957		animateTo = 1 - animateTo;
10958	}
10959
10960	elem.animate({
10961		opacity: animateTo
10962	}, duration, o.easing);
10963
10964	elem.queue(function() {
10965		if ( hide ) {
10966			elem.hide();
10967		}
10968		done();
10969	});
10970
10971	// We just queued up "anims" animations, we need to put them next in the queue
10972	if ( queuelen > 1 ) {
10973		queue.splice.apply( queue,
10974			[ 1, 0 ].concat( queue.splice( queuelen, anims + 1 ) ) );
10975	}
10976	elem.dequeue();
10977};
10978
10979})(jQuery);
10980
10981(function( $, undefined ) {
10982
10983$.effects.effect.puff = function( o, done ) {
10984	var elem = $( this ),
10985		mode = $.effects.setMode( elem, o.mode || "hide" ),
10986		hide = mode === "hide",
10987		percent = parseInt( o.percent, 10 ) || 150,
10988		factor = percent / 100,
10989		original = {
10990			height: elem.height(),
10991			width: elem.width(),
10992			outerHeight: elem.outerHeight(),
10993			outerWidth: elem.outerWidth()
10994		};
10995
10996	$.extend( o, {
10997		effect: "scale",
10998		queue: false,
10999		fade: true,
11000		mode: mode,
11001		complete: done,
11002		percent: hide ? percent : 100,
11003		from: hide ?
11004			original :
11005			{
11006				height: original.height * factor,
11007				width: original.width * factor,
11008				outerHeight: original.outerHeight * factor,
11009				outerWidth: original.outerWidth * factor
11010			}
11011	});
11012
11013	elem.effect( o );
11014};
11015
11016$.effects.effect.scale = function( o, done ) {
11017
11018	// Create element
11019	var el = $( this ),
11020		options = $.extend( true, {}, o ),
11021		mode = $.effects.setMode( el, o.mode || "effect" ),
11022		percent = parseInt( o.percent, 10 ) ||
11023			( parseInt( o.percent, 10 ) === 0 ? 0 : ( mode === "hide" ? 0 : 100 ) ),
11024		direction = o.direction || "both",
11025		origin = o.origin,
11026		original = {
11027			height: el.height(),
11028			width: el.width(),
11029			outerHeight: el.outerHeight(),
11030			outerWidth: el.outerWidth()
11031		},
11032		factor = {
11033			y: direction !== "horizontal" ? (percent / 100) : 1,
11034			x: direction !== "vertical" ? (percent / 100) : 1
11035		};
11036
11037	// We are going to pass this effect to the size effect:
11038	options.effect = "size";
11039	options.queue = false;
11040	options.complete = done;
11041
11042	// Set default origin and restore for show/hide
11043	if ( mode !== "effect" ) {
11044		options.origin = origin || ["middle","center"];
11045		options.restore = true;
11046	}
11047
11048	options.from = o.from || ( mode === "show" ? {
11049		height: 0,
11050		width: 0,
11051		outerHeight: 0,
11052		outerWidth: 0
11053	} : original );
11054	options.to = {
11055		height: original.height * factor.y,
11056		width: original.width * factor.x,
11057		outerHeight: original.outerHeight * factor.y,
11058		outerWidth: original.outerWidth * factor.x
11059	};
11060
11061	// Fade option to support puff
11062	if ( options.fade ) {
11063		if ( mode === "show" ) {
11064			options.from.opacity = 0;
11065			options.to.opacity = 1;
11066		}
11067		if ( mode === "hide" ) {
11068			options.from.opacity = 1;
11069			options.to.opacity = 0;
11070		}
11071	}
11072
11073	// Animate
11074	el.effect( options );
11075
11076};
11077
11078$.effects.effect.size = function( o, done ) {
11079
11080	// Create element
11081	var original, baseline, factor,
11082		el = $( this ),
11083		props0 = [ "position", "top", "bottom", "left", "right", "width", "height", "overflow", "opacity" ],
11084
11085		// Always restore
11086		props1 = [ "position", "top", "bottom", "left", "right", "overflow", "opacity" ],
11087
11088		// Copy for children
11089		props2 = [ "width", "height", "overflow" ],
11090		cProps = [ "fontSize" ],
11091		vProps = [ "borderTopWidth", "borderBottomWidth", "paddingTop", "paddingBottom" ],
11092		hProps = [ "borderLeftWidth", "borderRightWidth", "paddingLeft", "paddingRight" ],
11093
11094		// Set options
11095		mode = $.effects.setMode( el, o.mode || "effect" ),
11096		restore = o.restore || mode !== "effect",
11097		scale = o.scale || "both",
11098		origin = o.origin || [ "middle", "center" ],
11099		position = el.css( "position" ),
11100		props = restore ? props0 : props1,
11101		zero = {
11102			height: 0,
11103			width: 0,
11104			outerHeight: 0,
11105			outerWidth: 0
11106		};
11107
11108	if ( mode === "show" ) {
11109		el.show();
11110	}
11111	original = {
11112		height: el.height(),
11113		width: el.width(),
11114		outerHeight: el.outerHeight(),
11115		outerWidth: el.outerWidth()
11116	};
11117
11118	if ( o.mode === "toggle" && mode === "show" ) {
11119		el.from = o.to || zero;
11120		el.to = o.from || original;
11121	} else {
11122		el.from = o.from || ( mode === "show" ? zero : original );
11123		el.to = o.to || ( mode === "hide" ? zero : original );
11124	}
11125
11126	// Set scaling factor
11127	factor = {
11128		from: {
11129			y: el.from.height / original.height,
11130			x: el.from.width / original.width
11131		},
11132		to: {
11133			y: el.to.height / original.height,
11134			x: el.to.width / original.width
11135		}
11136	};
11137
11138	// Scale the css box
11139	if ( scale === "box" || scale === "both" ) {
11140
11141		// Vertical props scaling
11142		if ( factor.from.y !== factor.to.y ) {
11143			props = props.concat( vProps );
11144			el.from = $.effects.setTransition( el, vProps, factor.from.y, el.from );
11145			el.to = $.effects.setTransition( el, vProps, factor.to.y, el.to );
11146		}
11147
11148		// Horizontal props scaling
11149		if ( factor.from.x !== factor.to.x ) {
11150			props = props.concat( hProps );
11151			el.from = $.effects.setTransition( el, hProps, factor.from.x, el.from );
11152			el.to = $.effects.setTransition( el, hProps, factor.to.x, el.to );
11153		}
11154	}
11155
11156	// Scale the content
11157	if ( scale === "content" || scale === "both" ) {
11158
11159		// Vertical props scaling
11160		if ( factor.from.y !== factor.to.y ) {
11161			props = props.concat( cProps ).concat( props2 );
11162			el.from = $.effects.setTransition( el, cProps, factor.from.y, el.from );
11163			el.to = $.effects.setTransition( el, cProps, factor.to.y, el.to );
11164		}
11165	}
11166
11167	$.effects.save( el, props );
11168	el.show();
11169	$.effects.createWrapper( el );
11170	el.css( "overflow", "hidden" ).css( el.from );
11171
11172	// Adjust
11173	if (origin) { // Calculate baseline shifts
11174		baseline = $.effects.getBaseline( origin, original );
11175		el.from.top = ( original.outerHeight - el.outerHeight() ) * baseline.y;
11176		el.from.left = ( original.outerWidth - el.outerWidth() ) * baseline.x;
11177		el.to.top = ( original.outerHeight - el.to.outerHeight ) * baseline.y;
11178		el.to.left = ( original.outerWidth - el.to.outerWidth ) * baseline.x;
11179	}
11180	el.css( el.from ); // set top & left
11181
11182	// Animate
11183	if ( scale === "content" || scale === "both" ) { // Scale the children
11184
11185		// Add margins/font-size
11186		vProps = vProps.concat([ "marginTop", "marginBottom" ]).concat(cProps);
11187		hProps = hProps.concat([ "marginLeft", "marginRight" ]);
11188		props2 = props0.concat(vProps).concat(hProps);
11189
11190		el.find( "*[width]" ).each( function(){
11191			var child = $( this ),
11192				c_original = {
11193					height: child.height(),
11194					width: child.width(),
11195					outerHeight: child.outerHeight(),
11196					outerWidth: child.outerWidth()
11197				};
11198			if (restore) {
11199				$.effects.save(child, props2);
11200			}
11201
11202			child.from = {
11203				height: c_original.height * factor.from.y,
11204				width: c_original.width * factor.from.x,
11205				outerHeight: c_original.outerHeight * factor.from.y,
11206				outerWidth: c_original.outerWidth * factor.from.x
11207			};
11208			child.to = {
11209				height: c_original.height * factor.to.y,
11210				width: c_original.width * factor.to.x,
11211				outerHeight: c_original.height * factor.to.y,
11212				outerWidth: c_original.width * factor.to.x
11213			};
11214
11215			// Vertical props scaling
11216			if ( factor.from.y !== factor.to.y ) {
11217				child.from = $.effects.setTransition( child, vProps, factor.from.y, child.from );
11218				child.to = $.effects.setTransition( child, vProps, factor.to.y, child.to );
11219			}
11220
11221			// Horizontal props scaling
11222			if ( factor.from.x !== factor.to.x ) {
11223				child.from = $.effects.setTransition( child, hProps, factor.from.x, child.from );
11224				child.to = $.effects.setTransition( child, hProps, factor.to.x, child.to );
11225			}
11226
11227			// Animate children
11228			child.css( child.from );
11229			child.animate( child.to, o.duration, o.easing, function() {
11230
11231				// Restore children
11232				if ( restore ) {
11233					$.effects.restore( child, props2 );
11234				}
11235			});
11236		});
11237	}
11238
11239	// Animate
11240	el.animate( el.to, {
11241		queue: false,
11242		duration: o.duration,
11243		easing: o.easing,
11244		complete: function() {
11245			if ( el.to.opacity === 0 ) {
11246				el.css( "opacity", el.from.opacity );
11247			}
11248			if( mode === "hide" ) {
11249				el.hide();
11250			}
11251			$.effects.restore( el, props );
11252			if ( !restore ) {
11253
11254				// we need to calculate our new positioning based on the scaling
11255				if ( position === "static" ) {
11256					el.css({
11257						position: "relative",
11258						top: el.to.top,
11259						left: el.to.left
11260					});
11261				} else {
11262					$.each([ "top", "left" ], function( idx, pos ) {
11263						el.css( pos, function( _, str ) {
11264							var val = parseInt( str, 10 ),
11265								toRef = idx ? el.to.left : el.to.top;
11266
11267							// if original was "auto", recalculate the new value from wrapper
11268							if ( str === "auto" ) {
11269								return toRef + "px";
11270							}
11271
11272							return val + toRef + "px";
11273						});
11274					});
11275				}
11276			}
11277
11278			$.effects.removeWrapper( el );
11279			done();
11280		}
11281	});
11282
11283};
11284
11285})(jQuery);
11286
11287(function( $, undefined ) {
11288
11289$.effects.effect.shake = function( o, done ) {
11290
11291	var el = $( this ),
11292		props = [ "position", "top", "bottom", "left", "right", "height", "width" ],
11293		mode = $.effects.setMode( el, o.mode || "effect" ),
11294		direction = o.direction || "left",
11295		distance = o.distance || 20,
11296		times = o.times || 3,
11297		anims = times * 2 + 1,
11298		speed = Math.round(o.duration/anims),
11299		ref = (direction === "up" || direction === "down") ? "top" : "left",
11300		positiveMotion = (direction === "up" || direction === "left"),
11301		animation = {},
11302		animation1 = {},
11303		animation2 = {},
11304		i,
11305
11306		// we will need to re-assemble the queue to stack our animations in place
11307		queue = el.queue(),
11308		queuelen = queue.length;
11309
11310	$.effects.save( el, props );
11311	el.show();
11312	$.effects.createWrapper( el );
11313
11314	// Animation
11315	animation[ ref ] = ( positiveMotion ? "-=" : "+=" ) + distance;
11316	animation1[ ref ] = ( positiveMotion ? "+=" : "-=" ) + distance * 2;
11317	animation2[ ref ] = ( positiveMotion ? "-=" : "+=" ) + distance * 2;
11318
11319	// Animate
11320	el.animate( animation, speed, o.easing );
11321
11322	// Shakes
11323	for ( i = 1; i < times; i++ ) {
11324		el.animate( animation1, speed, o.easing ).animate( animation2, speed, o.easing );
11325	}
11326	el
11327		.animate( animation1, speed, o.easing )
11328		.animate( animation, speed / 2, o.easing )
11329		.queue(function() {
11330			if ( mode === "hide" ) {
11331				el.hide();
11332			}
11333			$.effects.restore( el, props );
11334			$.effects.removeWrapper( el );
11335			done();
11336		});
11337
11338	// inject all the animations we just queued to be first in line (after "inprogress")
11339	if ( queuelen > 1) {
11340		queue.splice.apply( queue,
11341			[ 1, 0 ].concat( queue.splice( queuelen, anims + 1 ) ) );
11342	}
11343	el.dequeue();
11344
11345};
11346
11347})(jQuery);
11348
11349(function( $, undefined ) {
11350
11351$.effects.effect.slide = function( o, done ) {
11352
11353	// Create element
11354	var el = $( this ),
11355		props = [ "position", "top", "bottom", "left", "right", "width", "height" ],
11356		mode = $.effects.setMode( el, o.mode || "show" ),
11357		show = mode === "show",
11358		direction = o.direction || "left",
11359		ref = (direction === "up" || direction === "down") ? "top" : "left",
11360		positiveMotion = (direction === "up" || direction === "left"),
11361		distance,
11362		animation = {};
11363
11364	// Adjust
11365	$.effects.save( el, props );
11366	el.show();
11367	distance = o.distance || el[ ref === "top" ? "outerHeight" : "outerWidth" ]( true );
11368
11369	$.effects.createWrapper( el ).css({
11370		overflow: "hidden"
11371	});
11372
11373	if ( show ) {
11374		el.css( ref, positiveMotion ? (isNaN(distance) ? "-" + distance : -distance) : distance );
11375	}
11376
11377	// Animation
11378	animation[ ref ] = ( show ?
11379		( positiveMotion ? "+=" : "-=") :
11380		( positiveMotion ? "-=" : "+=")) +
11381		distance;
11382
11383	// Animate
11384	el.animate( animation, {
11385		queue: false,
11386		duration: o.duration,
11387		easing: o.easing,
11388		complete: function() {
11389			if ( mode === "hide" ) {
11390				el.hide();
11391			}
11392			$.effects.restore( el, props );
11393			$.effects.removeWrapper( el );
11394			done();
11395		}
11396	});
11397};
11398
11399})(jQuery);
11400
11401(function( $, undefined ) {
11402
11403$.effects.effect.transfer = function( o, done ) {
11404	var elem = $( this ),
11405		target = $( o.to ),
11406		targetFixed = target.css( "position" ) === "fixed",
11407		body = $("body"),
11408		fixTop = targetFixed ? body.scrollTop() : 0,
11409		fixLeft = targetFixed ? body.scrollLeft() : 0,
11410		endPosition = target.offset(),
11411		animation = {
11412			top: endPosition.top - fixTop ,
11413			left: endPosition.left - fixLeft ,
11414			height: target.innerHeight(),
11415			width: target.innerWidth()
11416		},
11417		startPosition = elem.offset(),
11418		transfer = $( "<div class='ui-effects-transfer'></div>" )
11419			.appendTo( document.body )
11420			.addClass( o.className )
11421			.css({
11422				top: startPosition.top - fixTop ,
11423				left: startPosition.left - fixLeft ,
11424				height: elem.innerHeight(),
11425				width: elem.innerWidth(),
11426				position: targetFixed ? "fixed" : "absolute"
11427			})
11428			.animate( animation, o.duration, o.easing, function() {
11429				transfer.remove();
11430				done();
11431			});
11432};
11433
11434})(jQuery);
11435
11436(function( $, undefined ) {
11437
11438$.widget( "ui.menu", {
11439	version: "1.10.4",
11440	defaultElement: "<ul>",
11441	delay: 300,
11442	options: {
11443		icons: {
11444			submenu: "ui-icon-carat-1-e"
11445		},
11446		menus: "ul",
11447		position: {
11448			my: "left top",
11449			at: "right top"
11450		},
11451		role: "menu",
11452
11453		// callbacks
11454		blur: null,
11455		focus: null,
11456		select: null
11457	},
11458
11459	_create: function() {
11460		this.activeMenu = this.element;
11461		// flag used to prevent firing of the click handler
11462		// as the event bubbles up through nested menus
11463		this.mouseHandled = false;
11464		this.element
11465			.uniqueId()
11466			.addClass( "ui-menu ui-widget ui-widget-content ui-corner-all" )
11467			.toggleClass( "ui-menu-icons", !!this.element.find( ".ui-icon" ).length )
11468			.attr({
11469				role: this.options.role,
11470				tabIndex: 0
11471			})
11472			// need to catch all clicks on disabled menu
11473			// not possible through _on
11474			.bind( "click" + this.eventNamespace, $.proxy(function( event ) {
11475				if ( this.options.disabled ) {
11476					event.preventDefault();
11477				}
11478			}, this ));
11479
11480		if ( this.options.disabled ) {
11481			this.element
11482				.addClass( "ui-state-disabled" )
11483				.attr( "aria-disabled", "true" );
11484		}
11485
11486		this._on({
11487			// Prevent focus from sticking to links inside menu after clicking
11488			// them (focus should always stay on UL during navigation).
11489			"mousedown .ui-menu-item > a": function( event ) {
11490				event.preventDefault();
11491			},
11492			"click .ui-state-disabled > a": function( event ) {
11493				event.preventDefault();
11494			},
11495			"click .ui-menu-item:has(a)": function( event ) {
11496				var target = $( event.target ).closest( ".ui-menu-item" );
11497				if ( !this.mouseHandled && target.not( ".ui-state-disabled" ).length ) {
11498					this.select( event );
11499
11500					// Only set the mouseHandled flag if the event will bubble, see #9469.
11501					if ( !event.isPropagationStopped() ) {
11502						this.mouseHandled = true;
11503					}
11504
11505					// Open submenu on click
11506					if ( target.has( ".ui-menu" ).length ) {
11507						this.expand( event );
11508					} else if ( !this.element.is( ":focus" ) && $( this.document[ 0 ].activeElement ).closest( ".ui-menu" ).length ) {
11509
11510						// Redirect focus to the menu
11511						this.element.trigger( "focus", [ true ] );
11512
11513						// If the active item is on the top level, let it stay active.
11514						// Otherwise, blur the active item since it is no longer visible.
11515						if ( this.active && this.active.parents( ".ui-menu" ).length === 1 ) {
11516							clearTimeout( this.timer );
11517						}
11518					}
11519				}
11520			},
11521			"mouseenter .ui-menu-item": function( event ) {
11522				var target = $( event.currentTarget );
11523				// Remove ui-state-active class from siblings of the newly focused menu item
11524				// to avoid a jump caused by adjacent elements both having a class with a border
11525				target.siblings().children( ".ui-state-active" ).removeClass( "ui-state-active" );
11526				this.focus( event, target );
11527			},
11528			mouseleave: "collapseAll",
11529			"mouseleave .ui-menu": "collapseAll",
11530			focus: function( event, keepActiveItem ) {
11531				// If there's already an active item, keep it active
11532				// If not, activate the first item
11533				var item = this.active || this.element.children( ".ui-menu-item" ).eq( 0 );
11534
11535				if ( !keepActiveItem ) {
11536					this.focus( event, item );
11537				}
11538			},
11539			blur: function( event ) {
11540				this._delay(function() {
11541					if ( !$.contains( this.element[0], this.document[0].activeElement ) ) {
11542						this.collapseAll( event );
11543					}
11544				});
11545			},
11546			keydown: "_keydown"
11547		});
11548
11549		this.refresh();
11550
11551		// Clicks outside of a menu collapse any open menus
11552		this._on( this.document, {
11553			click: function( event ) {
11554				if ( !$( event.target ).closest( ".ui-menu" ).length ) {
11555					this.collapseAll( event );
11556				}
11557
11558				// Reset the mouseHandled flag
11559				this.mouseHandled = false;
11560			}
11561		});
11562	},
11563
11564	_destroy: function() {
11565		// Destroy (sub)menus
11566		this.element
11567			.removeAttr( "aria-activedescendant" )
11568			.find( ".ui-menu" ).addBack()
11569				.removeClass( "ui-menu ui-widget ui-widget-content ui-corner-all ui-menu-icons" )
11570				.removeAttr( "role" )
11571				.removeAttr( "tabIndex" )
11572				.removeAttr( "aria-labelledby" )
11573				.removeAttr( "aria-expanded" )
11574				.removeAttr( "aria-hidden" )
11575				.removeAttr( "aria-disabled" )
11576				.removeUniqueId()
11577				.show();
11578
11579		// Destroy menu items
11580		this.element.find( ".ui-menu-item" )
11581			.removeClass( "ui-menu-item" )
11582			.removeAttr( "role" )
11583			.removeAttr( "aria-disabled" )
11584			.children( "a" )
11585				.removeUniqueId()
11586				.removeClass( "ui-corner-all ui-state-hover" )
11587				.removeAttr( "tabIndex" )
11588				.removeAttr( "role" )
11589				.removeAttr( "aria-haspopup" )
11590				.children().each( function() {
11591					var elem = $( this );
11592					if ( elem.data( "ui-menu-submenu-carat" ) ) {
11593						elem.remove();
11594					}
11595				});
11596
11597		// Destroy menu dividers
11598		this.element.find( ".ui-menu-divider" ).removeClass( "ui-menu-divider ui-widget-content" );
11599	},
11600
11601	_keydown: function( event ) {
11602		var match, prev, character, skip, regex,
11603			preventDefault = true;
11604
11605		function escape( value ) {
11606			return value.replace( /[\-\[\]{}()*+?.,\\\^$|#\s]/g, "\\$&" );
11607		}
11608
11609		switch ( event.keyCode ) {
11610		case $.ui.keyCode.PAGE_UP:
11611			this.previousPage( event );
11612			break;
11613		case $.ui.keyCode.PAGE_DOWN:
11614			this.nextPage( event );
11615			break;
11616		case $.ui.keyCode.HOME:
11617			this._move( "first", "first", event );
11618			break;
11619		case $.ui.keyCode.END:
11620			this._move( "last", "last", event );
11621			break;
11622		case $.ui.keyCode.UP:
11623			this.previous( event );
11624			break;
11625		case $.ui.keyCode.DOWN:
11626			this.next( event );
11627			break;
11628		case $.ui.keyCode.LEFT:
11629			this.collapse( event );
11630			break;
11631		case $.ui.keyCode.RIGHT:
11632			if ( this.active && !this.active.is( ".ui-state-disabled" ) ) {
11633				this.expand( event );
11634			}
11635			break;
11636		case $.ui.keyCode.ENTER:
11637		case $.ui.keyCode.SPACE:
11638			this._activate( event );
11639			break;
11640		case $.ui.keyCode.ESCAPE:
11641			this.collapse( event );
11642			break;
11643		default:
11644			preventDefault = false;
11645			prev = this.previousFilter || "";
11646			character = String.fromCharCode( event.keyCode );
11647			skip = false;
11648
11649			clearTimeout( this.filterTimer );
11650
11651			if ( character === prev ) {
11652				skip = true;
11653			} else {
11654				character = prev + character;
11655			}
11656
11657			regex = new RegExp( "^" + escape( character ), "i" );
11658			match = this.activeMenu.children( ".ui-menu-item" ).filter(function() {
11659				return regex.test( $( this ).children( "a" ).text() );
11660			});
11661			match = skip && match.index( this.active.next() ) !== -1 ?
11662				this.active.nextAll( ".ui-menu-item" ) :
11663				match;
11664
11665			// If no matches on the current filter, reset to the last character pressed
11666			// to move down the menu to the first item that starts with that character
11667			if ( !match.length ) {
11668				character = String.fromCharCode( event.keyCode );
11669				regex = new RegExp( "^" + escape( character ), "i" );
11670				match = this.activeMenu.children( ".ui-menu-item" ).filter(function() {
11671					return regex.test( $( this ).children( "a" ).text() );
11672				});
11673			}
11674
11675			if ( match.length ) {
11676				this.focus( event, match );
11677				if ( match.length > 1 ) {
11678					this.previousFilter = character;
11679					this.filterTimer = this._delay(function() {
11680						delete this.previousFilter;
11681					}, 1000 );
11682				} else {
11683					delete this.previousFilter;
11684				}
11685			} else {
11686				delete this.previousFilter;
11687			}
11688		}
11689
11690		if ( preventDefault ) {
11691			event.preventDefault();
11692		}
11693	},
11694
11695	_activate: function( event ) {
11696		if ( !this.active.is( ".ui-state-disabled" ) ) {
11697			if ( this.active.children( "a[aria-haspopup='true']" ).length ) {
11698				this.expand( event );
11699			} else {
11700				this.select( event );
11701			}
11702		}
11703	},
11704
11705	refresh: function() {
11706		var menus,
11707			icon = this.options.icons.submenu,
11708			submenus = this.element.find( this.options.menus );
11709
11710		this.element.toggleClass( "ui-menu-icons", !!this.element.find( ".ui-icon" ).length );
11711
11712		// Initialize nested menus
11713		submenus.filter( ":not(.ui-menu)" )
11714			.addClass( "ui-menu ui-widget ui-widget-content ui-corner-all" )
11715			.hide()
11716			.attr({
11717				role: this.options.role,
11718				"aria-hidden": "true",
11719				"aria-expanded": "false"
11720			})
11721			.each(function() {
11722				var menu = $( this ),
11723					item = menu.prev( "a" ),
11724					submenuCarat = $( "<span>" )
11725						.addClass( "ui-menu-icon ui-icon " + icon )
11726						.data( "ui-menu-submenu-carat", true );
11727
11728				item
11729					.attr( "aria-haspopup", "true" )
11730					.prepend( submenuCarat );
11731				menu.attr( "aria-labelledby", item.attr( "id" ) );
11732			});
11733
11734		menus = submenus.add( this.element );
11735
11736		// Don't refresh list items that are already adapted
11737		menus.children( ":not(.ui-menu-item):has(a)" )
11738			.addClass( "ui-menu-item" )
11739			.attr( "role", "presentation" )
11740			.children( "a" )
11741				.uniqueId()
11742				.addClass( "ui-corner-all" )
11743				.attr({
11744					tabIndex: -1,
11745					role: this._itemRole()
11746				});
11747
11748		// Initialize unlinked menu-items containing spaces and/or dashes only as dividers
11749		menus.children( ":not(.ui-menu-item)" ).each(function() {
11750			var item = $( this );
11751			// hyphen, em dash, en dash
11752			if ( !/[^\-\u2014\u2013\s]/.test( item.text() ) ) {
11753				item.addClass( "ui-widget-content ui-menu-divider" );
11754			}
11755		});
11756
11757		// Add aria-disabled attribute to any disabled menu item
11758		menus.children( ".ui-state-disabled" ).attr( "aria-disabled", "true" );
11759
11760		// If the active item has been removed, blur the menu
11761		if ( this.active && !$.contains( this.element[ 0 ], this.active[ 0 ] ) ) {
11762			this.blur();
11763		}
11764	},
11765
11766	_itemRole: function() {
11767		return {
11768			menu: "menuitem",
11769			listbox: "option"
11770		}[ this.options.role ];
11771	},
11772
11773	_setOption: function( key, value ) {
11774		if ( key === "icons" ) {
11775			this.element.find( ".ui-menu-icon" )
11776				.removeClass( this.options.icons.submenu )
11777				.addClass( value.submenu );
11778		}
11779		this._super( key, value );
11780	},
11781
11782	focus: function( event, item ) {
11783		var nested, focused;
11784		this.blur( event, event && event.type === "focus" );
11785
11786		this._scrollIntoView( item );
11787
11788		this.active = item.first();
11789		focused = this.active.children( "a" ).addClass( "ui-state-focus" );
11790		// Only update aria-activedescendant if there's a role
11791		// otherwise we assume focus is managed elsewhere
11792		if ( this.options.role ) {
11793			this.element.attr( "aria-activedescendant", focused.attr( "id" ) );
11794		}
11795
11796		// Highlight active parent menu item, if any
11797		this.active
11798			.parent()
11799			.closest( ".ui-menu-item" )
11800			.children( "a:first" )
11801			.addClass( "ui-state-active" );
11802
11803		if ( event && event.type === "keydown" ) {
11804			this._close();
11805		} else {
11806			this.timer = this._delay(function() {
11807				this._close();
11808			}, this.delay );
11809		}
11810
11811		nested = item.children( ".ui-menu" );
11812		if ( nested.length && event && ( /^mouse/.test( event.type ) ) ) {
11813			this._startOpening(nested);
11814		}
11815		this.activeMenu = item.parent();
11816
11817		this._trigger( "focus", event, { item: item } );
11818	},
11819
11820	_scrollIntoView: function( item ) {
11821		var borderTop, paddingTop, offset, scroll, elementHeight, itemHeight;
11822		if ( this._hasScroll() ) {
11823			borderTop = parseFloat( $.css( this.activeMenu[0], "borderTopWidth" ) ) || 0;
11824			paddingTop = parseFloat( $.css( this.activeMenu[0], "paddingTop" ) ) || 0;
11825			offset = item.offset().top - this.activeMenu.offset().top - borderTop - paddingTop;
11826			scroll = this.activeMenu.scrollTop();
11827			elementHeight = this.activeMenu.height();
11828			itemHeight = item.height();
11829
11830			if ( offset < 0 ) {
11831				this.activeMenu.scrollTop( scroll + offset );
11832			} else if ( offset + itemHeight > elementHeight ) {
11833				this.activeMenu.scrollTop( scroll + offset - elementHeight + itemHeight );
11834			}
11835		}
11836	},
11837
11838	blur: function( event, fromFocus ) {
11839		if ( !fromFocus ) {
11840			clearTimeout( this.timer );
11841		}
11842
11843		if ( !this.active ) {
11844			return;
11845		}
11846
11847		this.active.children( "a" ).removeClass( "ui-state-focus" );
11848		this.active = null;
11849
11850		this._trigger( "blur", event, { item: this.active } );
11851	},
11852
11853	_startOpening: function( submenu ) {
11854		clearTimeout( this.timer );
11855
11856		// Don't open if already open fixes a Firefox bug that caused a .5 pixel
11857		// shift in the submenu position when mousing over the carat icon
11858		if ( submenu.attr( "aria-hidden" ) !== "true" ) {
11859			return;
11860		}
11861
11862		this.timer = this._delay(function() {
11863			this._close();
11864			this._open( submenu );
11865		}, this.delay );
11866	},
11867
11868	_open: function( submenu ) {
11869		var position = $.extend({
11870			of: this.active
11871		}, this.options.position );
11872
11873		clearTimeout( this.timer );
11874		this.element.find( ".ui-menu" ).not( submenu.parents( ".ui-menu" ) )
11875			.hide()
11876			.attr( "aria-hidden", "true" );
11877
11878		submenu
11879			.show()
11880			.removeAttr( "aria-hidden" )
11881			.attr( "aria-expanded", "true" )
11882			.position( position );
11883	},
11884
11885	collapseAll: function( event, all ) {
11886		clearTimeout( this.timer );
11887		this.timer = this._delay(function() {
11888			// If we were passed an event, look for the submenu that contains the event
11889			var currentMenu = all ? this.element :
11890				$( event && event.target ).closest( this.element.find( ".ui-menu" ) );
11891
11892			// If we found no valid submenu ancestor, use the main menu to close all sub menus anyway
11893			if ( !currentMenu.length ) {
11894				currentMenu = this.element;
11895			}
11896
11897			this._close( currentMenu );
11898
11899			this.blur( event );
11900			this.activeMenu = currentMenu;
11901		}, this.delay );
11902	},
11903
11904	// With no arguments, closes the currently active menu - if nothing is active
11905	// it closes all menus.  If passed an argument, it will search for menus BELOW
11906	_close: function( startMenu ) {
11907		if ( !startMenu ) {
11908			startMenu = this.active ? this.active.parent() : this.element;
11909		}
11910
11911		startMenu
11912			.find( ".ui-menu" )
11913				.hide()
11914				.attr( "aria-hidden", "true" )
11915				.attr( "aria-expanded", "false" )
11916			.end()
11917			.find( "a.ui-state-active" )
11918				.removeClass( "ui-state-active" );
11919	},
11920
11921	collapse: function( event ) {
11922		var newItem = this.active &&
11923			this.active.parent().closest( ".ui-menu-item", this.element );
11924		if ( newItem && newItem.length ) {
11925			this._close();
11926			this.focus( event, newItem );
11927		}
11928	},
11929
11930	expand: function( event ) {
11931		var newItem = this.active &&
11932			this.active
11933				.children( ".ui-menu " )
11934				.children( ".ui-menu-item" )
11935				.first();
11936
11937		if ( newItem && newItem.length ) {
11938			this._open( newItem.parent() );
11939
11940			// Delay so Firefox will not hide activedescendant change in expanding submenu from AT
11941			this._delay(function() {
11942				this.focus( event, newItem );
11943			});
11944		}
11945	},
11946
11947	next: function( event ) {
11948		this._move( "next", "first", event );
11949	},
11950
11951	previous: function( event ) {
11952		this._move( "prev", "last", event );
11953	},
11954
11955	isFirstItem: function() {
11956		return this.active && !this.active.prevAll( ".ui-menu-item" ).length;
11957	},
11958
11959	isLastItem: function() {
11960		return this.active && !this.active.nextAll( ".ui-menu-item" ).length;
11961	},
11962
11963	_move: function( direction, filter, event ) {
11964		var next;
11965		if ( this.active ) {
11966			if ( direction === "first" || direction === "last" ) {
11967				next = this.active
11968					[ direction === "first" ? "prevAll" : "nextAll" ]( ".ui-menu-item" )
11969					.eq( -1 );
11970			} else {
11971				next = this.active
11972					[ direction + "All" ]( ".ui-menu-item" )
11973					.eq( 0 );
11974			}
11975		}
11976		if ( !next || !next.length || !this.active ) {
11977			next = this.activeMenu.children( ".ui-menu-item" )[ filter ]();
11978		}
11979
11980		this.focus( event, next );
11981	},
11982
11983	nextPage: function( event ) {
11984		var item, base, height;
11985
11986		if ( !this.active ) {
11987			this.next( event );
11988			return;
11989		}
11990		if ( this.isLastItem() ) {
11991			return;
11992		}
11993		if ( this._hasScroll() ) {
11994			base = this.active.offset().top;
11995			height = this.element.height();
11996			this.active.nextAll( ".ui-menu-item" ).each(function() {
11997				item = $( this );
11998				return item.offset().top - base - height < 0;
11999			});
12000
12001			this.focus( event, item );
12002		} else {
12003			this.focus( event, this.activeMenu.children( ".ui-menu-item" )
12004				[ !this.active ? "first" : "last" ]() );
12005		}
12006	},
12007
12008	previousPage: function( event ) {
12009		var item, base, height;
12010		if ( !this.active ) {
12011			this.next( event );
12012			return;
12013		}
12014		if ( this.isFirstItem() ) {
12015			return;
12016		}
12017		if ( this._hasScroll() ) {
12018			base = this.active.offset().top;
12019			height = this.element.height();
12020			this.active.prevAll( ".ui-menu-item" ).each(function() {
12021				item = $( this );
12022				return item.offset().top - base + height > 0;
12023			});
12024
12025			this.focus( event, item );
12026		} else {
12027			this.focus( event, this.activeMenu.children( ".ui-menu-item" ).first() );
12028		}
12029	},
12030
12031	_hasScroll: function() {
12032		return this.element.outerHeight() < this.element.prop( "scrollHeight" );
12033	},
12034
12035	select: function( event ) {
12036		// TODO: It should never be possible to not have an active item at this
12037		// point, but the tests don't trigger mouseenter before click.
12038		this.active = this.active || $( event.target ).closest( ".ui-menu-item" );
12039		var ui = { item: this.active };
12040		if ( !this.active.has( ".ui-menu" ).length ) {
12041			this.collapseAll( event, true );
12042		}
12043		this._trigger( "select", event, ui );
12044	}
12045});
12046
12047}( jQuery ));
12048
12049(function( $, undefined ) {
12050
12051$.ui = $.ui || {};
12052
12053var cachedScrollbarWidth,
12054	max = Math.max,
12055	abs = Math.abs,
12056	round = Math.round,
12057	rhorizontal = /left|center|right/,
12058	rvertical = /top|center|bottom/,
12059	roffset = /[\+\-]\d+(\.[\d]+)?%?/,
12060	rposition = /^\w+/,
12061	rpercent = /%$/,
12062	_position = $.fn.position;
12063
12064function getOffsets( offsets, width, height ) {
12065	return [
12066		parseFloat( offsets[ 0 ] ) * ( rpercent.test( offsets[ 0 ] ) ? width / 100 : 1 ),
12067		parseFloat( offsets[ 1 ] ) * ( rpercent.test( offsets[ 1 ] ) ? height / 100 : 1 )
12068	];
12069}
12070
12071function parseCss( element, property ) {
12072	return parseInt( $.css( element, property ), 10 ) || 0;
12073}
12074
12075function getDimensions( elem ) {
12076	var raw = elem[0];
12077	if ( raw.nodeType === 9 ) {
12078		return {
12079			width: elem.width(),
12080			height: elem.height(),
12081			offset: { top: 0, left: 0 }
12082		};
12083	}
12084	if ( $.isWindow( raw ) ) {
12085		return {
12086			width: elem.width(),
12087			height: elem.height(),
12088			offset: { top: elem.scrollTop(), left: elem.scrollLeft() }
12089		};
12090	}
12091	if ( raw.preventDefault ) {
12092		return {
12093			width: 0,
12094			height: 0,
12095			offset: { top: raw.pageY, left: raw.pageX }
12096		};
12097	}
12098	return {
12099		width: elem.outerWidth(),
12100		height: elem.outerHeight(),
12101		offset: elem.offset()
12102	};
12103}
12104
12105$.position = {
12106	scrollbarWidth: function() {
12107		if ( cachedScrollbarWidth !== undefined ) {
12108			return cachedScrollbarWidth;
12109		}
12110		var w1, w2,
12111			div = $( "<div style='display:block;position:absolute;width:50px;height:50px;overflow:hidden;'><div style='height:100px;width:auto;'></div></div>" ),
12112			innerDiv = div.children()[0];
12113
12114		$( "body" ).append( div );
12115		w1 = innerDiv.offsetWidth;
12116		div.css( "overflow", "scroll" );
12117
12118		w2 = innerDiv.offsetWidth;
12119
12120		if ( w1 === w2 ) {
12121			w2 = div[0].clientWidth;
12122		}
12123
12124		div.remove();
12125
12126		return (cachedScrollbarWidth = w1 - w2);
12127	},
12128	getScrollInfo: function( within ) {
12129		var overflowX = within.isWindow || within.isDocument ? "" :
12130				within.element.css( "overflow-x" ),
12131			overflowY = within.isWindow || within.isDocument ? "" :
12132				within.element.css( "overflow-y" ),
12133			hasOverflowX = overflowX === "scroll" ||
12134				( overflowX === "auto" && within.width < within.element[0].scrollWidth ),
12135			hasOverflowY = overflowY === "scroll" ||
12136				( overflowY === "auto" && within.height < within.element[0].scrollHeight );
12137		return {
12138			width: hasOverflowY ? $.position.scrollbarWidth() : 0,
12139			height: hasOverflowX ? $.position.scrollbarWidth() : 0
12140		};
12141	},
12142	getWithinInfo: function( element ) {
12143		var withinElement = $( element || window ),
12144			isWindow = $.isWindow( withinElement[0] ),
12145			isDocument = !!withinElement[ 0 ] && withinElement[ 0 ].nodeType === 9;
12146		return {
12147			element: withinElement,
12148			isWindow: isWindow,
12149			isDocument: isDocument,
12150			offset: withinElement.offset() || { left: 0, top: 0 },
12151			scrollLeft: withinElement.scrollLeft(),
12152			scrollTop: withinElement.scrollTop(),
12153			width: isWindow ? withinElement.width() : withinElement.outerWidth(),
12154			height: isWindow ? withinElement.height() : withinElement.outerHeight()
12155		};
12156	}
12157};
12158
12159$.fn.position = function( options ) {
12160	if ( !options || !options.of ) {
12161		return _position.apply( this, arguments );
12162	}
12163
12164	// make a copy, we don't want to modify arguments
12165	options = $.extend( {}, options );
12166
12167	var atOffset, targetWidth, targetHeight, targetOffset, basePosition, dimensions,
12168		target = $( options.of ),
12169		within = $.position.getWithinInfo( options.within ),
12170		scrollInfo = $.position.getScrollInfo( within ),
12171		collision = ( options.collision || "flip" ).split( " " ),
12172		offsets = {};
12173
12174	dimensions = getDimensions( target );
12175	if ( target[0].preventDefault ) {
12176		// force left top to allow flipping
12177		options.at = "left top";
12178	}
12179	targetWidth = dimensions.width;
12180	targetHeight = dimensions.height;
12181	targetOffset = dimensions.offset;
12182	// clone to reuse original targetOffset later
12183	basePosition = $.extend( {}, targetOffset );
12184
12185	// force my and at to have valid horizontal and vertical positions
12186	// if a value is missing or invalid, it will be converted to center
12187	$.each( [ "my", "at" ], function() {
12188		var pos = ( options[ this ] || "" ).split( " " ),
12189			horizontalOffset,
12190			verticalOffset;
12191
12192		if ( pos.length === 1) {
12193			pos = rhorizontal.test( pos[ 0 ] ) ?
12194				pos.concat( [ "center" ] ) :
12195				rvertical.test( pos[ 0 ] ) ?
12196					[ "center" ].concat( pos ) :
12197					[ "center", "center" ];
12198		}
12199		pos[ 0 ] = rhorizontal.test( pos[ 0 ] ) ? pos[ 0 ] : "center";
12200		pos[ 1 ] = rvertical.test( pos[ 1 ] ) ? pos[ 1 ] : "center";
12201
12202		// calculate offsets
12203		horizontalOffset = roffset.exec( pos[ 0 ] );
12204		verticalOffset = roffset.exec( pos[ 1 ] );
12205		offsets[ this ] = [
12206			horizontalOffset ? horizontalOffset[ 0 ] : 0,
12207			verticalOffset ? verticalOffset[ 0 ] : 0
12208		];
12209
12210		// reduce to just the positions without the offsets
12211		options[ this ] = [
12212			rposition.exec( pos[ 0 ] )[ 0 ],
12213			rposition.exec( pos[ 1 ] )[ 0 ]
12214		];
12215	});
12216
12217	// normalize collision option
12218	if ( collision.length === 1 ) {
12219		collision[ 1 ] = collision[ 0 ];
12220	}
12221
12222	if ( options.at[ 0 ] === "right" ) {
12223		basePosition.left += targetWidth;
12224	} else if ( options.at[ 0 ] === "center" ) {
12225		basePosition.left += targetWidth / 2;
12226	}
12227
12228	if ( options.at[ 1 ] === "bottom" ) {
12229		basePosition.top += targetHeight;
12230	} else if ( options.at[ 1 ] === "center" ) {
12231		basePosition.top += targetHeight / 2;
12232	}
12233
12234	atOffset = getOffsets( offsets.at, targetWidth, targetHeight );
12235	basePosition.left += atOffset[ 0 ];
12236	basePosition.top += atOffset[ 1 ];
12237
12238	return this.each(function() {
12239		var collisionPosition, using,
12240			elem = $( this ),
12241			elemWidth = elem.outerWidth(),
12242			elemHeight = elem.outerHeight(),
12243			marginLeft = parseCss( this, "marginLeft" ),
12244			marginTop = parseCss( this, "marginTop" ),
12245			collisionWidth = elemWidth + marginLeft + parseCss( this, "marginRight" ) + scrollInfo.width,
12246			collisionHeight = elemHeight + marginTop + parseCss( this, "marginBottom" ) + scrollInfo.height,
12247			position = $.extend( {}, basePosition ),
12248			myOffset = getOffsets( offsets.my, elem.outerWidth(), elem.outerHeight() );
12249
12250		if ( options.my[ 0 ] === "right" ) {
12251			position.left -= elemWidth;
12252		} else if ( options.my[ 0 ] === "center" ) {
12253			position.left -= elemWidth / 2;
12254		}
12255
12256		if ( options.my[ 1 ] === "bottom" ) {
12257			position.top -= elemHeight;
12258		} else if ( options.my[ 1 ] === "center" ) {
12259			position.top -= elemHeight / 2;
12260		}
12261
12262		position.left += myOffset[ 0 ];
12263		position.top += myOffset[ 1 ];
12264
12265		// if the browser doesn't support fractions, then round for consistent results
12266		if ( !$.support.offsetFractions ) {
12267			position.left = round( position.left );
12268			position.top = round( position.top );
12269		}
12270
12271		collisionPosition = {
12272			marginLeft: marginLeft,
12273			marginTop: marginTop
12274		};
12275
12276		$.each( [ "left", "top" ], function( i, dir ) {
12277			if ( $.ui.position[ collision[ i ] ] ) {
12278				$.ui.position[ collision[ i ] ][ dir ]( position, {
12279					targetWidth: targetWidth,
12280					targetHeight: targetHeight,
12281					elemWidth: elemWidth,
12282					elemHeight: elemHeight,
12283					collisionPosition: collisionPosition,
12284					collisionWidth: collisionWidth,
12285					collisionHeight: collisionHeight,
12286					offset: [ atOffset[ 0 ] + myOffset[ 0 ], atOffset [ 1 ] + myOffset[ 1 ] ],
12287					my: options.my,
12288					at: options.at,
12289					within: within,
12290					elem : elem
12291				});
12292			}
12293		});
12294
12295		if ( options.using ) {
12296			// adds feedback as second argument to using callback, if present
12297			using = function( props ) {
12298				var left = targetOffset.left - position.left,
12299					right = left + targetWidth - elemWidth,
12300					top = targetOffset.top - position.top,
12301					bottom = top + targetHeight - elemHeight,
12302					feedback = {
12303						target: {
12304							element: target,
12305							left: targetOffset.left,
12306							top: targetOffset.top,
12307							width: targetWidth,
12308							height: targetHeight
12309						},
12310						element: {
12311							element: elem,
12312							left: position.left,
12313							top: position.top,
12314							width: elemWidth,
12315							height: elemHeight
12316						},
12317						horizontal: right < 0 ? "left" : left > 0 ? "right" : "center",
12318						vertical: bottom < 0 ? "top" : top > 0 ? "bottom" : "middle"
12319					};
12320				if ( targetWidth < elemWidth && abs( left + right ) < targetWidth ) {
12321					feedback.horizontal = "center";
12322				}
12323				if ( targetHeight < elemHeight && abs( top + bottom ) < targetHeight ) {
12324					feedback.vertical = "middle";
12325				}
12326				if ( max( abs( left ), abs( right ) ) > max( abs( top ), abs( bottom ) ) ) {
12327					feedback.important = "horizontal";
12328				} else {
12329					feedback.important = "vertical";
12330				}
12331				options.using.call( this, props, feedback );
12332			};
12333		}
12334
12335		elem.offset( $.extend( position, { using: using } ) );
12336	});
12337};
12338
12339$.ui.position = {
12340	fit: {
12341		left: function( position, data ) {
12342			var within = data.within,
12343				withinOffset = within.isWindow ? within.scrollLeft : within.offset.left,
12344				outerWidth = within.width,
12345				collisionPosLeft = position.left - data.collisionPosition.marginLeft,
12346				overLeft = withinOffset - collisionPosLeft,
12347				overRight = collisionPosLeft + data.collisionWidth - outerWidth - withinOffset,
12348				newOverRight;
12349
12350			// element is wider than within
12351			if ( data.collisionWidth > outerWidth ) {
12352				// element is initially over the left side of within
12353				if ( overLeft > 0 && overRight <= 0 ) {
12354					newOverRight = position.left + overLeft + data.collisionWidth - outerWidth - withinOffset;
12355					position.left += overLeft - newOverRight;
12356				// element is initially over right side of within
12357				} else if ( overRight > 0 && overLeft <= 0 ) {
12358					position.left = withinOffset;
12359				// element is initially over both left and right sides of within
12360				} else {
12361					if ( overLeft > overRight ) {
12362						position.left = withinOffset + outerWidth - data.collisionWidth;
12363					} else {
12364						position.left = withinOffset;
12365					}
12366				}
12367			// too far left -> align with left edge
12368			} else if ( overLeft > 0 ) {
12369				position.left += overLeft;
12370			// too far right -> align with right edge
12371			} else if ( overRight > 0 ) {
12372				position.left -= overRight;
12373			// adjust based on position and margin
12374			} else {
12375				position.left = max( position.left - collisionPosLeft, position.left );
12376			}
12377		},
12378		top: function( position, data ) {
12379			var within = data.within,
12380				withinOffset = within.isWindow ? within.scrollTop : within.offset.top,
12381				outerHeight = data.within.height,
12382				collisionPosTop = position.top - data.collisionPosition.marginTop,
12383				overTop = withinOffset - collisionPosTop,
12384				overBottom = collisionPosTop + data.collisionHeight - outerHeight - withinOffset,
12385				newOverBottom;
12386
12387			// element is taller than within
12388			if ( data.collisionHeight > outerHeight ) {
12389				// element is initially over the top of within
12390				if ( overTop > 0 && overBottom <= 0 ) {
12391					newOverBottom = position.top + overTop + data.collisionHeight - outerHeight - withinOffset;
12392					position.top += overTop - newOverBottom;
12393				// element is initially over bottom of within
12394				} else if ( overBottom > 0 && overTop <= 0 ) {
12395					position.top = withinOffset;
12396				// element is initially over both top and bottom of within
12397				} else {
12398					if ( overTop > overBottom ) {
12399						position.top = withinOffset + outerHeight - data.collisionHeight;
12400					} else {
12401						position.top = withinOffset;
12402					}
12403				}
12404			// too far up -> align with top
12405			} else if ( overTop > 0 ) {
12406				position.top += overTop;
12407			// too far down -> align with bottom edge
12408			} else if ( overBottom > 0 ) {
12409				position.top -= overBottom;
12410			// adjust based on position and margin
12411			} else {
12412				position.top = max( position.top - collisionPosTop, position.top );
12413			}
12414		}
12415	},
12416	flip: {
12417		left: function( position, data ) {
12418			var within = data.within,
12419				withinOffset = within.offset.left + within.scrollLeft,
12420				outerWidth = within.width,
12421				offsetLeft = within.isWindow ? within.scrollLeft : within.offset.left,
12422				collisionPosLeft = position.left - data.collisionPosition.marginLeft,
12423				overLeft = collisionPosLeft - offsetLeft,
12424				overRight = collisionPosLeft + data.collisionWidth - outerWidth - offsetLeft,
12425				myOffset = data.my[ 0 ] === "left" ?
12426					-data.elemWidth :
12427					data.my[ 0 ] === "right" ?
12428						data.elemWidth :
12429						0,
12430				atOffset = data.at[ 0 ] === "left" ?
12431					data.targetWidth :
12432					data.at[ 0 ] === "right" ?
12433						-data.targetWidth :
12434						0,
12435				offset = -2 * data.offset[ 0 ],
12436				newOverRight,
12437				newOverLeft;
12438
12439			if ( overLeft < 0 ) {
12440				newOverRight = position.left + myOffset + atOffset + offset + data.collisionWidth - outerWidth - withinOffset;
12441				if ( newOverRight < 0 || newOverRight < abs( overLeft ) ) {
12442					position.left += myOffset + atOffset + offset;
12443				}
12444			}
12445			else if ( overRight > 0 ) {
12446				newOverLeft = position.left - data.collisionPosition.marginLeft + myOffset + atOffset + offset - offsetLeft;
12447				if ( newOverLeft > 0 || abs( newOverLeft ) < overRight ) {
12448					position.left += myOffset + atOffset + offset;
12449				}
12450			}
12451		},
12452		top: function( position, data ) {
12453			var within = data.within,
12454				withinOffset = within.offset.top + within.scrollTop,
12455				outerHeight = within.height,
12456				offsetTop = within.isWindow ? within.scrollTop : within.offset.top,
12457				collisionPosTop = position.top - data.collisionPosition.marginTop,
12458				overTop = collisionPosTop - offsetTop,
12459				overBottom = collisionPosTop + data.collisionHeight - outerHeight - offsetTop,
12460				top = data.my[ 1 ] === "top",
12461				myOffset = top ?
12462					-data.elemHeight :
12463					data.my[ 1 ] === "bottom" ?
12464						data.elemHeight :
12465						0,
12466				atOffset = data.at[ 1 ] === "top" ?
12467					data.targetHeight :
12468					data.at[ 1 ] === "bottom" ?
12469						-data.targetHeight :
12470						0,
12471				offset = -2 * data.offset[ 1 ],
12472				newOverTop,
12473				newOverBottom;
12474			if ( overTop < 0 ) {
12475				newOverBottom = position.top + myOffset + atOffset + offset + data.collisionHeight - outerHeight - withinOffset;
12476				if ( ( position.top + myOffset + atOffset + offset) > overTop && ( newOverBottom < 0 || newOverBottom < abs( overTop ) ) ) {
12477					position.top += myOffset + atOffset + offset;
12478				}
12479			}
12480			else if ( overBottom > 0 ) {
12481				newOverTop = position.top - data.collisionPosition.marginTop + myOffset + atOffset + offset - offsetTop;
12482				if ( ( position.top + myOffset + atOffset + offset) > overBottom && ( newOverTop > 0 || abs( newOverTop ) < overBottom ) ) {
12483					position.top += myOffset + atOffset + offset;
12484				}
12485			}
12486		}
12487	},
12488	flipfit: {
12489		left: function() {
12490			$.ui.position.flip.left.apply( this, arguments );
12491			$.ui.position.fit.left.apply( this, arguments );
12492		},
12493		top: function() {
12494			$.ui.position.flip.top.apply( this, arguments );
12495			$.ui.position.fit.top.apply( this, arguments );
12496		}
12497	}
12498};
12499
12500// fraction support test
12501(function () {
12502	var testElement, testElementParent, testElementStyle, offsetLeft, i,
12503		body = document.getElementsByTagName( "body" )[ 0 ],
12504		div = document.createElement( "div" );
12505
12506	//Create a "fake body" for testing based on method used in jQuery.support
12507	testElement = document.createElement( body ? "div" : "body" );
12508	testElementStyle = {
12509		visibility: "hidden",
12510		width: 0,
12511		height: 0,
12512		border: 0,
12513		margin: 0,
12514		background: "none"
12515	};
12516	if ( body ) {
12517		$.extend( testElementStyle, {
12518			position: "absolute",
12519			left: "-1000px",
12520			top: "-1000px"
12521		});
12522	}
12523	for ( i in testElementStyle ) {
12524		testElement.style[ i ] = testElementStyle[ i ];
12525	}
12526	testElement.appendChild( div );
12527	testElementParent = body || document.documentElement;
12528	testElementParent.insertBefore( testElement, testElementParent.firstChild );
12529
12530	div.style.cssText = "position: absolute; left: 10.7432222px;";
12531
12532	offsetLeft = $( div ).offset().left;
12533	$.support.offsetFractions = offsetLeft > 10 && offsetLeft < 11;
12534
12535	testElement.innerHTML = "";
12536	testElementParent.removeChild( testElement );
12537})();
12538
12539}( jQuery ) );
12540
12541(function( $, undefined ) {
12542
12543$.widget( "ui.progressbar", {
12544	version: "1.10.4",
12545	options: {
12546		max: 100,
12547		value: 0,
12548
12549		change: null,
12550		complete: null
12551	},
12552
12553	min: 0,
12554
12555	_create: function() {
12556		// Constrain initial value
12557		this.oldValue = this.options.value = this._constrainedValue();
12558
12559		this.element
12560			.addClass( "ui-progressbar ui-widget ui-widget-content ui-corner-all" )
12561			.attr({
12562				// Only set static values, aria-valuenow and aria-valuemax are
12563				// set inside _refreshValue()
12564				role: "progressbar",
12565				"aria-valuemin": this.min
12566			});
12567
12568		this.valueDiv = $( "<div class='ui-progressbar-value ui-widget-header ui-corner-left'></div>" )
12569			.appendTo( this.element );
12570
12571		this._refreshValue();
12572	},
12573
12574	_destroy: function() {
12575		this.element
12576			.removeClass( "ui-progressbar ui-widget ui-widget-content ui-corner-all" )
12577			.removeAttr( "role" )
12578			.removeAttr( "aria-valuemin" )
12579			.removeAttr( "aria-valuemax" )
12580			.removeAttr( "aria-valuenow" );
12581
12582		this.valueDiv.remove();
12583	},
12584
12585	value: function( newValue ) {
12586		if ( newValue === undefined ) {
12587			return this.options.value;
12588		}
12589
12590		this.options.value = this._constrainedValue( newValue );
12591		this._refreshValue();
12592	},
12593
12594	_constrainedValue: function( newValue ) {
12595		if ( newValue === undefined ) {
12596			newValue = this.options.value;
12597		}
12598
12599		this.indeterminate = newValue === false;
12600
12601		// sanitize value
12602		if ( typeof newValue !== "number" ) {
12603			newValue = 0;
12604		}
12605
12606		return this.indeterminate ? false :
12607			Math.min( this.options.max, Math.max( this.min, newValue ) );
12608	},
12609
12610	_setOptions: function( options ) {
12611		// Ensure "value" option is set after other values (like max)
12612		var value = options.value;
12613		delete options.value;
12614
12615		this._super( options );
12616
12617		this.options.value = this._constrainedValue( value );
12618		this._refreshValue();
12619	},
12620
12621	_setOption: function( key, value ) {
12622		if ( key === "max" ) {
12623			// Don't allow a max less than min
12624			value = Math.max( this.min, value );
12625		}
12626
12627		this._super( key, value );
12628	},
12629
12630	_percentage: function() {
12631		return this.indeterminate ? 100 : 100 * ( this.options.value - this.min ) / ( this.options.max - this.min );
12632	},
12633
12634	_refreshValue: function() {
12635		var value = this.options.value,
12636			percentage = this._percentage();
12637
12638		this.valueDiv
12639			.toggle( this.indeterminate || value > this.min )
12640			.toggleClass( "ui-corner-right", value === this.options.max )
12641			.width( percentage.toFixed(0) + "%" );
12642
12643		this.element.toggleClass( "ui-progressbar-indeterminate", this.indeterminate );
12644
12645		if ( this.indeterminate ) {
12646			this.element.removeAttr( "aria-valuenow" );
12647			if ( !this.overlayDiv ) {
12648				this.overlayDiv = $( "<div class='ui-progressbar-overlay'></div>" ).appendTo( this.valueDiv );
12649			}
12650		} else {
12651			this.element.attr({
12652				"aria-valuemax": this.options.max,
12653				"aria-valuenow": value
12654			});
12655			if ( this.overlayDiv ) {
12656				this.overlayDiv.remove();
12657				this.overlayDiv = null;
12658			}
12659		}
12660
12661		if ( this.oldValue !== value ) {
12662			this.oldValue = value;
12663			this._trigger( "change" );
12664		}
12665		if ( value === this.options.max ) {
12666			this._trigger( "complete" );
12667		}
12668	}
12669});
12670
12671})( jQuery );
12672
12673(function( $, undefined ) {
12674
12675// number of pages in a slider
12676// (how many times can you page up/down to go through the whole range)
12677var numPages = 5;
12678
12679$.widget( "ui.slider", $.ui.mouse, {
12680	version: "1.10.4",
12681	widgetEventPrefix: "slide",
12682
12683	options: {
12684		animate: false,
12685		distance: 0,
12686		max: 100,
12687		min: 0,
12688		orientation: "horizontal",
12689		range: false,
12690		step: 1,
12691		value: 0,
12692		values: null,
12693
12694		// callbacks
12695		change: null,
12696		slide: null,
12697		start: null,
12698		stop: null
12699	},
12700
12701	_create: function() {
12702		this._keySliding = false;
12703		this._mouseSliding = false;
12704		this._animateOff = true;
12705		this._handleIndex = null;
12706		this._detectOrientation();
12707		this._mouseInit();
12708
12709		this.element
12710			.addClass( "ui-slider" +
12711				" ui-slider-" + this.orientation +
12712				" ui-widget" +
12713				" ui-widget-content" +
12714				" ui-corner-all");
12715
12716		this._refresh();
12717		this._setOption( "disabled", this.options.disabled );
12718
12719		this._animateOff = false;
12720	},
12721
12722	_refresh: function() {
12723		this._createRange();
12724		this._createHandles();
12725		this._setupEvents();
12726		this._refreshValue();
12727	},
12728
12729	_createHandles: function() {
12730		var i, handleCount,
12731			options = this.options,
12732			existingHandles = this.element.find( ".ui-slider-handle" ).addClass( "ui-state-default ui-corner-all" ),
12733			handle = "<a class='ui-slider-handle ui-state-default ui-corner-all' href='#'></a>",
12734			handles = [];
12735
12736		handleCount = ( options.values && options.values.length ) || 1;
12737
12738		if ( existingHandles.length > handleCount ) {
12739			existingHandles.slice( handleCount ).remove();
12740			existingHandles = existingHandles.slice( 0, handleCount );
12741		}
12742
12743		for ( i = existingHandles.length; i < handleCount; i++ ) {
12744			handles.push( handle );
12745		}
12746
12747		this.handles = existingHandles.add( $( handles.join( "" ) ).appendTo( this.element ) );
12748
12749		this.handle = this.handles.eq( 0 );
12750
12751		this.handles.each(function( i ) {
12752			$( this ).data( "ui-slider-handle-index", i );
12753		});
12754	},
12755
12756	_createRange: function() {
12757		var options = this.options,
12758			classes = "";
12759
12760		if ( options.range ) {
12761			if ( options.range === true ) {
12762				if ( !options.values ) {
12763					options.values = [ this._valueMin(), this._valueMin() ];
12764				} else if ( options.values.length && options.values.length !== 2 ) {
12765					options.values = [ options.values[0], options.values[0] ];
12766				} else if ( $.isArray( options.values ) ) {
12767					options.values = options.values.slice(0);
12768				}
12769			}
12770
12771			if ( !this.range || !this.range.length ) {
12772				this.range = $( "<div></div>" )
12773					.appendTo( this.element );
12774
12775				classes = "ui-slider-range" +
12776				// note: this isn't the most fittingly semantic framework class for this element,
12777				// but worked best visually with a variety of themes
12778				" ui-widget-header ui-corner-all";
12779			} else {
12780				this.range.removeClass( "ui-slider-range-min ui-slider-range-max" )
12781					// Handle range switching from true to min/max
12782					.css({
12783						"left": "",
12784						"bottom": ""
12785					});
12786			}
12787
12788			this.range.addClass( classes +
12789				( ( options.range === "min" || options.range === "max" ) ? " ui-slider-range-" + options.range : "" ) );
12790		} else {
12791			if ( this.range ) {
12792				this.range.remove();
12793			}
12794			this.range = null;
12795		}
12796	},
12797
12798	_setupEvents: function() {
12799		var elements = this.handles.add( this.range ).filter( "a" );
12800		this._off( elements );
12801		this._on( elements, this._handleEvents );
12802		this._hoverable( elements );
12803		this._focusable( elements );
12804	},
12805
12806	_destroy: function() {
12807		this.handles.remove();
12808		if ( this.range ) {
12809			this.range.remove();
12810		}
12811
12812		this.element
12813			.removeClass( "ui-slider" +
12814				" ui-slider-horizontal" +
12815				" ui-slider-vertical" +
12816				" ui-widget" +
12817				" ui-widget-content" +
12818				" ui-corner-all" );
12819
12820		this._mouseDestroy();
12821	},
12822
12823	_mouseCapture: function( event ) {
12824		var position, normValue, distance, closestHandle, index, allowed, offset, mouseOverHandle,
12825			that = this,
12826			o = this.options;
12827
12828		if ( o.disabled ) {
12829			return false;
12830		}
12831
12832		this.elementSize = {
12833			width: this.element.outerWidth(),
12834			height: this.element.outerHeight()
12835		};
12836		this.elementOffset = this.element.offset();
12837
12838		position = { x: event.pageX, y: event.pageY };
12839		normValue = this._normValueFromMouse( position );
12840		distance = this._valueMax() - this._valueMin() + 1;
12841		this.handles.each(function( i ) {
12842			var thisDistance = Math.abs( normValue - that.values(i) );
12843			if (( distance > thisDistance ) ||
12844				( distance === thisDistance &&
12845					(i === that._lastChangedValue || that.values(i) === o.min ))) {
12846				distance = thisDistance;
12847				closestHandle = $( this );
12848				index = i;
12849			}
12850		});
12851
12852		allowed = this._start( event, index );
12853		if ( allowed === false ) {
12854			return false;
12855		}
12856		this._mouseSliding = true;
12857
12858		this._handleIndex = index;
12859
12860		closestHandle
12861			.addClass( "ui-state-active" )
12862			.focus();
12863
12864		offset = closestHandle.offset();
12865		mouseOverHandle = !$( event.target ).parents().addBack().is( ".ui-slider-handle" );
12866		this._clickOffset = mouseOverHandle ? { left: 0, top: 0 } : {
12867			left: event.pageX - offset.left - ( closestHandle.width() / 2 ),
12868			top: event.pageY - offset.top -
12869				( closestHandle.height() / 2 ) -
12870				( parseInt( closestHandle.css("borderTopWidth"), 10 ) || 0 ) -
12871				( parseInt( closestHandle.css("borderBottomWidth"), 10 ) || 0) +
12872				( parseInt( closestHandle.css("marginTop"), 10 ) || 0)
12873		};
12874
12875		if ( !this.handles.hasClass( "ui-state-hover" ) ) {
12876			this._slide( event, index, normValue );
12877		}
12878		this._animateOff = true;
12879		return true;
12880	},
12881
12882	_mouseStart: function() {
12883		return true;
12884	},
12885
12886	_mouseDrag: function( event ) {
12887		var position = { x: event.pageX, y: event.pageY },
12888			normValue = this._normValueFromMouse( position );
12889
12890		this._slide( event, this._handleIndex, normValue );
12891
12892		return false;
12893	},
12894
12895	_mouseStop: function( event ) {
12896		this.handles.removeClass( "ui-state-active" );
12897		this._mouseSliding = false;
12898
12899		this._stop( event, this._handleIndex );
12900		this._change( event, this._handleIndex );
12901
12902		this._handleIndex = null;
12903		this._clickOffset = null;
12904		this._animateOff = false;
12905
12906		return false;
12907	},
12908
12909	_detectOrientation: function() {
12910		this.orientation = ( this.options.orientation === "vertical" ) ? "vertical" : "horizontal";
12911	},
12912
12913	_normValueFromMouse: function( position ) {
12914		var pixelTotal,
12915			pixelMouse,
12916			percentMouse,
12917			valueTotal,
12918			valueMouse;
12919
12920		if ( this.orientation === "horizontal" ) {
12921			pixelTotal = this.elementSize.width;
12922			pixelMouse = position.x - this.elementOffset.left - ( this._clickOffset ? this._clickOffset.left : 0 );
12923		} else {
12924			pixelTotal = this.elementSize.height;
12925			pixelMouse = position.y - this.elementOffset.top - ( this._clickOffset ? this._clickOffset.top : 0 );
12926		}
12927
12928		percentMouse = ( pixelMouse / pixelTotal );
12929		if ( percentMouse > 1 ) {
12930			percentMouse = 1;
12931		}
12932		if ( percentMouse < 0 ) {
12933			percentMouse = 0;
12934		}
12935		if ( this.orientation === "vertical" ) {
12936			percentMouse = 1 - percentMouse;
12937		}
12938
12939		valueTotal = this._valueMax() - this._valueMin();
12940		valueMouse = this._valueMin() + percentMouse * valueTotal;
12941
12942		return this._trimAlignValue( valueMouse );
12943	},
12944
12945	_start: function( event, index ) {
12946		var uiHash = {
12947			handle: this.handles[ index ],
12948			value: this.value()
12949		};
12950		if ( this.options.values && this.options.values.length ) {
12951			uiHash.value = this.values( index );
12952			uiHash.values = this.values();
12953		}
12954		return this._trigger( "start", event, uiHash );
12955	},
12956
12957	_slide: function( event, index, newVal ) {
12958		var otherVal,
12959			newValues,
12960			allowed;
12961
12962		if ( this.options.values && this.options.values.length ) {
12963			otherVal = this.values( index ? 0 : 1 );
12964
12965			if ( ( this.options.values.length === 2 && this.options.range === true ) &&
12966					( ( index === 0 && newVal > otherVal) || ( index === 1 && newVal < otherVal ) )
12967				) {
12968				newVal = otherVal;
12969			}
12970
12971			if ( newVal !== this.values( index ) ) {
12972				newValues = this.values();
12973				newValues[ index ] = newVal;
12974				// A slide can be canceled by returning false from the slide callback
12975				allowed = this._trigger( "slide", event, {
12976					handle: this.handles[ index ],
12977					value: newVal,
12978					values: newValues
12979				} );
12980				otherVal = this.values( index ? 0 : 1 );
12981				if ( allowed !== false ) {
12982					this.values( index, newVal );
12983				}
12984			}
12985		} else {
12986			if ( newVal !== this.value() ) {
12987				// A slide can be canceled by returning false from the slide callback
12988				allowed = this._trigger( "slide", event, {
12989					handle: this.handles[ index ],
12990					value: newVal
12991				} );
12992				if ( allowed !== false ) {
12993					this.value( newVal );
12994				}
12995			}
12996		}
12997	},
12998
12999	_stop: function( event, index ) {
13000		var uiHash = {
13001			handle: this.handles[ index ],
13002			value: this.value()
13003		};
13004		if ( this.options.values && this.options.values.length ) {
13005			uiHash.value = this.values( index );
13006			uiHash.values = this.values();
13007		}
13008
13009		this._trigger( "stop", event, uiHash );
13010	},
13011
13012	_change: function( event, index ) {
13013		if ( !this._keySliding && !this._mouseSliding ) {
13014			var uiHash = {
13015				handle: this.handles[ index ],
13016				value: this.value()
13017			};
13018			if ( this.options.values && this.options.values.length ) {
13019				uiHash.value = this.values( index );
13020				uiHash.values = this.values();
13021			}
13022
13023			//store the last changed value index for reference when handles overlap
13024			this._lastChangedValue = index;
13025
13026			this._trigger( "change", event, uiHash );
13027		}
13028	},
13029
13030	value: function( newValue ) {
13031		if ( arguments.length ) {
13032			this.options.value = this._trimAlignValue( newValue );
13033			this._refreshValue();
13034			this._change( null, 0 );
13035			return;
13036		}
13037
13038		return this._value();
13039	},
13040
13041	values: function( index, newValue ) {
13042		var vals,
13043			newValues,
13044			i;
13045
13046		if ( arguments.length > 1 ) {
13047			this.options.values[ index ] = this._trimAlignValue( newValue );
13048			this._refreshValue();
13049			this._change( null, index );
13050			return;
13051		}
13052
13053		if ( arguments.length ) {
13054			if ( $.isArray( arguments[ 0 ] ) ) {
13055				vals = this.options.values;
13056				newValues = arguments[ 0 ];
13057				for ( i = 0; i < vals.length; i += 1 ) {
13058					vals[ i ] = this._trimAlignValue( newValues[ i ] );
13059					this._change( null, i );
13060				}
13061				this._refreshValue();
13062			} else {
13063				if ( this.options.values && this.options.values.length ) {
13064					return this._values( index );
13065				} else {
13066					return this.value();
13067				}
13068			}
13069		} else {
13070			return this._values();
13071		}
13072	},
13073
13074	_setOption: function( key, value ) {
13075		var i,
13076			valsLength = 0;
13077
13078		if ( key === "range" && this.options.range === true ) {
13079			if ( value === "min" ) {
13080				this.options.value = this._values( 0 );
13081				this.options.values = null;
13082			} else if ( value === "max" ) {
13083				this.options.value = this._values( this.options.values.length-1 );
13084				this.options.values = null;
13085			}
13086		}
13087
13088		if ( $.isArray( this.options.values ) ) {
13089			valsLength = this.options.values.length;
13090		}
13091
13092		$.Widget.prototype._setOption.apply( this, arguments );
13093
13094		switch ( key ) {
13095			case "orientation":
13096				this._detectOrientation();
13097				this.element
13098					.removeClass( "ui-slider-horizontal ui-slider-vertical" )
13099					.addClass( "ui-slider-" + this.orientation );
13100				this._refreshValue();
13101				break;
13102			case "value":
13103				this._animateOff = true;
13104				this._refreshValue();
13105				this._change( null, 0 );
13106				this._animateOff = false;
13107				break;
13108			case "values":
13109				this._animateOff = true;
13110				this._refreshValue();
13111				for ( i = 0; i < valsLength; i += 1 ) {
13112					this._change( null, i );
13113				}
13114				this._animateOff = false;
13115				break;
13116			case "min":
13117			case "max":
13118				this._animateOff = true;
13119				this._refreshValue();
13120				this._animateOff = false;
13121				break;
13122			case "range":
13123				this._animateOff = true;
13124				this._refresh();
13125				this._animateOff = false;
13126				break;
13127		}
13128	},
13129
13130	//internal value getter
13131	// _value() returns value trimmed by min and max, aligned by step
13132	_value: function() {
13133		var val = this.options.value;
13134		val = this._trimAlignValue( val );
13135
13136		return val;
13137	},
13138
13139	//internal values getter
13140	// _values() returns array of values trimmed by min and max, aligned by step
13141	// _values( index ) returns single value trimmed by min and max, aligned by step
13142	_values: function( index ) {
13143		var val,
13144			vals,
13145			i;
13146
13147		if ( arguments.length ) {
13148			val = this.options.values[ index ];
13149			val = this._trimAlignValue( val );
13150
13151			return val;
13152		} else if ( this.options.values && this.options.values.length ) {
13153			// .slice() creates a copy of the array
13154			// this copy gets trimmed by min and max and then returned
13155			vals = this.options.values.slice();
13156			for ( i = 0; i < vals.length; i+= 1) {
13157				vals[ i ] = this._trimAlignValue( vals[ i ] );
13158			}
13159
13160			return vals;
13161		} else {
13162			return [];
13163		}
13164	},
13165
13166	// returns the step-aligned value that val is closest to, between (inclusive) min and max
13167	_trimAlignValue: function( val ) {
13168		if ( val <= this._valueMin() ) {
13169			return this._valueMin();
13170		}
13171		if ( val >= this._valueMax() ) {
13172			return this._valueMax();
13173		}
13174		var step = ( this.options.step > 0 ) ? this.options.step : 1,
13175			valModStep = (val - this._valueMin()) % step,
13176			alignValue = val - valModStep;
13177
13178		if ( Math.abs(valModStep) * 2 >= step ) {
13179			alignValue += ( valModStep > 0 ) ? step : ( -step );
13180		}
13181
13182		// Since JavaScript has problems with large floats, round
13183		// the final value to 5 digits after the decimal point (see #4124)
13184		return parseFloat( alignValue.toFixed(5) );
13185	},
13186
13187	_valueMin: function() {
13188		return this.options.min;
13189	},
13190
13191	_valueMax: function() {
13192		return this.options.max;
13193	},
13194
13195	_refreshValue: function() {
13196		var lastValPercent, valPercent, value, valueMin, valueMax,
13197			oRange = this.options.range,
13198			o = this.options,
13199			that = this,
13200			animate = ( !this._animateOff ) ? o.animate : false,
13201			_set = {};
13202
13203		if ( this.options.values && this.options.values.length ) {
13204			this.handles.each(function( i ) {
13205				valPercent = ( that.values(i) - that._valueMin() ) / ( that._valueMax() - that._valueMin() ) * 100;
13206				_set[ that.orientation === "horizontal" ? "left" : "bottom" ] = valPercent + "%";
13207				$( this ).stop( 1, 1 )[ animate ? "animate" : "css" ]( _set, o.animate );
13208				if ( that.options.range === true ) {
13209					if ( that.orientation === "horizontal" ) {
13210						if ( i === 0 ) {
13211							that.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { left: valPercent + "%" }, o.animate );
13212						}
13213						if ( i === 1 ) {
13214							that.range[ animate ? "animate" : "css" ]( { width: ( valPercent - lastValPercent ) + "%" }, { queue: false, duration: o.animate } );
13215						}
13216					} else {
13217						if ( i === 0 ) {
13218							that.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { bottom: ( valPercent ) + "%" }, o.animate );
13219						}
13220						if ( i === 1 ) {
13221							that.range[ animate ? "animate" : "css" ]( { height: ( valPercent - lastValPercent ) + "%" }, { queue: false, duration: o.animate } );
13222						}
13223					}
13224				}
13225				lastValPercent = valPercent;
13226			});
13227		} else {
13228			value = this.value();
13229			valueMin = this._valueMin();
13230			valueMax = this._valueMax();
13231			valPercent = ( valueMax !== valueMin ) ?
13232					( value - valueMin ) / ( valueMax - valueMin ) * 100 :
13233					0;
13234			_set[ this.orientation === "horizontal" ? "left" : "bottom" ] = valPercent + "%";
13235			this.handle.stop( 1, 1 )[ animate ? "animate" : "css" ]( _set, o.animate );
13236
13237			if ( oRange === "min" && this.orientation === "horizontal" ) {
13238				this.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { width: valPercent + "%" }, o.animate );
13239			}
13240			if ( oRange === "max" && this.orientation === "horizontal" ) {
13241				this.range[ animate ? "animate" : "css" ]( { width: ( 100 - valPercent ) + "%" }, { queue: false, duration: o.animate } );
13242			}
13243			if ( oRange === "min" && this.orientation === "vertical" ) {
13244				this.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { height: valPercent + "%" }, o.animate );
13245			}
13246			if ( oRange === "max" && this.orientation === "vertical" ) {
13247				this.range[ animate ? "animate" : "css" ]( { height: ( 100 - valPercent ) + "%" }, { queue: false, duration: o.animate } );
13248			}
13249		}
13250	},
13251
13252	_handleEvents: {
13253		keydown: function( event ) {
13254			var allowed, curVal, newVal, step,
13255				index = $( event.target ).data( "ui-slider-handle-index" );
13256
13257			switch ( event.keyCode ) {
13258				case $.ui.keyCode.HOME:
13259				case $.ui.keyCode.END:
13260				case $.ui.keyCode.PAGE_UP:
13261				case $.ui.keyCode.PAGE_DOWN:
13262				case $.ui.keyCode.UP:
13263				case $.ui.keyCode.RIGHT:
13264				case $.ui.keyCode.DOWN:
13265				case $.ui.keyCode.LEFT:
13266					event.preventDefault();
13267					if ( !this._keySliding ) {
13268						this._keySliding = true;
13269						$( event.target ).addClass( "ui-state-active" );
13270						allowed = this._start( event, index );
13271						if ( allowed === false ) {
13272							return;
13273						}
13274					}
13275					break;
13276			}
13277
13278			step = this.options.step;
13279			if ( this.options.values && this.options.values.length ) {
13280				curVal = newVal = this.values( index );
13281			} else {
13282				curVal = newVal = this.value();
13283			}
13284
13285			switch ( event.keyCode ) {
13286				case $.ui.keyCode.HOME:
13287					newVal = this._valueMin();
13288					break;
13289				case $.ui.keyCode.END:
13290					newVal = this._valueMax();
13291					break;
13292				case $.ui.keyCode.PAGE_UP:
13293					newVal = this._trimAlignValue( curVal + ( (this._valueMax() - this._valueMin()) / numPages ) );
13294					break;
13295				case $.ui.keyCode.PAGE_DOWN:
13296					newVal = this._trimAlignValue( curVal - ( (this._valueMax() - this._valueMin()) / numPages ) );
13297					break;
13298				case $.ui.keyCode.UP:
13299				case $.ui.keyCode.RIGHT:
13300					if ( curVal === this._valueMax() ) {
13301						return;
13302					}
13303					newVal = this._trimAlignValue( curVal + step );
13304					break;
13305				case $.ui.keyCode.DOWN:
13306				case $.ui.keyCode.LEFT:
13307					if ( curVal === this._valueMin() ) {
13308						return;
13309					}
13310					newVal = this._trimAlignValue( curVal - step );
13311					break;
13312			}
13313
13314			this._slide( event, index, newVal );
13315		},
13316		click: function( event ) {
13317			event.preventDefault();
13318		},
13319		keyup: function( event ) {
13320			var index = $( event.target ).data( "ui-slider-handle-index" );
13321
13322			if ( this._keySliding ) {
13323				this._keySliding = false;
13324				this._stop( event, index );
13325				this._change( event, index );
13326				$( event.target ).removeClass( "ui-state-active" );
13327			}
13328		}
13329	}
13330
13331});
13332
13333}(jQuery));
13334
13335(function( $ ) {
13336
13337function modifier( fn ) {
13338	return function() {
13339		var previous = this.element.val();
13340		fn.apply( this, arguments );
13341		this._refresh();
13342		if ( previous !== this.element.val() ) {
13343			this._trigger( "change" );
13344		}
13345	};
13346}
13347
13348$.widget( "ui.spinner", {
13349	version: "1.10.4",
13350	defaultElement: "<input>",
13351	widgetEventPrefix: "spin",
13352	options: {
13353		culture: null,
13354		icons: {
13355			down: "ui-icon-triangle-1-s",
13356			up: "ui-icon-triangle-1-n"
13357		},
13358		incremental: true,
13359		max: null,
13360		min: null,
13361		numberFormat: null,
13362		page: 10,
13363		step: 1,
13364
13365		change: null,
13366		spin: null,
13367		start: null,
13368		stop: null
13369	},
13370
13371	_create: function() {
13372		// handle string values that need to be parsed
13373		this._setOption( "max", this.options.max );
13374		this._setOption( "min", this.options.min );
13375		this._setOption( "step", this.options.step );
13376
13377		// Only format if there is a value, prevents the field from being marked
13378		// as invalid in Firefox, see #9573.
13379		if ( this.value() !== "" ) {
13380			// Format the value, but don't constrain.
13381			this._value( this.element.val(), true );
13382		}
13383
13384		this._draw();
13385		this._on( this._events );
13386		this._refresh();
13387
13388		// turning off autocomplete prevents the browser from remembering the
13389		// value when navigating through history, so we re-enable autocomplete
13390		// if the page is unloaded before the widget is destroyed. #7790
13391		this._on( this.window, {
13392			beforeunload: function() {
13393				this.element.removeAttr( "autocomplete" );
13394			}
13395		});
13396	},
13397
13398	_getCreateOptions: function() {
13399		var options = {},
13400			element = this.element;
13401
13402		$.each( [ "min", "max", "step" ], function( i, option ) {
13403			var value = element.attr( option );
13404			if ( value !== undefined && value.length ) {
13405				options[ option ] = value;
13406			}
13407		});
13408
13409		return options;
13410	},
13411
13412	_events: {
13413		keydown: function( event ) {
13414			if ( this._start( event ) && this._keydown( event ) ) {
13415				event.preventDefault();
13416			}
13417		},
13418		keyup: "_stop",
13419		focus: function() {
13420			this.previous = this.element.val();
13421		},
13422		blur: function( event ) {
13423			if ( this.cancelBlur ) {
13424				delete this.cancelBlur;
13425				return;
13426			}
13427
13428			this._stop();
13429			this._refresh();
13430			if ( this.previous !== this.element.val() ) {
13431				this._trigger( "change", event );
13432			}
13433		},
13434		mousewheel: function( event, delta ) {
13435			if ( !delta ) {
13436				return;
13437			}
13438			if ( !this.spinning && !this._start( event ) ) {
13439				return false;
13440			}
13441
13442			this._spin( (delta > 0 ? 1 : -1) * this.options.step, event );
13443			clearTimeout( this.mousewheelTimer );
13444			this.mousewheelTimer = this._delay(function() {
13445				if ( this.spinning ) {
13446					this._stop( event );
13447				}
13448			}, 100 );
13449			event.preventDefault();
13450		},
13451		"mousedown .ui-spinner-button": function( event ) {
13452			var previous;
13453
13454			// We never want the buttons to have focus; whenever the user is
13455			// interacting with the spinner, the focus should be on the input.
13456			// If the input is focused then this.previous is properly set from
13457			// when the input first received focus. If the input is not focused
13458			// then we need to set this.previous based on the value before spinning.
13459			previous = this.element[0] === this.document[0].activeElement ?
13460				this.previous : this.element.val();
13461			function checkFocus() {
13462				var isActive = this.element[0] === this.document[0].activeElement;
13463				if ( !isActive ) {
13464					this.element.focus();
13465					this.previous = previous;
13466					// support: IE
13467					// IE sets focus asynchronously, so we need to check if focus
13468					// moved off of the input because the user clicked on the button.
13469					this._delay(function() {
13470						this.previous = previous;
13471					});
13472				}
13473			}
13474
13475			// ensure focus is on (or stays on) the text field
13476			event.preventDefault();
13477			checkFocus.call( this );
13478
13479			// support: IE
13480			// IE doesn't prevent moving focus even with event.preventDefault()
13481			// so we set a flag to know when we should ignore the blur event
13482			// and check (again) if focus moved off of the input.
13483			this.cancelBlur = true;
13484			this._delay(function() {
13485				delete this.cancelBlur;
13486				checkFocus.call( this );
13487			});
13488
13489			if ( this._start( event ) === false ) {
13490				return;
13491			}
13492
13493			this._repeat( null, $( event.currentTarget ).hasClass( "ui-spinner-up" ) ? 1 : -1, event );
13494		},
13495		"mouseup .ui-spinner-button": "_stop",
13496		"mouseenter .ui-spinner-button": function( event ) {
13497			// button will add ui-state-active if mouse was down while mouseleave and kept down
13498			if ( !$( event.currentTarget ).hasClass( "ui-state-active" ) ) {
13499				return;
13500			}
13501
13502			if ( this._start( event ) === false ) {
13503				return false;
13504			}
13505			this._repeat( null, $( event.currentTarget ).hasClass( "ui-spinner-up" ) ? 1 : -1, event );
13506		},
13507		// TODO: do we really want to consider this a stop?
13508		// shouldn't we just stop the repeater and wait until mouseup before
13509		// we trigger the stop event?
13510		"mouseleave .ui-spinner-button": "_stop"
13511	},
13512
13513	_draw: function() {
13514		var uiSpinner = this.uiSpinner = this.element
13515			.addClass( "ui-spinner-input" )
13516			.attr( "autocomplete", "off" )
13517			.wrap( this._uiSpinnerHtml() )
13518			.parent()
13519				// add buttons
13520				.append( this._buttonHtml() );
13521
13522		this.element.attr( "role", "spinbutton" );
13523
13524		// button bindings
13525		this.buttons = uiSpinner.find( ".ui-spinner-button" )
13526			.attr( "tabIndex", -1 )
13527			.button()
13528			.removeClass( "ui-corner-all" );
13529
13530		// IE 6 doesn't understand height: 50% for the buttons
13531		// unless the wrapper has an explicit height
13532		if ( this.buttons.height() > Math.ceil( uiSpinner.height() * 0.5 ) &&
13533				uiSpinner.height() > 0 ) {
13534			uiSpinner.height( uiSpinner.height() );
13535		}
13536
13537		// disable spinner if element was already disabled
13538		if ( this.options.disabled ) {
13539			this.disable();
13540		}
13541	},
13542
13543	_keydown: function( event ) {
13544		var options = this.options,
13545			keyCode = $.ui.keyCode;
13546
13547		switch ( event.keyCode ) {
13548		case keyCode.UP:
13549			this._repeat( null, 1, event );
13550			return true;
13551		case keyCode.DOWN:
13552			this._repeat( null, -1, event );
13553			return true;
13554		case keyCode.PAGE_UP:
13555			this._repeat( null, options.page, event );
13556			return true;
13557		case keyCode.PAGE_DOWN:
13558			this._repeat( null, -options.page, event );
13559			return true;
13560		}
13561
13562		return false;
13563	},
13564
13565	_uiSpinnerHtml: function() {
13566		return "<span class='ui-spinner ui-widget ui-widget-content ui-corner-all'></span>";
13567	},
13568
13569	_buttonHtml: function() {
13570		return "" +
13571			"<a class='ui-spinner-button ui-spinner-up ui-corner-tr'>" +
13572				"<span class='ui-icon " + this.options.icons.up + "'>&#9650;</span>" +
13573			"</a>" +
13574			"<a class='ui-spinner-button ui-spinner-down ui-corner-br'>" +
13575				"<span class='ui-icon " + this.options.icons.down + "'>&#9660;</span>" +
13576			"</a>";
13577	},
13578
13579	_start: function( event ) {
13580		if ( !this.spinning && this._trigger( "start", event ) === false ) {
13581			return false;
13582		}
13583
13584		if ( !this.counter ) {
13585			this.counter = 1;
13586		}
13587		this.spinning = true;
13588		return true;
13589	},
13590
13591	_repeat: function( i, steps, event ) {
13592		i = i || 500;
13593
13594		clearTimeout( this.timer );
13595		this.timer = this._delay(function() {
13596			this._repeat( 40, steps, event );
13597		}, i );
13598
13599		this._spin( steps * this.options.step, event );
13600	},
13601
13602	_spin: function( step, event ) {
13603		var value = this.value() || 0;
13604
13605		if ( !this.counter ) {
13606			this.counter = 1;
13607		}
13608
13609		value = this._adjustValue( value + step * this._increment( this.counter ) );
13610
13611		if ( !this.spinning || this._trigger( "spin", event, { value: value } ) !== false) {
13612			this._value( value );
13613			this.counter++;
13614		}
13615	},
13616
13617	_increment: function( i ) {
13618		var incremental = this.options.incremental;
13619
13620		if ( incremental ) {
13621			return $.isFunction( incremental ) ?
13622				incremental( i ) :
13623				Math.floor( i*i*i/50000 - i*i/500 + 17*i/200 + 1 );
13624		}
13625
13626		return 1;
13627	},
13628
13629	_precision: function() {
13630		var precision = this._precisionOf( this.options.step );
13631		if ( this.options.min !== null ) {
13632			precision = Math.max( precision, this._precisionOf( this.options.min ) );
13633		}
13634		return precision;
13635	},
13636
13637	_precisionOf: function( num ) {
13638		var str = num.toString(),
13639			decimal = str.indexOf( "." );
13640		return decimal === -1 ? 0 : str.length - decimal - 1;
13641	},
13642
13643	_adjustValue: function( value ) {
13644		var base, aboveMin,
13645			options = this.options;
13646
13647		// make sure we're at a valid step
13648		// - find out where we are relative to the base (min or 0)
13649		base = options.min !== null ? options.min : 0;
13650		aboveMin = value - base;
13651		// - round to the nearest step
13652		aboveMin = Math.round(aboveMin / options.step) * options.step;
13653		// - rounding is based on 0, so adjust back to our base
13654		value = base + aboveMin;
13655
13656		// fix precision from bad JS floating point math
13657		value = parseFloat( value.toFixed( this._precision() ) );
13658
13659		// clamp the value
13660		if ( options.max !== null && value > options.max) {
13661			return options.max;
13662		}
13663		if ( options.min !== null && value < options.min ) {
13664			return options.min;
13665		}
13666
13667		return value;
13668	},
13669
13670	_stop: function( event ) {
13671		if ( !this.spinning ) {
13672			return;
13673		}
13674
13675		clearTimeout( this.timer );
13676		clearTimeout( this.mousewheelTimer );
13677		this.counter = 0;
13678		this.spinning = false;
13679		this._trigger( "stop", event );
13680	},
13681
13682	_setOption: function( key, value ) {
13683		if ( key === "culture" || key === "numberFormat" ) {
13684			var prevValue = this._parse( this.element.val() );
13685			this.options[ key ] = value;
13686			this.element.val( this._format( prevValue ) );
13687			return;
13688		}
13689
13690		if ( key === "max" || key === "min" || key === "step" ) {
13691			if ( typeof value === "string" ) {
13692				value = this._parse( value );
13693			}
13694		}
13695		if ( key === "icons" ) {
13696			this.buttons.first().find( ".ui-icon" )
13697				.removeClass( this.options.icons.up )
13698				.addClass( value.up );
13699			this.buttons.last().find( ".ui-icon" )
13700				.removeClass( this.options.icons.down )
13701				.addClass( value.down );
13702		}
13703
13704		this._super( key, value );
13705
13706		if ( key === "disabled" ) {
13707			if ( value ) {
13708				this.element.prop( "disabled", true );
13709				this.buttons.button( "disable" );
13710			} else {
13711				this.element.prop( "disabled", false );
13712				this.buttons.button( "enable" );
13713			}
13714		}
13715	},
13716
13717	_setOptions: modifier(function( options ) {
13718		this._super( options );
13719		this._value( this.element.val() );
13720	}),
13721
13722	_parse: function( val ) {
13723		if ( typeof val === "string" && val !== "" ) {
13724			val = window.Globalize && this.options.numberFormat ?
13725				Globalize.parseFloat( val, 10, this.options.culture ) : +val;
13726		}
13727		return val === "" || isNaN( val ) ? null : val;
13728	},
13729
13730	_format: function( value ) {
13731		if ( value === "" ) {
13732			return "";
13733		}
13734		return window.Globalize && this.options.numberFormat ?
13735			Globalize.format( value, this.options.numberFormat, this.options.culture ) :
13736			value;
13737	},
13738
13739	_refresh: function() {
13740		this.element.attr({
13741			"aria-valuemin": this.options.min,
13742			"aria-valuemax": this.options.max,
13743			// TODO: what should we do with values that can't be parsed?
13744			"aria-valuenow": this._parse( this.element.val() )
13745		});
13746	},
13747
13748	// update the value without triggering change
13749	_value: function( value, allowAny ) {
13750		var parsed;
13751		if ( value !== "" ) {
13752			parsed = this._parse( value );
13753			if ( parsed !== null ) {
13754				if ( !allowAny ) {
13755					parsed = this._adjustValue( parsed );
13756				}
13757				value = this._format( parsed );
13758			}
13759		}
13760		this.element.val( value );
13761		this._refresh();
13762	},
13763
13764	_destroy: function() {
13765		this.element
13766			.removeClass( "ui-spinner-input" )
13767			.prop( "disabled", false )
13768			.removeAttr( "autocomplete" )
13769			.removeAttr( "role" )
13770			.removeAttr( "aria-valuemin" )
13771			.removeAttr( "aria-valuemax" )
13772			.removeAttr( "aria-valuenow" );
13773		this.uiSpinner.replaceWith( this.element );
13774	},
13775
13776	stepUp: modifier(function( steps ) {
13777		this._stepUp( steps );
13778	}),
13779	_stepUp: function( steps ) {
13780		if ( this._start() ) {
13781			this._spin( (steps || 1) * this.options.step );
13782			this._stop();
13783		}
13784	},
13785
13786	stepDown: modifier(function( steps ) {
13787		this._stepDown( steps );
13788	}),
13789	_stepDown: function( steps ) {
13790		if ( this._start() ) {
13791			this._spin( (steps || 1) * -this.options.step );
13792			this._stop();
13793		}
13794	},
13795
13796	pageUp: modifier(function( pages ) {
13797		this._stepUp( (pages || 1) * this.options.page );
13798	}),
13799
13800	pageDown: modifier(function( pages ) {
13801		this._stepDown( (pages || 1) * this.options.page );
13802	}),
13803
13804	value: function( newVal ) {
13805		if ( !arguments.length ) {
13806			return this._parse( this.element.val() );
13807		}
13808		modifier( this._value ).call( this, newVal );
13809	},
13810
13811	widget: function() {
13812		return this.uiSpinner;
13813	}
13814});
13815
13816}( jQuery ) );
13817
13818(function( $, undefined ) {
13819
13820var tabId = 0,
13821	rhash = /#.*$/;
13822
13823function getNextTabId() {
13824	return ++tabId;
13825}
13826
13827function isLocal( anchor ) {
13828	// support: IE7
13829	// IE7 doesn't normalize the href property when set via script (#9317)
13830	anchor = anchor.cloneNode( false );
13831
13832	return anchor.hash.length > 1 &&
13833		decodeURIComponent( anchor.href.replace( rhash, "" ) ) ===
13834			decodeURIComponent( location.href.replace( rhash, "" ) );
13835}
13836
13837$.widget( "ui.tabs", {
13838	version: "1.10.4",
13839	delay: 300,
13840	options: {
13841		active: null,
13842		collapsible: false,
13843		event: "click",
13844		heightStyle: "content",
13845		hide: null,
13846		show: null,
13847
13848		// callbacks
13849		activate: null,
13850		beforeActivate: null,
13851		beforeLoad: null,
13852		load: null
13853	},
13854
13855	_create: function() {
13856		var that = this,
13857			options = this.options;
13858
13859		this.running = false;
13860
13861		this.element
13862			.addClass( "ui-tabs ui-widget ui-widget-content ui-corner-all" )
13863			.toggleClass( "ui-tabs-collapsible", options.collapsible )
13864			// Prevent users from focusing disabled tabs via click
13865			.delegate( ".ui-tabs-nav > li", "mousedown" + this.eventNamespace, function( event ) {
13866				if ( $( this ).is( ".ui-state-disabled" ) ) {
13867					event.preventDefault();
13868				}
13869			})
13870			// support: IE <9
13871			// Preventing the default action in mousedown doesn't prevent IE
13872			// from focusing the element, so if the anchor gets focused, blur.
13873			// We don't have to worry about focusing the previously focused
13874			// element since clicking on a non-focusable element should focus
13875			// the body anyway.
13876			.delegate( ".ui-tabs-anchor", "focus" + this.eventNamespace, function() {
13877				if ( $( this ).closest( "li" ).is( ".ui-state-disabled" ) ) {
13878					this.blur();
13879				}
13880			});
13881
13882		this._processTabs();
13883		options.active = this._initialActive();
13884
13885		// Take disabling tabs via class attribute from HTML
13886		// into account and update option properly.
13887		if ( $.isArray( options.disabled ) ) {
13888			options.disabled = $.unique( options.disabled.concat(
13889				$.map( this.tabs.filter( ".ui-state-disabled" ), function( li ) {
13890					return that.tabs.index( li );
13891				})
13892			) ).sort();
13893		}
13894
13895		// check for length avoids error when initializing empty list
13896		if ( this.options.active !== false && this.anchors.length ) {
13897			this.active = this._findActive( options.active );
13898		} else {
13899			this.active = $();
13900		}
13901
13902		this._refresh();
13903
13904		if ( this.active.length ) {
13905			this.load( options.active );
13906		}
13907	},
13908
13909	_initialActive: function() {
13910		var active = this.options.active,
13911			collapsible = this.options.collapsible,
13912			locationHash = location.hash.substring( 1 );
13913
13914		if ( active === null ) {
13915			// check the fragment identifier in the URL
13916			if ( locationHash ) {
13917				this.tabs.each(function( i, tab ) {
13918					if ( $( tab ).attr( "aria-controls" ) === locationHash ) {
13919						active = i;
13920						return false;
13921					}
13922				});
13923			}
13924
13925			// check for a tab marked active via a class
13926			if ( active === null ) {
13927				active = this.tabs.index( this.tabs.filter( ".ui-tabs-active" ) );
13928			}
13929
13930			// no active tab, set to false
13931			if ( active === null || active === -1 ) {
13932				active = this.tabs.length ? 0 : false;
13933			}
13934		}
13935
13936		// handle numbers: negative, out of range
13937		if ( active !== false ) {
13938			active = this.tabs.index( this.tabs.eq( active ) );
13939			if ( active === -1 ) {
13940				active = collapsible ? false : 0;
13941			}
13942		}
13943
13944		// don't allow collapsible: false and active: false
13945		if ( !collapsible && active === false && this.anchors.length ) {
13946			active = 0;
13947		}
13948
13949		return active;
13950	},
13951
13952	_getCreateEventData: function() {
13953		return {
13954			tab: this.active,
13955			panel: !this.active.length ? $() : this._getPanelForTab( this.active )
13956		};
13957	},
13958
13959	_tabKeydown: function( event ) {
13960		var focusedTab = $( this.document[0].activeElement ).closest( "li" ),
13961			selectedIndex = this.tabs.index( focusedTab ),
13962			goingForward = true;
13963
13964		if ( this._handlePageNav( event ) ) {
13965			return;
13966		}
13967
13968		switch ( event.keyCode ) {
13969			case $.ui.keyCode.RIGHT:
13970			case $.ui.keyCode.DOWN:
13971				selectedIndex++;
13972				break;
13973			case $.ui.keyCode.UP:
13974			case $.ui.keyCode.LEFT:
13975				goingForward = false;
13976				selectedIndex--;
13977				break;
13978			case $.ui.keyCode.END:
13979				selectedIndex = this.anchors.length - 1;
13980				break;
13981			case $.ui.keyCode.HOME:
13982				selectedIndex = 0;
13983				break;
13984			case $.ui.keyCode.SPACE:
13985				// Activate only, no collapsing
13986				event.preventDefault();
13987				clearTimeout( this.activating );
13988				this._activate( selectedIndex );
13989				return;
13990			case $.ui.keyCode.ENTER:
13991				// Toggle (cancel delayed activation, allow collapsing)
13992				event.preventDefault();
13993				clearTimeout( this.activating );
13994				// Determine if we should collapse or activate
13995				this._activate( selectedIndex === this.options.active ? false : selectedIndex );
13996				return;
13997			default:
13998				return;
13999		}
14000
14001		// Focus the appropriate tab, based on which key was pressed
14002		event.preventDefault();
14003		clearTimeout( this.activating );
14004		selectedIndex = this._focusNextTab( selectedIndex, goingForward );
14005
14006		// Navigating with control key will prevent automatic activation
14007		if ( !event.ctrlKey ) {
14008			// Update aria-selected immediately so that AT think the tab is already selected.
14009			// Otherwise AT may confuse the user by stating that they need to activate the tab,
14010			// but the tab will already be activated by the time the announcement finishes.
14011			focusedTab.attr( "aria-selected", "false" );
14012			this.tabs.eq( selectedIndex ).attr( "aria-selected", "true" );
14013
14014			this.activating = this._delay(function() {
14015				this.option( "active", selectedIndex );
14016			}, this.delay );
14017		}
14018	},
14019
14020	_panelKeydown: function( event ) {
14021		if ( this._handlePageNav( event ) ) {
14022			return;
14023		}
14024
14025		// Ctrl+up moves focus to the current tab
14026		if ( event.ctrlKey && event.keyCode === $.ui.keyCode.UP ) {
14027			event.preventDefault();
14028			this.active.focus();
14029		}
14030	},
14031
14032	// Alt+page up/down moves focus to the previous/next tab (and activates)
14033	_handlePageNav: function( event ) {
14034		if ( event.altKey && event.keyCode === $.ui.keyCode.PAGE_UP ) {
14035			this._activate( this._focusNextTab( this.options.active - 1, false ) );
14036			return true;
14037		}
14038		if ( event.altKey && event.keyCode === $.ui.keyCode.PAGE_DOWN ) {
14039			this._activate( this._focusNextTab( this.options.active + 1, true ) );
14040			return true;
14041		}
14042	},
14043
14044	_findNextTab: function( index, goingForward ) {
14045		var lastTabIndex = this.tabs.length - 1;
14046
14047		function constrain() {
14048			if ( index > lastTabIndex ) {
14049				index = 0;
14050			}
14051			if ( index < 0 ) {
14052				index = lastTabIndex;
14053			}
14054			return index;
14055		}
14056
14057		while ( $.inArray( constrain(), this.options.disabled ) !== -1 ) {
14058			index = goingForward ? index + 1 : index - 1;
14059		}
14060
14061		return index;
14062	},
14063
14064	_focusNextTab: function( index, goingForward ) {
14065		index = this._findNextTab( index, goingForward );
14066		this.tabs.eq( index ).focus();
14067		return index;
14068	},
14069
14070	_setOption: function( key, value ) {
14071		if ( key === "active" ) {
14072			// _activate() will handle invalid values and update this.options
14073			this._activate( value );
14074			return;
14075		}
14076
14077		if ( key === "disabled" ) {
14078			// don't use the widget factory's disabled handling
14079			this._setupDisabled( value );
14080			return;
14081		}
14082
14083		this._super( key, value);
14084
14085		if ( key === "collapsible" ) {
14086			this.element.toggleClass( "ui-tabs-collapsible", value );
14087			// Setting collapsible: false while collapsed; open first panel
14088			if ( !value && this.options.active === false ) {
14089				this._activate( 0 );
14090			}
14091		}
14092
14093		if ( key === "event" ) {
14094			this._setupEvents( value );
14095		}
14096
14097		if ( key === "heightStyle" ) {
14098			this._setupHeightStyle( value );
14099		}
14100	},
14101
14102	_tabId: function( tab ) {
14103		return tab.attr( "aria-controls" ) || "ui-tabs-" + getNextTabId();
14104	},
14105
14106	_sanitizeSelector: function( hash ) {
14107		return hash ? hash.replace( /[!"$%&'()*+,.\/:;<=>?@\[\]\^`{|}~]/g, "\\$&" ) : "";
14108	},
14109
14110	refresh: function() {
14111		var options = this.options,
14112			lis = this.tablist.children( ":has(a[href])" );
14113
14114		// get disabled tabs from class attribute from HTML
14115		// this will get converted to a boolean if needed in _refresh()
14116		options.disabled = $.map( lis.filter( ".ui-state-disabled" ), function( tab ) {
14117			return lis.index( tab );
14118		});
14119
14120		this._processTabs();
14121
14122		// was collapsed or no tabs
14123		if ( options.active === false || !this.anchors.length ) {
14124			options.active = false;
14125			this.active = $();
14126		// was active, but active tab is gone
14127		} else if ( this.active.length && !$.contains( this.tablist[ 0 ], this.active[ 0 ] ) ) {
14128			// all remaining tabs are disabled
14129			if ( this.tabs.length === options.disabled.length ) {
14130				options.active = false;
14131				this.active = $();
14132			// activate previous tab
14133			} else {
14134				this._activate( this._findNextTab( Math.max( 0, options.active - 1 ), false ) );
14135			}
14136		// was active, active tab still exists
14137		} else {
14138			// make sure active index is correct
14139			options.active = this.tabs.index( this.active );
14140		}
14141
14142		this._refresh();
14143	},
14144
14145	_refresh: function() {
14146		this._setupDisabled( this.options.disabled );
14147		this._setupEvents( this.options.event );
14148		this._setupHeightStyle( this.options.heightStyle );
14149
14150		this.tabs.not( this.active ).attr({
14151			"aria-selected": "false",
14152			tabIndex: -1
14153		});
14154		this.panels.not( this._getPanelForTab( this.active ) )
14155			.hide()
14156			.attr({
14157				"aria-expanded": "false",
14158				"aria-hidden": "true"
14159			});
14160
14161		// Make sure one tab is in the tab order
14162		if ( !this.active.length ) {
14163			this.tabs.eq( 0 ).attr( "tabIndex", 0 );
14164		} else {
14165			this.active
14166				.addClass( "ui-tabs-active ui-state-active" )
14167				.attr({
14168					"aria-selected": "true",
14169					tabIndex: 0
14170				});
14171			this._getPanelForTab( this.active )
14172				.show()
14173				.attr({
14174					"aria-expanded": "true",
14175					"aria-hidden": "false"
14176				});
14177		}
14178	},
14179
14180	_processTabs: function() {
14181		var that = this;
14182
14183		this.tablist = this._getList()
14184			.addClass( "ui-tabs-nav ui-helper-reset ui-helper-clearfix ui-widget-header ui-corner-all" )
14185			.attr( "role", "tablist" );
14186
14187		this.tabs = this.tablist.find( "> li:has(a[href])" )
14188			.addClass( "ui-state-default ui-corner-top" )
14189			.attr({
14190				role: "tab",
14191				tabIndex: -1
14192			});
14193
14194		this.anchors = this.tabs.map(function() {
14195				return $( "a", this )[ 0 ];
14196			})
14197			.addClass( "ui-tabs-anchor" )
14198			.attr({
14199				role: "presentation",
14200				tabIndex: -1
14201			});
14202
14203		this.panels = $();
14204
14205		this.anchors.each(function( i, anchor ) {
14206			var selector, panel, panelId,
14207				anchorId = $( anchor ).uniqueId().attr( "id" ),
14208				tab = $( anchor ).closest( "li" ),
14209				originalAriaControls = tab.attr( "aria-controls" );
14210
14211			// inline tab
14212			if ( isLocal( anchor ) ) {
14213				selector = anchor.hash;
14214				panel = that.element.find( that._sanitizeSelector( selector ) );
14215			// remote tab
14216			} else {
14217				panelId = that._tabId( tab );
14218				selector = "#" + panelId;
14219				panel = that.element.find( selector );
14220				if ( !panel.length ) {
14221					panel = that._createPanel( panelId );
14222					panel.insertAfter( that.panels[ i - 1 ] || that.tablist );
14223				}
14224				panel.attr( "aria-live", "polite" );
14225			}
14226
14227			if ( panel.length) {
14228				that.panels = that.panels.add( panel );
14229			}
14230			if ( originalAriaControls ) {
14231				tab.data( "ui-tabs-aria-controls", originalAriaControls );
14232			}
14233			tab.attr({
14234				"aria-controls": selector.substring( 1 ),
14235				"aria-labelledby": anchorId
14236			});
14237			panel.attr( "aria-labelledby", anchorId );
14238		});
14239
14240		this.panels
14241			.addClass( "ui-tabs-panel ui-widget-content ui-corner-bottom" )
14242			.attr( "role", "tabpanel" );
14243	},
14244
14245	// allow overriding how to find the list for rare usage scenarios (#7715)
14246	_getList: function() {
14247		return this.tablist || this.element.find( "ol,ul" ).eq( 0 );
14248	},
14249
14250	_createPanel: function( id ) {
14251		return $( "<div>" )
14252			.attr( "id", id )
14253			.addClass( "ui-tabs-panel ui-widget-content ui-corner-bottom" )
14254			.data( "ui-tabs-destroy", true );
14255	},
14256
14257	_setupDisabled: function( disabled ) {
14258		if ( $.isArray( disabled ) ) {
14259			if ( !disabled.length ) {
14260				disabled = false;
14261			} else if ( disabled.length === this.anchors.length ) {
14262				disabled = true;
14263			}
14264		}
14265
14266		// disable tabs
14267		for ( var i = 0, li; ( li = this.tabs[ i ] ); i++ ) {
14268			if ( disabled === true || $.inArray( i, disabled ) !== -1 ) {
14269				$( li )
14270					.addClass( "ui-state-disabled" )
14271					.attr( "aria-disabled", "true" );
14272			} else {
14273				$( li )
14274					.removeClass( "ui-state-disabled" )
14275					.removeAttr( "aria-disabled" );
14276			}
14277		}
14278
14279		this.options.disabled = disabled;
14280	},
14281
14282	_setupEvents: function( event ) {
14283		var events = {
14284			click: function( event ) {
14285				event.preventDefault();
14286			}
14287		};
14288		if ( event ) {
14289			$.each( event.split(" "), function( index, eventName ) {
14290				events[ eventName ] = "_eventHandler";
14291			});
14292		}
14293
14294		this._off( this.anchors.add( this.tabs ).add( this.panels ) );
14295		this._on( this.anchors, events );
14296		this._on( this.tabs, { keydown: "_tabKeydown" } );
14297		this._on( this.panels, { keydown: "_panelKeydown" } );
14298
14299		this._focusable( this.tabs );
14300		this._hoverable( this.tabs );
14301	},
14302
14303	_setupHeightStyle: function( heightStyle ) {
14304		var maxHeight,
14305			parent = this.element.parent();
14306
14307		if ( heightStyle === "fill" ) {
14308			maxHeight = parent.height();
14309			maxHeight -= this.element.outerHeight() - this.element.height();
14310
14311			this.element.siblings( ":visible" ).each(function() {
14312				var elem = $( this ),
14313					position = elem.css( "position" );
14314
14315				if ( position === "absolute" || position === "fixed" ) {
14316					return;
14317				}
14318				maxHeight -= elem.outerHeight( true );
14319			});
14320
14321			this.element.children().not( this.panels ).each(function() {
14322				maxHeight -= $( this ).outerHeight( true );
14323			});
14324
14325			this.panels.each(function() {
14326				$( this ).height( Math.max( 0, maxHeight -
14327					$( this ).innerHeight() + $( this ).height() ) );
14328			})
14329			.css( "overflow", "auto" );
14330		} else if ( heightStyle === "auto" ) {
14331			maxHeight = 0;
14332			this.panels.each(function() {
14333				maxHeight = Math.max( maxHeight, $( this ).height( "" ).height() );
14334			}).height( maxHeight );
14335		}
14336	},
14337
14338	_eventHandler: function( event ) {
14339		var options = this.options,
14340			active = this.active,
14341			anchor = $( event.currentTarget ),
14342			tab = anchor.closest( "li" ),
14343			clickedIsActive = tab[ 0 ] === active[ 0 ],
14344			collapsing = clickedIsActive && options.collapsible,
14345			toShow = collapsing ? $() : this._getPanelForTab( tab ),
14346			toHide = !active.length ? $() : this._getPanelForTab( active ),
14347			eventData = {
14348				oldTab: active,
14349				oldPanel: toHide,
14350				newTab: collapsing ? $() : tab,
14351				newPanel: toShow
14352			};
14353
14354		event.preventDefault();
14355
14356		if ( tab.hasClass( "ui-state-disabled" ) ||
14357				// tab is already loading
14358				tab.hasClass( "ui-tabs-loading" ) ||
14359				// can't switch durning an animation
14360				this.running ||
14361				// click on active header, but not collapsible
14362				( clickedIsActive && !options.collapsible ) ||
14363				// allow canceling activation
14364				( this._trigger( "beforeActivate", event, eventData ) === false ) ) {
14365			return;
14366		}
14367
14368		options.active = collapsing ? false : this.tabs.index( tab );
14369
14370		this.active = clickedIsActive ? $() : tab;
14371		if ( this.xhr ) {
14372			this.xhr.abort();
14373		}
14374
14375		if ( !toHide.length && !toShow.length ) {
14376			$.error( "jQuery UI Tabs: Mismatching fragment identifier." );
14377		}
14378
14379		if ( toShow.length ) {
14380			this.load( this.tabs.index( tab ), event );
14381		}
14382		this._toggle( event, eventData );
14383	},
14384
14385	// handles show/hide for selecting tabs
14386	_toggle: function( event, eventData ) {
14387		var that = this,
14388			toShow = eventData.newPanel,
14389			toHide = eventData.oldPanel;
14390
14391		this.running = true;
14392
14393		function complete() {
14394			that.running = false;
14395			that._trigger( "activate", event, eventData );
14396		}
14397
14398		function show() {
14399			eventData.newTab.closest( "li" ).addClass( "ui-tabs-active ui-state-active" );
14400
14401			if ( toShow.length && that.options.show ) {
14402				that._show( toShow, that.options.show, complete );
14403			} else {
14404				toShow.show();
14405				complete();
14406			}
14407		}
14408
14409		// start out by hiding, then showing, then completing
14410		if ( toHide.length && this.options.hide ) {
14411			this._hide( toHide, this.options.hide, function() {
14412				eventData.oldTab.closest( "li" ).removeClass( "ui-tabs-active ui-state-active" );
14413				show();
14414			});
14415		} else {
14416			eventData.oldTab.closest( "li" ).removeClass( "ui-tabs-active ui-state-active" );
14417			toHide.hide();
14418			show();
14419		}
14420
14421		toHide.attr({
14422			"aria-expanded": "false",
14423			"aria-hidden": "true"
14424		});
14425		eventData.oldTab.attr( "aria-selected", "false" );
14426		// If we're switching tabs, remove the old tab from the tab order.
14427		// If we're opening from collapsed state, remove the previous tab from the tab order.
14428		// If we're collapsing, then keep the collapsing tab in the tab order.
14429		if ( toShow.length && toHide.length ) {
14430			eventData.oldTab.attr( "tabIndex", -1 );
14431		} else if ( toShow.length ) {
14432			this.tabs.filter(function() {
14433				return $( this ).attr( "tabIndex" ) === 0;
14434			})
14435			.attr( "tabIndex", -1 );
14436		}
14437
14438		toShow.attr({
14439			"aria-expanded": "true",
14440			"aria-hidden": "false"
14441		});
14442		eventData.newTab.attr({
14443			"aria-selected": "true",
14444			tabIndex: 0
14445		});
14446	},
14447
14448	_activate: function( index ) {
14449		var anchor,
14450			active = this._findActive( index );
14451
14452		// trying to activate the already active panel
14453		if ( active[ 0 ] === this.active[ 0 ] ) {
14454			return;
14455		}
14456
14457		// trying to collapse, simulate a click on the current active header
14458		if ( !active.length ) {
14459			active = this.active;
14460		}
14461
14462		anchor = active.find( ".ui-tabs-anchor" )[ 0 ];
14463		this._eventHandler({
14464			target: anchor,
14465			currentTarget: anchor,
14466			preventDefault: $.noop
14467		});
14468	},
14469
14470	_findActive: function( index ) {
14471		return index === false ? $() : this.tabs.eq( index );
14472	},
14473
14474	_getIndex: function( index ) {
14475		// meta-function to give users option to provide a href string instead of a numerical index.
14476		if ( typeof index === "string" ) {
14477			index = this.anchors.index( this.anchors.filter( "[href$='" + index + "']" ) );
14478		}
14479
14480		return index;
14481	},
14482
14483	_destroy: function() {
14484		if ( this.xhr ) {
14485			this.xhr.abort();
14486		}
14487
14488		this.element.removeClass( "ui-tabs ui-widget ui-widget-content ui-corner-all ui-tabs-collapsible" );
14489
14490		this.tablist
14491			.removeClass( "ui-tabs-nav ui-helper-reset ui-helper-clearfix ui-widget-header ui-corner-all" )
14492			.removeAttr( "role" );
14493
14494		this.anchors
14495			.removeClass( "ui-tabs-anchor" )
14496			.removeAttr( "role" )
14497			.removeAttr( "tabIndex" )
14498			.removeUniqueId();
14499
14500		this.tabs.add( this.panels ).each(function() {
14501			if ( $.data( this, "ui-tabs-destroy" ) ) {
14502				$( this ).remove();
14503			} else {
14504				$( this )
14505					.removeClass( "ui-state-default ui-state-active ui-state-disabled " +
14506						"ui-corner-top ui-corner-bottom ui-widget-content ui-tabs-active ui-tabs-panel" )
14507					.removeAttr( "tabIndex" )
14508					.removeAttr( "aria-live" )
14509					.removeAttr( "aria-busy" )
14510					.removeAttr( "aria-selected" )
14511					.removeAttr( "aria-labelledby" )
14512					.removeAttr( "aria-hidden" )
14513					.removeAttr( "aria-expanded" )
14514					.removeAttr( "role" );
14515			}
14516		});
14517
14518		this.tabs.each(function() {
14519			var li = $( this ),
14520				prev = li.data( "ui-tabs-aria-controls" );
14521			if ( prev ) {
14522				li
14523					.attr( "aria-controls", prev )
14524					.removeData( "ui-tabs-aria-controls" );
14525			} else {
14526				li.removeAttr( "aria-controls" );
14527			}
14528		});
14529
14530		this.panels.show();
14531
14532		if ( this.options.heightStyle !== "content" ) {
14533			this.panels.css( "height", "" );
14534		}
14535	},
14536
14537	enable: function( index ) {
14538		var disabled = this.options.disabled;
14539		if ( disabled === false ) {
14540			return;
14541		}
14542
14543		if ( index === undefined ) {
14544			disabled = false;
14545		} else {
14546			index = this._getIndex( index );
14547			if ( $.isArray( disabled ) ) {
14548				disabled = $.map( disabled, function( num ) {
14549					return num !== index ? num : null;
14550				});
14551			} else {
14552				disabled = $.map( this.tabs, function( li, num ) {
14553					return num !== index ? num : null;
14554				});
14555			}
14556		}
14557		this._setupDisabled( disabled );
14558	},
14559
14560	disable: function( index ) {
14561		var disabled = this.options.disabled;
14562		if ( disabled === true ) {
14563			return;
14564		}
14565
14566		if ( index === undefined ) {
14567			disabled = true;
14568		} else {
14569			index = this._getIndex( index );
14570			if ( $.inArray( index, disabled ) !== -1 ) {
14571				return;
14572			}
14573			if ( $.isArray( disabled ) ) {
14574				disabled = $.merge( [ index ], disabled ).sort();
14575			} else {
14576				disabled = [ index ];
14577			}
14578		}
14579		this._setupDisabled( disabled );
14580	},
14581
14582	load: function( index, event ) {
14583		index = this._getIndex( index );
14584		var that = this,
14585			tab = this.tabs.eq( index ),
14586			anchor = tab.find( ".ui-tabs-anchor" ),
14587			panel = this._getPanelForTab( tab ),
14588			eventData = {
14589				tab: tab,
14590				panel: panel
14591			};
14592
14593		// not remote
14594		if ( isLocal( anchor[ 0 ] ) ) {
14595			return;
14596		}
14597
14598		this.xhr = $.ajax( this._ajaxSettings( anchor, event, eventData ) );
14599
14600		// support: jQuery <1.8
14601		// jQuery <1.8 returns false if the request is canceled in beforeSend,
14602		// but as of 1.8, $.ajax() always returns a jqXHR object.
14603		if ( this.xhr && this.xhr.statusText !== "canceled" ) {
14604			tab.addClass( "ui-tabs-loading" );
14605			panel.attr( "aria-busy", "true" );
14606
14607			this.xhr
14608				.success(function( response ) {
14609					// support: jQuery <1.8
14610					// http://bugs.jquery.com/ticket/11778
14611					setTimeout(function() {
14612						panel.html( response );
14613						that._trigger( "load", event, eventData );
14614					}, 1 );
14615				})
14616				.complete(function( jqXHR, status ) {
14617					// support: jQuery <1.8
14618					// http://bugs.jquery.com/ticket/11778
14619					setTimeout(function() {
14620						if ( status === "abort" ) {
14621							that.panels.stop( false, true );
14622						}
14623
14624						tab.removeClass( "ui-tabs-loading" );
14625						panel.removeAttr( "aria-busy" );
14626
14627						if ( jqXHR === that.xhr ) {
14628							delete that.xhr;
14629						}
14630					}, 1 );
14631				});
14632		}
14633	},
14634
14635	_ajaxSettings: function( anchor, event, eventData ) {
14636		var that = this;
14637		return {
14638			url: anchor.attr( "href" ),
14639			beforeSend: function( jqXHR, settings ) {
14640				return that._trigger( "beforeLoad", event,
14641					$.extend( { jqXHR : jqXHR, ajaxSettings: settings }, eventData ) );
14642			}
14643		};
14644	},
14645
14646	_getPanelForTab: function( tab ) {
14647		var id = $( tab ).attr( "aria-controls" );
14648		return this.element.find( this._sanitizeSelector( "#" + id ) );
14649	}
14650});
14651
14652})( jQuery );
14653
14654(function( $ ) {
14655
14656var increments = 0;
14657
14658function addDescribedBy( elem, id ) {
14659	var describedby = (elem.attr( "aria-describedby" ) || "").split( /\s+/ );
14660	describedby.push( id );
14661	elem
14662		.data( "ui-tooltip-id", id )
14663		.attr( "aria-describedby", $.trim( describedby.join( " " ) ) );
14664}
14665
14666function removeDescribedBy( elem ) {
14667	var id = elem.data( "ui-tooltip-id" ),
14668		describedby = (elem.attr( "aria-describedby" ) || "").split( /\s+/ ),
14669		index = $.inArray( id, describedby );
14670	if ( index !== -1 ) {
14671		describedby.splice( index, 1 );
14672	}
14673
14674	elem.removeData( "ui-tooltip-id" );
14675	describedby = $.trim( describedby.join( " " ) );
14676	if ( describedby ) {
14677		elem.attr( "aria-describedby", describedby );
14678	} else {
14679		elem.removeAttr( "aria-describedby" );
14680	}
14681}
14682
14683$.widget( "ui.tooltip", {
14684	version: "1.10.4",
14685	options: {
14686		content: function() {
14687			// support: IE<9, Opera in jQuery <1.7
14688			// .text() can't accept undefined, so coerce to a string
14689			var title = $( this ).attr( "title" ) || "";
14690			// Escape title, since we're going from an attribute to raw HTML
14691			return $( "<a>" ).text( title ).html();
14692		},
14693		hide: true,
14694		// Disabled elements have inconsistent behavior across browsers (#8661)
14695		items: "[title]:not([disabled])",
14696		position: {
14697			my: "left top+15",
14698			at: "left bottom",
14699			collision: "flipfit flip"
14700		},
14701		show: true,
14702		tooltipClass: null,
14703		track: false,
14704
14705		// callbacks
14706		close: null,
14707		open: null
14708	},
14709
14710	_create: function() {
14711		this._on({
14712			mouseover: "open",
14713			focusin: "open"
14714		});
14715
14716		// IDs of generated tooltips, needed for destroy
14717		this.tooltips = {};
14718		// IDs of parent tooltips where we removed the title attribute
14719		this.parents = {};
14720
14721		if ( this.options.disabled ) {
14722			this._disable();
14723		}
14724	},
14725
14726	_setOption: function( key, value ) {
14727		var that = this;
14728
14729		if ( key === "disabled" ) {
14730			this[ value ? "_disable" : "_enable" ]();
14731			this.options[ key ] = value;
14732			// disable element style changes
14733			return;
14734		}
14735
14736		this._super( key, value );
14737
14738		if ( key === "content" ) {
14739			$.each( this.tooltips, function( id, element ) {
14740				that._updateContent( element );
14741			});
14742		}
14743	},
14744
14745	_disable: function() {
14746		var that = this;
14747
14748		// close open tooltips
14749		$.each( this.tooltips, function( id, element ) {
14750			var event = $.Event( "blur" );
14751			event.target = event.currentTarget = element[0];
14752			that.close( event, true );
14753		});
14754
14755		// remove title attributes to prevent native tooltips
14756		this.element.find( this.options.items ).addBack().each(function() {
14757			var element = $( this );
14758			if ( element.is( "[title]" ) ) {
14759				element
14760					.data( "ui-tooltip-title", element.attr( "title" ) )
14761					.attr( "title", "" );
14762			}
14763		});
14764	},
14765
14766	_enable: function() {
14767		// restore title attributes
14768		this.element.find( this.options.items ).addBack().each(function() {
14769			var element = $( this );
14770			if ( element.data( "ui-tooltip-title" ) ) {
14771				element.attr( "title", element.data( "ui-tooltip-title" ) );
14772			}
14773		});
14774	},
14775
14776	open: function( event ) {
14777		var that = this,
14778			target = $( event ? event.target : this.element )
14779				// we need closest here due to mouseover bubbling,
14780				// but always pointing at the same event target
14781				.closest( this.options.items );
14782
14783		// No element to show a tooltip for or the tooltip is already open
14784		if ( !target.length || target.data( "ui-tooltip-id" ) ) {
14785			return;
14786		}
14787
14788		if ( target.attr( "title" ) ) {
14789			target.data( "ui-tooltip-title", target.attr( "title" ) );
14790		}
14791
14792		target.data( "ui-tooltip-open", true );
14793
14794		// kill parent tooltips, custom or native, for hover
14795		if ( event && event.type === "mouseover" ) {
14796			target.parents().each(function() {
14797				var parent = $( this ),
14798					blurEvent;
14799				if ( parent.data( "ui-tooltip-open" ) ) {
14800					blurEvent = $.Event( "blur" );
14801					blurEvent.target = blurEvent.currentTarget = this;
14802					that.close( blurEvent, true );
14803				}
14804				if ( parent.attr( "title" ) ) {
14805					parent.uniqueId();
14806					that.parents[ this.id ] = {
14807						element: this,
14808						title: parent.attr( "title" )
14809					};
14810					parent.attr( "title", "" );
14811				}
14812			});
14813		}
14814
14815		this._updateContent( target, event );
14816	},
14817
14818	_updateContent: function( target, event ) {
14819		var content,
14820			contentOption = this.options.content,
14821			that = this,
14822			eventType = event ? event.type : null;
14823
14824		if ( typeof contentOption === "string" ) {
14825			return this._open( event, target, contentOption );
14826		}
14827
14828		content = contentOption.call( target[0], function( response ) {
14829			// ignore async response if tooltip was closed already
14830			if ( !target.data( "ui-tooltip-open" ) ) {
14831				return;
14832			}
14833			// IE may instantly serve a cached response for ajax requests
14834			// delay this call to _open so the other call to _open runs first
14835			that._delay(function() {
14836				// jQuery creates a special event for focusin when it doesn't
14837				// exist natively. To improve performance, the native event
14838				// object is reused and the type is changed. Therefore, we can't
14839				// rely on the type being correct after the event finished
14840				// bubbling, so we set it back to the previous value. (#8740)
14841				if ( event ) {
14842					event.type = eventType;
14843				}
14844				this._open( event, target, response );
14845			});
14846		});
14847		if ( content ) {
14848			this._open( event, target, content );
14849		}
14850	},
14851
14852	_open: function( event, target, content ) {
14853		var tooltip, events, delayedShow,
14854			positionOption = $.extend( {}, this.options.position );
14855
14856		if ( !content ) {
14857			return;
14858		}
14859
14860		// Content can be updated multiple times. If the tooltip already
14861		// exists, then just update the content and bail.
14862		tooltip = this._find( target );
14863		if ( tooltip.length ) {
14864			tooltip.find( ".ui-tooltip-content" ).html( content );
14865			return;
14866		}
14867
14868		// if we have a title, clear it to prevent the native tooltip
14869		// we have to check first to avoid defining a title if none exists
14870		// (we don't want to cause an element to start matching [title])
14871		//
14872		// We use removeAttr only for key events, to allow IE to export the correct
14873		// accessible attributes. For mouse events, set to empty string to avoid
14874		// native tooltip showing up (happens only when removing inside mouseover).
14875		if ( target.is( "[title]" ) ) {
14876			if ( event && event.type === "mouseover" ) {
14877				target.attr( "title", "" );
14878			} else {
14879				target.removeAttr( "title" );
14880			}
14881		}
14882
14883		tooltip = this._tooltip( target );
14884		addDescribedBy( target, tooltip.attr( "id" ) );
14885		tooltip.find( ".ui-tooltip-content" ).html( content );
14886
14887		function position( event ) {
14888			positionOption.of = event;
14889			if ( tooltip.is( ":hidden" ) ) {
14890				return;
14891			}
14892			tooltip.position( positionOption );
14893		}
14894		if ( this.options.track && event && /^mouse/.test( event.type ) ) {
14895			this._on( this.document, {
14896				mousemove: position
14897			});
14898			// trigger once to override element-relative positioning
14899			position( event );
14900		} else {
14901			tooltip.position( $.extend({
14902				of: target
14903			}, this.options.position ) );
14904		}
14905
14906		tooltip.hide();
14907
14908		this._show( tooltip, this.options.show );
14909		// Handle tracking tooltips that are shown with a delay (#8644). As soon
14910		// as the tooltip is visible, position the tooltip using the most recent
14911		// event.
14912		if ( this.options.show && this.options.show.delay ) {
14913			delayedShow = this.delayedShow = setInterval(function() {
14914				if ( tooltip.is( ":visible" ) ) {
14915					position( positionOption.of );
14916					clearInterval( delayedShow );
14917				}
14918			}, $.fx.interval );
14919		}
14920
14921		this._trigger( "open", event, { tooltip: tooltip } );
14922
14923		events = {
14924			keyup: function( event ) {
14925				if ( event.keyCode === $.ui.keyCode.ESCAPE ) {
14926					var fakeEvent = $.Event(event);
14927					fakeEvent.currentTarget = target[0];
14928					this.close( fakeEvent, true );
14929				}
14930			},
14931			remove: function() {
14932				this._removeTooltip( tooltip );
14933			}
14934		};
14935		if ( !event || event.type === "mouseover" ) {
14936			events.mouseleave = "close";
14937		}
14938		if ( !event || event.type === "focusin" ) {
14939			events.focusout = "close";
14940		}
14941		this._on( true, target, events );
14942	},
14943
14944	close: function( event ) {
14945		var that = this,
14946			target = $( event ? event.currentTarget : this.element ),
14947			tooltip = this._find( target );
14948
14949		// disabling closes the tooltip, so we need to track when we're closing
14950		// to avoid an infinite loop in case the tooltip becomes disabled on close
14951		if ( this.closing ) {
14952			return;
14953		}
14954
14955		// Clear the interval for delayed tracking tooltips
14956		clearInterval( this.delayedShow );
14957
14958		// only set title if we had one before (see comment in _open())
14959		if ( target.data( "ui-tooltip-title" ) ) {
14960			target.attr( "title", target.data( "ui-tooltip-title" ) );
14961		}
14962
14963		removeDescribedBy( target );
14964
14965		tooltip.stop( true );
14966		this._hide( tooltip, this.options.hide, function() {
14967			that._removeTooltip( $( this ) );
14968		});
14969
14970		target.removeData( "ui-tooltip-open" );
14971		this._off( target, "mouseleave focusout keyup" );
14972		// Remove 'remove' binding only on delegated targets
14973		if ( target[0] !== this.element[0] ) {
14974			this._off( target, "remove" );
14975		}
14976		this._off( this.document, "mousemove" );
14977
14978		if ( event && event.type === "mouseleave" ) {
14979			$.each( this.parents, function( id, parent ) {
14980				$( parent.element ).attr( "title", parent.title );
14981				delete that.parents[ id ];
14982			});
14983		}
14984
14985		this.closing = true;
14986		this._trigger( "close", event, { tooltip: tooltip } );
14987		this.closing = false;
14988	},
14989
14990	_tooltip: function( element ) {
14991		var id = "ui-tooltip-" + increments++,
14992			tooltip = $( "<div>" )
14993				.attr({
14994					id: id,
14995					role: "tooltip"
14996				})
14997				.addClass( "ui-tooltip ui-widget ui-corner-all ui-widget-content " +
14998					( this.options.tooltipClass || "" ) );
14999		$( "<div>" )
15000			.addClass( "ui-tooltip-content" )
15001			.appendTo( tooltip );
15002		tooltip.appendTo( this.document[0].body );
15003		this.tooltips[ id ] = element;
15004		return tooltip;
15005	},
15006
15007	_find: function( target ) {
15008		var id = target.data( "ui-tooltip-id" );
15009		return id ? $( "#" + id ) : $();
15010	},
15011
15012	_removeTooltip: function( tooltip ) {
15013		tooltip.remove();
15014		delete this.tooltips[ tooltip.attr( "id" ) ];
15015	},
15016
15017	_destroy: function() {
15018		var that = this;
15019
15020		// close open tooltips
15021		$.each( this.tooltips, function( id, element ) {
15022			// Delegate to close method to handle common cleanup
15023			var event = $.Event( "blur" );
15024			event.target = event.currentTarget = element[0];
15025			that.close( event, true );
15026
15027			// Remove immediately; destroying an open tooltip doesn't use the
15028			// hide animation
15029			$( "#" + id ).remove();
15030
15031			// Restore the title
15032			if ( element.data( "ui-tooltip-title" ) ) {
15033				element.attr( "title", element.data( "ui-tooltip-title" ) );
15034				element.removeData( "ui-tooltip-title" );
15035			}
15036		});
15037	}
15038});
15039
15040}( 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.