PageSourceSearch

https://www.kagyumonlam.or.id/wp-content/themes/kingdom/scripts/jquery-ui-1.9.2.js?ver=5.5.22

js kagyumonlam.or.id collected 2026-10-06 13:14:53 UTC 450,163 bytes, 14,912 lines download raw bytes

vendor: 9,149 bytes, lines 1-321
1/*! jQuery UI - v1.9.2 - 2012-11-23
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 2012 jQuery Foundation and other contributors; Licensed MIT */
5
6(function( $, undefined ) {
7
8var uuid = 0,
9	runiqueId = /^ui-id-\d+$/;
10
11// prevent duplicate loading
12// this is only a problem because we proxy existing functions
13// and we don't want to double proxy them
14$.ui = $.ui || {};
15if ( $.ui.version ) {
16	return;
17}
18
19$.extend( $.ui, {
20	version: "1.9.2",
21
22	keyCode: {
23		BACKSPACE: 8,
24		COMMA: 188,
25		DELETE: 46,
26		DOWN: 40,
27		END: 35,
28		ENTER: 13,
29		ESCAPE: 27,
30		HOME: 36,
31		LEFT: 37,
32		NUMPAD_ADD: 107,
33		NUMPAD_DECIMAL: 110,
34		NUMPAD_DIVIDE: 111,
35		NUMPAD_ENTER: 108,
36		NUMPAD_MULTIPLY: 106,
37		NUMPAD_SUBTRACT: 109,
38		PAGE_DOWN: 34,
39		PAGE_UP: 33,
40		PERIOD: 190,
41		RIGHT: 39,
42		SPACE: 32,
43		TAB: 9,
44		UP: 38
45	}
46});
47
48// plugins
49$.fn.extend({
50	_focus: $.fn.focus,
51	focus: function( delay, fn ) {
52		return typeof delay === "number" ?
53			this.each(function() {
54				var elem = this;
55				setTimeout(function() {
56					$( elem ).focus();
57					if ( fn ) {
58						fn.call( elem );
59					}
60				}, delay );
61			}) :
62			this._focus.apply( this, arguments );
63	},
64
65	scrollParent: function() {
66		var scrollParent;
67		if (($.ui.ie && (/(static|relative)/).test(this.css('position'))) || (/absolute/).test(this.css('position'))) {
68			scrollParent = this.parents().filter(function() {
69				return (/(relative|absolute|fixed)/).test($.css(this,'position')) && (/(auto|scroll)/).test($.css(this,'overflow')+$.css(this,'overflow-y')+$.css(this,'overflow-x'));
70			}).eq(0);
71		} else {
72			scrollParent = this.parents().filter(function() {
73				return (/(auto|scroll)/).test($.css(this,'overflow')+$.css(this,'overflow-y')+$.css(this,'overflow-x'));
74			}).eq(0);
75		}
76
77		return (/fixed/).test(this.css('position')) || !scrollParent.length ? $(document) : scrollParent;
78	},
79
80	zIndex: function( zIndex ) {
81		if ( zIndex !== undefined ) {
82			return this.css( "zIndex", zIndex );
83		}
84
85		if ( this.length ) {
86			var elem = $( this[ 0 ] ), position, value;
87			while ( elem.length && elem[ 0 ] !== document ) {
88				// Ignore z-index if position is set to a value where z-index is ignored by the browser
89				// This makes behavior of this function consistent across browsers
90				// WebKit always returns auto if the element is positioned
91				position = elem.css( "position" );
92				if ( position === "absolute" || position === "relative" || position === "fixed" ) {
93					// IE returns 0 when zIndex is not specified
94					// other browsers return a string
95					// we ignore the case of nested elements with an explicit value of 0
96					// <div style="z-index: -10;"><div style="z-index: 0;"></div></div>
97					value = parseInt( elem.css( "zIndex" ), 10 );
98					if ( !isNaN( value ) && value !== 0 ) {
99						return value;
100					}
101				}
102				elem = elem.parent();
103			}
104		}
105
106		return 0;
107	},
108
109	uniqueId: function() {
110		return this.each(function() {
111			if ( !this.id ) {
112				this.id = "ui-id-" + (++uuid);
113			}
114		});
115	},
116
117	removeUniqueId: function() {
118		return this.each(function() {
119			if ( runiqueId.test( this.id ) ) {
120				$( this ).removeAttr( "id" );
121			}
122		});
123	}
124});
125
126// selectors
127function focusable( element, isTabIndexNotNaN ) {
128	var map, mapName, img,
129		nodeName = element.nodeName.toLowerCase();
130	if ( "area" === nodeName ) {
131		map = element.parentNode;
132		mapName = map.name;
133		if ( !element.href || !mapName || map.nodeName.toLowerCase() !== "map" ) {
134			return false;
135		}
136		img = $( "img[usemap=#" + mapName + "]" )[0];
137		return !!img && visible( img );
138	}
139	return ( /input|select|textarea|button|object/.test( nodeName ) ?
140		!element.disabled :
141		"a" === nodeName ?
142			element.href || isTabIndexNotNaN :
143			isTabIndexNotNaN) &&
144		// the element and all of its ancestors must be visible
145		visible( element );
146}
147
148function visible( element ) {
149	return $.expr.filters.visible( element ) &&
150		!$( element ).parents().andSelf().filter(function() {
151			return $.css( this, "visibility" ) === "hidden";
152		}).length;
153}
154
155$.extend( $.expr[ ":" ], {
156	data: $.expr.createPseudo ?
157		$.expr.createPseudo(function( dataName ) {
158			return function( elem ) {
159				return !!$.data( elem, dataName );
160			};
161		}) :
162		// support: jQuery <1.8
163		function( elem, i, match ) {
164			return !!$.data( elem, match[ 3 ] );
165		},
166
167	focusable: function( element ) {
168		return focusable( element, !isNaN( $.attr( element, "tabindex" ) ) );
169	},
170
171	tabbable: function( element ) {
172		var tabIndex = $.attr( element, "tabindex" ),
173			isTabIndexNaN = isNaN( tabIndex );
174		return ( isTabIndexNaN || tabIndex >= 0 ) && focusable( element, !isTabIndexNaN );
175	}
176});
177
178// support
179$(function() {
180	var body = document.body,
181		div = body.appendChild( div = document.createElement( "div" ) );
182
183	// access offsetHeight before setting the style to prevent a layout bug
184	// in IE 9 which causes the element to continue to take up space even
185	// after it is removed from the DOM (#8026)
186	div.offsetHeight;
187
188	$.extend( div.style, {
189		minHeight: "100px",
190		height: "auto",
191		padding: 0,
192		borderWidth: 0
193	});
194
195	$.support.minHeight = div.offsetHeight === 100;
196	$.support.selectstart = "onselectstart" in div;
197
198	// set display to none to avoid a layout bug in IE
199	// http://dev.jquery.com/ticket/4014
200	body.removeChild( div ).style.display = "none";
201});
202
203// support: jQuery <1.8
204if ( !$( "<a>" ).outerWidth( 1 ).jquery ) {
205	$.each( [ "Width", "Height" ], function( i, name ) {
206		var side = name === "Width" ? [ "Left", "Right" ] : [ "Top", "Bottom" ],
207			type = name.toLowerCase(),
208			orig = {
209				innerWidth: $.fn.innerWidth,
210				innerHeight: $.fn.innerHeight,
211				outerWidth: $.fn.outerWidth,
212				outerHeight: $.fn.outerHeight
213			};
214
215		function reduce( elem, size, border, margin ) {
216			$.each( side, function() {
217				size -= parseFloat( $.css( elem, "padding" + this ) ) || 0;
218				if ( border ) {
219					size -= parseFloat( $.css( elem, "border" + this + "Width" ) ) || 0;
220				}
221				if ( margin ) {
222					size -= parseFloat( $.css( elem, "margin" + this ) ) || 0;
223				}
224			});
225			return size;
226		}
227
228		$.fn[ "inner" + name ] = function( size ) {
229			if ( size === undefined ) {
230				return orig[ "inner" + name ].call( this );
231			}
232
233			return this.each(function() {
234				$( this ).css( type, reduce( this, size ) + "px" );
235			});
236		};
237
238		$.fn[ "outer" + name] = function( size, margin ) {
239			if ( typeof size !== "number" ) {
240				return orig[ "outer" + name ].call( this, size );
241			}
242
243			return this.each(function() {
244				$( this).css( type, reduce( this, size, true, margin ) + "px" );
245			});
246		};
247	});
248}
249
250// support: jQuery 1.6.1, 1.6.2 (http://bugs.jquery.com/ticket/9413)
251if ( $( "<a>" ).data( "a-b", "a" ).removeData( "a-b" ).data( "a-b" ) ) {
252	$.fn.removeData = (function( removeData ) {
253		return function( key ) {
254			if ( arguments.length ) {
255				return removeData.call( this, $.camelCase( key ) );
256			} else {
257				return removeData.call( this );
258			}
259		};
260	})( $.fn.removeData );
261}
262
263
264
265
266
267// deprecated
268
269(function() {
270	var uaMatch = /msie ([\w.]+)/.exec( navigator.userAgent.toLowerCase() ) || [];
271	$.ui.ie = uaMatch.length ? true : false;
272	$.ui.ie6 = parseFloat( uaMatch[ 1 ], 10 ) === 6;
273})();
274
275$.fn.extend({
276	disableSelection: function() {
277		return this.bind( ( $.support.selectstart ? "selectstart" : "mousedown" ) +
278			".ui-disableSelection", function( event ) {
279				event.preventDefault();
280			});
281	},
282
283	enableSelection: function() {
284		return this.unbind( ".ui-disableSelection" );
285	}
286});
287
288$.extend( $.ui, {
289	// $.ui.plugin is deprecated.  Use the proxy pattern instead.
290	plugin: {
291		add: function( module, option, set ) {
292			var i,
293				proto = $.ui[ module ].prototype;
294			for ( i in set ) {
295				proto.plugins[ i ] = proto.plugins[ i ] || [];
296				proto.plugins[ i ].push( [ option, set[ i ] ] );
297			}
298		},
299		call: function( instance, name, args ) {
300			var i,
301				set = instance.plugins[ name ];
302			if ( !set || !instance.element[ 0 ].parentNode || instance.element[ 0 ].parentNode.nodeType === 11 ) {
303				return;
304			}
305
306			for ( i = 0; i < set.length; i++ ) {
307				if ( instance.options[ set[ i ][ 0 ] ] ) {
308					set[ i ][ 1 ].apply( instance.element, args );
309				}
310			}
311		}
312	},
313
314	contains: $.contains,
315
316	// only used by resizable
317	hasScroll: function( el, a ) {
318
319		//If overflow is hidden, the element might have extra content, but the user wants to hide it
320		if ( $( el ).css( "overflow" ) === "hidden") {
321			return false;
vendor: 4,238 bytes, lines 322-459
322		}
323
324		var scroll = ( a && a === "left" ) ? "scrollLeft" : "scrollTop",
325			has = false;
326
327		if ( el[ scroll ] > 0 ) {
328			return true;
329		}
330
331		// TODO: determine which cases actually cause this to happen
332		// if the element doesn't have the scroll set, see if it's possible to
333		// set the scroll
334		el[ scroll ] = 1;
335		has = ( el[ scroll ] > 0 );
336		el[ scroll ] = 0;
337		return has;
338	},
339
340	// these are odd functions, fix the API or move into individual plugins
341	isOverAxis: function( x, reference, size ) {
342		//Determines when x coordinate is over "b" element axis
343		return ( x > reference ) && ( x < ( reference + size ) );
344	},
345	isOver: function( y, x, top, left, height, width ) {
346		//Determines when x, y coordinates is over "b" element
347		return $.ui.isOverAxis( y, top, height ) && $.ui.isOverAxis( x, left, width );
348	}
349});
350
351})( jQuery );
352
353(function( $, undefined ) {
354
355var uuid = 0,
356	slice = Array.prototype.slice,
357	_cleanData = $.cleanData;
358$.cleanData = function( elems ) {
359	for ( var i = 0, elem; (elem = elems[i]) != null; i++ ) {
360		try {
361			$( elem ).triggerHandler( "remove" );
362		// http://bugs.jquery.com/ticket/8235
363		} catch( e ) {}
364	}
365	_cleanData( elems );
366};
367
368$.widget = function( name, base, prototype ) {
369	var fullName, existingConstructor, constructor, basePrototype,
370		namespace = name.split( "." )[ 0 ];
371
372	name = name.split( "." )[ 1 ];
373	fullName = namespace + "-" + name;
374
375	if ( !prototype ) {
376		prototype = base;
377		base = $.Widget;
378	}
379
380	// create selector for plugin
381	$.expr[ ":" ][ fullName.toLowerCase() ] = function( elem ) {
382		return !!$.data( elem, fullName );
383	};
384
385	$[ namespace ] = $[ namespace ] || {};
386	existingConstructor = $[ namespace ][ name ];
387	constructor = $[ namespace ][ name ] = function( options, element ) {
388		// allow instantiation without "new" keyword
389		if ( !this._createWidget ) {
390			return new constructor( options, element );
391		}
392
393		// allow instantiation without initializing for simple inheritance
394		// must use "new" keyword (the code above always passes args)
395		if ( arguments.length ) {
396			this._createWidget( options, element );
397		}
398	};
399	// extend with the existing constructor to carry over any static properties
400	$.extend( constructor, existingConstructor, {
401		version: prototype.version,
402		// copy the object used to create the prototype in case we need to
403		// redefine the widget later
404		_proto: $.extend( {}, prototype ),
405		// track widgets that inherit from this widget in case this widget is
406		// redefined after a widget inherits from it
407		_childConstructors: []
408	});
409
410	basePrototype = new base();
411	// we need to make the options hash a property directly on the new instance
412	// otherwise we'll modify the options hash on the prototype that we're
413	// inheriting from
414	basePrototype.options = $.widget.extend( {}, basePrototype.options );
415	$.each( prototype, function( prop, value ) {
416		if ( $.isFunction( value ) ) {
417			prototype[ prop ] = (function() {
418				var _super = function() {
419						return base.prototype[ prop ].apply( this, arguments );
420					},
421					_superApply = function( args ) {
422						return base.prototype[ prop ].apply( this, args );
423					};
424				return function() {
425					var __super = this._super,
426						__superApply = this._superApply,
427						returnValue;
428
429					this._super = _super;
430					this._superApply = _superApply;
431
432					returnValue = value.apply( this, arguments );
433
434					this._super = __super;
435					this._superApply = __superApply;
436
437					return returnValue;
438				};
439			})();
440		}
441	});
442	constructor.prototype = $.widget.extend( basePrototype, {
443		// TODO: remove support for widgetEventPrefix
444		// always use the name + a colon as the prefix, e.g., draggable:start
445		// don't prefix for widgets that aren't DOM-based
446		widgetEventPrefix: existingConstructor ? basePrototype.widgetEventPrefix : name
447	}, prototype, {
448		constructor: constructor,
449		namespace: namespace,
450		widgetName: name,
451		// TODO remove widgetBaseClass, see #8155
452		widgetBaseClass: fullName,
453		widgetFullName: fullName
454	});
455
456	// If this widget is being redefined then we need to find all widgets that
457	// are inheriting from it and redefine all of them so that they inherit from
458	// the new version of this widget. We're essentially trying to replace one
459	// level in the prototype chain.
vendor: 11,206 bytes, lines 460-849
460	if ( existingConstructor ) {
461		$.each( existingConstructor._childConstructors, function( i, child ) {
462			var childPrototype = child.prototype;
463
464			// redefine the child widget using the same prototype that was
465			// originally used, but inherit from the new version of the base
466			$.widget( childPrototype.namespace + "." + childPrototype.widgetName, constructor, child._proto );
467		});
468		// remove the list of existing child constructors from the old constructor
469		// so the old child constructors can be garbage collected
470		delete existingConstructor._childConstructors;
471	} else {
472		base._childConstructors.push( constructor );
473	}
474
475	$.widget.bridge( name, constructor );
476};
477
478$.widget.extend = function( target ) {
479	var input = slice.call( arguments, 1 ),
480		inputIndex = 0,
481		inputLength = input.length,
482		key,
483		value;
484	for ( ; inputIndex < inputLength; inputIndex++ ) {
485		for ( key in input[ inputIndex ] ) {
486			value = input[ inputIndex ][ key ];
487			if ( input[ inputIndex ].hasOwnProperty( key ) && value !== undefined ) {
488				// Clone objects
489				if ( $.isPlainObject( value ) ) {
490					target[ key ] = $.isPlainObject( target[ key ] ) ?
491						$.widget.extend( {}, target[ key ], value ) :
492						// Don't extend strings, arrays, etc. with objects
493						$.widget.extend( {}, value );
494				// Copy everything else by reference
495				} else {
496					target[ key ] = value;
497				}
498			}
499		}
500	}
501	return target;
502};
503
504$.widget.bridge = function( name, object ) {
505	var fullName = object.prototype.widgetFullName || name;
506	$.fn[ name ] = function( options ) {
507		var isMethodCall = typeof options === "string",
508			args = slice.call( arguments, 1 ),
509			returnValue = this;
510
511		// allow multiple hashes to be passed on init
512		options = !isMethodCall && args.length ?
513			$.widget.extend.apply( null, [ options ].concat(args) ) :
514			options;
515
516		if ( isMethodCall ) {
517			this.each(function() {
518				var methodValue,
519					instance = $.data( this, fullName );
520				if ( !instance ) {
521					return $.error( "cannot call methods on " + name + " prior to initialization; " +
522						"attempted to call method '" + options + "'" );
523				}
524				if ( !$.isFunction( instance[options] ) || options.charAt( 0 ) === "_" ) {
525					return $.error( "no such method '" + options + "' for " + name + " widget instance" );
526				}
527				methodValue = instance[ options ].apply( instance, args );
528				if ( methodValue !== instance && methodValue !== undefined ) {
529					returnValue = methodValue && methodValue.jquery ?
530						returnValue.pushStack( methodValue.get() ) :
531						methodValue;
532					return false;
533				}
534			});
535		} else {
536			this.each(function() {
537				var instance = $.data( this, fullName );
538				if ( instance ) {
539					instance.option( options || {} )._init();
540				} else {
541					$.data( this, fullName, new object( options, this ) );
542				}
543			});
544		}
545
546		return returnValue;
547	};
548};
549
550$.Widget = function( /* options, element */ ) {};
551$.Widget._childConstructors = [];
552
553$.Widget.prototype = {
554	widgetName: "widget",
555	widgetEventPrefix: "",
556	defaultElement: "<div>",
557	options: {
558		disabled: false,
559
560		// callbacks
561		create: null
562	},
563	_createWidget: function( options, element ) {
564		element = $( element || this.defaultElement || this )[ 0 ];
565		this.element = $( element );
566		this.uuid = uuid++;
567		this.eventNamespace = "." + this.widgetName + this.uuid;
568		this.options = $.widget.extend( {},
569			this.options,
570			this._getCreateOptions(),
571			options );
572
573		this.bindings = $();
574		this.hoverable = $();
575		this.focusable = $();
576
577		if ( element !== this ) {
578			// 1.9 BC for #7810
579			// TODO remove dual storage
580			$.data( element, this.widgetName, this );
581			$.data( element, this.widgetFullName, this );
582			this._on( true, this.element, {
583				remove: function( event ) {
584					if ( event.target === element ) {
585						this.destroy();
586					}
587				}
588			});
589			this.document = $( element.style ?
590				// element within the document
591				element.ownerDocument :
592				// element is window or document
593				element.document || element );
594			this.window = $( this.document[0].defaultView || this.document[0].parentWindow );
595		}
596
597		this._create();
598		this._trigger( "create", null, this._getCreateEventData() );
599		this._init();
600	},
601	_getCreateOptions: $.noop,
602	_getCreateEventData: $.noop,
603	_create: $.noop,
604	_init: $.noop,
605
606	destroy: function() {
607		this._destroy();
608		// we can probably remove the unbind calls in 2.0
609		// all event bindings should go through this._on()
610		this.element
611			.unbind( this.eventNamespace )
612			// 1.9 BC for #7810
613			// TODO remove dual storage
614			.removeData( this.widgetName )
615			.removeData( this.widgetFullName )
616			// support: jquery <1.6.3
617			// http://bugs.jquery.com/ticket/9413
618			.removeData( $.camelCase( this.widgetFullName ) );
619		this.widget()
620			.unbind( this.eventNamespace )
621			.removeAttr( "aria-disabled" )
622			.removeClass(
623				this.widgetFullName + "-disabled " +
624				"ui-state-disabled" );
625
626		// clean up events and states
627		this.bindings.unbind( this.eventNamespace );
628		this.hoverable.removeClass( "ui-state-hover" );
629		this.focusable.removeClass( "ui-state-focus" );
630	},
631	_destroy: $.noop,
632
633	widget: function() {
634		return this.element;
635	},
636
637	option: function( key, value ) {
638		var options = key,
639			parts,
640			curOption,
641			i;
642
643		if ( arguments.length === 0 ) {
644			// don't return a reference to the internal hash
645			return $.widget.extend( {}, this.options );
646		}
647
648		if ( typeof key === "string" ) {
649			// handle nested keys, e.g., "foo.bar" => { foo: { bar: ___ } }
650			options = {};
651			parts = key.split( "." );
652			key = parts.shift();
653			if ( parts.length ) {
654				curOption = options[ key ] = $.widget.extend( {}, this.options[ key ] );
655				for ( i = 0; i < parts.length - 1; i++ ) {
656					curOption[ parts[ i ] ] = curOption[ parts[ i ] ] || {};
657					curOption = curOption[ parts[ i ] ];
658				}
659				key = parts.pop();
660				if ( value === undefined ) {
661					return curOption[ key ] === undefined ? null : curOption[ key ];
662				}
663				curOption[ key ] = value;
664			} else {
665				if ( value === undefined ) {
666					return this.options[ key ] === undefined ? null : this.options[ key ];
667				}
668				options[ key ] = value;
669			}
670		}
671
672		this._setOptions( options );
673
674		return this;
675	},
676	_setOptions: function( options ) {
677		var key;
678
679		for ( key in options ) {
680			this._setOption( key, options[ key ] );
681		}
682
683		return this;
684	},
685	_setOption: function( key, value ) {
686		this.options[ key ] = value;
687
688		if ( key === "disabled" ) {
689			this.widget()
690				.toggleClass( this.widgetFullName + "-disabled ui-state-disabled", !!value )
691				.attr( "aria-disabled", value );
692			this.hoverable.removeClass( "ui-state-hover" );
693			this.focusable.removeClass( "ui-state-focus" );
694		}
695
696		return this;
697	},
698
699	enable: function() {
700		return this._setOption( "disabled", false );
701	},
702	disable: function() {
703		return this._setOption( "disabled", true );
704	},
705
706	_on: function( suppressDisabledCheck, element, handlers ) {
707		var delegateElement,
708			instance = this;
709
710		// no suppressDisabledCheck flag, shuffle arguments
711		if ( typeof suppressDisabledCheck !== "boolean" ) {
712			handlers = element;
713			element = suppressDisabledCheck;
714			suppressDisabledCheck = false;
715		}
716
717		// no element argument, shuffle and use this.element
718		if ( !handlers ) {
719			handlers = element;
720			element = this.element;
721			delegateElement = this.widget();
722		} else {
723			// accept selectors, DOM elements
724			element = delegateElement = $( element );
725			this.bindings = this.bindings.add( element );
726		}
727
728		$.each( handlers, function( event, handler ) {
729			function handlerProxy() {
730				// allow widgets to customize the disabled handling
731				// - disabled as an array instead of boolean
732				// - disabled class as method for disabling individual parts
733				if ( !suppressDisabledCheck &&
734						( instance.options.disabled === true ||
735							$( this ).hasClass( "ui-state-disabled" ) ) ) {
736					return;
737				}
738				return ( typeof handler === "string" ? instance[ handler ] : handler )
739					.apply( instance, arguments );
740			}
741
742			// copy the guid so direct unbinding works
743			if ( typeof handler !== "string" ) {
744				handlerProxy.guid = handler.guid =
745					handler.guid || handlerProxy.guid || $.guid++;
746			}
747
748			var match = event.match( /^(\w+)\s*(.*)$/ ),
749				eventName = match[1] + instance.eventNamespace,
750				selector = match[2];
751			if ( selector ) {
752				delegateElement.delegate( selector, eventName, handlerProxy );
753			} else {
754				element.bind( eventName, handlerProxy );
755			}
756		});
757	},
758
759	_off: function( element, eventName ) {
760		eventName = (eventName || "").split( " " ).join( this.eventNamespace + " " ) + this.eventNamespace;
761		element.unbind( eventName ).undelegate( eventName );
762	},
763
764	_delay: function( handler, delay ) {
765		function handlerProxy() {
766			return ( typeof handler === "string" ? instance[ handler ] : handler )
767				.apply( instance, arguments );
768		}
769		var instance = this;
770		return setTimeout( handlerProxy, delay || 0 );
771	},
772
773	_hoverable: function( element ) {
774		this.hoverable = this.hoverable.add( element );
775		this._on( element, {
776			mouseenter: function( event ) {
777				$( event.currentTarget ).addClass( "ui-state-hover" );
778			},
779			mouseleave: function( event ) {
780				$( event.currentTarget ).removeClass( "ui-state-hover" );
781			}
782		});
783	},
784
785	_focusable: function( element ) {
786		this.focusable = this.focusable.add( element );
787		this._on( element, {
788			focusin: function( event ) {
789				$( event.currentTarget ).addClass( "ui-state-focus" );
790			},
791			focusout: function( event ) {
792				$( event.currentTarget ).removeClass( "ui-state-focus" );
793			}
794		});
795	},
796
797	_trigger: function( type, event, data ) {
798		var prop, orig,
799			callback = this.options[ type ];
800
801		data = data || {};
802		event = $.Event( event );
803		event.type = ( type === this.widgetEventPrefix ?
804			type :
805			this.widgetEventPrefix + type ).toLowerCase();
806		// the original event may come from any element
807		// so we need to reset the target on the new event
808		event.target = this.element[ 0 ];
809
810		// copy original event properties over to the new event
811		orig = event.originalEvent;
812		if ( orig ) {
813			for ( prop in orig ) {
814				if ( !( prop in event ) ) {
815					event[ prop ] = orig[ prop ];
816				}
817			}
818		}
819
820		this.element.trigger( event, data );
821		return !( $.isFunction( callback ) &&
822			callback.apply( this.element[0], [ event ].concat( data ) ) === false ||
823			event.isDefaultPrevented() );
824	}
825};
826
827$.each( { show: "fadeIn", hide: "fadeOut" }, function( method, defaultEffect ) {
828	$.Widget.prototype[ "_" + method ] = function( element, options, callback ) {
829		if ( typeof options === "string" ) {
830			options = { effect: options };
831		}
832		var hasOptions,
833			effectName = !options ?
834				method :
835				options === true || typeof options === "number" ?
836					defaultEffect :
837					options.effect || defaultEffect;
838		options = options || {};
839		if ( typeof options === "number" ) {
840			options = { duration: options };
841		}
842		hasOptions = !$.isEmptyObject( options );
843		options.complete = callback;
844		if ( options.delay ) {
845			element.delay( options.delay );
846		}
847		if ( hasOptions && $.effects && ( $.effects.effect[ effectName ] || $.uiBackCompat !== false && $.effects[ effectName ] ) ) {
848			element[ method ]( options );
849		} else if ( effectName !== method && element[ effectName ] ) {
vendor: 4,171 bytes, lines 850-1005
850			element[ effectName ]( options.duration, options.easing, callback );
851		} else {
852			element.queue(function( next ) {
853				$( this )[ method ]();
854				if ( callback ) {
855					callback.call( element[ 0 ] );
856				}
857				next();
858			});
859		}
860	};
861});
862
863// DEPRECATED
864if ( $.uiBackCompat !== false ) {
865	$.Widget.prototype._getCreateOptions = function() {
866		return $.metadata && $.metadata.get( this.element[0] )[ this.widgetName ];
867	};
868}
869
870})( jQuery );
871
872(function( $, undefined ) {
873
874var mouseHandled = false;
875$( document ).mouseup( function( e ) {
876	mouseHandled = false;
877});
878
879$.widget("ui.mouse", {
880	version: "1.9.2",
881	options: {
882		cancel: 'input,textarea,button,select,option',
883		distance: 1,
884		delay: 0
885	},
886	_mouseInit: function() {
887		var that = this;
888
889		this.element
890			.bind('mousedown.'+this.widgetName, function(event) {
891				return that._mouseDown(event);
892			})
893			.bind('click.'+this.widgetName, function(event) {
894				if (true === $.data(event.target, that.widgetName + '.preventClickEvent')) {
895					$.removeData(event.target, that.widgetName + '.preventClickEvent');
896					event.stopImmediatePropagation();
897					return false;
898				}
899			});
900
901		this.started = false;
902	},
903
904	// TODO: make sure destroying one instance of mouse doesn't mess with
905	// other instances of mouse
906	_mouseDestroy: function() {
907		this.element.unbind('.'+this.widgetName);
908		if ( this._mouseMoveDelegate ) {
909			$(document)
910				.unbind('mousemove.'+this.widgetName, this._mouseMoveDelegate)
911				.unbind('mouseup.'+this.widgetName, this._mouseUpDelegate);
912		}
913	},
914
915	_mouseDown: function(event) {
916		// don't let more than one widget handle mouseStart
917		if( mouseHandled ) { return; }
918
919		// we may have missed mouseup (out of window)
920		(this._mouseStarted && this._mouseUp(event));
921
922		this._mouseDownEvent = event;
923
924		var that = this,
925			btnIsLeft = (event.which === 1),
926			// event.target.nodeName works around a bug in IE 8 with
927			// disabled inputs (#7620)
928			elIsCancel = (typeof this.options.cancel === "string" && event.target.nodeName ? $(event.target).closest(this.options.cancel).length : false);
929		if (!btnIsLeft || elIsCancel || !this._mouseCapture(event)) {
930			return true;
931		}
932
933		this.mouseDelayMet = !this.options.delay;
934		if (!this.mouseDelayMet) {
935			this._mouseDelayTimer = setTimeout(function() {
936				that.mouseDelayMet = true;
937			}, this.options.delay);
938		}
939
940		if (this._mouseDistanceMet(event) && this._mouseDelayMet(event)) {
941			this._mouseStarted = (this._mouseStart(event) !== false);
942			if (!this._mouseStarted) {
943				event.preventDefault();
944				return true;
945			}
946		}
947
948		// Click event may never have fired (Gecko & Opera)
949		if (true === $.data(event.target, this.widgetName + '.preventClickEvent')) {
950			$.removeData(event.target, this.widgetName + '.preventClickEvent');
951		}
952
953		// these delegates are required to keep context
954		this._mouseMoveDelegate = function(event) {
955			return that._mouseMove(event);
956		};
957		this._mouseUpDelegate = function(event) {
958			return that._mouseUp(event);
959		};
960		$(document)
961			.bind('mousemove.'+this.widgetName, this._mouseMoveDelegate)
962			.bind('mouseup.'+this.widgetName, this._mouseUpDelegate);
963
964		event.preventDefault();
965
966		mouseHandled = true;
967		return true;
968	},
969
970	_mouseMove: function(event) {
971		// IE mouseup check - mouseup happened when mouse was out of window
972		if ($.ui.ie && !(document.documentMode >= 9) && !event.button) {
973			return this._mouseUp(event);
974		}
975
976		if (this._mouseStarted) {
977			this._mouseDrag(event);
978			return event.preventDefault();
979		}
980
981		if (this._mouseDistanceMet(event) && this._mouseDelayMet(event)) {
982			this._mouseStarted =
983				(this._mouseStart(this._mouseDownEvent, event) !== false);
984			(this._mouseStarted ? this._mouseDrag(event) : this._mouseUp(event));
985		}
986
987		return !this._mouseStarted;
988	},
989
990	_mouseUp: function(event) {
991		$(document)
992			.unbind('mousemove.'+this.widgetName, this._mouseMoveDelegate)
993			.unbind('mouseup.'+this.widgetName, this._mouseUpDelegate);
994
995		if (this._mouseStarted) {
996			this._mouseStarted = false;
997
998			if (event.target === this._mouseDownEvent.target) {
999				$.data(event.target, this.widgetName + '.preventClickEvent', true);
1000			}
1001
1002			this._mouseStop(event);
1003		}
1004
1005		return false;
1006	},
1007
1008	_mouseDistanceMet: function(event) {
1009		return (Math.max(
1010				Math.abs(this._mouseDownEvent.pageX - event.pageX),
1011				Math.abs(this._mouseDownEvent.pageY - event.pageY)
1012			) >= this.options.distance
1013		);
1014	},
1015
1016	_mouseDelayMet: function(event) {
1017		return this.mouseDelayMet;
1018	},
1019
1020	// These are placeholder methods, to be overriden by extending plugin
1021	_mouseStart: function(event) {},
1022	_mouseDrag: function(event) {},
1023	_mouseStop: function(event) {},
1024	_mouseCapture: function(event) { return true; }
1025});
1026
1027})(jQuery);
1028
1029(function( $, undefined ) {
1030
1031$.widget("ui.draggable", $.ui.mouse, {
1032	version: "1.9.2",
1033	widgetEventPrefix: "drag",
1034	options: {
1035		addClasses: true,
1036		appendTo: "parent",
1037		axis: false,
1038		connectToSortable: false,
1039		containment: false,
1040		cursor: "auto",
1041		cursorAt: false,
1042		grid: false,
1043		handle: false,
1044		helper: "original",
1045		iframeFix: false,
1046		opacity: false,
1047		refreshPositions: false,
1048		revert: false,
1049		revertDuration: 500,
1050		scope: "default",
1051		scroll: true,
1052		scrollSensitivity: 20,
1053		scrollSpeed: 20,
1054		snap: false,
1055		snapMode: "both",
1056		snapTolerance: 20,
1057		stack: false,
1058		zIndex: false
1059	},
1060	_create: function() {
1061
1062		if (this.options.helper == 'original' && !(/^(?:r|a|f)/).test(this.element.css("position")))
1063			this.element[0].style.position = 'relative';
1064
1065		(this.options.addClasses && this.element.addClass("ui-draggable"));
1066		(this.options.disabled && this.element.addClass("ui-draggable-disabled"));
1067
1068		this._mouseInit();
1069
1070	},
1071
1072	_destroy: function() {
1073		this.element.removeClass( "ui-draggable ui-draggable-dragging ui-draggable-disabled" );
1074		this._mouseDestroy();
1075	},
1076
1077	_mouseCapture: function(event) {
1078
1079		var o = this.options;
1080
1081		// among others, prevent a drag on a resizable-handle
1082		if (this.helper || o.disabled || $(event.target).is('.ui-resizable-handle'))
1083			return false;
1084
1085		//Quit if we're not on a valid handle
1086		this.handle = this._getHandle(event);
1087		if (!this.handle)
1088			return false;
1089
1090		$(o.iframeFix === true ? "iframe" : o.iframeFix).each(function() {
1091			$('<div class="ui-draggable-iframeFix" style="background: #fff;"></div>')
1092			.css({
1093				width: this.offsetWidth+"px", height: this.offsetHeight+"px",
1094				position: "absolute", opacity: "0.001", zIndex: 1000
1095			})
1096			.css($(this).offset())
1097			.appendTo("body");
1098		});
1099
1100		return true;
1101
1102	},
1103
1104	_mouseStart: function(event) {
1105
1106		var o = this.options;
1107
1108		//Create and append the visible helper
1109		this.helper = this._createHelper(event);
1110
1111		this.helper.addClass("ui-draggable-dragging");
1112
1113		//Cache the helper size
1114		this._cacheHelperProportions();
1115
1116		//If ddmanager is used for droppables, set the global draggable
1117		if($.ui.ddmanager)
1118			$.ui.ddmanager.current = this;
1119
1120		/*
1121		 * - Position generation -
1122		 * This block generates everything position related - it's the core of draggables.
1123		 */
1124
1125		//Cache the margins of the original element
1126		this._cacheMargins();
1127
1128		//Store the helper's css position
1129		this.cssPosition = this.helper.css("position");
1130		this.scrollParent = this.helper.scrollParent();
1131
1132		//The element's absolute position on the page minus margins
1133		this.offset = this.positionAbs = this.element.offset();
1134		this.offset = {
1135			top: this.offset.top - this.margins.top,
1136			left: this.offset.left - this.margins.left
1137		};
1138
1139		$.extend(this.offset, {
1140			click: { //Where the click happened, relative to the element
1141				left: event.pageX - this.offset.left,
1142				top: event.pageY - this.offset.top
1143			},
1144			parent: this._getParentOffset(),
1145			relative: this._getRelativeOffset() //This is a relative to absolute position minus the actual position calculation - only used for relative positioned helper
1146		});
1147
1148		//Generate the original position
1149		this.originalPosition = this.position = this._generatePosition(event);
1150		this.originalPageX = event.pageX;
1151		this.originalPageY = event.pageY;
1152
1153		//Adjust the mouse offset relative to the helper if 'cursorAt' is supplied
1154		(o.cursorAt && this._adjustOffsetFromHelper(o.cursorAt));
1155
1156		//Set a containment if given in the options
1157		if(o.containment)
1158			this._setContainment();
1159
1160		//Trigger event + callbacks
1161		if(this._trigger("start", event) === false) {
1162			this._clear();
1163			return false;
1164		}
1165
1166		//Recache the helper size
1167		this._cacheHelperProportions();
1168
1169		//Prepare the droppable offsets
1170		if ($.ui.ddmanager && !o.dropBehaviour)
1171			$.ui.ddmanager.prepareOffsets(this, event);
1172
1173
1174		this._mouseDrag(event, true); //Execute the drag once - this causes the helper not to be visible before getting its correct position
1175
1176		//If the ddmanager is used for droppables, inform the manager that dragging has started (see #5003)
1177		if ( $.ui.ddmanager ) $.ui.ddmanager.dragStart(this, event);
1178
1179		return true;
1180	},
1181
1182	_mouseDrag: function(event, noPropagation) {
1183
1184		//Compute the helpers position
1185		this.position = this._generatePosition(event);
1186		this.positionAbs = this._convertPositionTo("absolute");
1187
1188		//Call plugins and callbacks and use the resulting position if something is returned
1189		if (!noPropagation) {
1190			var ui = this._uiHash();
1191			if(this._trigger('drag', event, ui) === false) {
1192				this._mouseUp({});
1193				return false;
1194			}
1195			this.position = ui.position;
1196		}
1197
1198		if(!this.options.axis || this.options.axis != "y") this.helper[0].style.left = this.position.left+'px';
1199		if(!this.options.axis || this.options.axis != "x") this.helper[0].style.top = this.position.top+'px';
1200		if($.ui.ddmanager) $.ui.ddmanager.drag(this, event);
1201
1202		return false;
1203	},
1204
1205	_mouseStop: function(event) {
1206
1207		//If we are using droppables, inform the manager about the drop
1208		var dropped = false;
1209		if ($.ui.ddmanager && !this.options.dropBehaviour)
1210			dropped = $.ui.ddmanager.drop(this, event);
1211
1212		//if a drop comes from outside (a sortable)
1213		if(this.dropped) {
1214			dropped = this.dropped;
1215			this.dropped = false;
1216		}
1217
1218		//if the original element is no longer in the DOM don't bother to continue (see #8269)
1219		var element = this.element[0], elementInDom = false;
1220		while ( element && (element = element.parentNode) ) {
1221			if (element == document ) {
1222				elementInDom = true;
1223			}
1224		}
1225		if ( !elementInDom && this.options.helper === "original" )
1226			return false;
1227
1228		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))) {
1229			var that = this;
1230			$(this.helper).animate(this.originalPosition, parseInt(this.options.revertDuration, 10), function() {
1231				if(that._trigger("stop", event) !== false) {
1232					that._clear();
1233				}
1234			});
1235		} else {
1236			if(this._trigger("stop", event) !== false) {
1237				this._clear();
1238			}
1239		}
1240
1241		return false;
1242	},
1243
1244	_mouseUp: function(event) {
1245		//Remove frame helpers
1246		$("div.ui-draggable-iframeFix").each(function() {
1247			this.parentNode.removeChild(this);
1248		});
1249
1250		//If the ddmanager is used for droppables, inform the manager that dragging has stopped (see #5003)
1251		if( $.ui.ddmanager ) $.ui.ddmanager.dragStop(this, event);
1252
1253		return $.ui.mouse.prototype._mouseUp.call(this, event);
1254	},
1255
1256	cancel: function() {
1257
1258		if(this.helper.is(".ui-draggable-dragging")) {
1259			this._mouseUp({});
1260		} else {
1261			this._clear();
1262		}
1263
1264		return this;
1265
1266	},
1267
1268	_getHandle: function(event) {
1269
1270		var handle = !this.options.handle || !$(this.options.handle, this.element).length ? true : false;
1271		$(this.options.handle, this.element)
1272			.find("*")
1273			.andSelf()
1274			.each(function() {
1275				if(this == event.target) handle = true;
1276			});
1277
1278		return handle;
1279
1280	},
1281
1282	_createHelper: function(event) {
1283
1284		var o = this.options;
1285		var helper = $.isFunction(o.helper) ? $(o.helper.apply(this.element[0], [event])) : (o.helper == 'clone' ? this.element.clone().removeAttr('id') : this.element);
1286
1287		if(!helper.parents('body').length)
1288			helper.appendTo((o.appendTo == 'parent' ? this.element[0].parentNode : o.appendTo));
1289
1290		if(helper[0] != this.element[0] && !(/(fixed|absolute)/).test(helper.css("position")))
1291			helper.css("position", "absolute");
1292
1293		return helper;
1294
1295	},
1296
1297	_adjustOffsetFromHelper: function(obj) {
1298		if (typeof obj == 'string') {
1299			obj = obj.split(' ');
1300		}
1301		if ($.isArray(obj)) {
1302			obj = {left: +obj[0], top: +obj[1] || 0};
1303		}
1304		if ('left' in obj) {
1305			this.offset.click.left = obj.left + this.margins.left;
1306		}
1307		if ('right' in obj) {
1308			this.offset.click.left = this.helperProportions.width - obj.right + this.margins.left;
1309		}
1310		if ('top' in obj) {
1311			this.offset.click.top = obj.top + this.margins.top;
1312		}
1313		if ('bottom' in obj) {
1314			this.offset.click.top = this.helperProportions.height - obj.bottom + this.margins.top;
1315		}
1316	},
1317
1318	_getParentOffset: function() {
1319
1320		//Get the offsetParent and cache its position
1321		this.offsetParent = this.helper.offsetParent();
1322		var po = this.offsetParent.offset();
1323
1324		// This is a special case where we need to modify a offset calculated on start, since the following happened:
1325		// 1. The position of the helper is absolute, so it's position is calculated based on the next positioned parent
1326		// 2. The actual offset parent is a child of the scroll parent, and the scroll parent isn't the document, which means that
1327		//    the scroll is included in the initial calculation of the offset of the parent, and never recalculated upon drag
1328		if(this.cssPosition == 'absolute' && this.scrollParent[0] != document && $.contains(this.scrollParent[0], this.offsetParent[0])) {
1329			po.left += this.scrollParent.scrollLeft();
1330			po.top += this.scrollParent.scrollTop();
1331		}
1332
1333		if((this.offsetParent[0] == document.body) //This needs to be actually done for all browsers, since pageX/pageY includes this information
1334		|| (this.offsetParent[0].tagName && this.offsetParent[0].tagName.toLowerCase() == 'html' && $.ui.ie)) //Ugly IE fix
1335			po = { top: 0, left: 0 };
1336
1337		return {
1338			top: po.top + (parseInt(this.offsetParent.css("borderTopWidth"),10) || 0),
1339			left: po.left + (parseInt(this.offsetParent.css("borderLeftWidth"),10) || 0)
1340		};
1341
1342	},
1343
1344	_getRelativeOffset: function() {
1345
1346		if(this.cssPosition == "relative") {
1347			var p = this.element.position();
1348			return {
1349				top: p.top - (parseInt(this.helper.css("top"),10) || 0) + this.scrollParent.scrollTop(),
1350				left: p.left - (parseInt(this.helper.css("left"),10) || 0) + this.scrollParent.scrollLeft()
1351			};
1352		} else {
1353			return { top: 0, left: 0 };
1354		}
1355
1356	},
1357
1358	_cacheMargins: function() {
1359		this.margins = {
1360			left: (parseInt(this.element.css("marginLeft"),10) || 0),
1361			top: (parseInt(this.element.css("marginTop"),10) || 0),
1362			right: (parseInt(this.element.css("marginRight"),10) || 0),
1363			bottom: (parseInt(this.element.css("marginBottom"),10) || 0)
1364		};
1365	},
1366
1367	_cacheHelperProportions: function() {
1368		this.helperProportions = {
1369			width: this.helper.outerWidth(),
1370			height: this.helper.outerHeight()
1371		};
1372	},
1373
1374	_setContainment: function() {
1375
1376		var o = this.options;
1377		if(o.containment == 'parent') o.containment = this.helper[0].parentNode;
1378		if(o.containment == 'document' || o.containment == 'window') this.containment = [
1379			o.containment == 'document' ? 0 : $(window).scrollLeft() - this.offset.relative.left - this.offset.parent.left,
1380			o.containment == 'document' ? 0 : $(window).scrollTop() - this.offset.relative.top - this.offset.parent.top,
1381			(o.containment == 'document' ? 0 : $(window).scrollLeft()) + $(o.containment == 'document' ? document : window).width() - this.helperProportions.width - this.margins.left,
1382			(o.containment == 'document' ? 0 : $(window).scrollTop()) + ($(o.containment == 'document' ? document : window).height() || document.body.parentNode.scrollHeight) - this.helperProportions.height - this.margins.top
1383		];
1384
1385		if(!(/^(document|window|parent)$/).test(o.containment) && o.containment.constructor != Array) {
1386			var c = $(o.containment);
1387			var ce = c[0]; if(!ce) return;
1388			var co = c.offset();
1389			var over = ($(ce).css("overflow") != 'hidden');
1390
1391			this.containment = [
1392				(parseInt($(ce).css("borderLeftWidth"),10) || 0) + (parseInt($(ce).css("paddingLeft"),10) || 0),
1393				(parseInt($(ce).css("borderTopWidth"),10) || 0) + (parseInt($(ce).css("paddingTop"),10) || 0),
1394				(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 - this.margins.right,
1395				(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  - this.margins.bottom
1396			];
1397			this.relative_container = c;
1398
1399		} else if(o.containment.constructor == Array) {
1400			this.containment = o.containment;
1401		}
1402
1403	},
1404
1405	_convertPositionTo: function(d, pos) {
1406
1407		if(!pos) pos = this.position;
1408		var mod = d == "absolute" ? 1 : -1;
1409		var o = this.options, 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);
1410
1411		return {
1412			top: (
1413				pos.top																	// The absolute mouse position
1414				+ this.offset.relative.top * mod										// Only for relative positioned nodes: Relative offset from element to offset parent
1415				+ this.offset.parent.top * mod											// The offsetParent's offset without borders (offset + border)
1416				- ( ( this.cssPosition == 'fixed' ? -this.scrollParent.scrollTop() : ( scrollIsRootNode ? 0 : scroll.scrollTop() ) ) * mod)
1417			),
1418			left: (
1419				pos.left																// The absolute mouse position
1420				+ this.offset.relative.left * mod										// Only for relative positioned nodes: Relative offset from element to offset parent
1421				+ this.offset.parent.left * mod											// The offsetParent's offset without borders (offset + border)
1422				- ( ( this.cssPosition == 'fixed' ? -this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 : scroll.scrollLeft() ) * mod)
1423			)
1424		};
1425
1426	},
1427
1428	_generatePosition: function(event) {
1429
1430		var o = this.options, 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);
1431		var pageX = event.pageX;
1432		var pageY = event.pageY;
1433
1434		/*
1435		 * - Position constraining -
1436		 * Constrain the position to a mix of grid, containment.
1437		 */
1438
1439		if(this.originalPosition) { //If we are not dragging yet, we won't check for options
1440			var containment;
1441			if(this.containment) {
1442			if (this.relative_container){
1443				var co = this.relative_container.offset();
1444				containment = [ this.containment[0] + co.left,
1445					this.containment[1] + co.top,
1446					this.containment[2] + co.left,
1447					this.containment[3] + co.top ];
1448			}
1449			else {
1450				containment = this.containment;
1451			}
1452
1453				if(event.pageX - this.offset.click.left < containment[0]) pageX = containment[0] + this.offset.click.left;
1454				if(event.pageY - this.offset.click.top < containment[1]) pageY = containment[1] + this.offset.click.top;
1455				if(event.pageX - this.offset.click.left > containment[2]) pageX = containment[2] + this.offset.click.left;
1456				if(event.pageY - this.offset.click.top > containment[3]) pageY = containment[3] + this.offset.click.top;
1457			}
1458
1459			if(o.grid) {
1460				//Check for grid elements set to 0 to prevent divide by 0 error causing invalid argument errors in IE (see ticket #6950)
1461				var top = o.grid[1] ? this.originalPageY + Math.round((pageY - this.originalPageY) / o.grid[1]) * o.grid[1] : this.originalPageY;
1462				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;
1463
1464				var left = o.grid[0] ? this.originalPageX + Math.round((pageX - this.originalPageX) / o.grid[0]) * o.grid[0] : this.originalPageX;
1465				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;
1466			}
1467
1468		}
1469
1470		return {
1471			top: (
1472				pageY																// The absolute mouse position
1473				- this.offset.click.top													// Click offset (relative to the element)
1474				- this.offset.relative.top												// Only for relative positioned nodes: Relative offset from element to offset parent
1475				- this.offset.parent.top												// The offsetParent's offset without borders (offset + border)
1476				+ ( ( this.cssPosition == 'fixed' ? -this.scrollParent.scrollTop() : ( scrollIsRootNode ? 0 : scroll.scrollTop() ) ))
1477			),
1478			left: (
1479				pageX																// The absolute mouse position
1480				- this.offset.click.left												// Click offset (relative to the element)
1481				- this.offset.relative.left												// Only for relative positioned nodes: Relative offset from element to offset parent
1482				- this.offset.parent.left												// The offsetParent's offset without borders (offset + border)
1483				+ ( ( this.cssPosition == 'fixed' ? -this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 : scroll.scrollLeft() ))
1484			)
1485		};
1486
1487	},
1488
1489	_clear: function() {
1490		this.helper.removeClass("ui-draggable-dragging");
1491		if(this.helper[0] != this.element[0] && !this.cancelHelperRemoval) this.helper.remove();
1492		//if($.ui.ddmanager) $.ui.ddmanager.current = null;
1493		this.helper = null;
1494		this.cancelHelperRemoval = false;
1495	},
1496
1497	// From now on bulk stuff - mainly helpers
1498
1499	_trigger: function(type, event, ui) {
1500		ui = ui || this._uiHash();
1501		$.ui.plugin.call(this, type, [event, ui]);
1502		if(type == "drag") this.positionAbs = this._convertPositionTo("absolute"); //The absolute position has to be recalculated after plugins
1503		return $.Widget.prototype._trigger.call(this, type, event, ui);
1504	},
1505
1506	plugins: {},
1507
1508	_uiHash: function(event) {
1509		return {
1510			helper: this.helper,
1511			position: this.position,
1512			originalPosition: this.originalPosition,
1513			offset: this.positionAbs
1514		};
1515	}
1516
1517});
1518
1519$.ui.plugin.add("draggable", "connectToSortable", {
1520	start: function(event, ui) {
1521
1522		var inst = $(this).data("draggable"), o = inst.options,
1523			uiSortable = $.extend({}, ui, { item: inst.element });
1524		inst.sortables = [];
1525		$(o.connectToSortable).each(function() {
1526			var sortable = $.data(this, 'sortable');
1527			if (sortable && !sortable.options.disabled) {
1528				inst.sortables.push({
1529					instance: sortable,
1530					shouldRevert: sortable.options.revert
1531				});
1532				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).
1533				sortable._trigger("activate", event, uiSortable);
1534			}
1535		});
1536
1537	},
1538	stop: function(event, ui) {
1539
1540		//If we are still over the sortable, we fake the stop event of the sortable, but also remove helper
1541		var inst = $(this).data("draggable"),
1542			uiSortable = $.extend({}, ui, { item: inst.element });
1543
1544		$.each(inst.sortables, function() {
1545			if(this.instance.isOver) {
1546
1547				this.instance.isOver = 0;
1548
1549				inst.cancelHelperRemoval = true; //Don't remove the helper in the draggable instance
1550				this.instance.cancelHelperRemoval = false; //Remove it in the sortable instance (so sortable plugins like revert still work)
1551
1552				//The sortable revert is supported, and we have to set a temporary dropped variable on the draggable to support revert: 'valid/invalid'
1553				if(this.shouldRevert) this.instance.options.revert = true;
1554
1555				//Trigger the stop of the sortable
1556				this.instance._mouseStop(event);
1557
1558				this.instance.options.helper = this.instance.options._helper;
1559
1560				//If the helper has been the original item, restore properties in the sortable
1561				if(inst.options.helper == 'original')
1562					this.instance.currentItem.css({ top: 'auto', left: 'auto' });
1563
1564			} else {
1565				this.instance.cancelHelperRemoval = false; //Remove the helper in the sortable instance
1566				this.instance._trigger("deactivate", event, uiSortable);
1567			}
1568
1569		});
1570
1571	},
1572	drag: function(event, ui) {
1573
1574		var inst = $(this).data("draggable"), that = this;
1575
1576		var checkPos = function(o) {
1577			var dyClick = this.offset.click.top, dxClick = this.offset.click.left;
1578			var helperTop = this.positionAbs.top, helperLeft = this.positionAbs.left;
1579			var itemHeight = o.height, itemWidth = o.width;
1580			var itemTop = o.top, itemLeft = o.left;
1581
1582			return $.ui.isOver(helperTop + dyClick, helperLeft + dxClick, itemTop, itemLeft, itemHeight, itemWidth);
1583		};
1584
1585		$.each(inst.sortables, function(i) {
1586
1587			var innermostIntersecting = false;
1588			var thisSortable = this;
1589			//Copy over some variables to allow calling the sortable's native _intersectsWith
1590			this.instance.positionAbs = inst.positionAbs;
1591			this.instance.helperProportions = inst.helperProportions;
1592			this.instance.offset.click = inst.offset.click;
1593
1594			if(this.instance._intersectsWith(this.instance.containerCache)) {
1595				innermostIntersecting = true;
1596				$.each(inst.sortables, function () {
1597					this.instance.positionAbs = inst.positionAbs;
1598					this.instance.helperProportions = inst.helperProportions;
1599					this.instance.offset.click = inst.offset.click;
1600					if  (this != thisSortable
1601						&& this.instance._intersectsWith(this.instance.containerCache)
1602						&& $.ui.contains(thisSortable.instance.element[0], this.instance.element[0]))
1603						innermostIntersecting = false;
1604						return innermostIntersecting;
1605				});
1606			}
1607
1608
1609			if(innermostIntersecting) {
1610				//If it intersects, we use a little isOver variable and set it once, so our move-in stuff gets fired only once
1611				if(!this.instance.isOver) {
1612
1613					this.instance.isOver = 1;
1614					//Now we fake the start of dragging for the sortable instance,
1615					//by cloning the list group item, appending it to the sortable and using it as inst.currentItem
1616					//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)
1617					this.instance.currentItem = $(that).clone().removeAttr('id').appendTo(this.instance.element).data("sortable-item", true);
1618					this.instance.options._helper = this.instance.options.helper; //Store helper option to later restore it
1619					this.instance.options.helper = function() { return ui.helper[0]; };
1620
1621					event.target = this.instance.currentItem[0];
1622					this.instance._mouseCapture(event, true);
1623					this.instance._mouseStart(event, true, true);
1624
1625					//Because the browser event is way off the new appended portlet, we modify a couple of variables to reflect the changes
1626					this.instance.offset.click.top = inst.offset.click.top;
1627					this.instance.offset.click.left = inst.offset.click.left;
1628					this.instance.offset.parent.left -= inst.offset.parent.left - this.instance.offset.parent.left;
1629					this.instance.offset.parent.top -= inst.offset.parent.top - this.instance.offset.parent.top;
1630
1631					inst._trigger("toSortable", event);
1632					inst.dropped = this.instance.element; //draggable revert needs that
1633					//hack so receive/update callbacks work (mostly)
1634					inst.currentItem = inst.element;
1635					this.instance.fromOutside = inst;
1636
1637				}
1638
1639				//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
1640				if(this.instance.currentItem) this.instance._mouseDrag(event);
1641
1642			} else {
1643
1644				//If it doesn't intersect with the sortable, and it intersected before,
1645				//we fake the drag stop of the sortable, but make sure it doesn't remove the helper by using cancelHelperRemoval
1646				if(this.instance.isOver) {
1647
1648					this.instance.isOver = 0;
1649					this.instance.cancelHelperRemoval = true;
1650
1651					//Prevent reverting on this forced stop
1652					this.instance.options.revert = false;
1653
1654					// The out event needs to be triggered independently
1655					this.instance._trigger('out', event, this.instance._uiHash(this.instance));
1656
1657					this.instance._mouseStop(event, true);
1658					this.instance.options.helper = this.instance.options._helper;
1659
1660					//Now we remove our currentItem, the list group clone again, and the placeholder, and animate the helper back to it's original size
1661					this.instance.currentItem.remove();
1662					if(this.instance.placeholder) this.instance.placeholder.remove();
1663
1664					inst._trigger("fromSortable", event);
1665					inst.dropped = false; //draggable revert needs that
1666				}
1667
1668			};
1669
1670		});
1671
1672	}
1673});
1674
1675$.ui.plugin.add("draggable", "cursor", {
1676	start: function(event, ui) {
1677		var t = $('body'), o = $(this).data('draggable').options;
1678		if (t.css("cursor")) o._cursor = t.css("cursor");
1679		t.css("cursor", o.cursor);
1680	},
1681	stop: function(event, ui) {
1682		var o = $(this).data('draggable').options;
1683		if (o._cursor) $('body').css("cursor", o._cursor);
1684	}
1685});
1686
1687$.ui.plugin.add("draggable", "opacity", {
1688	start: function(event, ui) {
1689		var t = $(ui.helper), o = $(this).data('draggable').options;
1690		if(t.css("opacity")) o._opacity = t.css("opacity");
1691		t.css('opacity', o.opacity);
1692	},
1693	stop: function(event, ui) {
1694		var o = $(this).data('draggable').options;
1695		if(o._opacity) $(ui.helper).css('opacity', o._opacity);
1696	}
1697});
1698
1699$.ui.plugin.add("draggable", "scroll", {
1700	start: function(event, ui) {
1701		var i = $(this).data("draggable");
1702		if(i.scrollParent[0] != document && i.scrollParent[0].tagName != 'HTML') i.overflowOffset = i.scrollParent.offset();
1703	},
1704	drag: function(event, ui) {
1705
1706		var i = $(this).data("draggable"), o = i.options, scrolled = false;
1707
1708		if(i.scrollParent[0] != document && i.scrollParent[0].tagName != 'HTML') {
1709
1710			if(!o.axis || o.axis != 'x') {
1711				if((i.overflowOffset.top + i.scrollParent[0].offsetHeight) - event.pageY < o.scrollSensitivity)
1712					i.scrollParent[0].scrollTop = scrolled = i.scrollParent[0].scrollTop + o.scrollSpeed;
1713				else if(event.pageY - i.overflowOffset.top < o.scrollSensitivity)
1714					i.scrollParent[0].scrollTop = scrolled = i.scrollParent[0].scrollTop - o.scrollSpeed;
1715			}
1716
1717			if(!o.axis || o.axis != 'y') {
1718				if((i.overflowOffset.left + i.scrollParent[0].offsetWidth) - event.pageX < o.scrollSensitivity)
1719					i.scrollParent[0].scrollLeft = scrolled = i.scrollParent[0].scrollLeft + o.scrollSpeed;
1720				else if(event.pageX - i.overflowOffset.left < o.scrollSensitivity)
1721					i.scrollParent[0].scrollLeft = scrolled = i.scrollParent[0].scrollLeft - o.scrollSpeed;
1722			}
1723
1724		} else {
1725
1726			if(!o.axis || o.axis != 'x') {
1727				if(event.pageY - $(document).scrollTop() < o.scrollSensitivity)
1728					scrolled = $(document).scrollTop($(document).scrollTop() - o.scrollSpeed);
1729				else if($(window).height() - (event.pageY - $(document).scrollTop()) < o.scrollSensitivity)
1730					scrolled = $(document).scrollTop($(document).scrollTop() + o.scrollSpeed);
1731			}
1732
1733			if(!o.axis || o.axis != 'y') {
1734				if(event.pageX - $(document).scrollLeft() < o.scrollSensitivity)
1735					scrolled = $(document).scrollLeft($(document).scrollLeft() - o.scrollSpeed);
1736				else if($(window).width() - (event.pageX - $(document).scrollLeft()) < o.scrollSensitivity)
1737					scrolled = $(document).scrollLeft($(document).scrollLeft() + o.scrollSpeed);
1738			}
1739
1740		}
1741
1742		if(scrolled !== false && $.ui.ddmanager && !o.dropBehaviour)
1743			$.ui.ddmanager.prepareOffsets(i, event);
1744
1745	}
1746});
1747
1748$.ui.plugin.add("draggable", "snap", {
1749	start: function(event, ui) {
1750
1751		var i = $(this).data("draggable"), o = i.options;
1752		i.snapElements = [];
1753
1754		$(o.snap.constructor != String ? ( o.snap.items || ':data(draggable)' ) : o.snap).each(function() {
1755			var $t = $(this); var $o = $t.offset();
1756			if(this != i.element[0]) i.snapElements.push({
1757				item: this,
1758				width: $t.outerWidth(), height: $t.outerHeight(),
1759				top: $o.top, left: $o.left
1760			});
1761		});
1762
1763	},
1764	drag: function(event, ui) {
1765
1766		var inst = $(this).data("draggable"), o = inst.options;
1767		var d = o.snapTolerance;
1768
1769		var x1 = ui.offset.left, x2 = x1 + inst.helperProportions.width,
1770			y1 = ui.offset.top, y2 = y1 + inst.helperProportions.height;
1771
1772		for (var i = inst.snapElements.length - 1; i >= 0; i--){
1773
1774			var l = inst.snapElements[i].left, r = l + inst.snapElements[i].width,
1775				t = inst.snapElements[i].top, b = t + inst.snapElements[i].height;
1776
1777			//Yes, I know, this is insane ;)
1778			if(!((l-d < x1 && x1 < r+d && t-d < y1 && y1 < b+d) || (l-d < x1 && x1 < r+d && t-d < y2 && y2 < b+d) || (l-d < x2 && x2 < r+d && t-d < y1 && y1 < b+d) || (l-d < x2 && x2 < r+d && t-d < y2 && y2 < b+d))) {
1779				if(inst.snapElements[i].snapping) (inst.options.snap.release && inst.options.snap.release.call(inst.element, event, $.extend(inst._uiHash(), { snapItem: inst.snapElements[i].item })));
1780				inst.snapElements[i].snapping = false;
1781				continue;
1782			}
1783
1784			if(o.snapMode != 'inner') {
1785				var ts = Math.abs(t - y2) <= d;
1786				var bs = Math.abs(b - y1) <= d;
1787				var ls = Math.abs(l - x2) <= d;
1788				var rs = Math.abs(r - x1) <= d;
1789				if(ts) ui.position.top = inst._convertPositionTo("relative", { top: t - inst.helperProportions.height, left: 0 }).top - inst.margins.top;
1790				if(bs) ui.position.top = inst._convertPositionTo("relative", { top: b, left: 0 }).top - inst.margins.top;
1791				if(ls) ui.position.left = inst._convertPositionTo("relative", { top: 0, left: l - inst.helperProportions.width }).left - inst.margins.left;
1792				if(rs) ui.position.left = inst._convertPositionTo("relative", { top: 0, left: r }).left - inst.margins.left;
1793			}
1794
1795			var first = (ts || bs || ls || rs);
1796
1797			if(o.snapMode != 'outer') {
1798				var ts = Math.abs(t - y1) <= d;
1799				var bs = Math.abs(b - y2) <= d;
1800				var ls = Math.abs(l - x1) <= d;
1801				var rs = Math.abs(r - x2) <= d;
1802				if(ts) ui.position.top = inst._convertPositionTo("relative", { top: t, left: 0 }).top - inst.margins.top;
1803				if(bs) ui.position.top = inst._convertPositionTo("relative", { top: b - inst.helperProportions.height, left: 0 }).top - inst.margins.top;
1804				if(ls) ui.position.left = inst._convertPositionTo("relative", { top: 0, left: l }).left - inst.margins.left;
1805				if(rs) ui.position.left = inst._convertPositionTo("relative", { top: 0, left: r - inst.helperProportions.width }).left - inst.margins.left;
1806			}
1807
1808			if(!inst.snapElements[i].snapping && (ts || bs || ls || rs || first))
1809				(inst.options.snap.snap && inst.options.snap.snap.call(inst.element, event, $.extend(inst._uiHash(), { snapItem: inst.snapElements[i].item })));
1810			inst.snapElements[i].snapping = (ts || bs || ls || rs || first);
1811
1812		};
1813
1814	}
1815});
1816
1817$.ui.plugin.add("draggable", "stack", {
1818	start: function(event, ui) {
1819
1820		var o = $(this).data("draggable").options;
1821
1822		var group = $.makeArray($(o.stack)).sort(function(a,b) {
1823			return (parseInt($(a).css("zIndex"),10) || 0) - (parseInt($(b).css("zIndex"),10) || 0);
1824		});
1825		if (!group.length) { return; }
1826
1827		var min = parseInt(group[0].style.zIndex) || 0;
1828		$(group).each(function(i) {
1829			this.style.zIndex = min + i;
1830		});
1831
1832		this[0].style.zIndex = min + group.length;
1833
1834	}
1835});
1836
1837$.ui.plugin.add("draggable", "zIndex", {
1838	start: function(event, ui) {
1839		var t = $(ui.helper), o = $(this).data("draggable").options;
1840		if(t.css("zIndex")) o._zIndex = t.css("zIndex");
1841		t.css('zIndex', o.zIndex);
1842	},
1843	stop: function(event, ui) {
1844		var o = $(this).data("draggable").options;
1845		if(o._zIndex) $(ui.helper).css('zIndex', o._zIndex);
1846	}
1847});
1848
1849})(jQuery);
1850
1851(function( $, undefined ) {
1852
1853$.widget("ui.droppable", {
1854	version: "1.9.2",
1855	widgetEventPrefix: "drop",
1856	options: {
1857		accept: '*',
1858		activeClass: false,
1859		addClasses: true,
1860		greedy: false,
1861		hoverClass: false,
1862		scope: 'default',
1863		tolerance: 'intersect'
1864	},
1865	_create: function() {
1866
1867		var o = this.options, accept = o.accept;
1868		this.isover = 0; this.isout = 1;
1869
1870		this.accept = $.isFunction(accept) ? accept : function(d) {
1871			return d.is(accept);
1872		};
1873
1874		//Store the droppable's proportions
1875		this.proportions = { width: this.element[0].offsetWidth, height: this.element[0].offsetHeight };
1876
1877		// Add the reference and positions to the manager
1878		$.ui.ddmanager.droppables[o.scope] = $.ui.ddmanager.droppables[o.scope] || [];
1879		$.ui.ddmanager.droppables[o.scope].push(this);
1880
1881		(o.addClasses && this.element.addClass("ui-droppable"));
1882
1883	},
1884
1885	_destroy: function() {
1886		var drop = $.ui.ddmanager.droppables[this.options.scope];
1887		for ( var i = 0; i < drop.length; i++ )
1888			if ( drop[i] == this )
1889				drop.splice(i, 1);
1890
1891		this.element.removeClass("ui-droppable ui-droppable-disabled");
1892	},
1893
1894	_setOption: function(key, value) {
1895
1896		if(key == 'accept') {
1897			this.accept = $.isFunction(value) ? value : function(d) {
1898				return d.is(value);
1899			};
1900		}
1901		$.Widget.prototype._setOption.apply(this, arguments);
1902	},
1903
1904	_activate: function(event) {
1905		var draggable = $.ui.ddmanager.current;
1906		if(this.options.activeClass) this.element.addClass(this.options.activeClass);
1907		(draggable && this._trigger('activate', event, this.ui(draggable)));
1908	},
1909
1910	_deactivate: function(event) {
1911		var draggable = $.ui.ddmanager.current;
1912		if(this.options.activeClass) this.element.removeClass(this.options.activeClass);
1913		(draggable && this._trigger('deactivate', event, this.ui(draggable)));
1914	},
1915
1916	_over: function(event) {
1917
1918		var draggable = $.ui.ddmanager.current;
1919		if (!draggable || (draggable.currentItem || draggable.element)[0] == this.element[0]) return; // Bail if draggable and droppable are same element
1920
1921		if (this.accept.call(this.element[0],(draggable.currentItem || draggable.element))) {
1922			if(this.options.hoverClass) this.element.addClass(this.options.hoverClass);
1923			this._trigger('over', event, this.ui(draggable));
1924		}
1925
1926	},
1927
1928	_out: function(event) {
1929
1930		var draggable = $.ui.ddmanager.current;
1931		if (!draggable || (draggable.currentItem || draggable.element)[0] == this.element[0]) return; // Bail if draggable and droppable are same element
1932
1933		if (this.accept.call(this.element[0],(draggable.currentItem || draggable.element))) {
1934			if(this.options.hoverClass) this.element.removeClass(this.options.hoverClass);
1935			this._trigger('out', event, this.ui(draggable));
1936		}
1937
1938	},
1939
1940	_drop: function(event,custom) {
1941
1942		var draggable = custom || $.ui.ddmanager.current;
1943		if (!draggable || (draggable.currentItem || draggable.element)[0] == this.element[0]) return false; // Bail if draggable and droppable are same element
1944
1945		var childrenIntersection = false;
1946		this.element.find(":data(droppable)").not(".ui-draggable-dragging").each(function() {
1947			var inst = $.data(this, 'droppable');
1948			if(
1949				inst.options.greedy
1950				&& !inst.options.disabled
1951				&& inst.options.scope == draggable.options.scope
1952				&& inst.accept.call(inst.element[0], (draggable.currentItem || draggable.element))
1953				&& $.ui.intersect(draggable, $.extend(inst, { offset: inst.element.offset() }), inst.options.tolerance)
1954			) { childrenIntersection = true; return false; }
1955		});
1956		if(childrenIntersection) return false;
1957
1958		if(this.accept.call(this.element[0],(draggable.currentItem || draggable.element))) {
1959			if(this.options.activeClass) this.element.removeClass(this.options.activeClass);
1960			if(this.options.hoverClass) this.element.removeClass(this.options.hoverClass);
1961			this._trigger('drop', event, this.ui(draggable));
1962			return this.element;
1963		}
1964
1965		return false;
1966
1967	},
1968
1969	ui: function(c) {
1970		return {
1971			draggable: (c.currentItem || c.element),
1972			helper: c.helper,
1973			position: c.position,
1974			offset: c.positionAbs
1975		};
1976	}
1977
1978});
1979
1980$.ui.intersect = function(draggable, droppable, toleranceMode) {
1981
1982	if (!droppable.offset) return false;
1983
1984	var x1 = (draggable.positionAbs || draggable.position.absolute).left, x2 = x1 + draggable.helperProportions.width,
1985		y1 = (draggable.positionAbs || draggable.position.absolute).top, y2 = y1 + draggable.helperProportions.height;
1986	var l = droppable.offset.left, r = l + droppable.proportions.width,
1987		t = droppable.offset.top, b = t + droppable.proportions.height;
1988
1989	switch (toleranceMode) {
1990		case 'fit':
1991			return (l <= x1 && x2 <= r
1992				&& t <= y1 && y2 <= b);
1993			break;
1994		case 'intersect':
1995			return (l < x1 + (draggable.helperProportions.width / 2) // Right Half
1996				&& x2 - (draggable.helperProportions.width / 2) < r // Left Half
1997				&& t < y1 + (draggable.helperProportions.height / 2) // Bottom Half
1998				&& y2 - (draggable.helperProportions.height / 2) < b ); // Top Half
1999			break;
2000		case 'pointer':
2001			var draggableLeft = ((draggable.positionAbs || draggable.position.absolute).left + (draggable.clickOffset || draggable.offset.click).left),
2002				draggableTop = ((draggable.positionAbs || draggable.position.absolute).top + (draggable.clickOffset || draggable.offset.click).top),
2003				isOver = $.ui.isOver(draggableTop, draggableLeft, t, l, droppable.proportions.height, droppable.proportions.width);
2004			return isOver;
2005			break;
2006		case 'touch':
2007			return (
2008					(y1 >= t && y1 <= b) ||	// Top edge touching
2009					(y2 >= t && y2 <= b) ||	// Bottom edge touching
2010					(y1 < t && y2 > b)		// Surrounded vertically
2011				) && (
2012					(x1 >= l && x1 <= r) ||	// Left edge touching
2013					(x2 >= l && x2 <= r) ||	// Right edge touching
2014					(x1 < l && x2 > r)		// Surrounded horizontally
2015				);
2016			break;
2017		default:
2018			return false;
2019			break;
2020		}
2021
2022};
2023
2024/*
2025	This manager tracks offsets of draggables and droppables
2026*/
2027$.ui.ddmanager = {
2028	current: null,
2029	droppables: { 'default': [] },
2030	prepareOffsets: function(t, event) {
2031
2032		var m = $.ui.ddmanager.droppables[t.options.scope] || [];
2033		var type = event ? event.type : null; // workaround for #2317
2034		var list = (t.currentItem || t.element).find(":data(droppable)").andSelf();
2035
2036		droppablesLoop: for (var i = 0; i < m.length; i++) {
2037
2038			if(m[i].options.disabled || (t && !m[i].accept.call(m[i].element[0],(t.currentItem || t.element)))) continue;	//No disabled and non-accepted
2039			for (var j=0; j < list.length; j++) { if(list[j] == m[i].element[0]) { m[i].proportions.height = 0; continue droppablesLoop; } }; //Filter out elements in the current dragged item
2040			m[i].visible = m[i].element.css("display") != "none"; if(!m[i].visible) continue; 									//If the element is not visible, continue
2041
2042			if(type == "mousedown") m[i]._activate.call(m[i], event); //Activate the droppable if used directly from draggables
2043
2044			m[i].offset = m[i].element.offset();
2045			m[i].proportions = { width: m[i].element[0].offsetWidth, height: m[i].element[0].offsetHeight };
2046
2047		}
2048
2049	},
2050	drop: function(draggable, event) {
2051
2052		var dropped = false;
2053		$.each($.ui.ddmanager.droppables[draggable.options.scope] || [], function() {
2054
2055			if(!this.options) return;
2056			if (!this.options.disabled && this.visible && $.ui.intersect(draggable, this, this.options.tolerance))
2057				dropped = this._drop.call(this, event) || dropped;
2058
2059			if (!this.options.disabled && this.visible && this.accept.call(this.element[0],(draggable.currentItem || draggable.element))) {
2060				this.isout = 1; this.isover = 0;
2061				this._deactivate.call(this, event);
2062			}
2063
2064		});
2065		return dropped;
2066
2067	},
2068	dragStart: function( draggable, event ) {
2069		//Listen for scrolling so that if the dragging causes scrolling the position of the droppables can be recalculated (see #5003)
2070		draggable.element.parentsUntil( "body" ).bind( "scroll.droppable", function() {
2071			if( !draggable.options.refreshPositions ) $.ui.ddmanager.prepareOffsets( draggable, event );
2072		});
2073	},
2074	drag: function(draggable, event) {
2075
2076		//If you have a highly dynamic page, you might try this option. It renders positions every time you move the mouse.
2077		if(draggable.options.refreshPositions) $.ui.ddmanager.prepareOffsets(draggable, event);
2078
2079		//Run through all droppables and check their positions based on specific tolerance options
2080		$.each($.ui.ddmanager.droppables[draggable.options.scope] || [], function() {
2081
2082			if(this.options.disabled || this.greedyChild || !this.visible) return;
2083			var intersects = $.ui.intersect(draggable, this, this.options.tolerance);
2084
2085			var c = !intersects && this.isover == 1 ? 'isout' : (intersects && this.isover == 0 ? 'isover' : null);
2086			if(!c) return;
2087
2088			var parentInstance;
2089			if (this.options.greedy) {
2090				// find droppable parents with same scope
2091				var scope = this.options.scope;
2092				var parent = this.element.parents(':data(droppable)').filter(function () {
2093					return $.data(this, 'droppable').options.scope === scope;
2094				});
2095
2096				if (parent.length) {
2097					parentInstance = $.data(parent[0], 'droppable');
2098					parentInstance.greedyChild = (c == 'isover' ? 1 : 0);
2099				}
2100			}
2101
2102			// we just moved into a greedy child
2103			if (parentInstance && c == 'isover') {
2104				parentInstance['isover'] = 0;
2105				parentInstance['isout'] = 1;
2106				parentInstance._out.call(parentInstance, event);
2107			}
2108
2109			this[c] = 1; this[c == 'isout' ? 'isover' : 'isout'] = 0;
2110			this[c == "isover" ? "_over" : "_out"].call(this, event);
2111
2112			// we just moved out of a greedy child
2113			if (parentInstance && c == 'isout') {
2114				parentInstance['isout'] = 0;
2115				parentInstance['isover'] = 1;
2116				parentInstance._over.call(parentInstance, event);
2117			}
2118		});
2119
2120	},
2121	dragStop: function( draggable, event ) {
2122		draggable.element.parentsUntil( "body" ).unbind( "scroll.droppable" );
2123		//Call prepareOffsets one final time since IE does not fire return scroll events when overflow was caused by drag (see #5003)
2124		if( !draggable.options.refreshPositions ) $.ui.ddmanager.prepareOffsets( draggable, event );
2125	}
2126};
2127
2128})(jQuery);
2129
2130(function( $, undefined ) {
2131
2132$.widget("ui.resizable", $.ui.mouse, {
2133	version: "1.9.2",
2134	widgetEventPrefix: "resize",
2135	options: {
2136		alsoResize: false,
2137		animate: false,
2138		animateDuration: "slow",
2139		animateEasing: "swing",
2140		aspectRatio: false,
2141		autoHide: false,
2142		containment: false,
2143		ghost: false,
2144		grid: false,
2145		handles: "e,s,se",
2146		helper: false,
2147		maxHeight: null,
2148		maxWidth: null,
2149		minHeight: 10,
2150		minWidth: 10,
2151		zIndex: 1000
2152	},
2153	_create: function() {
2154
2155		var that = this, o = this.options;
2156		this.element.addClass("ui-resizable");
2157
2158		$.extend(this, {
2159			_aspectRatio: !!(o.aspectRatio),
2160			aspectRatio: o.aspectRatio,
2161			originalElement: this.element,
2162			_proportionallyResizeElements: [],
2163			_helper: o.helper || o.ghost || o.animate ? o.helper || 'ui-resizable-helper' : null
2164		});
2165
2166		//Wrap the element if it cannot hold child nodes
2167		if(this.element[0].nodeName.match(/canvas|textarea|input|select|button|img/i)) {
2168
2169			//Create a wrapper element and set the wrapper to the new current internal element
2170			this.element.wrap(
2171				$('<div class="ui-wrapper" style="overflow: hidden;"></div>').css({
2172					position: this.element.css('position'),
2173					width: this.element.outerWidth(),
2174					height: this.element.outerHeight(),
2175					top: this.element.css('top'),
2176					left: this.element.css('left')
2177				})
2178			);
2179
2180			//Overwrite the original this.element
2181			this.element = this.element.parent().data(
2182				"resizable", this.element.data('resizable')
2183			);
2184
2185			this.elementIsWrapper = true;
2186
2187			//Move margins to the wrapper
2188			this.element.css({ marginLeft: this.originalElement.css("marginLeft"), marginTop: this.originalElement.css("marginTop"), marginRight: this.originalElement.css("marginRight"), marginBottom: this.originalElement.css("marginBottom") });
2189			this.originalElement.css({ marginLeft: 0, marginTop: 0, marginRight: 0, marginBottom: 0});
2190
2191			//Prevent Safari textarea resize
2192			this.originalResizeStyle = this.originalElement.css('resize');
2193			this.originalElement.css('resize', 'none');
2194
2195			//Push the actual element to our proportionallyResize internal array
2196			this._proportionallyResizeElements.push(this.originalElement.css({ position: 'static', zoom: 1, display: 'block' }));
2197
2198			// avoid IE jump (hard set the margin)
2199			this.originalElement.css({ margin: this.originalElement.css('margin') });
2200
2201			// fix handlers offset
2202			this._proportionallyResize();
2203
2204		}
2205
2206		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' });
2207		if(this.handles.constructor == String) {
2208
2209			if(this.handles == 'all') this.handles = 'n,e,s,w,se,sw,ne,nw';
2210			var n = this.handles.split(","); this.handles = {};
2211
2212			for(var i = 0; i < n.length; i++) {
2213
2214				var handle = $.trim(n[i]), hname = 'ui-resizable-'+handle;
2215				var axis = $('<div class="ui-resizable-handle ' + hname + '"></div>');
2216
2217				// Apply zIndex to all handles - see #7960
2218				axis.css({ zIndex: o.zIndex });
2219
2220				//TODO : What's going on here?
2221				if ('se' == handle) {
2222					axis.addClass('ui-icon ui-icon-gripsmall-diagonal-se');
2223				};
2224
2225				//Insert into internal handles object and append to element
2226				this.handles[handle] = '.ui-resizable-'+handle;
2227				this.element.append(axis);
2228			}
2229
2230		}
2231
2232		this._renderAxis = function(target) {
2233
2234			target = target || this.element;
2235
2236			for(var i in this.handles) {
2237
2238				if(this.handles[i].constructor == String)
2239					this.handles[i] = $(this.handles[i], this.element).show();
2240
2241				//Apply pad to wrapper element, needed to fix axis position (textarea, inputs, scrolls)
2242				if (this.elementIsWrapper && this.originalElement[0].nodeName.match(/textarea|input|select|button/i)) {
2243
2244					var axis = $(this.handles[i], this.element), padWrapper = 0;
2245
2246					//Checking the correct pad and border
2247					padWrapper = /sw|ne|nw|se|n|s/.test(i) ? axis.outerHeight() : axis.outerWidth();
2248
2249					//The padding type i have to apply...
2250					var padPos = [ 'padding',
2251						/ne|nw|n/.test(i) ? 'Top' :
2252						/se|sw|s/.test(i) ? 'Bottom' :
2253						/^e$/.test(i) ? 'Right' : 'Left' ].join("");
2254
2255					target.css(padPos, padWrapper);
2256
2257					this._proportionallyResize();
2258
2259				}
2260
2261				//TODO: What's that good for? There's not anything to be executed left
2262				if(!$(this.handles[i]).length)
2263					continue;
2264
2265			}
2266		};
2267
2268		//TODO: make renderAxis a prototype function
2269		this._renderAxis(this.element);
2270
2271		this._handles = $('.ui-resizable-handle', this.element)
2272			.disableSelection();
2273
2274		//Matching axis name
2275		this._handles.mouseover(function() {
2276			if (!that.resizing) {
2277				if (this.className)
2278					var axis = this.className.match(/ui-resizable-(se|sw|ne|nw|n|e|s|w)/i);
2279				//Axis, default = se
2280				that.axis = axis && axis[1] ? axis[1] : 'se';
2281			}
2282		});
2283
2284		//If we want to auto hide the elements
2285		if (o.autoHide) {
2286			this._handles.hide();
2287			$(this.element)
2288				.addClass("ui-resizable-autohide")
2289				.mouseenter(function() {
2290					if (o.disabled) return;
2291					$(this).removeClass("ui-resizable-autohide");
2292					that._handles.show();
2293				})
2294				.mouseleave(function(){
2295					if (o.disabled) return;
2296					if (!that.resizing) {
2297						$(this).addClass("ui-resizable-autohide");
2298						that._handles.hide();
2299					}
2300				});
2301		}
2302
2303		//Initialize the mouse interaction
2304		this._mouseInit();
2305
2306	},
2307
2308	_destroy: function() {
2309
2310		this._mouseDestroy();
2311
2312		var _destroy = function(exp) {
2313			$(exp).removeClass("ui-resizable ui-resizable-disabled ui-resizable-resizing")
2314				.removeData("resizable").removeData("ui-resizable").unbind(".resizable").find('.ui-resizable-handle').remove();
2315		};
2316
2317		//TODO: Unwrap at same DOM position
2318		if (this.elementIsWrapper) {
2319			_destroy(this.element);
2320			var wrapper = this.element;
2321			this.originalElement.css({
2322				position: wrapper.css('position'),
2323				width: wrapper.outerWidth(),
2324				height: wrapper.outerHeight(),
2325				top: wrapper.css('top'),
2326				left: wrapper.css('left')
2327			}).insertAfter( wrapper );
2328			wrapper.remove();
2329		}
2330
2331		this.originalElement.css('resize', this.originalResizeStyle);
2332		_destroy(this.originalElement);
2333
2334		return this;
2335	},
2336
2337	_mouseCapture: function(event) {
2338		var handle = false;
2339		for (var i in this.handles) {
2340			if ($(this.handles[i])[0] == event.target) {
2341				handle = true;
2342			}
2343		}
2344
2345		return !this.options.disabled && handle;
2346	},
2347
2348	_mouseStart: function(event) {
2349
2350		var o = this.options, iniPos = this.element.position(), el = this.element;
2351
2352		this.resizing = true;
2353		this.documentScroll = { top: $(document).scrollTop(), left: $(document).scrollLeft() };
2354
2355		// bugfix for http://dev.jquery.com/ticket/1749
2356		if (el.is('.ui-draggable') || (/absolute/).test(el.css('position'))) {
2357			el.css({ position: 'absolute', top: iniPos.top, left: iniPos.left });
2358		}
2359
2360		this._renderProxy();
2361
2362		var curleft = num(this.helper.css('left')), curtop = num(this.helper.css('top'));
2363
2364		if (o.containment) {
2365			curleft += $(o.containment).scrollLeft() || 0;
2366			curtop += $(o.containment).scrollTop() || 0;
2367		}
2368
2369		//Store needed variables
2370		this.offset = this.helper.offset();
2371		this.position = { left: curleft, top: curtop };
2372		this.size = this._helper ? { width: el.outerWidth(), height: el.outerHeight() } : { width: el.width(), height: el.height() };
2373		this.originalSize = this._helper ? { width: el.outerWidth(), height: el.outerHeight() } : { width: el.width(), height: el.height() };
2374		this.originalPosition = { left: curleft, top: curtop };
2375		this.sizeDiff = { width: el.outerWidth() - el.width(), height: el.outerHeight() - el.height() };
2376		this.originalMousePosition = { left: event.pageX, top: event.pageY };
2377
2378		//Aspect Ratio
2379		this.aspectRatio = (typeof o.aspectRatio == 'number') ? o.aspectRatio : ((this.originalSize.width / this.originalSize.height) || 1);
2380
2381		var cursor = $('.ui-resizable-' + this.axis).css('cursor');
2382		$('body').css('cursor', cursor == 'auto' ? this.axis + '-resize' : cursor);
2383
2384		el.addClass("ui-resizable-resizing");
2385		this._propagate("start", event);
2386		return true;
2387	},
2388
2389	_mouseDrag: function(event) {
2390
2391		//Increase performance, avoid regex
2392		var el = this.helper, o = this.options, props = {},
2393			that = this, smp = this.originalMousePosition, a = this.axis;
2394
2395		var dx = (event.pageX-smp.left)||0, dy = (event.pageY-smp.top)||0;
2396		var trigger = this._change[a];
2397		if (!trigger) return false;
2398
2399		// Calculate the attrs that will be change
2400		var data = trigger.apply(this, [event, dx, dy]);
2401
2402		// Put this in the mouseDrag handler since the user can start pressing shift while resizing
2403		this._updateVirtualBoundaries(event.shiftKey);
2404		if (this._aspectRatio || event.shiftKey)
2405			data = this._updateRatio(data, event);
2406
2407		data = this._respectSize(data, event);
2408
2409		// plugins callbacks need to be called first
2410		this._propagate("resize", event);
2411
2412		el.css({
2413			top: this.position.top + "px", left: this.position.left + "px",
2414			width: this.size.width + "px", height: this.size.height + "px"
2415		});
2416
2417		if (!this._helper && this._proportionallyResizeElements.length)
2418			this._proportionallyResize();
2419
2420		this._updateCache(data);
2421
2422		// calling the user callback at the end
2423		this._trigger('resize', event, this.ui());
2424
2425		return false;
2426	},
2427
2428	_mouseStop: function(event) {
2429
2430		this.resizing = false;
2431		var o = this.options, that = this;
2432
2433		if(this._helper) {
2434			var pr = this._proportionallyResizeElements, ista = pr.length && (/textarea/i).test(pr[0].nodeName),
2435				soffseth = ista && $.ui.hasScroll(pr[0], 'left') /* TODO - jump height */ ? 0 : that.sizeDiff.height,
2436				soffsetw = ista ? 0 : that.sizeDiff.width;
2437
2438			var s = { width: (that.helper.width()  - soffsetw), height: (that.helper.height() - soffseth) },
2439				left = (parseInt(that.element.css('left'), 10) + (that.position.left - that.originalPosition.left)) || null,
2440				top = (parseInt(that.element.css('top'), 10) + (that.position.top - that.originalPosition.top)) || null;
2441
2442			if (!o.animate)
2443				this.element.css($.extend(s, { top: top, left: left }));
2444
2445			that.helper.height(that.size.height);
2446			that.helper.width(that.size.width);
2447
2448			if (this._helper && !o.animate) this._proportionallyResize();
2449		}
2450
2451		$('body').css('cursor', 'auto');
2452
2453		this.element.removeClass("ui-resizable-resizing");
2454
2455		this._propagate("stop", event);
2456
2457		if (this._helper) this.helper.remove();
2458		return false;
2459
2460	},
2461
2462	_updateVirtualBoundaries: function(forceAspectRatio) {
2463		var o = this.options, pMinWidth, pMaxWidth, pMinHeight, pMaxHeight, b;
2464
2465		b = {
2466			minWidth: isNumber(o.minWidth) ? o.minWidth : 0,
2467			maxWidth: isNumber(o.maxWidth) ? o.maxWidth : Infinity,
2468			minHeight: isNumber(o.minHeight) ? o.minHeight : 0,
2469			maxHeight: isNumber(o.maxHeight) ? o.maxHeight : Infinity
2470		};
2471
2472		if(this._aspectRatio || forceAspectRatio) {
2473			// We want to create an enclosing box whose aspect ration is the requested one
2474			// First, compute the "projected" size for each dimension based on the aspect ratio and other dimension
2475			pMinWidth = b.minHeight * this.aspectRatio;
2476			pMinHeight = b.minWidth / this.aspectRatio;
2477			pMaxWidth = b.maxHeight * this.aspectRatio;
2478			pMaxHeight = b.maxWidth / this.aspectRatio;
2479
2480			if(pMinWidth > b.minWidth) b.minWidth = pMinWidth;
2481			if(pMinHeight > b.minHeight) b.minHeight = pMinHeight;
2482			if(pMaxWidth < b.maxWidth) b.maxWidth = pMaxWidth;
2483			if(pMaxHeight < b.maxHeight) b.maxHeight = pMaxHeight;
2484		}
2485		this._vBoundaries = b;
2486	},
2487
2488	_updateCache: function(data) {
2489		var o = this.options;
2490		this.offset = this.helper.offset();
2491		if (isNumber(data.left)) this.position.left = data.left;
2492		if (isNumber(data.top)) this.position.top = data.top;
2493		if (isNumber(data.height)) this.size.height = data.height;
2494		if (isNumber(data.width)) this.size.width = data.width;
2495	},
2496
2497	_updateRatio: function(data, event) {
2498
2499		var o = this.options, cpos = this.position, csize = this.size, a = this.axis;
2500
2501		if (isNumber(data.height)) data.width = (data.height * this.aspectRatio);
2502		else if (isNumber(data.width)) data.height = (data.width / this.aspectRatio);
2503
2504		if (a == 'sw') {
2505			data.left = cpos.left + (csize.width - data.width);
2506			data.top = null;
2507		}
2508		if (a == 'nw') {
2509			data.top = cpos.top + (csize.height - data.height);
2510			data.left = cpos.left + (csize.width - data.width);
2511		}
2512
2513		return data;
2514	},
2515
2516	_respectSize: function(data, event) {
2517
2518		var el = this.helper, o = this._vBoundaries, pRatio = this._aspectRatio || event.shiftKey, a = this.axis,
2519				ismaxw = isNumber(data.width) && o.maxWidth && (o.maxWidth < data.width), ismaxh = isNumber(data.height) && o.maxHeight && (o.maxHeight < data.height),
2520					isminw = isNumber(data.width) && o.minWidth && (o.minWidth > data.width), isminh = isNumber(data.height) && o.minHeight && (o.minHeight > data.height);
2521
2522		if (isminw) data.width = o.minWidth;
2523		if (isminh) data.height = o.minHeight;
2524		if (ismaxw) data.width = o.maxWidth;
2525		if (ismaxh) data.height = o.maxHeight;
2526
2527		var dw = this.originalPosition.left + this.originalSize.width, dh = this.position.top + this.size.height;
2528		var cw = /sw|nw|w/.test(a), ch = /nw|ne|n/.test(a);
2529
2530		if (isminw && cw) data.left = dw - o.minWidth;
2531		if (ismaxw && cw) data.left = dw - o.maxWidth;
2532		if (isminh && ch)	data.top = dh - o.minHeight;
2533		if (ismaxh && ch)	data.top = dh - o.maxHeight;
2534
2535		// fixing jump error on top/left - bug #2330
2536		var isNotwh = !data.width && !data.height;
2537		if (isNotwh && !data.left && data.top) data.top = null;
2538		else if (isNotwh && !data.top && data.left) data.left = null;
2539
2540		return data;
2541	},
2542
2543	_proportionallyResize: function() {
2544
2545		var o = this.options;
2546		if (!this._proportionallyResizeElements.length) return;
2547		var element = this.helper || this.element;
2548
2549		for (var i=0; i < this._proportionallyResizeElements.length; i++) {
2550
2551			var prel = this._proportionallyResizeElements[i];
2552
2553			if (!this.borderDif) {
2554				var b = [prel.css('borderTopWidth'), prel.css('borderRightWidth'), prel.css('borderBottomWidth'), prel.css('borderLeftWidth')],
2555					p = [prel.css('paddingTop'), prel.css('paddingRight'), prel.css('paddingBottom'), prel.css('paddingLeft')];
2556
2557				this.borderDif = $.map(b, function(v, i) {
2558					var border = parseInt(v,10)||0, padding = parseInt(p[i],10)||0;
2559					return border + padding;
2560				});
2561			}
2562
2563			prel.css({
2564				height: (element.height() - this.borderDif[0] - this.borderDif[2]) || 0,
2565				width: (element.width() - this.borderDif[1] - this.borderDif[3]) || 0
2566			});
2567
2568		};
2569
2570	},
2571
2572	_renderProxy: function() {
2573
2574		var el = this.element, o = this.options;
2575		this.elementOffset = el.offset();
2576
2577		if(this._helper) {
2578
2579			this.helper = this.helper || $('<div style="overflow:hidden;"></div>');
2580
2581			// fix ie6 offset TODO: This seems broken
2582			var ie6offset = ($.ui.ie6 ? 1 : 0),
2583			pxyoffset = ( $.ui.ie6 ? 2 : -1 );
2584
2585			this.helper.addClass(this._helper).css({
2586				width: this.element.outerWidth() + pxyoffset,
2587				height: this.element.outerHeight() + pxyoffset,
2588				position: 'absolute',
2589				left: this.elementOffset.left - ie6offset +'px',
2590				top: this.elementOffset.top - ie6offset +'px',
2591				zIndex: ++o.zIndex //TODO: Don't modify option
2592			});
2593
2594			this.helper
2595				.appendTo("body")
2596				.disableSelection();
2597
2598		} else {
2599			this.helper = this.element;
2600		}
2601
2602	},
2603
2604	_change: {
2605		e: function(event, dx, dy) {
2606			return { width: this.originalSize.width + dx };
2607		},
2608		w: function(event, dx, dy) {
2609			var o = this.options, cs = this.originalSize, sp = this.originalPosition;
2610			return { left: sp.left + dx, width: cs.width - dx };
2611		},
2612		n: function(event, dx, dy) {
2613			var o = this.options, cs = this.originalSize, sp = this.originalPosition;
2614			return { top: sp.top + dy, height: cs.height - dy };
2615		},
2616		s: function(event, dx, dy) {
2617			return { height: this.originalSize.height + dy };
2618		},
2619		se: function(event, dx, dy) {
2620			return $.extend(this._change.s.apply(this, arguments), this._change.e.apply(this, [event, dx, dy]));
2621		},
2622		sw: function(event, dx, dy) {
2623			return $.extend(this._change.s.apply(this, arguments), this._change.w.apply(this, [event, dx, dy]));
2624		},
2625		ne: function(event, dx, dy) {
2626			return $.extend(this._change.n.apply(this, arguments), this._change.e.apply(this, [event, dx, dy]));
2627		},
2628		nw: function(event, dx, dy) {
2629			return $.extend(this._change.n.apply(this, arguments), this._change.w.apply(this, [event, dx, dy]));
2630		}
2631	},
2632
2633	_propagate: function(n, event) {
2634		$.ui.plugin.call(this, n, [event, this.ui()]);
2635		(n != "resize" && this._trigger(n, event, this.ui()));
2636	},
2637
2638	plugins: {},
2639
2640	ui: function() {
2641		return {
2642			originalElement: this.originalElement,
2643			element: this.element,
2644			helper: this.helper,
2645			position: this.position,
2646			size: this.size,
2647			originalSize: this.originalSize,
2648			originalPosition: this.originalPosition
2649		};
2650	}
2651
2652});
2653
2654/*
2655 * Resizable Extensions
2656 */
2657
2658$.ui.plugin.add("resizable", "alsoResize", {
2659
2660	start: function (event, ui) {
2661		var that = $(this).data("resizable"), o = that.options;
2662
2663		var _store = function (exp) {
2664			$(exp).each(function() {
2665				var el = $(this);
2666				el.data("resizable-alsoresize", {
2667					width: parseInt(el.width(), 10), height: parseInt(el.height(), 10),
2668					left: parseInt(el.css('left'), 10), top: parseInt(el.css('top'), 10)
2669				});
2670			});
2671		};
2672
2673		if (typeof(o.alsoResize) == 'object' && !o.alsoResize.parentNode) {
2674			if (o.alsoResize.length) { o.alsoResize = o.alsoResize[0]; _store(o.alsoResize); }
2675			else { $.each(o.alsoResize, function (exp) { _store(exp); }); }
2676		}else{
2677			_store(o.alsoResize);
2678		}
2679	},
2680
2681	resize: function (event, ui) {
2682		var that = $(this).data("resizable"), o = that.options, os = that.originalSize, op = that.originalPosition;
2683
2684		var delta = {
2685			height: (that.size.height - os.height) || 0, width: (that.size.width - os.width) || 0,
2686			top: (that.position.top - op.top) || 0, left: (that.position.left - op.left) || 0
2687		},
2688
2689		_alsoResize = function (exp, c) {
2690			$(exp).each(function() {
2691				var el = $(this), start = $(this).data("resizable-alsoresize"), style = {},
2692					css = c && c.length ? c : el.parents(ui.originalElement[0]).length ? ['width', 'height'] : ['width', 'height', 'top', 'left'];
2693
2694				$.each(css, function (i, prop) {
2695					var sum = (start[prop]||0) + (delta[prop]||0);
2696					if (sum && sum >= 0)
2697						style[prop] = sum || null;
2698				});
2699
2700				el.css(style);
2701			});
2702		};
2703
2704		if (typeof(o.alsoResize) == 'object' && !o.alsoResize.nodeType) {
2705			$.each(o.alsoResize, function (exp, c) { _alsoResize(exp, c); });
2706		}else{
2707			_alsoResize(o.alsoResize);
2708		}
2709	},
2710
2711	stop: function (event, ui) {
2712		$(this).removeData("resizable-alsoresize");
2713	}
2714});
2715
2716$.ui.plugin.add("resizable", "animate", {
2717
2718	stop: function(event, ui) {
2719		var that = $(this).data("resizable"), o = that.options;
2720
2721		var pr = that._proportionallyResizeElements, ista = pr.length && (/textarea/i).test(pr[0].nodeName),
2722					soffseth = ista && $.ui.hasScroll(pr[0], 'left') /* TODO - jump height */ ? 0 : that.sizeDiff.height,
2723						soffsetw = ista ? 0 : that.sizeDiff.width;
2724
2725		var style = { width: (that.size.width - soffsetw), height: (that.size.height - soffseth) },
2726					left = (parseInt(that.element.css('left'), 10) + (that.position.left - that.originalPosition.left)) || null,
2727						top = (parseInt(that.element.css('top'), 10) + (that.position.top - that.originalPosition.top)) || null;
2728
2729		that.element.animate(
2730			$.extend(style, top && left ? { top: top, left: left } : {}), {
2731				duration: o.animateDuration,
2732				easing: o.animateEasing,
2733				step: function() {
2734
2735					var data = {
2736						width: parseInt(that.element.css('width'), 10),
2737						height: parseInt(that.element.css('height'), 10),
2738						top: parseInt(that.element.css('top'), 10),
2739						left: parseInt(that.element.css('left'), 10)
2740					};
2741
2742					if (pr && pr.length) $(pr[0]).css({ width: data.width, height: data.height });
2743
2744					// propagating resize, and updating values for each animation step
2745					that._updateCache(data);
2746					that._propagate("resize", event);
2747
2748				}
2749			}
2750		);
2751	}
2752
2753});
2754
2755$.ui.plugin.add("resizable", "containment", {
2756
2757	start: function(event, ui) {
2758		var that = $(this).data("resizable"), o = that.options, el = that.element;
2759		var oc = o.containment,	ce = (oc instanceof $) ? oc.get(0) : (/parent/.test(oc)) ? el.parent().get(0) : oc;
2760		if (!ce) return;
2761
2762		that.containerElement = $(ce);
2763
2764		if (/document/.test(oc) || oc == document) {
2765			that.containerOffset = { left: 0, top: 0 };
2766			that.containerPosition = { left: 0, top: 0 };
2767
2768			that.parentData = {
2769				element: $(document), left: 0, top: 0,
2770				width: $(document).width(), height: $(document).height() || document.body.parentNode.scrollHeight
2771			};
2772		}
2773
2774		// i'm a node, so compute top, left, right, bottom
2775		else {
2776			var element = $(ce), p = [];
2777			$([ "Top", "Right", "Left", "Bottom" ]).each(function(i, name) { p[i] = num(element.css("padding" + name)); });
2778
2779			that.containerOffset = element.offset();
2780			that.containerPosition = element.position();
2781			that.containerSize = { height: (element.innerHeight() - p[3]), width: (element.innerWidth() - p[1]) };
2782
2783			var co = that.containerOffset, ch = that.containerSize.height,	cw = that.containerSize.width,
2784						width = ($.ui.hasScroll(ce, "left") ? ce.scrollWidth : cw ), height = ($.ui.hasScroll(ce) ? ce.scrollHeight : ch);
2785
2786			that.parentData = {
2787				element: ce, left: co.left, top: co.top, width: width, height: height
2788			};
2789		}
2790	},
2791
2792	resize: function(event, ui) {
2793		var that = $(this).data("resizable"), o = that.options,
2794				ps = that.containerSize, co = that.containerOffset, cs = that.size, cp = that.position,
2795				pRatio = that._aspectRatio || event.shiftKey, cop = { top:0, left:0 }, ce = that.containerElement;
2796
2797		if (ce[0] != document && (/static/).test(ce.css('position'))) cop = co;
2798
2799		if (cp.left < (that._helper ? co.left : 0)) {
2800			that.size.width = that.size.width + (that._helper ? (that.position.left - co.left) : (that.position.left - cop.left));
2801			if (pRatio) that.size.height = that.size.width / that.aspectRatio;
2802			that.position.left = o.helper ? co.left : 0;
2803		}
2804
2805		if (cp.top < (that._helper ? co.top : 0)) {
2806			that.size.height = that.size.height + (that._helper ? (that.position.top - co.top) : that.position.top);
2807			if (pRatio) that.size.width = that.size.height * that.aspectRatio;
2808			that.position.top = that._helper ? co.top : 0;
2809		}
2810
2811		that.offset.left = that.parentData.left+that.position.left;
2812		that.offset.top = that.parentData.top+that.position.top;
2813
2814		var woset = Math.abs( (that._helper ? that.offset.left - cop.left : (that.offset.left - cop.left)) + that.sizeDiff.width ),
2815					hoset = Math.abs( (that._helper ? that.offset.top - cop.top : (that.offset.top - co.top)) + that.sizeDiff.height );
2816
2817		var isParent = that.containerElement.get(0) == that.element.parent().get(0),
2818			isOffsetRelative = /relative|absolute/.test(that.containerElement.css('position'));
2819
2820		if(isParent && isOffsetRelative) woset -= that.parentData.left;
2821
2822		if (woset + that.size.width >= that.parentData.width) {
2823			that.size.width = that.parentData.width - woset;
2824			if (pRatio) that.size.height = that.size.width / that.aspectRatio;
2825		}
2826
2827		if (hoset + that.size.height >= that.parentData.height) {
2828			that.size.height = that.parentData.height - hoset;
2829			if (pRatio) that.size.width = that.size.height * that.aspectRatio;
2830		}
2831	},
2832
2833	stop: function(event, ui){
2834		var that = $(this).data("resizable"), o = that.options, cp = that.position,
2835				co = that.containerOffset, cop = that.containerPosition, ce = that.containerElement;
2836
2837		var helper = $(that.helper), ho = helper.offset(), w = helper.outerWidth() - that.sizeDiff.width, h = helper.outerHeight() - that.sizeDiff.height;
2838
2839		if (that._helper && !o.animate && (/relative/).test(ce.css('position')))
2840			$(this).css({ left: ho.left - cop.left - co.left, width: w, height: h });
2841
2842		if (that._helper && !o.animate && (/static/).test(ce.css('position')))
2843			$(this).css({ left: ho.left - cop.left - co.left, width: w, height: h });
2844
2845	}
2846});
2847
2848$.ui.plugin.add("resizable", "ghost", {
2849
2850	start: function(event, ui) {
2851
2852		var that = $(this).data("resizable"), o = that.options, cs = that.size;
2853
2854		that.ghost = that.originalElement.clone();
2855		that.ghost
2856			.css({ opacity: .25, display: 'block', position: 'relative', height: cs.height, width: cs.width, margin: 0, left: 0, top: 0 })
2857			.addClass('ui-resizable-ghost')
2858			.addClass(typeof o.ghost == 'string' ? o.ghost : '');
2859
2860		that.ghost.appendTo(that.helper);
2861
2862	},
2863
2864	resize: function(event, ui){
2865		var that = $(this).data("resizable"), o = that.options;
2866		if (that.ghost) that.ghost.css({ position: 'relative', height: that.size.height, width: that.size.width });
2867	},
2868
2869	stop: function(event, ui){
2870		var that = $(this).data("resizable"), o = that.options;
2871		if (that.ghost && that.helper) that.helper.get(0).removeChild(that.ghost.get(0));
2872	}
2873
2874});
2875
2876$.ui.plugin.add("resizable", "grid", {
2877
2878	resize: function(event, ui) {
2879		var that = $(this).data("resizable"), o = that.options, cs = that.size, os = that.originalSize, op = that.originalPosition, a = that.axis, ratio = o._aspectRatio || event.shiftKey;
2880		o.grid = typeof o.grid == "number" ? [o.grid, o.grid] : o.grid;
2881		var ox = Math.round((cs.width - os.width) / (o.grid[0]||1)) * (o.grid[0]||1), oy = Math.round((cs.height - os.height) / (o.grid[1]||1)) * (o.grid[1]||1);
2882
2883		if (/^(se|s|e)$/.test(a)) {
2884			that.size.width = os.width + ox;
2885			that.size.height = os.height + oy;
2886		}
2887		else if (/^(ne)$/.test(a)) {
2888			that.size.width = os.width + ox;
2889			that.size.height = os.height + oy;
2890			that.position.top = op.top - oy;
2891		}
2892		else if (/^(sw)$/.test(a)) {
2893			that.size.width = os.width + ox;
2894			that.size.height = os.height + oy;
2895			that.position.left = op.left - ox;
2896		}
2897		else {
2898			that.size.width = os.width + ox;
2899			that.size.height = os.height + oy;
2900			that.position.top = op.top - oy;
2901			that.position.left = op.left - ox;
2902		}
2903	}
2904
2905});
2906
2907var num = function(v) {
2908	return parseInt(v, 10) || 0;
2909};
2910
2911var isNumber = function(value) {
2912	return !isNaN(parseInt(value, 10));
2913};
2914
2915})(jQuery);
2916
2917(function( $, undefined ) {
2918
2919$.widget("ui.selectable", $.ui.mouse, {
2920	version: "1.9.2",
2921	options: {
2922		appendTo: 'body',
2923		autoRefresh: true,
2924		distance: 0,
2925		filter: '*',
2926		tolerance: 'touch'
2927	},
2928	_create: function() {
2929		var that = this;
2930
2931		this.element.addClass("ui-selectable");
2932
2933		this.dragged = false;
2934
2935		// cache selectee children based on filter
2936		var selectees;
2937		this.refresh = function() {
2938			selectees = $(that.options.filter, that.element[0]);
2939			selectees.addClass("ui-selectee");
2940			selectees.each(function() {
2941				var $this = $(this);
2942				var pos = $this.offset();
2943				$.data(this, "selectable-item", {
2944					element: this,
2945					$element: $this,
2946					left: pos.left,
2947					top: pos.top,
2948					right: pos.left + $this.outerWidth(),
2949					bottom: pos.top + $this.outerHeight(),
2950					startselected: false,
2951					selected: $this.hasClass('ui-selected'),
2952					selecting: $this.hasClass('ui-selecting'),
2953					unselecting: $this.hasClass('ui-unselecting')
2954				});
2955			});
2956		};
2957		this.refresh();
2958
2959		this.selectees = selectees.addClass("ui-selectee");
2960
2961		this._mouseInit();
2962
2963		this.helper = $("<div class='ui-selectable-helper'></div>");
2964	},
2965
2966	_destroy: function() {
2967		this.selectees
2968			.removeClass("ui-selectee")
2969			.removeData("selectable-item");
2970		this.element
2971			.removeClass("ui-selectable ui-selectable-disabled");
2972		this._mouseDestroy();
2973	},
2974
2975	_mouseStart: function(event) {
2976		var that = this;
2977
2978		this.opos = [event.pageX, event.pageY];
2979
2980		if (this.options.disabled)
2981			return;
2982
2983		var options = this.options;
2984
2985		this.selectees = $(options.filter, this.element[0]);
2986
2987		this._trigger("start", event);
2988
2989		$(options.appendTo).append(this.helper);
2990		// position helper (lasso)
2991		this.helper.css({
2992			"left": event.clientX,
2993			"top": event.clientY,
2994			"width": 0,
2995			"height": 0
2996		});
2997
2998		if (options.autoRefresh) {
2999			this.refresh();
3000		}
3001
3002		this.selectees.filter('.ui-selected').each(function() {
3003			var selectee = $.data(this, "selectable-item");
3004			selectee.startselected = true;
3005			if (!event.metaKey && !event.ctrlKey) {
3006				selectee.$element.removeClass('ui-selected');
3007				selectee.selected = false;
vendor: 4,195 bytes, lines 3008-3146
3008				selectee.$element.addClass('ui-unselecting');
3009				selectee.unselecting = true;
3010				// selectable UNSELECTING callback
3011				that._trigger("unselecting", event, {
3012					unselecting: selectee.element
3013				});
3014			}
3015		});
3016
3017		$(event.target).parents().andSelf().each(function() {
3018			var selectee = $.data(this, "selectable-item");
3019			if (selectee) {
3020				var doSelect = (!event.metaKey && !event.ctrlKey) || !selectee.$element.hasClass('ui-selected');
3021				selectee.$element
3022					.removeClass(doSelect ? "ui-unselecting" : "ui-selected")
3023					.addClass(doSelect ? "ui-selecting" : "ui-unselecting");
3024				selectee.unselecting = !doSelect;
3025				selectee.selecting = doSelect;
3026				selectee.selected = doSelect;
3027				// selectable (UN)SELECTING callback
3028				if (doSelect) {
3029					that._trigger("selecting", event, {
3030						selecting: selectee.element
3031					});
3032				} else {
3033					that._trigger("unselecting", event, {
3034						unselecting: selectee.element
3035					});
3036				}
3037				return false;
3038			}
3039		});
3040
3041	},
3042
3043	_mouseDrag: function(event) {
3044		var that = this;
3045		this.dragged = true;
3046
3047		if (this.options.disabled)
3048			return;
3049
3050		var options = this.options;
3051
3052		var x1 = this.opos[0], y1 = this.opos[1], x2 = event.pageX, y2 = event.pageY;
3053		if (x1 > x2) { var tmp = x2; x2 = x1; x1 = tmp; }
3054		if (y1 > y2) { var tmp = y2; y2 = y1; y1 = tmp; }
3055		this.helper.css({left: x1, top: y1, width: x2-x1, height: y2-y1});
3056
3057		this.selectees.each(function() {
3058			var selectee = $.data(this, "selectable-item");
3059			//prevent helper from being selected if appendTo: selectable
3060			if (!selectee || selectee.element == that.element[0])
3061				return;
3062			var hit = false;
3063			if (options.tolerance == 'touch') {
3064				hit = ( !(selectee.left > x2 || selectee.right < x1 || selectee.top > y2 || selectee.bottom < y1) );
3065			} else if (options.tolerance == 'fit') {
3066				hit = (selectee.left > x1 && selectee.right < x2 && selectee.top > y1 && selectee.bottom < y2);
3067			}
3068
3069			if (hit) {
3070				// SELECT
3071				if (selectee.selected) {
3072					selectee.$element.removeClass('ui-selected');
3073					selectee.selected = false;
3074				}
3075				if (selectee.unselecting) {
3076					selectee.$element.removeClass('ui-unselecting');
3077					selectee.unselecting = false;
3078				}
3079				if (!selectee.selecting) {
3080					selectee.$element.addClass('ui-selecting');
3081					selectee.selecting = true;
3082					// selectable SELECTING callback
3083					that._trigger("selecting", event, {
3084						selecting: selectee.element
3085					});
3086				}
3087			} else {
3088				// UNSELECT
3089				if (selectee.selecting) {
3090					if ((event.metaKey || event.ctrlKey) && selectee.startselected) {
3091						selectee.$element.removeClass('ui-selecting');
3092						selectee.selecting = false;
3093						selectee.$element.addClass('ui-selected');
3094						selectee.selected = true;
3095					} else {
3096						selectee.$element.removeClass('ui-selecting');
3097						selectee.selecting = false;
3098						if (selectee.startselected) {
3099							selectee.$element.addClass('ui-unselecting');
3100							selectee.unselecting = true;
3101						}
3102						// selectable UNSELECTING callback
3103						that._trigger("unselecting", event, {
3104							unselecting: selectee.element
3105						});
3106					}
3107				}
3108				if (selectee.selected) {
3109					if (!event.metaKey && !event.ctrlKey && !selectee.startselected) {
3110						selectee.$element.removeClass('ui-selected');
3111						selectee.selected = false;
3112
3113						selectee.$element.addClass('ui-unselecting');
3114						selectee.unselecting = true;
3115						// selectable UNSELECTING callback
3116						that._trigger("unselecting", event, {
3117							unselecting: selectee.element
3118						});
3119					}
3120				}
3121			}
3122		});
3123
3124		return false;
3125	},
3126
3127	_mouseStop: function(event) {
3128		var that = this;
3129
3130		this.dragged = false;
3131
3132		var options = this.options;
3133
3134		$('.ui-unselecting', this.element[0]).each(function() {
3135			var selectee = $.data(this, "selectable-item");
3136			selectee.$element.removeClass('ui-unselecting');
3137			selectee.unselecting = false;
3138			selectee.startselected = false;
3139			that._trigger("unselected", event, {
3140				unselected: selectee.element
3141			});
3142		});
3143		$('.ui-selecting', this.element[0]).each(function() {
3144			var selectee = $.data(this, "selectable-item");
3145			selectee.$element.removeClass('ui-selecting').addClass('ui-selected');
3146			selectee.selecting = false;
3147			selectee.selected = true;
3148			selectee.startselected = true;
3149			that._trigger("selected", event, {
3150				selected: selectee.element
3151			});
3152		});
3153		this._trigger("stop", event);
3154
3155		this.helper.remove();
3156
3157		return false;
3158	}
3159
3160});
3161
3162})(jQuery);
3163
3164(function( $, undefined ) {
3165
3166$.widget("ui.sortable", $.ui.mouse, {
3167	version: "1.9.2",
3168	widgetEventPrefix: "sort",
3169	ready: false,
3170	options: {
3171		appendTo: "parent",
3172		axis: false,
3173		connectWith: false,
3174		containment: false,
3175		cursor: 'auto',
3176		cursorAt: false,
3177		dropOnEmpty: true,
3178		forcePlaceholderSize: false,
3179		forceHelperSize: false,
3180		grid: false,
3181		handle: false,
3182		helper: "original",
3183		items: '> *',
3184		opacity: false,
3185		placeholder: false,
3186		revert: false,
3187		scroll: true,
3188		scrollSensitivity: 20,
3189		scrollSpeed: 20,
3190		scope: "default",
3191		tolerance: "intersect",
3192		zIndex: 1000
3193	},
3194	_create: function() {
3195
3196		var o = this.options;
3197		this.containerCache = {};
3198		this.element.addClass("ui-sortable");
3199
3200		//Get the items
3201		this.refresh();
3202
3203		//Let's determine if the items are being displayed horizontally
3204		this.floating = this.items.length ? o.axis === 'x' || (/left|right/).test(this.items[0].item.css('float')) || (/inline|table-cell/).test(this.items[0].item.css('display')) : false;
3205
3206		//Let's determine the parent's offset
3207		this.offset = this.element.offset();
3208
3209		//Initialize mouse events for interaction
3210		this._mouseInit();
3211
3212		//We're ready to go
3213		this.ready = true
3214
3215	},
3216
3217	_destroy: function() {
3218		this.element
3219			.removeClass("ui-sortable ui-sortable-disabled");
3220		this._mouseDestroy();
3221
3222		for ( var i = this.items.length - 1; i >= 0; i-- )
3223			this.items[i].item.removeData(this.widgetName + "-item");
3224
3225		return this;
3226	},
3227
3228	_setOption: function(key, value){
3229		if ( key === "disabled" ) {
3230			this.options[ key ] = value;
3231
3232			this.widget().toggleClass( "ui-sortable-disabled", !!value );
3233		} else {
3234			// Don't call widget base _setOption for disable as it adds ui-state-disabled class
3235			$.Widget.prototype._setOption.apply(this, arguments);
3236		}
3237	},
3238
3239	_mouseCapture: function(event, overrideHandle) {
3240		var that = this;
3241
3242		if (this.reverting) {
3243			return false;
3244		}
3245
3246		if(this.options.disabled || this.options.type == 'static') return false;
3247
3248		//We have to refresh the items data once first
3249		this._refreshItems(event);
3250
3251		//Find out if the clicked node (or one of its parents) is a actual item in this.items
3252		var currentItem = null, nodes = $(event.target).parents().each(function() {
3253			if($.data(this, that.widgetName + '-item') == that) {
3254				currentItem = $(this);
3255				return false;
3256			}
3257		});
3258		if($.data(event.target, that.widgetName + '-item') == that) currentItem = $(event.target);
3259
3260		if(!currentItem) return false;
3261		if(this.options.handle && !overrideHandle) {
3262			var validHandle = false;
3263
3264			$(this.options.handle, currentItem).find("*").andSelf().each(function() { if(this == event.target) validHandle = true; });
3265			if(!validHandle) return false;
3266		}
3267
3268		this.currentItem = currentItem;
3269		this._removeCurrentsFromItems();
3270		return true;
3271
3272	},
3273
3274	_mouseStart: function(event, overrideHandle, noActivation) {
3275
3276		var o = this.options;
3277		this.currentContainer = this;
3278
3279		//We only need to call refreshPositions, because the refreshItems call has been moved to mouseCapture
3280		this.refreshPositions();
3281
3282		//Create and append the visible helper
3283		this.helper = this._createHelper(event);
3284
3285		//Cache the helper size
3286		this._cacheHelperProportions();
3287
3288		/*
3289		 * - Position generation -
3290		 * This block generates everything position related - it's the core of draggables.
3291		 */
3292
3293		//Cache the margins of the original element
3294		this._cacheMargins();
3295
3296		//Get the next scrolling parent
3297		this.scrollParent = this.helper.scrollParent();
3298
3299		//The element's absolute position on the page minus margins
3300		this.offset = this.currentItem.offset();
3301		this.offset = {
3302			top: this.offset.top - this.margins.top,
3303			left: this.offset.left - this.margins.left
3304		};
3305
3306		$.extend(this.offset, {
3307			click: { //Where the click happened, relative to the element
3308				left: event.pageX - this.offset.left,
3309				top: event.pageY - this.offset.top
3310			},
3311			parent: this._getParentOffset(),
3312			relative: this._getRelativeOffset() //This is a relative to absolute position minus the actual position calculation - only used for relative positioned helper
3313		});
3314
3315		// Only after we got the offset, we can change the helper's position to absolute
3316		// TODO: Still need to figure out a way to make relative sorting possible
3317		this.helper.css("position", "absolute");
3318		this.cssPosition = this.helper.css("position");
3319
3320		//Generate the original position
3321		this.originalPosition = this._generatePosition(event);
3322		this.originalPageX = event.pageX;
3323		this.originalPageY = event.pageY;
3324
3325		//Adjust the mouse offset relative to the helper if 'cursorAt' is supplied
3326		(o.cursorAt && this._adjustOffsetFromHelper(o.cursorAt));
3327
3328		//Cache the former DOM position
3329		this.domPosition = { prev: this.currentItem.prev()[0], parent: this.currentItem.parent()[0] };
3330
3331		//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
3332		if(this.helper[0] != this.currentItem[0]) {
3333			this.currentItem.hide();
3334		}
3335
3336		//Create the placeholder
3337		this._createPlaceholder();
3338
3339		//Set a containment if given in the options
3340		if(o.containment)
3341			this._setContainment();
3342
3343		if(o.cursor) { // cursor option
3344			if ($('body').css("cursor")) this._storedCursor = $('body').css("cursor");
3345			$('body').css("cursor", o.cursor);
3346		}
3347
3348		if(o.opacity) { // opacity option
3349			if (this.helper.css("opacity")) this._storedOpacity = this.helper.css("opacity");
3350			this.helper.css("opacity", o.opacity);
3351		}
3352
3353		if(o.zIndex) { // zIndex option
3354			if (this.helper.css("zIndex")) this._storedZIndex = this.helper.css("zIndex");
3355			this.helper.css("zIndex", o.zIndex);
3356		}
3357
3358		//Prepare scrolling
3359		if(this.scrollParent[0] != document && this.scrollParent[0].tagName != 'HTML')
3360			this.overflowOffset = this.scrollParent.offset();
3361
3362		//Call callbacks
3363		this._trigger("start", event, this._uiHash());
3364
3365		//Recache the helper size
3366		if(!this._preserveHelperProportions)
3367			this._cacheHelperProportions();
3368
3369
3370		//Post 'activate' events to possible containers
3371		if(!noActivation) {
3372			 for (var i = this.containers.length - 1; i >= 0; i--) { this.containers[i]._trigger("activate", event, this._uiHash(this)); }
3373		}
3374
3375		//Prepare possible droppables
3376		if($.ui.ddmanager)
3377			$.ui.ddmanager.current = this;
3378
3379		if ($.ui.ddmanager && !o.dropBehaviour)
3380			$.ui.ddmanager.prepareOffsets(this, event);
3381
3382		this.dragging = true;
3383
3384		this.helper.addClass("ui-sortable-helper");
3385		this._mouseDrag(event); //Execute the drag once - this causes the helper not to be visible before getting its correct position
3386		return true;
3387
3388	},
3389
3390	_mouseDrag: function(event) {
3391
3392		//Compute the helpers position
3393		this.position = this._generatePosition(event);
3394		this.positionAbs = this._convertPositionTo("absolute");
3395
3396		if (!this.lastPositionAbs) {
3397			this.lastPositionAbs = this.positionAbs;
3398		}
3399
3400		//Do scrolling
3401		if(this.options.scroll) {
3402			var o = this.options, scrolled = false;
3403			if(this.scrollParent[0] != document && this.scrollParent[0].tagName != 'HTML') {
3404
3405				if((this.overflowOffset.top + this.scrollParent[0].offsetHeight) - event.pageY < o.scrollSensitivity)
3406					this.scrollParent[0].scrollTop = scrolled = this.scrollParent[0].scrollTop + o.scrollSpeed;
3407				else if(event.pageY - this.overflowOffset.top < o.scrollSensitivity)
3408					this.scrollParent[0].scrollTop = scrolled = this.scrollParent[0].scrollTop - o.scrollSpeed;
3409
3410				if((this.overflowOffset.left + this.scrollParent[0].offsetWidth) - event.pageX < o.scrollSensitivity)
3411					this.scrollParent[0].scrollLeft = scrolled = this.scrollParent[0].scrollLeft + o.scrollSpeed;
3412				else if(event.pageX - this.overflowOffset.left < o.scrollSensitivity)
3413					this.scrollParent[0].scrollLeft = scrolled = this.scrollParent[0].scrollLeft - o.scrollSpeed;
3414
3415			} else {
3416
3417				if(event.pageY - $(document).scrollTop() < o.scrollSensitivity)
3418					scrolled = $(document).scrollTop($(document).scrollTop() - o.scrollSpeed);
3419				else if($(window).height() - (event.pageY - $(document).scrollTop()) < o.scrollSensitivity)
3420					scrolled = $(document).scrollTop($(document).scrollTop() + o.scrollSpeed);
3421
3422				if(event.pageX - $(document).scrollLeft() < o.scrollSensitivity)
3423					scrolled = $(document).scrollLeft($(document).scrollLeft() - o.scrollSpeed);
3424				else if($(window).width() - (event.pageX - $(document).scrollLeft()) < o.scrollSensitivity)
3425					scrolled = $(document).scrollLeft($(document).scrollLeft() + o.scrollSpeed);
3426
3427			}
3428
3429			if(scrolled !== false && $.ui.ddmanager && !o.dropBehaviour)
3430				$.ui.ddmanager.prepareOffsets(this, event);
3431		}
3432
3433		//Regenerate the absolute position used for position checks
3434		this.positionAbs = this._convertPositionTo("absolute");
3435
3436		//Set the helper position
3437		if(!this.options.axis || this.options.axis != "y") this.helper[0].style.left = this.position.left+'px';
3438		if(!this.options.axis || this.options.axis != "x") this.helper[0].style.top = this.position.top+'px';
3439
3440		//Rearrange
3441		for (var i = this.items.length - 1; i >= 0; i--) {
3442
3443			//Cache variables and intersection, continue if no intersection
3444			var item = this.items[i], itemElement = item.item[0], intersection = this._intersectsWithPointer(item);
3445			if (!intersection) continue;
3446
3447			// Only put the placeholder inside the current Container, skip all
3448			// items form other containers. This works because when moving
3449			// an item from one container to another the
3450			// currentContainer is switched before the placeholder is moved.
3451			//
3452			// Without this moving items in "sub-sortables" can cause the placeholder to jitter
3453			// beetween the outer and inner container.
3454			if (item.instance !== this.currentContainer) continue;
3455
3456			if (itemElement != this.currentItem[0] //cannot intersect with itself
3457				&&	this.placeholder[intersection == 1 ? "next" : "prev"]()[0] != itemElement //no useless actions that have been done before
3458				&&	!$.contains(this.placeholder[0], itemElement) //no action if the item moved is the parent of the item checked
3459				&& (this.options.type == 'semi-dynamic' ? !$.contains(this.element[0], itemElement) : true)
3460				//&& itemElement.parentNode == this.placeholder[0].parentNode // only rearrange items within the same container
3461			) {
3462
3463				this.direction = intersection == 1 ? "down" : "up";
3464
3465				if (this.options.tolerance == "pointer" || this._intersectsWithSides(item)) {
3466					this._rearrange(event, item);
3467				} else {
3468					break;
3469				}
3470
3471				this._trigger("change", event, this._uiHash());
3472				break;
3473			}
3474		}
3475
3476		//Post events to containers
3477		this._contactContainers(event);
3478
3479		//Interconnect with droppables
3480		if($.ui.ddmanager) $.ui.ddmanager.drag(this, event);
3481
3482		//Call callbacks
3483		this._trigger('sort', event, this._uiHash());
3484
3485		this.lastPositionAbs = this.positionAbs;
3486		return false;
3487
3488	},
3489
3490	_mouseStop: function(event, noPropagation) {
3491
3492		if(!event) return;
3493
3494		//If we are using droppables, inform the manager about the drop
3495		if ($.ui.ddmanager && !this.options.dropBehaviour)
3496			$.ui.ddmanager.drop(this, event);
3497
3498		if(this.options.revert) {
3499			var that = this;
3500			var cur = this.placeholder.offset();
3501
3502			this.reverting = true;
3503
3504			$(this.helper).animate({
3505				left: cur.left - this.offset.parent.left - this.margins.left + (this.offsetParent[0] == document.body ? 0 : this.offsetParent[0].scrollLeft),
3506				top: cur.top - this.offset.parent.top - this.margins.top + (this.offsetParent[0] == document.body ? 0 : this.offsetParent[0].scrollTop)
3507			}, parseInt(this.options.revert, 10) || 500, function() {
3508				that._clear(event);
3509			});
3510		} else {
3511			this._clear(event, noPropagation);
3512		}
3513
3514		return false;
3515
3516	},
3517
3518	cancel: function() {
3519
3520		if(this.dragging) {
3521
3522			this._mouseUp({ target: null });
3523
3524			if(this.options.helper == "original")
3525				this.currentItem.css(this._storedCSS).removeClass("ui-sortable-helper");
3526			else
3527				this.currentItem.show();
3528
3529			//Post deactivating events to containers
3530			for (var i = this.containers.length - 1; i >= 0; i--){
3531				this.containers[i]._trigger("deactivate", null, this._uiHash(this));
3532				if(this.containers[i].containerCache.over) {
3533					this.containers[i]._trigger("out", null, this._uiHash(this));
3534					this.containers[i].containerCache.over = 0;
3535				}
3536			}
3537
3538		}
3539
3540		if (this.placeholder) {
3541			//$(this.placeholder[0]).remove(); would have been the jQuery way - unfortunately, it unbinds ALL events from the original node!
3542			if(this.placeholder[0].parentNode) this.placeholder[0].parentNode.removeChild(this.placeholder[0]);
3543			if(this.options.helper != "original" && this.helper && this.helper[0].parentNode) this.helper.remove();
3544
3545			$.extend(this, {
3546				helper: null,
3547				dragging: false,
3548				reverting: false,
3549				_noFinalSort: null
3550			});
3551
3552			if(this.domPosition.prev) {
3553				$(this.domPosition.prev).after(this.currentItem);
3554			} else {
3555				$(this.domPosition.parent).prepend(this.currentItem);
3556			}
3557		}
3558
3559		return this;
3560
3561	},
3562
3563	serialize: function(o) {
3564
3565		var items = this._getItemsAsjQuery(o && o.connected);
3566		var str = []; o = o || {};
3567
3568		$(items).each(function() {
3569			var res = ($(o.item || this).attr(o.attribute || 'id') || '').match(o.expression || (/(.+)[-=_](.+)/));
3570			if(res) str.push((o.key || res[1]+'[]')+'='+(o.key && o.expression ? res[1] : res[2]));
3571		});
3572
3573		if(!str.length && o.key) {
3574			str.push(o.key + '=');
3575		}
3576
3577		return str.join('&');
3578
3579	},
3580
3581	toArray: function(o) {
3582
3583		var items = this._getItemsAsjQuery(o && o.connected);
3584		var ret = []; o = o || {};
3585
3586		items.each(function() { ret.push($(o.item || this).attr(o.attribute || 'id') || ''); });
3587		return ret;
3588
3589	},
3590
3591	/* Be careful with the following core functions */
3592	_intersectsWith: function(item) {
3593
3594		var x1 = this.positionAbs.left,
3595			x2 = x1 + this.helperProportions.width,
3596			y1 = this.positionAbs.top,
3597			y2 = y1 + this.helperProportions.height;
3598
3599		var l = item.left,
3600			r = l + item.width,
3601			t = item.top,
3602			b = t + item.height;
3603
3604		var dyClick = this.offset.click.top,
3605			dxClick = this.offset.click.left;
3606
3607		var isOverElement = (y1 + dyClick) > t && (y1 + dyClick) < b && (x1 + dxClick) > l && (x1 + dxClick) < r;
3608
3609		if(	   this.options.tolerance == "pointer"
3610			|| this.options.forcePointerForContainers
3611			|| (this.options.tolerance != "pointer" && this.helperProportions[this.floating ? 'width' : 'height'] > item[this.floating ? 'width' : 'height'])
3612		) {
3613			return isOverElement;
3614		} else {
3615
3616			return (l < x1 + (this.helperProportions.width / 2) // Right Half
3617				&& x2 - (this.helperProportions.width / 2) < r // Left Half
3618				&& t < y1 + (this.helperProportions.height / 2) // Bottom Half
3619				&& y2 - (this.helperProportions.height / 2) < b ); // Top Half
3620
3621		}
3622	},
3623
3624	_intersectsWithPointer: function(item) {
3625
3626		var isOverElementHeight = (this.options.axis === 'x') || $.ui.isOverAxis(this.positionAbs.top + this.offset.click.top, item.top, item.height),
3627			isOverElementWidth = (this.options.axis === 'y') || $.ui.isOverAxis(this.positionAbs.left + this.offset.click.left, item.left, item.width),
3628			isOverElement = isOverElementHeight && isOverElementWidth,
3629			verticalDirection = this._getDragVerticalDirection(),
3630			horizontalDirection = this._getDragHorizontalDirection();
3631
3632		if (!isOverElement)
3633			return false;
3634
3635		return this.floating ?
3636			( ((horizontalDirection && horizontalDirection == "right") || verticalDirection == "down") ? 2 : 1 )
3637			: ( verticalDirection && (verticalDirection == "down" ? 2 : 1) );
3638
3639	},
3640
3641	_intersectsWithSides: function(item) {
3642
3643		var isOverBottomHalf = $.ui.isOverAxis(this.positionAbs.top + this.offset.click.top, item.top + (item.height/2), item.height),
3644			isOverRightHalf = $.ui.isOverAxis(this.positionAbs.left + this.offset.click.left, item.left + (item.width/2), item.width),
3645			verticalDirection = this._getDragVerticalDirection(),
3646			horizontalDirection = this._getDragHorizontalDirection();
3647
3648		if (this.floating && horizontalDirection) {
3649			return ((horizontalDirection == "right" && isOverRightHalf) || (horizontalDirection == "left" && !isOverRightHalf));
3650		} else {
3651			return verticalDirection && ((verticalDirection == "down" && isOverBottomHalf) || (verticalDirection == "up" && !isOverBottomHalf));
3652		}
3653
3654	},
3655
3656	_getDragVerticalDirection: function() {
3657		var delta = this.positionAbs.top - this.lastPositionAbs.top;
3658		return delta != 0 && (delta > 0 ? "down" : "up");
3659	},
3660
3661	_getDragHorizontalDirection: function() {
3662		var delta = this.positionAbs.left - this.lastPositionAbs.left;
3663		return delta != 0 && (delta > 0 ? "right" : "left");
3664	},
3665
3666	refresh: function(event) {
3667		this._refreshItems(event);
3668		this.refreshPositions();
3669		return this;
3670	},
3671
3672	_connectWith: function() {
3673		var options = this.options;
3674		return options.connectWith.constructor == String
3675			? [options.connectWith]
3676			: options.connectWith;
3677	},
3678
3679	_getItemsAsjQuery: function(connected) {
3680
3681		var items = [];
3682		var queries = [];
3683		var connectWith = this._connectWith();
3684
3685		if(connectWith && connected) {
3686			for (var i = connectWith.length - 1; i >= 0; i--){
3687				var cur = $(connectWith[i]);
3688				for (var j = cur.length - 1; j >= 0; j--){
3689					var inst = $.data(cur[j], this.widgetName);
3690					if(inst && inst != this && !inst.options.disabled) {
3691						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]);
3692					}
3693				};
3694			};
3695		}
3696
3697		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]);
3698
3699		for (var i = queries.length - 1; i >= 0; i--){
3700			queries[i][0].each(function() {
3701				items.push(this);
3702			});
3703		};
3704
3705		return $(items);
3706
3707	},
3708
3709	_removeCurrentsFromItems: function() {
3710
3711		var list = this.currentItem.find(":data(" + this.widgetName + "-item)");
3712
3713		this.items = $.grep(this.items, function (item) {
3714			for (var j=0; j < list.length; j++) {
3715				if(list[j] == item.item[0])
3716					return false;
3717			};
3718			return true;
3719		});
3720
3721	},
3722
3723	_refreshItems: function(event) {
3724
3725		this.items = [];
3726		this.containers = [this];
3727		var items = this.items;
3728		var queries = [[$.isFunction(this.options.items) ? this.options.items.call(this.element[0], event, { item: this.currentItem }) : $(this.options.items, this.element), this]];
3729		var connectWith = this._connectWith();
3730
3731		if(connectWith && this.ready) { //Shouldn't be run the first time through due to massive slow-down
3732			for (var i = connectWith.length - 1; i >= 0; i--){
3733				var cur = $(connectWith[i]);
3734				for (var j = cur.length - 1; j >= 0; j--){
3735					var inst = $.data(cur[j], this.widgetName);
3736					if(inst && inst != this && !inst.options.disabled) {
3737						queries.push([$.isFunction(inst.options.items) ? inst.options.items.call(inst.element[0], event, { item: this.currentItem }) : $(inst.options.items, inst.element), inst]);
3738						this.containers.push(inst);
3739					}
3740				};
3741			};
3742		}
3743
3744		for (var i = queries.length - 1; i >= 0; i--) {
3745			var targetData = queries[i][1];
3746			var _queries = queries[i][0];
3747
3748			for (var j=0, queriesLength = _queries.length; j < queriesLength; j++) {
3749				var item = $(_queries[j]);
3750
3751				item.data(this.widgetName + '-item', targetData); // Data for target checking (mouse manager)
3752
3753				items.push({
3754					item: item,
3755					instance: targetData,
3756					width: 0, height: 0,
3757					left: 0, top: 0
3758				});
3759			};
3760		};
3761
3762	},
3763
3764	refreshPositions: function(fast) {
3765
3766		//This has to be redone because due to the item being moved out/into the offsetParent, the offsetParent's position will change
3767		if(this.offsetParent && this.helper) {
3768			this.offset.parent = this._getParentOffset();
3769		}
3770
3771		for (var i = this.items.length - 1; i >= 0; i--){
3772			var item = this.items[i];
3773
3774			//We ignore calculating positions of all connected containers when we're not over them
3775			if(item.instance != this.currentContainer && this.currentContainer && item.item[0] != this.currentItem[0])
3776				continue;
3777
3778			var t = this.options.toleranceElement ? $(this.options.toleranceElement, item.item) : item.item;
3779
3780			if (!fast) {
3781				item.width = t.outerWidth();
3782				item.height = t.outerHeight();
3783			}
3784
3785			var p = t.offset();
3786			item.left = p.left;
3787			item.top = p.top;
3788		};
3789
3790		if(this.options.custom && this.options.custom.refreshContainers
3790) {
3791			this.options.custom.refreshContainers.call(this);
3792		} else {
3793			for (var i = this.containers.length - 1; i >= 0; i--){
3794				var p = this.containers[i].element.offset();
3795				this.containers[i].containerCache.left = p.left;
3796				this.containers[i].containerCache.top = p.top;
3797				this.containers[i].containerCache.width	= this.containers[i].element.outerWidth();
3798				this.containers[i].containerCache.height = this.containers[i].element.outerHeight();
3799			};
3800		}
3801
3802		return this;
3803	},
3804
3805	_createPlaceholder: function(that) {
3806		that = that || this;
3807		var o = that.options;
3808
3809		if(!o.placeholder || o.placeholder.constructor == String) {
3810			var className = o.placeholder;
3811			o.placeholder = {
3812				element: function() {
3813
3814					var el = $(document.createElement(that.currentItem[0].nodeName))
3815						.addClass(className || that.currentItem[0].className+" ui-sortable-placeholder")
3816						.removeClass("ui-sortable-helper")[0];
3817
3818					if(!className)
3819						el.style.visibility = "hidden";
3820
3821					return el;
3822				},
3823				update: function(container, p) {
3824
3825					// 1. If a className is set as 'placeholder option, we don't force sizes - the class is responsible for that
3826					// 2. The option 'forcePlaceholderSize can be enabled to force it even if a class name is specified
3827					if(className && !o.forcePlaceholderSize) return;
3828
3829					//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
3830					if(!p.height()) { p.height(that.currentItem.innerHeight() - parseInt(that.currentItem.css('paddingTop')||0, 10) - parseInt(that.currentItem.css('paddingBottom')||0, 10)); };
3831					if(!p.width()) { p.width(that.currentItem.innerWidth() - parseInt(that.currentItem.css('paddingLeft')||0, 10) - parseInt(that.currentItem.css('paddingRight')||0, 10)); };
3832				}
3833			};
3834		}
3835
3836		//Create the placeholder
3837		that.placeholder = $(o.placeholder.element.call(that.element, that.currentItem));
3838
3839		//Append it after the actual current item
3840		that.currentItem.after(that.placeholder);
3841
3842		//Update the size of the placeholder (TODO: Logic to fuzzy, see line 316/317)
3843		o.placeholder.update(that, that.placeholder);
3844
3845	},
3846
3847	_contactContainers: function(event) {
3848
3849		// get innermost container that intersects with item
3850		var innermostContainer = null, innermostIndex = null;
3851
3852
3853		for (var i = this.containers.length - 1; i >= 0; i--){
3854
3855			// never consider a container that's located within the item itself
3856			if($.contains(this.currentItem[0], this.containers[i].element[0]))
3857				continue;
3858
3859			if(this._intersectsWith(this.containers[i].containerCache)) {
3860
3861				// if we've already found a container and it's more "inner" than this, then continue
3862				if(innermostContainer && $.contains(this.containers[i].element[0], innermostContainer.element[0]))
3863					continue;
3864
3865				innermostContainer = this.containers[i];
3866				innermostIndex = i;
3867
3868			} else {
3869				// container doesn't intersect. trigger "out" event if necessary
3870				if(this.containers[i].containerCache.over) {
3871					this.containers[i]._trigger("out", event, this._uiHash(this));
3872					this.containers[i].containerCache.over = 0;
3873				}
3874			}
3875
3876		}
3877
3878		// if no intersecting containers found, return
3879		if(!innermostContainer) return;
3880
3881		// move the item into the container if it's not there already
3882		if(this.containers.length === 1) {
3883			this.containers[innermostIndex]._trigger("over", event, this._uiHash(this));
3884			this.containers[innermostIndex].containerCache.over = 1;
3885		} else {
3886
3887			//When entering a new container, we will find the item with the least distance and append our item near it
3888			var dist = 10000; var itemWithLeastDistance = null;
3889			var posProperty = this.containers[innermostIndex].floating ? 'left' : 'top';
3890			var sizeProperty = this.containers[innermostIndex].floating ? 'width' : 'height';
3891			var base = this.positionAbs[posProperty] + this.offset.click[posProperty];
3892			for (var j = this.items.length - 1; j >= 0; j--) {
3893				if(!$.contains(this.containers[innermostIndex].element[0], this.items[j].item[0])) continue;
3894				if(this.items[j].item[0] == this.currentItem[0]) continue;
3895				var cur = this.items[j].item.offset()[posProperty];
3896				var nearBottom = false;
3897				if(Math.abs(cur - base) > Math.abs(cur + this.items[j][sizeProperty] - base)){
3898					nearBottom = true;
3899					cur += this.items[j][sizeProperty];
3900				}
3901
3902				if(Math.abs(cur - base) < dist) {
3903					dist = Math.abs(cur - base); itemWithLeastDistance = this.items[j];
3904					this.direction = nearBottom ? "up": "down";
3905				}
3906			}
3907
3908			if(!itemWithLeastDistance && !this.options.dropOnEmpty) //Check if dropOnEmpty is enabled
3909				return;
3910
3911			this.currentContainer = this.containers[innermostIndex];
3912			itemWithLeastDistance ? this._rearrange(event, itemWithLeastDistance, null, true) : this._rearrange(event, null, this.containers[innermostIndex].element, true);
3913			this._trigger("change", event, this._uiHash());
3914			this.containers[innermostIndex]._trigger("change", event, this._uiHash(this));
3915
3916			//Update the placeholder
3917			this.options.placeholder.update(this.currentContainer, this.placeholder);
3918
3919			this.containers[innermostIndex]._trigger("over", event, this._uiHash(this));
3920			this.containers[innermostIndex].containerCache.over = 1;
3921		}
3922
3923
3924	},
3925
3926	_createHelper: function(event) {
3927
3928		var o = this.options;
3929		var helper = $.isFunction(o.helper) ? $(o.helper.apply(this.element[0], [event, this.currentItem])) : (o.helper == 'clone' ? this.currentItem.clone() : this.currentItem);
3930
3931		if(!helper.parents('body').length) //Add the helper to the DOM if that didn't happen already
3932			$(o.appendTo != 'parent' ? o.appendTo : this.currentItem[0].parentNode)[0].appendChild(helper[0]);
3933
3934		if(helper[0] == this.currentItem[0])
3935			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
3935: this.currentItem.css("left") };
3936
3937		if(helper[0].style.width == '' || o.forceHelperSize) helper.width(this.currentItem.width());
3938		if(helper[0].style.height == '' || o.forceHelperSize) helper.height(this.currentItem.height());
3939
3940		return helper;
3941
3942	},
3943
3944	_adjustOffsetFromHelper: function(obj) {
3945		if (typeof obj == 'string') {
3946			obj = obj.split(' ');
3947		}
3948		if ($.isArray(obj)) {
3949			obj = {left: +obj[0], top: +obj[1] || 0};
3950		}
3951		if ('left' in obj) {
3952			this.offset.click.left = obj.left + this.margins.left;
3953		}
3954		if ('right' in obj) {
3955			this.offset.click.left = this.helperProportions.width - obj.right + this.margins.left;
3956		}
3957		if ('top' in obj) {
3958			this.offset.click.top = obj.top + this.margins.top;
3959		}
3960		if ('bottom' in obj) {
3961			this.offset.click.top = this.helperProportions.height - obj.bottom + this.margins.top;
3962		}
3963	},
3964
3965	_getParentOffset: function() {
3966
3967
3968		//Get the offsetParent and cache its position
3969		this.offsetParent = this.helper.offsetParent();
3970		var po = this.offsetParent.offset();
3971
3972		// This is a special case where we need to modify a offset calculated on start, since the following happened:
3973		// 1. The position of the helper is absolute, so it's position is calculated based on the next positioned parent
3974		// 2. The actual offset parent is a child of the scroll parent, and the scroll parent isn't the document, which means that
3975		//    the scroll is included in the initial calculation of the offset of the parent, and never recalculated upon drag
3976		if(this.cssPosition == 'absolute' && this.scrollParent[0] != document && $.contains(this.scrollParent[0], this.offsetParent[0])) {
3977			po.left += this.scrollParent.scrollLeft();
3978			po.top += this.scrollParent.scrollTop();
3979		}
3980
3981		if((this.offsetParent[0] == document.body) //This needs to be actually done for all browsers, since pageX/pageY includes this information
3982		|| (this.offsetParent[0].tagName && this.offsetParent[0].tagName.toLowerCase() == 'html' && $.ui.ie)) //Ugly IE fix
3983			po = { top: 0, left: 0 };
3984
3985		return {
3986			top: po.top + (parseInt(this.offsetParent.css("borderTopWidth"),10) || 0),
3987			left: po.left + (parseInt(this.offsetParent.css("borderLeftWidth"),10) || 0)
3988		};
3989
3990	},
3991
3992	_getRelativeOffset: function() {
3993
3994		if(this.cssPosition == "relative") {
3995			var p = this.currentItem.position();
3996			return {
3997				top: p.top - (parseInt(this.helper.css("top"),10) || 0) + this.scrollParent.scrollTop(),
3998				left: p.left - (parseInt(this.helper.css("left"),10) || 0) + this.scrollParent.scrollLeft()
3999			};
4000		} else {
4001			return { top: 0, left: 0 };
4002		}
4003
4004	},
4005
4006	_cacheMargins: function() {
4007		this.margins = {
4008			left: (parseInt(this.currentItem.css("marginLeft"),10) || 0),
4009			top: (parseInt(this.currentItem.css("marginTop"),10) || 0)
4010		};
4011	},
4012
4013	_cacheHelperProportions: function() {
4014		this.helperProportions = {
4015			width: this.helper.outerWidth(),
4016			height: this.helper.outerHeight()
4017		};
4018	},
4019
4020	_setContainment: function() {
4021
4022		var o = this.options;
4023		if(o.containment == 'parent') o.containment = this.helper[0].parentNode;
4024		if(o.containment == 'document' || o.containment == 'window') this.containment = [
4025			0 - this.offset.relative.left - this.offset.parent.left,
4026			0 - this.offset.relative.top - this.offset.parent.top,
4027			$(o.containment == 'document' ? document : window).width() - this.helperProportions.width - this.margins.left,
4028			($(o.containment == 'document' ? document : window).height() || document.body.parentNode.scrollHeight) - this.helperProportions.height - this.margins.top
4029		];
4030
4031		if(!(/^(document|window|parent)$/).test(o.containment)) {
4032			var ce = $(o.containment)[0];
4033			var co = $(o.containment).offset();
4034			var over = ($(ce).css("overflow") != 'hidden');
4035
4036			this.containment = [
4037				co.left + (parseInt($(ce).css("borderLeftWidth"),10) || 0) + (parseInt($(ce).css("paddingLeft"),10) || 0) - this.margins.left,
4038				co.top + (parseInt($(ce).css("borderTopWidth"),10) || 0) + (parseInt($(ce).css("paddingTop"),10) || 0) - this.margins.top,
4039				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,
4040				co.top+(over ? Math.max(ce.scrollHeight,ce.offsetHeight) : ce.offsetHeight) - (parseInt($(ce).css("borderTopWidth"),
404010) || 0) - (parseInt($(ce).css("paddingBottom"),10) || 0) - this.helperProportions.height - this.margins.top
4041			];
4042		}
4043
4044	},
4045
4046	_convertPositionTo: function(d, pos) {
4047
4048		if(!pos) pos = this.position;
4049		var mod = d == "absolute" ? 1 : -1;
4050		var o = this.options, 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);
4051
4052		return {
4053			top: (
4054				pos.top																	// The absolute mouse position
4055				+ this.offset.relative.top * mod										// Only for relative positioned nodes: Relative offset from element to offset parent
4056				+ this.offset.parent.top * mod											// The offsetParent's offset without borders (offset + border)
4057				- ( ( this.cssPosition == 'fixed' ? -this.scrollParent.scrollTop() : ( scrollIsRootNode ? 0 : scroll.scrollTop() ) ) * mod)
4058			),
4059			left: (
4060				pos.left																// The absolute mouse position
4061				+ this.offset.relative.left * mod										// Only for relative positioned nodes: Relative offset from element to offset parent
4062				+ this.offset.parent.left * mod											// The offsetParent's offset without borders (offset + border)
4063				- ( ( this.cssPosition == 'fixed' ? -this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 : scroll.scrollLeft() ) * mod)
4064			)
4065		};
4066
4067	},
4068
4069	_generatePosition: function(event) {
4070
4071		var o = this.options, 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);
4072
4073		// This is another very weird special case that only happens for relative elements:
4074		// 1. If the css position is relative
4075		// 2. and the scroll parent is the document or similar to the offset parent
4076		// we have to refresh the relative offset during the scroll so there are no jumps
4077		if(this.cssPosition == 'relative' && !(this.scrollParent[0] != document && this.scrollParent[0] != this.offsetParent[0])) {
4078			this.offset.relative = this._getRelativeOffset();
4079		}
4080
4081		var pageX = event.pageX;
4082		var pageY = event.pageY;
4083
4084		/*
4085		 * - Position constraining -
4086		 * Constrain the position to a mix of grid, containment.
4087		 */
4088
4089		if(this.originalPosition) { //If we are not dragging yet, we won't check for options
4090
4091			if(this.containment) {
4092				if(event.pageX - this.offset.click.left < this.containment[0]) pageX = this.containment[0] + this.offset.click.left;
4093				if(event.pageY - this.offset.click.top < this.containment[1]) pageY = this.containment[1] + this.offset.click.top;
4094				if(event.pageX - this.offset.click.left > this.containment[2]) pageX = this.containment[2] + this.offset.click.left;
4095				if(event.pageY - this.offset.click.top > this.containment[3]) pageY = this.containment[3] + this.offset.click.top;
4096			}
4097
4098			if(o.grid) {
4099				var top = this.originalPageY + Math.round((pageY - this.originalPageY) / o.grid[1]) * o.grid[1];
4100				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;
4101
4102				var left = this.originalPageX + Math.round((pageX - this.originalPageX) / o.grid[0]) * o.grid[0];
4103				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;
4104			}
4105
4106		}
4107
4108		return {
4109			top: (
4110				pageY																// The absolute mouse position
4111				- this.offset.click.top													// Click offset (relative to the element)
4112				- this.offset.relative.top												// Only for relative positioned nodes: Relative offset from element to offset parent
4113				- this.offset.parent.top												// The offsetParent's offset without borders (offset + border)
4114				+ ( ( this.cssPosition == 'fixed' ? -this.scrollParent.scrollTop() : ( scrollIsRootNode ? 0 : scroll.scrollTop() ) ))
4115			),
4116			left: (
4117				pageX																// The absolute mouse position
4118				- this.offset.click.left												// Click offset (relative to the element)
4119				- this.offset.relative.left												// Only for relative positioned nodes: Relative offset from element to offset parent
4120				- this.offset.parent.left												// The offsetParent's offset without borders (offset + border)
4121				+ ( ( this.cssPosition == 'fixed' ? -this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 : scroll.scrollLeft() ))
4122			)
4123		};
4124
4125	},
4126
4127	_rearrange: function(event, i, a, hardRefresh) {
4128
4129		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));
4130
4131		//Various things done here to improve the performance:
4132		// 1. we create a setTimeout, that calls refreshPositions
4133		// 2. on the instance, we have a counter variable, that get's higher after every append
4134		// 3. on the local scope, we copy the counter variable, and check in the timeout, if it's still the same
4135		// 4. this lets only the last addition to the timeout stack through
4136		this.counter = this.counter ? ++this.counter : 1;
4137		var counter = this.counter;
4138
4139		this._delay(function() {
4140			if(counter == this.counter) this.refreshPositions(!hardRefresh); //Precompute after each DOM insertion, NOT on mousemove
4141		});
4142
4143	},
4144
4145	_clear: function(event, noPropagation) {
4146
4147		this.reverting = false;
4148		// We delay all events that have to be triggered to after the point where the placeholder has been removed and
4149		// everything else normalized again
4150		var delayedTriggers = [];
4151
4152		// We first have to update the dom position of the actual currentItem
4153		// Note: don't do it if the current item is already removed (by a user), or it gets reappended (see #4088)
4154		if(!this._noFinalSort && this.currentItem.parent().length) this.placeholder.before(this.currentItem);
4155		this._noFinalSort = null;
4156
4157		if(this.helper[0] == this.currentItem[0]) {
4158			for(var i in this._storedCSS) {
4159				if(this._storedCSS[i] == 'auto' || this._storedCSS[i] == 'static') this._storedCSS[i] = '';
4160			}
4161			this.currentItem.css(this._storedCSS).removeClass("ui-sortable-helper");
4162		} else {
4163			this.currentItem.show();
4164		}
4165
4166		if(this.fromOutside && !noPropagation) delayedTriggers.push(function(event) { this._trigger("receive", event, this._uiHash(this.fromOutside)); });
4167		if((this.fromOutside || this.domPosition.prev != this.currentItem.prev().not(".ui-sortable-helper")[0] || this.domPosition.parent != this.currentItem.parent()[0]) && !noPropagation) delayedTriggers.push(function(event) { this._trigger("update", event, this._uiHash()); }); //Trigger update callback if the DOM position has changed
4168
4169		// Check if the items Container has Changed and trigger appropriate
4170		// events.
4171		if (this !== this.currentContainer) {
4172			if(!noPropagation) {
4173				delayedTriggers.push(function(event) { this._trigger("remove", event, this._uiHash()); });
4174				delayedTriggers.push((function(c) { return function(event) { c._trigger("receive", event, this._uiHash(this)); };  }).call(this, this.currentContainer));
4175				delayedTriggers.push((function(c) { return function(event) { c._trigger("update", event, this._uiHash(this));  }; }).call(this, this.currentContainer));
4176			}
4177		}
4178
4179
4180		//Post events to containers
4181		for (var i = this.containers.length - 1; i >= 0; i--){
4182			if(!noPropagation) delayedTriggers.push((function(c) { return function(event) { c._trigger("deactivate", event, this._uiHash(this)); };  }).call(this, this.containers[i]));
4183			if(this.containers[i].containerCache.over) {
4184				delayedTriggers.push((function(c) { return function(event) { c._trigger("out", event, this._uiHash(this)); };  }).call(this, this.containers[i]));
4185				this.containers[i].containerCache.over = 0;
4186			}
4187		}
4188
4189		//Do what was originally in plugins
4190		if(this._storedCursor) $('body').css("cursor", this._storedCursor); //Reset cursor
4191		if(this._storedOpacity) this.helper.css("opacity", this._storedOpacity); //Reset opacity
4192		if(this._storedZIndex) this.helper.css("zIndex", this._storedZIndex == 'auto' ? '' : this._storedZIndex); //Reset z-index
4193
4194		this.dragging = false;
4195		if(this.cancelHelperRemoval) {
4196			if(!noPropagation) {
4197				this._trigger("beforeStop", event, this._uiHash());
4198				for (var i=0; i < delayedTriggers.length; i++) { delayedTriggers[i].call(this, event); }; //Trigger all delayed events
4199				this._trigger("stop", event, this._uiHash());
4200			}
4201
4202			this.fromOutside = false;
vendor: 32,198 bytes, lines 4203-5501
4203			return false;
4204		}
4205
4206		if(!noPropagation) this._trigger("beforeStop", event, this._uiHash());
4207
4208		//$(this.placeholder[0]).remove(); would have been the jQuery way - unfortunately, it unbinds ALL events from the original node!
4209		this.placeholder[0].parentNode.removeChild(this.placeholder[0]);
4210
4211		if(this.helper[0] != this.currentItem[0]) this.helper.remove(); this.helper = null;
4212
4213		if(!noPropagation) {
4214			for (var i=0; i < delayedTriggers.length; i++) { delayedTriggers[i].call(this, event); }; //Trigger all delayed events
4215			this._trigger("stop", event, this._uiHash());
4216		}
4217
4218		this.fromOutside = false;
4219		return true;
4220
4221	},
4222
4223	_trigger: function() {
4224		if ($.Widget.prototype._trigger.apply(this, arguments) === false) {
4225			this.cancel();
4226		}
4227	},
4228
4229	_uiHash: function(_inst) {
4230		var inst = _inst || this;
4231		return {
4232			helper: inst.helper,
4233			placeholder: inst.placeholder || $([]),
4234			position: inst.position,
4235			originalPosition: inst.originalPosition,
4236			offset: inst.positionAbs,
4237			item: inst.currentItem,
4238			sender: _inst ? _inst.element : null
4239		};
4240	}
4241
4242});
4243
4244})(jQuery);
4245
4246;(jQuery.effects || (function($, undefined) {
4247
4248var backCompat = $.uiBackCompat !== false,
4249	// prefix used for storing data on .data()
4250	dataSpace = "ui-effects-";
4251
4252$.effects = {
4253	effect: {}
4254};
4255
4256/*!
4257 * jQuery Color Animations v2.0.0
4258 * http://jquery.com/
4259 *
4260 * Copyright 2012 jQuery Foundation and other contributors
4261 * Released under the MIT license.
4262 * http://jquery.org/license
4263 *
4264 * Date: Mon Aug 13 13:41:02 2012 -0500
4265 */
4266(function( jQuery, undefined ) {
4267
4268	var stepHooks = "backgroundColor borderBottomColor borderLeftColor borderRightColor borderTopColor color columnRuleColor outlineColor textDecorationColor textEmphasisColor".split(" "),
4269
4270	// plusequals test for += 100 -= 100
4271	rplusequals = /^([\-+])=\s*(\d+\.?\d*)/,
4272	// a set of RE's that can match strings and generate color tuples.
4273	stringParsers = [{
4274			re: /rgba?\(\s*(\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(\d{1,3})\s*(?:,\s*(\d+(?:\.\d+)?)\s*)?\)/,
4275			parse: function( execResult ) {
4276				return [
4277					execResult[ 1 ],
4278					execResult[ 2 ],
4279					execResult[ 3 ],
4280					execResult[ 4 ]
4281				];
4282			}
4283		}, {
4284			re: /rgba?\(\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*(?:,\s*(\d+(?:\.\d+)?)\s*)?\)/,
4285			parse: function( execResult ) {
4286				return [
4287					execResult[ 1 ] * 2.55,
4288					execResult[ 2 ] * 2.55,
4289					execResult[ 3 ] * 2.55,
4290					execResult[ 4 ]
4291				];
4292			}
4293		}, {
4294			// this regex ignores A-F because it's compared against an already lowercased string
4295			re: /#([a-f0-9]{2})([a-f0-9]{2})([a-f0-9]{2})/,
4296			parse: function( execResult ) {
4297				return [
4298					parseInt( execResult[ 1 ], 16 ),
4299					parseInt( execResult[ 2 ], 16 ),
4300					parseInt( execResult[ 3 ], 16 )
4301				];
4302			}
4303		}, {
4304			// this regex ignores A-F because it's compared against an already lowercased string
4305			re: /#([a-f0-9])([a-f0-9])([a-f0-9])/,
4306			parse: function( execResult ) {
4307				return [
4308					parseInt( execResult[ 1 ] + execResult[ 1 ], 16 ),
4309					parseInt( execResult[ 2 ] + execResult[ 2 ], 16 ),
4310					parseInt( execResult[ 3 ] + execResult[ 3 ], 16 )
4311				];
4312			}
4313		}, {
4314			re: /hsla?\(\s*(\d+(?:\.\d+)?)\s*,\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*(?:,\s*(\d+(?:\.\d+)?)\s*)?\)/,
4315			space: "hsla",
4316			parse: function( execResult ) {
4317				return [
4318					execResult[ 1 ],
4319					execResult[ 2 ] / 100,
4320					execResult[ 3 ] / 100,
4321					execResult[ 4 ]
4322				];
4323			}
4324		}],
4325
4326	// jQuery.Color( )
4327	color = jQuery.Color = function( color, green, blue, alpha ) {
4328		return new jQuery.Color.fn.parse( color, green, blue, alpha );
4329	},
4330	spaces = {
4331		rgba: {
4332			props: {
4333				red: {
4334					idx: 0,
4335					type: "byte"
4336				},
4337				green: {
4338					idx: 1,
4339					type: "byte"
4340				},
4341				blue: {
4342					idx: 2,
4343					type: "byte"
4344				}
4345			}
4346		},
4347
4348		hsla: {
4349			props: {
4350				hue: {
4351					idx: 0,
4352					type: "degrees"
4353				},
4354				saturation: {
4355					idx: 1,
4356					type: "percent"
4357				},
4358				lightness: {
4359					idx: 2,
4360					type: "percent"
4361				}
4362			}
4363		}
4364	},
4365	propTypes = {
4366		"byte": {
4367			floor: true,
4368			max: 255
4369		},
4370		"percent": {
4371			max: 1
4372		},
4373		"degrees": {
4374			mod: 360,
4375			floor: true
4376		}
4377	},
4378	support = color.support = {},
4379
4380	// element for support tests
4381	supportElem = jQuery( "<p>" )[ 0 ],
4382
4383	// colors = jQuery.Color.names
4384	colors,
4385
4386	// local aliases of functions called often
4387	each = jQuery.each;
4388
4389// determine rgba support immediately
4390supportElem.style.cssText = "background-color:rgba(1,1,1,.5)";
4391support.rgba = supportElem.style.backgroundColor.indexOf( "rgba" ) > -1;
4392
4393// define cache name and alpha properties
4394// for rgba and hsla spaces
4395each( spaces, function( spaceName, space ) {
4396	space.cache = "_" + spaceName;
4397	space.props.alpha = {
4398		idx: 3,
4399		type: "percent",
4400		def: 1
4401	};
4402});
4403
4404function clamp( value, prop, allowEmpty ) {
4405	var type = propTypes[ prop.type ] || {};
4406
4407	if ( value == null ) {
4408		return (allowEmpty || !prop.def) ? null : prop.def;
4409	}
4410
4411	// ~~ is an short way of doing floor for positive numbers
4412	value = type.floor ? ~~value : parseFloat( value );
4413
4414	// IE will pass in empty strings as value for alpha,
4415	// which will hit this case
4416	if ( isNaN( value ) ) {
4417		return prop.def;
4418	}
4419
4420	if ( type.mod ) {
4421		// we add mod before modding to make sure that negatives values
4422		// get converted properly: -10 -> 350
4423		return (value + type.mod) % type.mod;
4424	}
4425
4426	// for now all property types without mod have min and max
4427	return 0 > value ? 0 : type.max < value ? type.max : value;
4428}
4429
4430function stringParse( string ) {
4431	var inst = color(),
4432		rgba = inst._rgba = [];
4433
4434	string = string.toLowerCase();
4435
4436	each( stringParsers, function( i, parser ) {
4437		var parsed,
4438			match = parser.re.exec( string ),
4439			values = match && parser.parse( match ),
4440			spaceName = parser.space || "rgba";
4441
4442		if ( values ) {
4443			parsed = inst[ spaceName ]( values );
4444
4445			// if this was an rgba parse the assignment might happen twice
4446			// oh well....
4447			inst[ spaces[ spaceName ].cache ] = parsed[ spaces[ spaceName ].cache ];
4448			rgba = inst._rgba = parsed._rgba;
4449
4450			// exit each( stringParsers ) here because we matched
4451			return false;
4452		}
4453	});
4454
4455	// Found a stringParser that handled it
4456	if ( rgba.length ) {
4457
4458		// if this came from a parsed string, force "transparent" when alpha is 0
4459		// chrome, (and maybe others) return "transparent" as rgba(0,0,0,0)
4460		if ( rgba.join() === "0,0,0,0" ) {
4461			jQuery.extend( rgba, colors.transparent );
4462		}
4463		return inst;
4464	}
4465
4466	// named colors
4467	return colors[ string ];
4468}
4469
4470color.fn = jQuery.extend( color.prototype, {
4471	parse: function( red, green, blue, alpha ) {
4472		if ( red === undefined ) {
4473			this._rgba = [ null, null, null, null ];
4474			return this;
4475		}
4476		if ( red.jquery || red.nodeType ) {
4477			red = jQuery( red ).css( green );
4478			green = undefined;
4479		}
4480
4481		var inst = this,
4482			type = jQuery.type( red ),
4483			rgba = this._rgba = [];
4484
4485		// more than 1 argument specified - assume ( red, green, blue, alpha )
4486		if ( green !== undefined ) {
4487			red = [ red, green, blue, alpha ];
4488			type = "array";
4489		}
4490
4491		if ( type === "string" ) {
4492			return this.parse( stringParse( red ) || colors._default );
4493		}
4494
4495		if ( type === "array" ) {
4496			each( spaces.rgba.props, function( key, prop ) {
4497				rgba[ prop.idx ] = clamp( red[ prop.idx ], prop );
4498			});
4499			return this;
4500		}
4501
4502		if ( type === "object" ) {
4503			if ( red instanceof color ) {
4504				each( spaces, function( spaceName, space ) {
4505					if ( red[ space.cache ] ) {
4506						inst[ space.cache ] = red[ space.cache ].slice();
4507					}
4508				});
4509			} else {
4510				each( spaces, function( spaceName, space ) {
4511					var cache = space.cache;
4512					each( space.props, function( key, prop ) {
4513
4514						// if the cache doesn't exist, and we know how to convert
4515						if ( !inst[ cache ] && space.to ) {
4516
4517							// if the value was null, we don't need to copy it
4518							// if the key was alpha, we don't need to copy it either
4519							if ( key === "alpha" || red[ key ] == null ) {
4520								return;
4521							}
4522							inst[ cache ] = space.to( inst._rgba );
4523						}
4524
4525						// this is the only case where we allow nulls for ALL properties.
4526						// call clamp with alwaysAllowEmpty
4527						inst[ cache ][ prop.idx ] = clamp( red[ key ], prop, true );
4528					});
4529
4530					// everything defined but alpha?
4531					if ( inst[ cache ] && $.inArray( null, inst[ cache ].slice( 0, 3 ) ) < 0 ) {
4532						// use the default of 1
4533						inst[ cache ][ 3 ] = 1;
4534						if ( space.from ) {
4535							inst._rgba = space.from( inst[ cache ] );
4536						}
4537					}
4538				});
4539			}
4540			return this;
4541		}
4542	},
4543	is: function( compare ) {
4544		var is = color( compare ),
4545			same = true,
4546			inst = this;
4547
4548		each( spaces, function( _, space ) {
4549			var localCache,
4550				isCache = is[ space.cache ];
4551			if (isCache) {
4552				localCache = inst[ space.cache ] || space.to && space.to( inst._rgba ) || [];
4553				each( space.props, function( _, prop ) {
4554					if ( isCache[ prop.idx ] != null ) {
4555						same = ( isCache[ prop.idx ] === localCache[ prop.idx ] );
4556						return same;
4557					}
4558				});
4559			}
4560			return same;
4561		});
4562		return same;
4563	},
4564	_space: function() {
4565		var used = [],
4566			inst = this;
4567		each( spaces, function( spaceName, space ) {
4568			if ( inst[ space.cache ] ) {
4569				used.push( spaceName );
4570			}
4571		});
4572		return used.pop();
4573	},
4574	transition: function( other, distance ) {
4575		var end = color( other ),
4576			spaceName = end._space(),
4577			space = spaces[ spaceName ],
4578			startColor = this.alpha() === 0 ? color( "transparent" ) : this,
4579			start = startColor[ space.cache ] || space.to( startColor._rgba ),
4580			result = start.slice();
4581
4582		end = end[ space.cache ];
4583		each( space.props, function( key, prop ) {
4584			var index = prop.idx,
4585				startValue = start[ index ],
4586				endValue = end[ index ],
4587				type = propTypes[ prop.type ] || {};
4588
4589			// if null, don't override start value
4590			if ( endValue === null ) {
4591				return;
4592			}
4593			// if null - use end
4594			if ( startValue === null ) {
4595				result[ index ] = endValue;
4596			} else {
4597				if ( type.mod ) {
4598					if ( endValue - startValue > type.mod / 2 ) {
4599						startValue += type.mod;
4600					} else if ( startValue - endValue > type.mod / 2 ) {
4601						startValue -= type.mod;
4602					}
4603				}
4604				result[ index ] = clamp( ( endValue - startValue ) * distance + startValue, prop );
4605			}
4606		});
4607		return this[ spaceName ]( result );
4608	},
4609	blend: function( opaque ) {
4610		// if we are already opaque - return ourself
4611		if ( this._rgba[ 3 ] === 1 ) {
4612			return this;
4613		}
4614
4615		var rgb = this._rgba.slice(),
4616			a = rgb.pop(),
4617			blend = color( opaque )._rgba;
4618
4619		return color( jQuery.map( rgb, function( v, i ) {
4620			return ( 1 - a ) * blend[ i ] + a * v;
4621		}));
4622	},
4623	toRgbaString: function() {
4624		var prefix = "rgba(",
4625			rgba = jQuery.map( this._rgba, function( v, i ) {
4626				return v == null ? ( i > 2 ? 1 : 0 ) : v;
4627			});
4628
4629		if ( rgba[ 3 ] === 1 ) {
4630			rgba.pop();
4631			prefix = "rgb(";
4632		}
4633
4634		return prefix + rgba.join() + ")";
4635	},
4636	toHslaString: function() {
4637		var prefix = "hsla(",
4638			hsla = jQuery.map( this.hsla(), function( v, i ) {
4639				if ( v == null ) {
4640					v = i > 2 ? 1 : 0;
4641				}
4642
4643				// catch 1 and 2
4644				if ( i && i < 3 ) {
4645					v = Math.round( v * 100 ) + "%";
4646				}
4647				return v;
4648			});
4649
4650		if ( hsla[ 3 ] === 1 ) {
4651			hsla.pop();
4652			prefix = "hsl(";
4653		}
4654		return prefix + hsla.join() + ")";
4655	},
4656	toHexString: function( includeAlpha ) {
4657		var rgba = this._rgba.slice(),
4658			alpha = rgba.pop();
4659
4660		if ( includeAlpha ) {
4661			rgba.push( ~~( alpha * 255 ) );
4662		}
4663
4664		return "#" + jQuery.map( rgba, function( v ) {
4665
4666			// default to 0 when nulls exist
4667			v = ( v || 0 ).toString( 16 );
4668			return v.length === 1 ? "0" + v : v;
4669		}).join("");
4670	},
4671	toString: function() {
4672		return this._rgba[ 3 ] === 0 ? "transparent" : this.toRgbaString();
4673	}
4674});
4675color.fn.parse.prototype = color.fn;
4676
4677// hsla conversions adapted from:
4678// https://code.google.com/p/maashaack/source/browse/packages/graphics/trunk/src/graphics/colors/HUE2RGB.as?r=5021
4679
4680function hue2rgb( p, q, h ) {
4681	h = ( h + 1 ) % 1;
4682	if ( h * 6 < 1 ) {
4683		return p + (q - p) * h * 6;
4684	}
4685	if ( h * 2 < 1) {
4686		return q;
4687	}
4688	if ( h * 3 < 2 ) {
4689		return p + (q - p) * ((2/3) - h) * 6;
4690	}
4691	return p;
4692}
4693
4694spaces.hsla.to = function ( rgba ) {
4695	if ( rgba[ 0 ] == null || rgba[ 1 ] == null || rgba[ 2 ] == null ) {
4696		return [ null, null, null, rgba[ 3 ] ];
4697	}
4698	var r = rgba[ 0 ] / 255,
4699		g = rgba[ 1 ] / 255,
4700		b = rgba[ 2 ] / 255,
4701		a = rgba[ 3 ],
4702		max = Math.max( r, g, b ),
4703		min = Math.min( r, g, b ),
4704		diff = max - min,
4705		add = max + min,
4706		l = add * 0.5,
4707		h, s;
4708
4709	if ( min === max ) {
4710		h = 0;
4711	} else if ( r === max ) {
4712		h = ( 60 * ( g - b ) / diff ) + 360;
4713	} else if ( g === max ) {
4714		h = ( 60 * ( b - r ) / diff ) + 120;
4715	} else {
4716		h = ( 60 * ( r - g ) / diff ) + 240;
4717	}
4718
4719	if ( l === 0 || l === 1 ) {
4720		s = l;
4721	} else if ( l <= 0.5 ) {
4722		s = diff / add;
4723	} else {
4724		s = diff / ( 2 - add );
4725	}
4726	return [ Math.round(h) % 360, s, l, a == null ? 1 : a ];
4727};
4728
4729spaces.hsla.from = function ( hsla ) {
4730	if ( hsla[ 0 ] == null || hsla[ 1 ] == null || hsla[ 2 ] == null ) {
4731		return [ null, null, null, hsla[ 3 ] ];
4732	}
4733	var h = hsla[ 0 ] / 360,
4734		s = hsla[ 1 ],
4735		l = hsla[ 2 ],
4736		a = hsla[ 3 ],
4737		q = l <= 0.5 ? l * ( 1 + s ) : l + s - l * s,
4738		p = 2 * l - q;
4739
4740	return [
4741		Math.round( hue2rgb( p, q, h + ( 1 / 3 ) ) * 255 ),
4742		Math.round( hue2rgb( p, q, h ) * 255 ),
4743		Math.round( hue2rgb( p, q, h - ( 1 / 3 ) ) * 255 ),
4744		a
4745	];
4746};
4747
4748
4749each( spaces, function( spaceName, space ) {
4750	var props = space.props,
4751		cache = space.cache,
4752		to = space.to,
4753		from = space.from;
4754
4755	// makes rgba() and hsla()
4756	color.fn[ spaceName ] = function( value ) {
4757
4758		// generate a cache for this space if it doesn't exist
4759		if ( to && !this[ cache ] ) {
4760			this[ cache ] = to( this._rgba );
4761		}
4762		if ( value === undefined ) {
4763			return this[ cache ].slice();
4764		}
4765
4766		var ret,
4767			type = jQuery.type( value ),
4768			arr = ( type === "array" || type === "object" ) ? value : arguments,
4769			local = this[ cache ].slice();
4770
4771		each( props, function( key, prop ) {
4772			var val = arr[ type === "object" ? key : prop.idx ];
4773			if ( val == null ) {
4774				val = local[ prop.idx ];
4775			}
4776			local[ prop.idx ] = clamp( val, prop );
4777		});
4778
4779		if ( from ) {
4780			ret = color( from( local ) );
4781			ret[ cache ] = local;
4782			return ret;
4783		} else {
4784			return color( local );
4785		}
4786	};
4787
4788	// makes red() green() blue() alpha() hue() saturation() lightness()
4789	each( props, function( key, prop ) {
4790		// alpha is included in more than one space
4791		if ( color.fn[ key ] ) {
4792			return;
4793		}
4794		color.fn[ key ] = function( value ) {
4795			var vtype = jQuery.type( value ),
4796				fn = ( key === "alpha" ? ( this._hsla ? "hsla" : "rgba" ) : spaceName ),
4797				local = this[ fn ](),
4798				cur = local[ prop.idx ],
4799				match;
4800
4801			if ( vtype === "undefined" ) {
4802				return cur;
4803			}
4804
4805			if ( vtype === "function" ) {
4806				value = value.call( this, cur );
4807				vtype = jQuery.type( value );
4808			}
4809			if ( value == null && prop.empty ) {
4810				return this;
4811			}
4812			if ( vtype === "string" ) {
4813				match = rplusequals.exec( value );
4814				if ( match ) {
4815					value = cur + parseFloat( match[ 2 ] ) * ( match[ 1 ] === "+" ? 1 : -1 );
4816				}
4817			}
4818			local[ prop.idx ] = value;
4819			return this[ fn ]( local );
4820		};
4821	});
4822});
4823
4824// add .fx.step functions
4825each( stepHooks, function( i, hook ) {
4826	jQuery.cssHooks[ hook ] = {
4827		set: function( elem, value ) {
4828			var parsed, curElem,
4829				backgroundColor = "";
4830
4831			if ( jQuery.type( value ) !== "string" || ( parsed = stringParse( value ) ) ) {
4832				value = color( parsed || value );
4833				if ( !support.rgba && value._rgba[ 3 ] !== 1 ) {
4834					curElem = hook === "backgroundColor" ? elem.parentNode : elem;
4835					while (
4836						(backgroundColor === "" || backgroundColor === "transparent") &&
4837						curElem && curElem.style
4838					) {
4839						try {
4840							backgroundColor = jQuery.css( curElem, "backgroundColor" );
4841							curElem = curElem.parentNode;
4842						} catch ( e ) {
4843						}
4844					}
4845
4846					value = value.blend( backgroundColor && backgroundColor !== "transparent" ?
4847						backgroundColor :
4848						"_default" );
4849				}
4850
4851				value = value.toRgbaString();
4852			}
4853			try {
4854				elem.style[ hook ] = value;
4855			} catch( error ) {
4856				// wrapped to prevent IE from throwing errors on "invalid" values like 'auto' or 'inherit'
4857			}
4858		}
4859	};
4860	jQuery.fx.step[ hook ] = function( fx ) {
4861		if ( !fx.colorInit ) {
4862			fx.start = color( fx.elem, hook );
4863			fx.end = color( fx.end );
4864			fx.colorInit = true;
4865		}
4866		jQuery.cssHooks[ hook ].set( fx.elem, fx.start.transition( fx.end, fx.pos ) );
4867	};
4868});
4869
4870jQuery.cssHooks.borderColor = {
4871	expand: function( value ) {
4872		var expanded = {};
4873
4874		each( [ "Top", "Right", "Bottom", "Left" ], function( i, part ) {
4875			expanded[ "border" + part + "Color" ] = value;
4876		});
4877		return expanded;
4878	}
4879};
4880
4881// Basic color names only.
4882// Usage of any of the other color names requires adding yourself or including
4883// jquery.color.svg-names.js.
4884colors = jQuery.Color.names = {
4885	// 4.1. Basic color keywords
4886	aqua: "#00ffff",
4887	black: "#000000",
4888	blue: "#0000ff",
4889	fuchsia: "#ff00ff",
4890	gray: "#808080",
4891	green: "#008000",
4892	lime: "#00ff00",
4893	maroon: "#800000",
4894	navy: "#000080",
4895	olive: "#808000",
4896	purple: "#800080",
4897	red: "#ff0000",
4898	silver: "#c0c0c0",
4899	teal: "#008080",
4900	white: "#ffffff",
4901	yellow: "#ffff00",
4902
4903	// 4.2.3. "transparent" color keyword
4904	transparent: [ null, null, null, 0 ],
4905
4906	_default: "#ffffff"
4907};
4908
4909})( jQuery );
4910
4911
4912
4913/******************************************************************************/
4914/****************************** CLASS ANIMATIONS ******************************/
4915/******************************************************************************/
4916(function() {
4917
4918var classAnimationActions = [ "add", "remove", "toggle" ],
4919	shorthandStyles = {
4920		border: 1,
4921		borderBottom: 1,
4922		borderColor: 1,
4923		borderLeft: 1,
4924		borderRight: 1,
4925		borderTop: 1,
4926		borderWidth: 1,
4927		margin: 1,
4928		padding: 1
4929	};
4930
4931$.each([ "borderLeftStyle", "borderRightStyle", "borderBottomStyle", "borderTopStyle" ], function( _, prop ) {
4932	$.fx.step[ prop ] = function( fx ) {
4933		if ( fx.end !== "none" && !fx.setAttr || fx.pos === 1 && !fx.setAttr ) {
4934			jQuery.style( fx.elem, prop, fx.end );
4935			fx.setAttr = true;
4936		}
4937	};
4938});
4939
4940function getElementStyles() {
4941	var style = this.ownerDocument.defaultView ?
4942			this.ownerDocument.defaultView.getComputedStyle( this, null ) :
4943			this.currentStyle,
4944		newStyle = {},
4945		key,
4946		len;
4947
4948	// webkit enumerates style porperties
4949	if ( style && style.length && style[ 0 ] && style[ style[ 0 ] ] ) {
4950		len = style.length;
4951		while ( len-- ) {
4952			key = style[ len ];
4953			if ( typeof style[ key ] === "string" ) {
4954				newStyle[ $.camelCase( key ) ] = style[ key ];
4955			}
4956		}
4957	} else {
4958		for ( key in style ) {
4959			if ( typeof style[ key ] === "string" ) {
4960				newStyle[ key ] = style[ key ];
4961			}
4962		}
4963	}
4964
4965	return newStyle;
4966}
4967
4968
4969function styleDifference( oldStyle, newStyle ) {
4970	var diff = {},
4971		name, value;
4972
4973	for ( name in newStyle ) {
4974		value = newStyle[ name ];
4975		if ( oldStyle[ name ] !== value ) {
4976			if ( !shorthandStyles[ name ] ) {
4977				if ( $.fx.step[ name ] || !isNaN( parseFloat( value ) ) ) {
4978					diff[ name ] = value;
4979				}
4980			}
4981		}
4982	}
4983
4984	return diff;
4985}
4986
4987$.effects.animateClass = function( value, duration, easing, callback ) {
4988	var o = $.speed( duration, easing, callback );
4989
4990	return this.queue( function() {
4991		var animated = $( this ),
4992			baseClass = animated.attr( "class" ) || "",
4993			applyClassChange,
4994			allAnimations = o.children ? animated.find( "*" ).andSelf() : animated;
4995
4996		// map the animated objects to store the original styles.
4997		allAnimations = allAnimations.map(function() {
4998			var el = $( this );
4999			return {
5000				el: el,
5001				start: getElementStyles.call( this )
5002			};
5003		});
5004
5005		// apply class change
5006		applyClassChange = function() {
5007			$.each( classAnimationActions, function(i, action) {
5008				if ( value[ action ] ) {
5009					animated[ action + "Class" ]( value[ action ] );
5010				}
5011			});
5012		};
5013		applyClassChange();
5014
5015		// map all animated objects again - calculate new styles and diff
5016		allAnimations = allAnimations.map(function() {
5017			this.end = getElementStyles.call( this.el[ 0 ] );
5018			this.diff = styleDifference( this.start, this.end );
5019			return this;
5020		});
5021
5022		// apply original class
5023		animated.attr( "class", baseClass );
5024
5025		// map all animated objects again - this time collecting a promise
5026		allAnimations = allAnimations.map(function() {
5027			var styleInfo = this,
5028				dfd = $.Deferred(),
5029				opts = jQuery.extend({}, o, {
5030					queue: false,
5031					complete: function() {
5032						dfd.resolve( styleInfo );
5033					}
5034				});
5035
5036			this.el.animate( this.diff, opts );
5037			return dfd.promise();
5038		});
5039
5040		// once all animations have completed:
5041		$.when.apply( $, allAnimations.get() ).done(function() {
5042
5043			// set the final class
5044			applyClassChange();
5045
5046			// for each animated element,
5047			// clear all css properties that were animated
5048			$.each( arguments, function() {
5049				var el = this.el;
5050				$.each( this.diff, function(key) {
5051					el.css( key, '' );
5052				});
5053			});
5054
5055			// this is guarnteed to be there if you use jQuery.speed()
5056			// it also handles dequeuing the next anim...
5057			o.complete.call( animated[ 0 ] );
5058		});
5059	});
5060};
5061
5062$.fn.extend({
5063	_addClass: $.fn.addClass,
5064	addClass: function( classNames, speed, easing, callback ) {
5065		return speed ?
5066			$.effects.animateClass.call( this,
5067				{ add: classNames }, speed, easing, callback ) :
5068			this._addClass( classNames );
5069	},
5070
5071	_removeClass: $.fn.removeClass,
5072	removeClass: function( classNames, speed, easing, callback ) {
5073		return speed ?
5074			$.effects.animateClass.call( this,
5075				{ remove: classNames }, speed, easing, callback ) :
5076			this._removeClass( classNames );
5077	},
5078
5079	_toggleClass: $.fn.toggleClass,
5080	toggleClass: function( classNames, force, speed, easing, callback ) {
5081		if ( typeof force === "boolean" || force === undefined ) {
5082			if ( !speed ) {
5083				// without speed parameter
5084				return this._toggleClass( classNames, force );
5085			} else {
5086				return $.effects.animateClass.call( this,
5087					(force ? { add: classNames } : { remove: classNames }),
5088					speed, easing, callback );
5089			}
5090		} else {
5091			// without force parameter
5092			return $.effects.animateClass.call( this,
5093				{ toggle: classNames }, force, speed, easing );
5094		}
5095	},
5096
5097	switchClass: function( remove, add, speed, easing, callback) {
5098		return $.effects.animateClass.call( this, {
5099			add: add,
5100			remove: remove
5101		}, speed, easing, callback );
5102	}
5103});
5104
5105})();
5106
5107/******************************************************************************/
5108/*********************************** EFFECTS **********************************/
5109/******************************************************************************/
5110
5111(function() {
5112
5113$.extend( $.effects, {
5114	version: "1.9.2",
5115
5116	// Saves a set of properties in a data storage
5117	save: function( element, set ) {
5118		for( var i=0; i < set.length; i++ ) {
5119			if ( set[ i ] !== null ) {
5120				element.data( dataSpace + set[ i ], element[ 0 ].style[ set[ i ] ] );
5121			}
5122		}
5123	},
5124
5125	// Restores a set of previously saved properties from a data storage
5126	restore: function( element, set ) {
5127		var val, i;
5128		for( i=0; i < set.length; i++ ) {
5129			if ( set[ i ] !== null ) {
5130				val = element.data( dataSpace + set[ i ] );
5131				// support: jQuery 1.6.2
5132				// http://bugs.jquery.com/ticket/9917
5133				// jQuery 1.6.2 incorrectly returns undefined for any falsy value.
5134				// We can't differentiate between "" and 0 here, so we just assume
5135				// empty string since it's likely to be a more common value...
5136				if ( val === undefined ) {
5137					val = "";
5138				}
5139				element.css( set[ i ], val );
5140			}
5141		}
5142	},
5143
5144	setMode: function( el, mode ) {
5145		if (mode === "toggle") {
5146			mode = el.is( ":hidden" ) ? "show" : "hide";
5147		}
5148		return mode;
5149	},
5150
5151	// Translates a [top,left] array into a baseline value
5152	// this should be a little more flexible in the future to handle a string & hash
5153	getBaseline: function( origin, original ) {
5154		var y, x;
5155		switch ( origin[ 0 ] ) {
5156			case "top": y = 0; break;
5157			case "middle": y = 0.5; break;
5158			case "bottom": y = 1; break;
5159			default: y = origin[ 0 ] / original.height;
5160		}
5161		switch ( origin[ 1 ] ) {
5162			case "left": x = 0; break;
5163			case "center": x = 0.5; break;
5164			case "right": x = 1; break;
5165			default: x = origin[ 1 ] / original.width;
5166		}
5167		return {
5168			x: x,
5169			y: y
5170		};
5171	},
5172
5173	// Wraps the element around a wrapper that copies position properties
5174	createWrapper: function( element ) {
5175
5176		// if the element is already wrapped, return it
5177		if ( element.parent().is( ".ui-effects-wrapper" )) {
5178			return element.parent();
5179		}
5180
5181		// wrap the element
5182		var props = {
5183				width: element.outerWidth(true),
5184				height: element.outerHeight(true),
5185				"float": element.css( "float" )
5186			},
5187			wrapper = $( "<div></div>" )
5188				.addClass( "ui-effects-wrapper" )
5189				.css({
5190					fontSize: "100%",
5191					background: "transparent",
5192					border: "none",
5193					margin: 0,
5194					padding: 0
5195				}),
5196			// Store the size in case width/height are defined in % - Fixes #5245
5197			size = {
5198				width: element.width(),
5199				height: element.height()
5200			},
5201			active = document.activeElement;
5202
5203		// support: Firefox
5204		// Firefox incorrectly exposes anonymous content
5205		// https://bugzilla.mozilla.org/show_bug.cgi?id=561664
5206		try {
5207			active.id;
5208		} catch( e ) {
5209			active = document.body;
5210		}
5211
5212		element.wrap( wrapper );
5213
5214		// Fixes #7595 - Elements lose focus when wrapped.
5215		if ( element[ 0 ] === active || $.contains( element[ 0 ], active ) ) {
5216			$( active ).focus();
5217		}
5218
5219		wrapper = element.parent(); //Hotfix for jQuery 1.4 since some change in wrap() seems to actually lose the reference to the wrapped element
5220
5221		// transfer positioning properties to the wrapper
5222		if ( element.css( "position" ) === "static" ) {
5223			wrapper.css({ position: "relative" });
5224			element.css({ position: "relative" });
5225		} else {
5226			$.extend( props, {
5227				position: element.css( "position" ),
5228				zIndex: element.css( "z-index" )
5229			});
5230			$.each([ "top", "left", "bottom", "right" ], function(i, pos) {
5231				props[ pos ] = element.css( pos );
5232				if ( isNaN( parseInt( props[ pos ], 10 ) ) ) {
5233					props[ pos ] = "auto";
5234				}
5235			});
5236			element.css({
5237				position: "relative",
5238				top: 0,
5239				left: 0,
5240				right: "auto",
5241				bottom: "auto"
5242			});
5243		}
5244		element.css(size);
5245
5246		return wrapper.css( props ).show();
5247	},
5248
5249	removeWrapper: function( element ) {
5250		var active = document.activeElement;
5251
5252		if ( element.parent().is( ".ui-effects-wrapper" ) ) {
5253			element.parent().replaceWith( element );
5254
5255			// Fixes #7595 - Elements lose focus when wrapped.
5256			if ( element[ 0 ] === active || $.contains( element[ 0 ], active ) ) {
5257				$( active ).focus();
5258			}
5259		}
5260
5261
5262		return element;
5263	},
5264
5265	setTransition: function( element, list, factor, value ) {
5266		value = value || {};
5267		$.each( list, function( i, x ) {
5268			var unit = element.cssUnit( x );
5269			if ( unit[ 0 ] > 0 ) {
5270				value[ x ] = unit[ 0 ] * factor + unit[ 1 ];
5271			}
5272		});
5273		return value;
5274	}
5275});
5276
5277// return an effect options object for the given parameters:
5278function _normalizeArguments( effect, options, speed, callback ) {
5279
5280	// allow passing all options as the first parameter
5281	if ( $.isPlainObject( effect ) ) {
5282		options = effect;
5283		effect = effect.effect;
5284	}
5285
5286	// convert to an object
5287	effect = { effect: effect };
5288
5289	// catch (effect, null, ...)
5290	if ( options == null ) {
5291		options = {};
5292	}
5293
5294	// catch (effect, callback)
5295	if ( $.isFunction( options ) ) {
5296		callback = options;
5297		speed = null;
5298		options = {};
5299	}
5300
5301	// catch (effect, speed, ?)
5302	if ( typeof options === "number" || $.fx.speeds[ options ] ) {
5303		callback = speed;
5304		speed = options;
5305		options = {};
5306	}
5307
5308	// catch (effect, options, callback)
5309	if ( $.isFunction( speed ) ) {
5310		callback = speed;
5311		speed = null;
5312	}
5313
5314	// add options to effect
5315	if ( options ) {
5316		$.extend( effect, options );
5317	}
5318
5319	speed = speed || options.duration;
5320	effect.duration = $.fx.off ? 0 :
5321		typeof speed === "number" ? speed :
5322		speed in $.fx.speeds ? $.fx.speeds[ speed ] :
5323		$.fx.speeds._default;
5324
5325	effect.complete = callback || options.complete;
5326
5327	return effect;
5328}
5329
5330function standardSpeed( speed ) {
5331	// valid standard speeds
5332	if ( !speed || typeof speed === "number" || $.fx.speeds[ speed ] ) {
5333		return true;
5334	}
5335
5336	// invalid strings - treat as "normal" speed
5337	if ( typeof speed === "string" && !$.effects.effect[ speed ] ) {
5338		// TODO: remove in 2.0 (#7115)
5339		if ( backCompat && $.effects[ speed ] ) {
5340			return false;
5341		}
5342		return true;
5343	}
5344
5345	return false;
5346}
5347
5348$.fn.extend({
5349	effect: function( /* effect, options, speed, callback */ ) {
5350		var args = _normalizeArguments.apply( this, arguments ),
5351			mode = args.mode,
5352			queue = args.queue,
5353			effectMethod = $.effects.effect[ args.effect ],
5354
5355			// DEPRECATED: remove in 2.0 (#7115)
5356			oldEffectMethod = !effectMethod && backCompat && $.effects[ args.effect ];
5357
5358		if ( $.fx.off || !( effectMethod || oldEffectMethod ) ) {
5359			// delegate to the original method (e.g., .show()) if possible
5360			if ( mode ) {
5361				return this[ mode ]( args.duration, args.complete );
5362			} else {
5363				return this.each( function() {
5364					if ( args.complete ) {
5365						args.complete.call( this );
5366					}
5367				});
5368			}
5369		}
5370
5371		function run( next ) {
5372			var elem = $( this ),
5373				complete = args.complete,
5374				mode = args.mode;
5375
5376			function done() {
5377				if ( $.isFunction( complete ) ) {
5378					complete.call( elem[0] );
5379				}
5380				if ( $.isFunction( next ) ) {
5381					next();
5382				}
5383			}
5384
5385			// if the element is hiddden and mode is hide,
5386			// or element is visible and mode is show
5387			if ( elem.is( ":hidden" ) ? mode === "hide" : mode === "show" ) {
5388				done();
5389			} else {
5390				effectMethod.call( elem[0], args, done );
5391			}
5392		}
5393
5394		// TODO: remove this check in 2.0, effectMethod will always be true
5395		if ( effectMethod ) {
5396			return queue === false ? this.each( run ) : this.queue( queue || "fx", run );
5397		} else {
5398			// DEPRECATED: remove in 2.0 (#7115)
5399			return oldEffectMethod.call(this, {
5400				options: args,
5401				duration: args.duration,
5402				callback: args.complete,
5403				mode: args.mode
5404			});
5405		}
5406	},
5407
5408	_show: $.fn.show,
5409	show: function( speed ) {
5410		if ( standardSpeed( speed ) ) {
5411			return this._show.apply( this, arguments );
5412		} else {
5413			var args = _normalizeArguments.apply( this, arguments );
5414			args.mode = "show";
5415			return this.effect.call( this, args );
5416		}
5417	},
5418
5419	_hide: $.fn.hide,
5420	hide: function( speed ) {
5421		if ( standardSpeed( speed ) ) {
5422			return this._hide.apply( this, arguments );
5423		} else {
5424			var args = _normalizeArguments.apply( this, arguments );
5425			args.mode = "hide";
5426			return this.effect.call( this, args );
5427		}
5428	},
5429
5430	// jQuery core overloads toggle and creates _toggle
5431	__toggle: $.fn.toggle,
5432	toggle: function( speed ) {
5433		if ( standardSpeed( speed ) || typeof speed === "boolean" || $.isFunction( speed ) ) {
5434			return this.__toggle.apply( this, arguments );
5435		} else {
5436			var args = _normalizeArguments.apply( this, arguments );
5437			args.mode = "toggle";
5438			return this.effect.call( this, args );
5439		}
5440	},
5441
5442	// helper functions
5443	cssUnit: function(key) {
5444		var style = this.css( key ),
5445			val = [];
5446
5447		$.each( [ "em", "px", "%", "pt" ], function( i, unit ) {
5448			if ( style.indexOf( unit ) > 0 ) {
5449				val = [ parseFloat( style ), unit ];
5450			}
5451		});
5452		return val;
5453	}
5454});
5455
5456})();
5457
5458/******************************************************************************/
5459/*********************************** EASING ***********************************/
5460/******************************************************************************/
5461
5462(function() {
5463
5464// based on easing equations from Robert Penner (http://www.robertpenner.com/easing)
5465
5466var baseEasings = {};
5467
5468$.each( [ "Quad", "Cubic", "Quart", "Quint", "Expo" ], function( i, name ) {
5469	baseEasings[ name ] = function( p ) {
5470		return Math.pow( p, i + 2 );
5471	};
5472});
5473
5474$.extend( baseEasings, {
5475	Sine: function ( p ) {
5476		return 1 - Math.cos( p * Math.PI / 2 );
5477	},
5478	Circ: function ( p ) {
5479		return 1 - Math.sqrt( 1 - p * p );
5480	},
5481	Elastic: function( p ) {
5482		return p === 0 || p === 1 ? p :
5483			-Math.pow( 2, 8 * (p - 1) ) * Math.sin( ( (p - 1) * 80 - 7.5 ) * Math.PI / 15 );
5484	},
5485	Back: function( p ) {
5486		return p * p * ( 3 * p - 2 );
5487	},
5488	Bounce: function ( p ) {
5489		var pow2,
5490			bounce = 4;
5491
5492		while ( p < ( ( pow2 = Math.pow( 2, --bounce ) ) - 1 ) / 11 ) {}
5493		return 1 / Math.pow( 4, 3 - bounce ) - 7.5625 * Math.pow( ( pow2 * 3 - 2 ) / 22 - p, 2 );
5494	}
5495});
5496
5497$.each( baseEasings, function( name, easeIn ) {
5498	$.easing[ "easeIn" + name ] = easeIn;
5499	$.easing[ "easeOut" + name ] = function( p ) {
5500		return 1 - easeIn( 1 - p );
5501	};
vendor: 6,279 bytes, lines 5502-5746
5502	$.easing[ "easeInOut" + name ] = function( p ) {
5503		return p < 0.5 ?
5504			easeIn( p * 2 ) / 2 :
5505			1 - easeIn( p * -2 + 2 ) / 2;
5506	};
5507});
5508
5509})();
5510
5511})(jQuery));
5512
5513(function( $, undefined ) {
5514
5515var uid = 0,
5516	hideProps = {},
5517	showProps = {};
5518
5519hideProps.height = hideProps.paddingTop = hideProps.paddingBottom =
5520	hideProps.borderTopWidth = hideProps.borderBottomWidth = "hide";
5521showProps.height = showProps.paddingTop = showProps.paddingBottom =
5522	showProps.borderTopWidth = showProps.borderBottomWidth = "show";
5523
5524$.widget( "ui.accordion", {
5525	version: "1.9.2",
5526	options: {
5527		active: 0,
5528		animate: {},
5529		collapsible: false,
5530		event: "click",
5531		header: "> li > :first-child,> :not(li):even",
5532		heightStyle: "auto",
5533		icons: {
5534			activeHeader: "ui-icon-triangle-1-s",
5535			header: "ui-icon-triangle-1-e"
5536		},
5537
5538		// callbacks
5539		activate: null,
5540		beforeActivate: null
5541	},
5542
5543	_create: function() {
5544		var accordionId = this.accordionId = "ui-accordion-" +
5545				(this.element.attr( "id" ) || ++uid),
5546			options = this.options;
5547
5548		this.prevShow = this.prevHide = $();
5549		this.element.addClass( "ui-accordion ui-widget ui-helper-reset" );
5550
5551		this.headers = this.element.find( options.header )
5552			.addClass( "ui-accordion-header ui-helper-reset ui-state-default ui-corner-all" );
5553		this._hoverable( this.headers );
5554		this._focusable( this.headers );
5555
5556		this.headers.next()
5557			.addClass( "ui-accordion-content ui-helper-reset ui-widget-content ui-corner-bottom" )
5558			.hide();
5559
5560		// don't allow collapsible: false and active: false / null
5561		if ( !options.collapsible && (options.active === false || options.active == null) ) {
5562			options.active = 0;
5563		}
5564		// handle negative values
5565		if ( options.active < 0 ) {
5566			options.active += this.headers.length;
5567		}
5568		this.active = this._findActive( options.active )
5569			.addClass( "ui-accordion-header-active ui-state-active" )
5570			.toggleClass( "ui-corner-all ui-corner-top" );
5571		this.active.next()
5572			.addClass( "ui-accordion-content-active" )
5573			.show();
5574
5575		this._createIcons();
5576		this.refresh();
5577
5578		// ARIA
5579		this.element.attr( "role", "tablist" );
5580
5581		this.headers
5582			.attr( "role", "tab" )
5583			.each(function( i ) {
5584				var header = $( this ),
5585					headerId = header.attr( "id" ),
5586					panel = header.next(),
5587					panelId = panel.attr( "id" );
5588				if ( !headerId ) {
5589					headerId = accordionId + "-header-" + i;
5590					header.attr( "id", headerId );
5591				}
5592				if ( !panelId ) {
5593					panelId = accordionId + "-panel-" + i;
5594					panel.attr( "id", panelId );
5595				}
5596				header.attr( "aria-controls", panelId );
5597				panel.attr( "aria-labelledby", headerId );
5598			})
5599			.next()
5600				.attr( "role", "tabpanel" );
5601
5602		this.headers
5603			.not( this.active )
5604			.attr({
5605				"aria-selected": "false",
5606				tabIndex: -1
5607			})
5608			.next()
5609				.attr({
5610					"aria-expanded": "false",
5611					"aria-hidden": "true"
5612				})
5613				.hide();
5614
5615		// make sure at least one header is in the tab order
5616		if ( !this.active.length ) {
5617			this.headers.eq( 0 ).attr( "tabIndex", 0 );
5618		} else {
5619			this.active.attr({
5620				"aria-selected": "true",
5621				tabIndex: 0
5622			})
5623			.next()
5624				.attr({
5625					"aria-expanded": "true",
5626					"aria-hidden": "false"
5627				});
5628		}
5629
5630		this._on( this.headers, { keydown: "_keydown" });
5631		this._on( this.headers.next(), { keydown: "_panelKeyDown" });
5632		this._setupEvents( options.event );
5633	},
5634
5635	_getCreateEventData: function() {
5636		return {
5637			header: this.active,
5638			content: !this.active.length ? $() : this.active.next()
5639		};
5640	},
5641
5642	_createIcons: function() {
5643		var icons = this.options.icons;
5644		if ( icons ) {
5645			$( "<span>" )
5646				.addClass( "ui-accordion-header-icon ui-icon " + icons.header )
5647				.prependTo( this.headers );
5648			this.active.children( ".ui-accordion-header-icon" )
5649				.removeClass( icons.header )
5650				.addClass( icons.activeHeader );
5651			this.headers.addClass( "ui-accordion-icons" );
5652		}
5653	},
5654
5655	_destroyIcons: function() {
5656		this.headers
5657			.removeClass( "ui-accordion-icons" )
5658			.children( ".ui-accordion-header-icon" )
5659				.remove();
5660	},
5661
5662	_destroy: function() {
5663		var contents;
5664
5665		// clean up main element
5666		this.element
5667			.removeClass( "ui-accordion ui-widget ui-helper-reset" )
5668			.removeAttr( "role" );
5669
5670		// clean up headers
5671		this.headers
5672			.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" )
5673			.removeAttr( "role" )
5674			.removeAttr( "aria-selected" )
5675			.removeAttr( "aria-controls" )
5676			.removeAttr( "tabIndex" )
5677			.each(function() {
5678				if ( /^ui-accordion/.test( this.id ) ) {
5679					this.removeAttribute( "id" );
5680				}
5681			});
5682		this._destroyIcons();
5683
5684		// clean up content panels
5685		contents = this.headers.next()
5686			.css( "display", "" )
5687			.removeAttr( "role" )
5688			.removeAttr( "aria-expanded" )
5689			.removeAttr( "aria-hidden" )
5690			.removeAttr( "aria-labelledby" )
5691			.removeClass( "ui-helper-reset ui-widget-content ui-corner-bottom ui-accordion-content ui-accordion-content-active ui-state-disabled" )
5692			.each(function() {
5693				if ( /^ui-accordion/.test( this.id ) ) {
5694					this.removeAttribute( "id" );
5695				}
5696			});
5697		if ( this.options.heightStyle !== "content" ) {
5698			contents.css( "height", "" );
5699		}
5700	},
5701
5702	_setOption: function( key, value ) {
5703		if ( key === "active" ) {
5704			// _activate() will handle invalid values and update this.options
5705			this._activate( value );
5706			return;
5707		}
5708
5709		if ( key === "event" ) {
5710			if ( this.options.event ) {
5711				this._off( this.headers, this.options.event );
5712			}
5713			this._setupEvents( value );
5714		}
5715
5716		this._super( key, value );
5717
5718		// setting collapsible: false while collapsed; open first panel
5719		if ( key === "collapsible" && !value && this.options.active === false ) {
5720			this._activate( 0 );
5721		}
5722
5723		if ( key === "icons" ) {
5724			this._destroyIcons();
5725			if ( value ) {
5726				this._createIcons();
5727			}
5728		}
5729
5730		// #5332 - opacity doesn't cascade to positioned elements in IE
5731		// so we need to add the disabled class to the headers and panels
5732		if ( key === "disabled" ) {
5733			this.headers.add( this.headers.next() )
5734				.toggleClass( "ui-state-disabled", !!value );
5735		}
5736	},
5737
5738	_keydown: function( event ) {
5739		if ( event.altKey || event.ctrlKey ) {
5740			return;
5741		}
5742
5743		var keyCode = $.ui.keyCode,
5744			length = this.headers.length,
5745			currentIndex = this.headers.index( event.target ),
5746			toFocus = false;
vendor: 4,224 bytes, lines 5747-5902
5747
5748		switch ( event.keyCode ) {
5749			case keyCode.RIGHT:
5750			case keyCode.DOWN:
5751				toFocus = this.headers[ ( currentIndex + 1 ) % length ];
5752				break;
5753			case keyCode.LEFT:
5754			case keyCode.UP:
5755				toFocus = this.headers[ ( currentIndex - 1 + length ) % length ];
5756				break;
5757			case keyCode.SPACE:
5758			case keyCode.ENTER:
5759				this._eventHandler( event );
5760				break;
5761			case keyCode.HOME:
5762				toFocus = this.headers[ 0 ];
5763				break;
5764			case keyCode.END:
5765				toFocus = this.headers[ length - 1 ];
5766				break;
5767		}
5768
5769		if ( toFocus ) {
5770			$( event.target ).attr( "tabIndex", -1 );
5771			$( toFocus ).attr( "tabIndex", 0 );
5772			toFocus.focus();
5773			event.preventDefault();
5774		}
5775	},
5776
5777	_panelKeyDown : function( event ) {
5778		if ( event.keyCode === $.ui.keyCode.UP && event.ctrlKey ) {
5779			$( event.currentTarget ).prev().focus();
5780		}
5781	},
5782
5783	refresh: function() {
5784		var maxHeight, overflow,
5785			heightStyle = this.options.heightStyle,
5786			parent = this.element.parent();
5787
5788
5789		if ( heightStyle === "fill" ) {
5790			// IE 6 treats height like minHeight, so we need to turn off overflow
5791			// in order to get a reliable height
5792			// we use the minHeight support test because we assume that only
5793			// browsers that don't support minHeight will treat height as minHeight
5794			if ( !$.support.minHeight ) {
5795				overflow = parent.css( "overflow" );
5796				parent.css( "overflow", "hidden");
5797			}
5798			maxHeight = parent.height();
5799			this.element.siblings( ":visible" ).each(function() {
5800				var elem = $( this ),
5801					position = elem.css( "position" );
5802
5803				if ( position === "absolute" || position === "fixed" ) {
5804					return;
5805				}
5806				maxHeight -= elem.outerHeight( true );
5807			});
5808			if ( overflow ) {
5809				parent.css( "overflow", overflow );
5810			}
5811
5812			this.headers.each(function() {
5813				maxHeight -= $( this ).outerHeight( true );
5814			});
5815
5816			this.headers.next()
5817				.each(function() {
5818					$( this ).height( Math.max( 0, maxHeight -
5819						$( this ).innerHeight() + $( this ).height() ) );
5820				})
5821				.css( "overflow", "auto" );
5822		} else if ( heightStyle === "auto" ) {
5823			maxHeight = 0;
5824			this.headers.next()
5825				.each(function() {
5826					maxHeight = Math.max( maxHeight, $( this ).css( "height", "" ).height() );
5827				})
5828				.height( maxHeight );
5829		}
5830	},
5831
5832	_activate: function( index ) {
5833		var active = this._findActive( index )[ 0 ];
5834
5835		// trying to activate the already active panel
5836		if ( active === this.active[ 0 ] ) {
5837			return;
5838		}
5839
5840		// trying to collapse, simulate a click on the currently active header
5841		active = active || this.active[ 0 ];
5842
5843		this._eventHandler({
5844			target: active,
5845			currentTarget: active,
5846			preventDefault: $.noop
5847		});
5848	},
5849
5850	_findActive: function( selector ) {
5851		return typeof selector === "number" ? this.headers.eq( selector ) : $();
5852	},
5853
5854	_setupEvents: function( event ) {
5855		var events = {};
5856		if ( !event ) {
5857			return;
5858		}
5859		$.each( event.split(" "), function( index, eventName ) {
5860			events[ eventName ] = "_eventHandler";
5861		});
5862		this._on( this.headers, events );
5863	},
5864
5865	_eventHandler: function( event ) {
5866		var options = this.options,
5867			active = this.active,
5868			clicked = $( event.currentTarget ),
5869			clickedIsActive = clicked[ 0 ] === active[ 0 ],
5870			collapsing = clickedIsActive && options.collapsible,
5871			toShow = collapsing ? $() : clicked.next(),
5872			toHide = active.next(),
5873			eventData = {
5874				oldHeader: active,
5875				oldPanel: toHide,
5876				newHeader: collapsing ? $() : clicked,
5877				newPanel: toShow
5878			};
5879
5880		event.preventDefault();
5881
5882		if (
5883				// click on active header, but not collapsible
5884				( clickedIsActive && !options.collapsible ) ||
5885				// allow canceling activation
5886				( this._trigger( "beforeActivate", event, eventData ) === false ) ) {
5887			return;
5888		}
5889
5890		options.active = collapsing ? false : this.headers.index( clicked );
5891
5892		// when the call to ._toggle() comes after the class changes
5893		// it causes a very odd bug in IE 8 (see #6720)
5894		this.active = clickedIsActive ? $() : clicked;
5895		this._toggle( eventData );
5896
5897		// switch classes
5898		// corner classes on the previously active header stay after the animation
5899		active.removeClass( "ui-accordion-header-active ui-state-active" );
5900		if ( options.icons ) {
5901			active.children( ".ui-accordion-header-icon" )
5902				.removeClass( options.icons.activeHeader )
5903				.addClass( options.icons.header );
5904		}
5905
5906		if ( !clickedIsActive ) {
5907			clicked
5908				.removeClass( "ui-corner-all" )
5909				.addClass( "ui-accordion-header-active ui-state-active ui-corner-top" );
5910			if ( options.icons ) {
5911				clicked.children( ".ui-accordion-header-icon" )
5912					.removeClass( options.icons.header )
5913					.addClass( options.icons.activeHeader );
5914			}
5915
5916			clicked
5917				.next()
5918				.addClass( "ui-accordion-content-active" );
5919		}
5920	},
5921
5922	_toggle: function( data ) {
5923		var toShow = data.newPanel,
5924			toHide = this.prevShow.length ? this.prevShow : data.oldPanel;
5925
5926		// handle activating a panel during the animation for another activation
5927		this.prevShow.add( this.prevHide ).stop( true, true );
5928		this.prevShow = toShow;
5929		this.prevHide = toHide;
5930
5931		if ( this.options.animate ) {
5932			this._animate( toShow, toHide, data );
5933		} else {
5934			toHide.hide();
5935			toShow.show();
5936			this._toggleComplete( data );
5937		}
5938
5939		toHide.attr({
5940			"aria-expanded": "false",
5941			"aria-hidden": "true"
5942		});
5943		toHide.prev().attr( "aria-selected", "false" );
5944		// if we're switching panels, remove the old header from the tab order
5945		// if we're opening from collapsed state, remove the previous header from the tab order
5946		// if we're collapsing, then keep the collapsing header in the tab order
5947		if ( toShow.length && toHide.length ) {
5948			toHide.prev().attr( "tabIndex", -1 );
5949		} else if ( toShow.length ) {
5950			this.headers.filter(function() {
5951				return $( this ).attr( "tabIndex" ) === 0;
5952			})
5953			.attr( "tabIndex", -1 );
5954		}
5955
5956		toShow
5957			.attr({
5958				"aria-expanded": "true",
5959				"aria-hidden": "false"
5960			})
5961			.prev()
5962				.attr({
5963					"aria-selected": "true",
5964					tabIndex: 0
5965				});
5966	},
5967
5968	_animate: function( toShow, toHide, data ) {
5969		var total, easing, duration,
5970			that = this,
5971			adjust = 0,
5972			down = toShow.length &&
5973				( !toHide.length || ( toShow.index() < toHide.index() ) ),
5974			animate = this.options.animate || {},
5975			options = down && animate.down || animate,
5976			complete = function() {
5977				that._toggleComplete( data );
5978			};
5979
5980		if ( typeof options === "number" ) {
5981			duration = options;
5982		}
5983		if ( typeof options === "string" ) {
5984			easing = options;
5985		}
5986		// fall back from options to animation in case of partial down settings
5987		easing = easing || options.easing || animate.easing;
5988		duration = duration || options.duration || animate.duration;
5989
5990		if ( !toHide.length ) {
5991			return toShow.animate( showProps, duration, easing, complete );
5992		}
5993		if ( !toShow.length ) {
5994			return toHide.animate( hideProps, duration, easing, complete );
5995		}
5996
5997		total = toShow.show().outerHeight();
5998		toHide.animate( hideProps, {
5999			duration: duration,
6000			easing: easing,
6001			step: function( now, fx ) {
6002				fx.now = Math.round( now );
6003			}
6004		});
6005		toShow
6006			.hide()
6007			.animate( showProps, {
6008				duration: duration,
6009				easing: easing,
6010				complete: complete,
6011				step: function( now, fx ) {
6012					fx.now = Math.round( now );
6013					if ( fx.prop !== "height" ) {
6014						adjust += fx.now;
6015					} else if ( that.options.heightStyle !== "content" ) {
6016						fx.now = Math.round( total - toHide.outerHeight() - adjust );
6017						adjust = 0;
6018					}
6019				}
6020			});
6021	},
6022
6023	_toggleComplete: function( data ) {
6024		var toHide = data.oldPanel;
6025
6026		toHide
6027			.removeClass( "ui-accordion-content-active" )
6028			.prev()
6029				.removeClass( "ui-corner-top" )
6030				.addClass( "ui-corner-all" );
6031
6032		// Work around for rendering bug in IE (#5421)
6033		if ( toHide.length ) {
6034			toHide.parent()[0].className = toHide.parent()[0].className;
6035		}
6036
6037		this._trigger( "activate", null, data );
6038	}
6039});
6040
6041
6042
6043// DEPRECATED
6044if ( $.uiBackCompat !== false ) {
6045	// navigation options
6046	(function( $, prototype ) {
6047		$.extend( prototype.options, {
6048			navigation: false,
6049			navigationFilter: function() {
6050				return this.href.toLowerCase() === location.href.toLowerCase();
6051			}
6052		});
6053
6054		var _create = prototype._create;
6055		prototype._create = function() {
6056			if ( this.options.navigation ) {
6057				var that = this,
6058					headers = this.element.find( this.options.header ),
6059					content = headers.next(),
6060					current = headers.add( content )
6061						.find( "a" )
6062						.filter( this.options.navigationFilter )
6063						[ 0 ];
6064				if ( current ) {
6065					headers.add( content ).each( function( index ) {
6066						if ( $.contains( this, current ) ) {
6067							that.options.active = Math.floor( index / 2 );
6068							return false;
6069						}
6070					});
6071				}
6072			}
6073			_create.call( this );
6074		};
6075	}( jQuery, jQuery.ui.accordion.prototype ) );
6076
6077	// height options
6078	(function( $, prototype ) {
6079		$.extend( prototype.options, {
6080			heightStyle: null, // remove default so we fall back to old values
6081			autoHeight: true, // use heightStyle: "auto"
6082			clearStyle: false, // use heightStyle: "content"
6083			fillSpace: false // use heightStyle: "fill"
6084		});
6085
6086		var _create = prototype._create,
6087			_setOption = prototype._setOption;
6088
6089		$.extend( prototype, {
6090			_create: function() {
6091				this.options.heightStyle = this.options.heightStyle ||
6092					this._mergeHeightStyle();
6093
6094				_create.call( this );
6095			},
6096
6097			_setOption: function( key ) {
6098				if ( key === "autoHeight" || key === "clearStyle" || key === "fillSpace" ) {
6099					this.options.heightStyle = this._mergeHeightStyle();
6100				}
6101				_setOption.apply( this, arguments );
6102			},
6103
6104			_mergeHeightStyle: function() {
6105				var options = this.options;
6106
6107				if ( options.fillSpace ) {
6108					return "fill";
6109				}
6110
6111				if ( options.clearStyle ) {
6112					return "content";
6113				}
6114
6115				if ( options.autoHeight ) {
6116					return "auto";
6117				}
6118			}
6119		});
6120	}( jQuery, jQuery.ui.accordion.prototype ) );
6121
6122	// icon options
6123	(function( $, prototype ) {
6124		$.extend( prototype.options.icons, {
6125			activeHeader: null, // remove default so we fall back to old values
6126			headerSelected: "ui-icon-triangle-1-s"
6127		});
6128
6129		var _createIcons = prototype._createIcons;
6130		prototype._createIcons = function() {
6131			if ( this.options.icons ) {
6132				this.options.icons.activeHeader = this.options.icons.activeHeader ||
6133					this.options.icons.headerSelected;
6134			}
6135			_createIcons.call( this );
6136		};
6137	}( jQuery, jQuery.ui.accordion.prototype ) );
6138
6139	// expanded active option, activate method
6140	(function( $, prototype ) {
6141		prototype.activate = prototype._activate;
6142
6143		var _findActive = prototype._findActive;
6144		prototype._findActive = function( index ) {
6145			if ( index === -1 ) {
6146				index = false;
6147			}
6148			if ( index && typeof index !== "number" ) {
6149				index = this.headers.index( this.headers.filter( index ) );
6150				if ( index === -1 ) {
6151					index = false;
6152				}
6153			}
6154			return _findActive.call( this, index );
6155		};
6156	}( jQuery, jQuery.ui.accordion.prototype ) );
6157
6158	// resize method
6159	jQuery.ui.accordion.prototype.resize = jQuery.ui.accordion.prototype.refresh;
6160
6161	// change events
6162	(function( $, prototype ) {
6163		$.extend( prototype.options, {
6164			change: null,
6165			changestart: null
6166		});
6167
6168		var _trigger = prototype._trigger;
6169		prototype._trigger = function( type, event, data ) {
6170			var ret = _trigger.apply( this, arguments );
6171			if ( !ret ) {
6172				return false;
6173			}
6174
6175			if ( type === "beforeActivate" ) {
6176				ret = _trigger.call( this, "changestart", event, {
6177					oldHeader: data.oldHeader,
6178					oldContent: data.oldPanel,
6179					newHeader: data.newHeader,
6180					newContent: data.newPanel
6181				});
6182			} else if ( type === "activate" ) {
6183				ret = _trigger.call( this, "change", event, {
6184					oldHeader: data.oldHeader,
6185					oldContent: data.oldPanel,
6186					newHeader: data.newHeader,
6187					newContent: data.newPanel
6188				});
6189			}
6190			return ret;
6191		};
6192	}( jQuery, jQuery.ui.accordion.prototype ) );
6193
6194	// animated option
6195	// NOTE: this only provides support for "slide", "bounceslide", and easings
6196	// not the full $.ui.accordion.animations API
6197	(function( $, prototype ) {
6198		$.extend( prototype.options, {
6199			animate: null,
6200			animated: "slide"
6201		});
6202
6203		var _create = prototype._create;
6204		prototype._create = function() {
6205			var options = this.options;
6206			if ( options.animate === null ) {
6207				if ( !options.animated ) {
6208					options.animate = false;
6209				} else if ( options.animated === "slide" ) {
6210					options.animate = 300;
6211				} else if ( options.animated === "bounceslide" ) {
6212					options.animate = {
6213						duration: 200,
6214						down: {
6215							easing: "easeOutBounce",
6216							duration: 1000
6217						}
6218					};
6219				} else {
6220					options.animate = options.animated;
6221				}
6222			}
6223
6224			_create.call( this );
6225		};
6226	}( jQuery, jQuery.ui.accordion.prototype ) );
6227}
6228
6229})( jQuery );
6230
6231(function( $, undefined ) {
6232
6233// used to prevent race conditions with remote data sources
6234var requestIndex = 0;
6235
6236$.widget( "ui.autocomplete", {
6237	version: "1.9.2",
6238	defaultElement: "<input>",
6239	options: {
6240		appendTo: "body",
6241		autoFocus: false,
6242		delay: 300,
6243		minLength: 1,
6244		position: {
6245			my: "left top",
6246			at: "left bottom",
6247			collision: "none"
6248		},
6249		source: null,
6250
6251		// callbacks
6252		change: null,
6253		close: null,
6254		focus: null,
6255		open: null,
6256		response: null,
6257		search: null,
6258		select: null
6259	},
6260
6261	pending: 0,
6262
6263	_create: function() {
6264		// Some browsers only repeat keydown events, not keypress events,
6265		// so we use the suppressKeyPress flag to determine if we've already
6266		// handled the keydown event. #7269
6267		// Unfortunately the code for & in keypress is the same as the up arrow,
6268		// so we use the suppressKeyPressRepeat flag to avoid handling keypress
6269		// events when we know the keydown event was used to modify the
6270		// search term. #7799
6271		var suppressKeyPress, suppressKeyPressRepeat, suppressInput;
6272
6273		this.isMultiLine = this._isMultiLine();
6274		this.valueMethod = this.element[ this.element.is( "input,textarea" ) ? "val" : "text" ];
6275		this.isNewMenu = true;
6276
6277		this.element
6278			.addClass( "ui-autocomplete-input" )
6279			.attr( "autocomplete", "off" );
6280
6281		this._on( this.element, {
6282			keydown: function( event ) {
6283				if ( this.element.prop( "readOnly" ) ) {
6284					suppressKeyPress = true;
6285					suppressInput = true;
6286					suppressKeyPressRepeat = true;
6287					return;
6288				}
6289
6290				suppressKeyPress = false;
vendor: 21,657 bytes, lines 6291-7070
6291				suppressInput = false;
6292				suppressKeyPressRepeat = false;
6293				var keyCode = $.ui.keyCode;
6294				switch( event.keyCode ) {
6295				case keyCode.PAGE_UP:
6296					suppressKeyPress = true;
6297					this._move( "previousPage", event );
6298					break;
6299				case keyCode.PAGE_DOWN:
6300					suppressKeyPress = true;
6301					this._move( "nextPage", event );
6302					break;
6303				case keyCode.UP:
6304					suppressKeyPress = true;
6305					this._keyEvent( "previous", event );
6306					break;
6307				case keyCode.DOWN:
6308					suppressKeyPress = true;
6309					this._keyEvent( "next", event );
6310					break;
6311				case keyCode.ENTER:
6312				case keyCode.NUMPAD_ENTER:
6313					// when menu is open and has focus
6314					if ( this.menu.active ) {
6315						// #6055 - Opera still allows the keypress to occur
6316						// which causes forms to submit
6317						suppressKeyPress = true;
6318						event.preventDefault();
6319						this.menu.select( event );
6320					}
6321					break;
6322				case keyCode.TAB:
6323					if ( this.menu.active ) {
6324						this.menu.select( event );
6325					}
6326					break;
6327				case keyCode.ESCAPE:
6328					if ( this.menu.element.is( ":visible" ) ) {
6329						this._value( this.term );
6330						this.close( event );
6331						// Different browsers have different default behavior for escape
6332						// Single press can mean undo or clear
6333						// Double press in IE means clear the whole form
6334						event.preventDefault();
6335					}
6336					break;
6337				default:
6338					suppressKeyPressRepeat = true;
6339					// search timeout should be triggered before the input value is changed
6340					this._searchTimeout( event );
6341					break;
6342				}
6343			},
6344			keypress: function( event ) {
6345				if ( suppressKeyPress ) {
6346					suppressKeyPress = false;
6347					event.preventDefault();
6348					return;
6349				}
6350				if ( suppressKeyPressRepeat ) {
6351					return;
6352				}
6353
6354				// replicate some key handlers to allow them to repeat in Firefox and Opera
6355				var keyCode = $.ui.keyCode;
6356				switch( event.keyCode ) {
6357				case keyCode.PAGE_UP:
6358					this._move( "previousPage", event );
6359					break;
6360				case keyCode.PAGE_DOWN:
6361					this._move( "nextPage", event );
6362					break;
6363				case keyCode.UP:
6364					this._keyEvent( "previous", event );
6365					break;
6366				case keyCode.DOWN:
6367					this._keyEvent( "next", event );
6368					break;
6369				}
6370			},
6371			input: function( event ) {
6372				if ( suppressInput ) {
6373					suppressInput = false;
6374					event.preventDefault();
6375					return;
6376				}
6377				this._searchTimeout( event );
6378			},
6379			focus: function() {
6380				this.selectedItem = null;
6381				this.previous = this._value();
6382			},
6383			blur: function( event ) {
6384				if ( this.cancelBlur ) {
6385					delete this.cancelBlur;
6386					return;
6387				}
6388
6389				clearTimeout( this.searching );
6390				this.close( event );
6391				this._change( event );
6392			}
6393		});
6394
6395		this._initSource();
6396		this.menu = $( "<ul>" )
6397			.addClass( "ui-autocomplete" )
6398			.appendTo( this.document.find( this.options.appendTo || "body" )[ 0 ] )
6399			.menu({
6400				// custom key handling for now
6401				input: $(),
6402				// disable ARIA support, the live region takes care of that
6403				role: null
6404			})
6405			.zIndex( this.element.zIndex() + 1 )
6406			.hide()
6407			.data( "menu" );
6408
6409		this._on( this.menu.element, {
6410			mousedown: function( event ) {
6411				// prevent moving focus out of the text field
6412				event.preventDefault();
6413
6414				// IE doesn't prevent moving focus even with event.preventDefault()
6415				// so we set a flag to know when we should ignore the blur event
6416				this.cancelBlur = true;
6417				this._delay(function() {
6418					delete this.cancelBlur;
6419				});
6420
6421				// clicking on the scrollbar causes focus to shift to the body
6422				// but we can't detect a mouseup or a click immediately afterward
6423				// so we have to track the next mousedown and close the menu if
6424				// the user clicks somewhere outside of the autocomplete
6425				var menuElement = this.menu.element[ 0 ];
6426				if ( !$( event.target ).closest( ".ui-menu-item" ).length ) {
6427					this._delay(function() {
6428						var that = this;
6429						this.document.one( "mousedown", function( event ) {
6430							if ( event.target !== that.element[ 0 ] &&
6431									event.target !== menuElement &&
6432									!$.contains( menuElement, event.target ) ) {
6433								that.close();
6434							}
6435						});
6436					});
6437				}
6438			},
6439			menufocus: function( event, ui ) {
6440				// #7024 - Prevent accidental activation of menu items in Firefox
6441				if ( this.isNewMenu ) {
6442					this.isNewMenu = false;
6443					if ( event.originalEvent && /^mouse/.test( event.originalEvent.type ) ) {
6444						this.menu.blur();
6445
6446						this.document.one( "mousemove", function() {
6447							$( event.target ).trigger( event.originalEvent );
6448						});
6449
6450						return;
6451					}
6452				}
6453
6454				// back compat for _renderItem using item.autocomplete, via #7810
6455				// TODO remove the fallback, see #8156
6456				var item = ui.item.data( "ui-autocomplete-item" ) || ui.item.data( "item.autocomplete" );
6457				if ( false !== this._trigger( "focus", event, { item: item } ) ) {
6458					// use value to match what will end up in the input, if it was a key event
6459					if ( event.originalEvent && /^key/.test( event.originalEvent.type ) ) {
6460						this._value( item.value );
6461					}
6462				} else {
6463					// Normally the input is populated with the item's value as the
6464					// menu is navigated, causing screen readers to notice a change and
6465					// announce the item. Since the focus event was canceled, this doesn't
6466					// happen, so we update the live region so that screen readers can
6467					// still notice the change and announce it.
6468					this.liveRegion.text( item.value );
6469				}
6470			},
6471			menuselect: function( event, ui ) {
6472				// back compat for _renderItem using item.autocomplete, via #7810
6473				// TODO remove the fallback, see #8156
6474				var item = ui.item.data( "ui-autocomplete-item" ) || ui.item.data( "item.autocomplete" ),
6475					previous = this.previous;
6476
6477				// only trigger when focus was lost (click on menu)
6478				if ( this.element[0] !== this.document[0].activeElement ) {
6479					this.element.focus();
6480					this.previous = previous;
6481					// #6109 - IE triggers two focus events and the second
6482					// is asynchronous, so we need to reset the previous
6483					// term synchronously and asynchronously :-(
6484					this._delay(function() {
6485						this.previous = previous;
6486						this.selectedItem = item;
6487					});
6488				}
6489
6490				if ( false !== this._trigger( "select", event, { item: item } ) ) {
6491					this._value( item.value );
6492				}
6493				// reset the term after the select event
6494				// this allows custom select handling to work properly
6495				this.term = this._value();
6496
6497				this.close( event );
6498				this.selectedItem = item;
6499			}
6500		});
6501
6502		this.liveRegion = $( "<span>", {
6503				role: "status",
6504				"aria-live": "polite"
6505			})
6506			.addClass( "ui-helper-hidden-accessible" )
6507			.insertAfter( this.element );
6508
6509		if ( $.fn.bgiframe ) {
6510			this.menu.element.bgiframe();
6511		}
6512
6513		// turning off autocomplete prevents the browser from remembering the
6514		// value when navigating through history, so we re-enable autocomplete
6515		// if the page is unloaded before the widget is destroyed. #7790
6516		this._on( this.window, {
6517			beforeunload: function() {
6518				this.element.removeAttr( "autocomplete" );
6519			}
6520		});
6521	},
6522
6523	_destroy: function() {
6524		clearTimeout( this.searching );
6525		this.element
6526			.removeClass( "ui-autocomplete-input" )
6527			.removeAttr( "autocomplete" );
6528		this.menu.element.remove();
6529		this.liveRegion.remove();
6530	},
6531
6532	_setOption: function( key, value ) {
6533		this._super( key, value );
6534		if ( key === "source" ) {
6535			this._initSource();
6536		}
6537		if ( key === "appendTo" ) {
6538			this.menu.element.appendTo( this.document.find( value || "body" )[0] );
6539		}
6540		if ( key === "disabled" && value && this.xhr ) {
6541			this.xhr.abort();
6542		}
6543	},
6544
6545	_isMultiLine: function() {
6546		// Textareas are always multi-line
6547		if ( this.element.is( "textarea" ) ) {
6548			return true;
6549		}
6550		// Inputs are always single-line, even if inside a contentEditable element
6551		// IE also treats inputs as contentEditable
6552		if ( this.element.is( "input" ) ) {
6553			return false;
6554		}
6555		// All other element types are determined by whether or not they're contentEditable
6556		return this.element.prop( "isContentEditable" );
6557	},
6558
6559	_initSource: function() {
6560		var array, url,
6561			that = this;
6562		if ( $.isArray(this.options.source) ) {
6563			array = this.options.source;
6564			this.source = function( request, response ) {
6565				response( $.ui.autocomplete.filter( array, request.term ) );
6566			};
6567		} else if ( typeof this.options.source === "string" ) {
6568			url = this.options.source;
6569			this.source = function( request, response ) {
6570				if ( that.xhr ) {
6571					that.xhr.abort();
6572				}
6573				that.xhr = $.ajax({
6574					url: url,
6575					data: request,
6576					dataType: "json",
6577					success: function( data ) {
6578						response( data );
6579					},
6580					error: function() {
6581						response( [] );
6582					}
6583				});
6584			};
6585		} else {
6586			this.source = this.options.source;
6587		}
6588	},
6589
6590	_searchTimeout: function( event ) {
6591		clearTimeout( this.searching );
6592		this.searching = this._delay(function() {
6593			// only search if the value has changed
6594			if ( this.term !== this._value() ) {
6595				this.selectedItem = null;
6596				this.search( null, event );
6597			}
6598		}, this.options.delay );
6599	},
6600
6601	search: function( value, event ) {
6602		value = value != null ? value : this._value();
6603
6604		// always save the actual value, not the one passed as an argument
6605		this.term = this._value();
6606
6607		if ( value.length < this.options.minLength ) {
6608			return this.close( event );
6609		}
6610
6611		if ( this._trigger( "search", event ) === false ) {
6612			return;
6613		}
6614
6615		return this._search( value );
6616	},
6617
6618	_search: function( value ) {
6619		this.pending++;
6620		this.element.addClass( "ui-autocomplete-loading" );
6621		this.cancelSearch = false;
6622
6623		this.source( { term: value }, this._response() );
6624	},
6625
6626	_response: function() {
6627		var that = this,
6628			index = ++requestIndex;
6629
6630		return function( content ) {
6631			if ( index === requestIndex ) {
6632				that.__response( content );
6633			}
6634
6635			that.pending--;
6636			if ( !that.pending ) {
6637				that.element.removeClass( "ui-autocomplete-loading" );
6638			}
6639		};
6640	},
6641
6642	__response: function( content ) {
6643		if ( content ) {
6644			content = this._normalize( content );
6645		}
6646		this._trigger( "response", null, { content: content } );
6647		if ( !this.options.disabled && content && content.length && !this.cancelSearch ) {
6648			this._suggest( content );
6649			this._trigger( "open" );
6650		} else {
6651			// use ._close() instead of .close() so we don't cancel future searches
6652			this._close();
6653		}
6654	},
6655
6656	close: function( event ) {
6657		this.cancelSearch = true;
6658		this._close( event );
6659	},
6660
6661	_close: function( event ) {
6662		if ( this.menu.element.is( ":visible" ) ) {
6663			this.menu.element.hide();
6664			this.menu.blur();
6665			this.isNewMenu = true;
6666			this._trigger( "close", event );
6667		}
6668	},
6669
6670	_change: function( event ) {
6671		if ( this.previous !== this._value() ) {
6672			this._trigger( "change", event, { item: this.selectedItem } );
6673		}
6674	},
6675
6676	_normalize: function( items ) {
6677		// assume all items have the right format when the first item is complete
6678		if ( items.length && items[0].label && items[0].value ) {
6679			return items;
6680		}
6681		return $.map( items, function( item ) {
6682			if ( typeof item === "string" ) {
6683				return {
6684					label: item,
6685					value: item
6686				};
6687			}
6688			return $.extend({
6689				label: item.label || item.value,
6690				value: item.value || item.label
6691			}, item );
6692		});
6693	},
6694
6695	_suggest: function( items ) {
6696		var ul = this.menu.element
6697			.empty()
6698			.zIndex( this.element.zIndex() + 1 );
6699		this._renderMenu( ul, items );
6700		this.menu.refresh();
6701
6702		// size and position menu
6703		ul.show();
6704		this._resizeMenu();
6705		ul.position( $.extend({
6706			of: this.element
6707		}, this.options.position ));
6708
6709		if ( this.options.autoFocus ) {
6710			this.menu.next();
6711		}
6712	},
6713
6714	_resizeMenu: function() {
6715		var ul = this.menu.element;
6716		ul.outerWidth( Math.max(
6717			// Firefox wraps long text (possibly a rounding bug)
6718			// so we add 1px to avoid the wrapping (#7513)
6719			ul.width( "" ).outerWidth() + 1,
6720			this.element.outerWidth()
6721		) );
6722	},
6723
6724	_renderMenu: function( ul, items ) {
6725		var that = this;
6726		$.each( items, function( index, item ) {
6727			that._renderItemData( ul, item );
6728		});
6729	},
6730
6731	_renderItemData: function( ul, item ) {
6732		return this._renderItem( ul, item ).data( "ui-autocomplete-item", item );
6733	},
6734
6735	_renderItem: function( ul, item ) {
6736		return $( "<li>" )
6737			.append( $( "<a>" ).text( item.label ) )
6738			.appendTo( ul );
6739	},
6740
6741	_move: function( direction, event ) {
6742		if ( !this.menu.element.is( ":visible" ) ) {
6743			this.search( null, event );
6744			return;
6745		}
6746		if ( this.menu.isFirstItem() && /^previous/.test( direction ) ||
6747				this.menu.isLastItem() && /^next/.test( direction ) ) {
6748			this._value( this.term );
6749			this.menu.blur();
6750			return;
6751		}
6752		this.menu[ direction ]( event );
6753	},
6754
6755	widget: function() {
6756		return this.menu.element;
6757	},
6758
6759	_value: function() {
6760		return this.valueMethod.apply( this.element, arguments );
6761	},
6762
6763	_keyEvent: function( keyEvent, event ) {
6764		if ( !this.isMultiLine || this.menu.element.is( ":visible" ) ) {
6765			this._move( keyEvent, event );
6766
6767			// prevents moving cursor to beginning/end of the text field in some browsers
6768			event.preventDefault();
6769		}
6770	}
6771});
6772
6773$.extend( $.ui.autocomplete, {
6774	escapeRegex: function( value ) {
6775		return value.replace(/[\-\[\]{}()*+?.,\\\^$|#\s]/g, "\\$&");
6776	},
6777	filter: function(array, term) {
6778		var matcher = new RegExp( $.ui.autocomplete.escapeRegex(term), "i" );
6779		return $.grep( array, function(value) {
6780			return matcher.test( value.label || value.value || value );
6781		});
6782	}
6783});
6784
6785
6786// live region extension, adding a `messages` option
6787// NOTE: This is an experimental API. We are still investigating
6788// a full solution for string manipulation and internationalization.
6789$.widget( "ui.autocomplete", $.ui.autocomplete, {
6790	options: {
6791		messages: {
6792			noResults: "No search results.",
6793			results: function( amount ) {
6794				return amount + ( amount > 1 ? " results are" : " result is" ) +
6795					" available, use up and down arrow keys to navigate.";
6796			}
6797		}
6798	},
6799
6800	__response: function( content ) {
6801		var message;
6802		this._superApply( arguments );
6803		if ( this.options.disabled || this.cancelSearch ) {
6804			return;
6805		}
6806		if ( content && content.length ) {
6807			message = this.options.messages.results( content.length );
6808		} else {
6809			message = this.options.messages.noResults;
6810		}
6811		this.liveRegion.text( message );
6812	}
6813});
6814
6815
6816}( jQuery ));
6817
6818(function( $, undefined ) {
6819
6820var lastActive, startXPos, startYPos, clickDragged,
6821	baseClasses = "ui-button ui-widget ui-state-default ui-corner-all",
6822	stateClasses = "ui-state-hover ui-state-active ",
6823	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",
6824	formResetHandler = function() {
6825		var buttons = $( this ).find( ":ui-button" );
6826		setTimeout(function() {
6827			buttons.button( "refresh" );
6828		}, 1 );
6829	},
6830	radioGroup = function( radio ) {
6831		var name = radio.name,
6832			form = radio.form,
6833			radios = $( [] );
6834		if ( name ) {
6835			if ( form ) {
6836				radios = $( form ).find( "[name='" + name + "']" );
6837			} else {
6838				radios = $( "[name='" + name + "']", radio.ownerDocument )
6839					.filter(function() {
6840						return !this.form;
6841					});
6842			}
6843		}
6844		return radios;
6845	};
6846
6847$.widget( "ui.button", {
6848	version: "1.9.2",
6849	defaultElement: "<button>",
6850	options: {
6851		disabled: null,
6852		text: true,
6853		label: null,
6854		icons: {
6855			primary: null,
6856			secondary: null
6857		}
6858	},
6859	_create: function() {
6860		this.element.closest( "form" )
6861			.unbind( "reset" + this.eventNamespace )
6862			.bind( "reset" + this.eventNamespace, formResetHandler );
6863
6864		if ( typeof this.options.disabled !== "boolean" ) {
6865			this.options.disabled = !!this.element.prop( "disabled" );
6866		} else {
6867			this.element.prop( "disabled", this.options.disabled );
6868		}
6869
6870		this._determineButtonType();
6871		this.hasTitle = !!this.buttonElement.attr( "title" );
6872
6873		var that = this,
6874			options = this.options,
6875			toggleButton = this.type === "checkbox" || this.type === "radio",
6876			activeClass = !toggleButton ? "ui-state-active" : "",
6877			focusClass = "ui-state-focus";
6878
6879		if ( options.label === null ) {
6880			options.label = (this.type === "input" ? this.buttonElement.val() : this.buttonElement.html());
6881		}
6882
6883		this._hoverable( this.buttonElement );
6884
6885		this.buttonElement
6886			.addClass( baseClasses )
6887			.attr( "role", "button" )
6888			.bind( "mouseenter" + this.eventNamespace, function() {
6889				if ( options.disabled ) {
6890					return;
6891				}
6892				if ( this === lastActive ) {
6893					$( this ).addClass( "ui-state-active" );
6894				}
6895			})
6896			.bind( "mouseleave" + this.eventNamespace, function() {
6897				if ( options.disabled ) {
6898					return;
6899				}
6900				$( this ).removeClass( activeClass );
6901			})
6902			.bind( "click" + this.eventNamespace, function( event ) {
6903				if ( options.disabled ) {
6904					event.preventDefault();
6905					event.stopImmediatePropagation();
6906				}
6907			});
6908
6909		this.element
6910			.bind( "focus" + this.eventNamespace, function() {
6911				// no need to check disabled, focus won't be triggered anyway
6912				that.buttonElement.addClass( focusClass );
6913			})
6914			.bind( "blur" + this.eventNamespace, function() {
6915				that.buttonElement.removeClass( focusClass );
6916			});
6917
6918		if ( toggleButton ) {
6919			this.element.bind( "change" + this.eventNamespace, function() {
6920				if ( clickDragged ) {
6921					return;
6922				}
6923				that.refresh();
6924			});
6925			// if mouse moves between mousedown and mouseup (drag) set clickDragged flag
6926			// prevents issue where button state changes but checkbox/radio checked state
6927			// does not in Firefox (see ticket #6970)
6928			this.buttonElement
6929				.bind( "mousedown" + this.eventNamespace, function( event ) {
6930					if ( options.disabled ) {
6931						return;
6932					}
6933					clickDragged = false;
6934					startXPos = event.pageX;
6935					startYPos = event.pageY;
6936				})
6937				.bind( "mouseup" + this.eventNamespace, function( event ) {
6938					if ( options.disabled ) {
6939						return;
6940					}
6941					if ( startXPos !== event.pageX || startYPos !== event.pageY ) {
6942						clickDragged = true;
6943					}
6944			});
6945		}
6946
6947		if ( this.type === "checkbox" ) {
6948			this.buttonElement.bind( "click" + this.eventNamespace, function() {
6949				if ( options.disabled || clickDragged ) {
6950					return false;
6951				}
6952				$( this ).toggleClass( "ui-state-active" );
6953				that.buttonElement.attr( "aria-pressed", that.element[0].checked );
6954			});
6955		} else if ( this.type === "radio" ) {
6956			this.buttonElement.bind( "click" + this.eventNamespace, function() {
6957				if ( options.disabled || clickDragged ) {
6958					return false;
6959				}
6960				$( this ).addClass( "ui-state-active" );
6961				that.buttonElement.attr( "aria-pressed", "true" );
6962
6963				var radio = that.element[ 0 ];
6964				radioGroup( radio )
6965					.not( radio )
6966					.map(function() {
6967						return $( this ).button( "widget" )[ 0 ];
6968					})
6969					.removeClass( "ui-state-active" )
6970					.attr( "aria-pressed", "false" );
6971			});
6972		} else {
6973			this.buttonElement
6974				.bind( "mousedown" + this.eventNamespace, function() {
6975					if ( options.disabled ) {
6976						return false;
6977					}
6978					$( this ).addClass( "ui-state-active" );
6979					lastActive = this;
6980					that.document.one( "mouseup", function() {
6981						lastActive = null;
6982					});
6983				})
6984				.bind( "mouseup" + this.eventNamespace, function() {
6985					if ( options.disabled ) {
6986						return false;
6987					}
6988					$( this ).removeClass( "ui-state-active" );
6989				})
6990				.bind( "keydown" + this.eventNamespace, function(event) {
6991					if ( options.disabled ) {
6992						return false;
6993					}
6994					if ( event.keyCode === $.ui.keyCode.SPACE || event.keyCode === $.ui.keyCode.ENTER ) {
6995						$( this ).addClass( "ui-state-active" );
6996					}
6997				})
6998				.bind( "keyup" + this.eventNamespace, function() {
6999					$( this ).removeClass( "ui-state-active" );
7000				});
7001
7002			if ( this.buttonElement.is("a") ) {
7003				this.buttonElement.keyup(function(event) {
7004					if ( event.keyCode === $.ui.keyCode.SPACE ) {
7005						// TODO pass through original event correctly (just as 2nd argument doesn't work)
7006						$( this ).click();
7007					}
7008				});
7009			}
7010		}
7011
7012		// TODO: pull out $.Widget's handling for the disabled option into
7013		// $.Widget.prototype._setOptionDisabled so it's easy to proxy and can
7014		// be overridden by individual plugins
7015		this._setOption( "disabled", options.disabled );
7016		this._resetButton();
7017	},
7018
7019	_determineButtonType: function() {
7020		var ancestor, labelSelector, checked;
7021
7022		if ( this.element.is("[type=checkbox]") ) {
7023			this.type = "checkbox";
7024		} else if ( this.element.is("[type=radio]") ) {
7025			this.type = "radio";
7026		} else if ( this.element.is("input") ) {
7027			this.type = "input";
7028		} else {
7029			this.type = "button";
7030		}
7031
7032		if ( this.type === "checkbox" || this.type === "radio" ) {
7033			// we don't search against the document in case the element
7034			// is disconnected from the DOM
7035			ancestor = this.element.parents().last();
7036			labelSelector = "label[for='" + this.element.attr("id") + "']";
7037			this.buttonElement = ancestor.find( labelSelector );
7038			if ( !this.buttonElement.length ) {
7039				ancestor = ancestor.length ? ancestor.siblings() : this.element.siblings();
7040				this.buttonElement = ancestor.filter( labelSelector );
7041				if ( !this.buttonElement.length ) {
7042					this.buttonElement = ancestor.find( labelSelector );
7043				}
7044			}
7045			this.element.addClass( "ui-helper-hidden-accessible" );
7046
7047			checked = this.element.is( ":checked" );
7048			if ( checked ) {
7049				this.buttonElement.addClass( "ui-state-active" );
7050			}
7051			this.buttonElement.prop( "aria-pressed", checked );
7052		} else {
7053			this.buttonElement = this.element;
7054		}
7055	},
7056
7057	widget: function() {
7058		return this.buttonElement;
7059	},
7060
7061	_destroy: function() {
7062		this.element
7063			.removeClass( "ui-helper-hidden-accessible" );
7064		this.buttonElement
7065			.removeClass( baseClasses + " " + stateClasses + " " + typeClasses )
7066			.removeAttr( "role" )
7067			.removeAttr( "aria-pressed" )
7068			.html( this.buttonElement.find(".ui-button-text").html() );
7069
7070		if ( !this.hasTitle ) {
vendor: 6,498 bytes, lines 7071-7262
7071			this.buttonElement.removeAttr( "title" );
7072		}
7073	},
7074
7075	_setOption: function( key, value ) {
7076		this._super( key, value );
7077		if ( key === "disabled" ) {
7078			if ( value ) {
7079				this.element.prop( "disabled", true );
7080			} else {
7081				this.element.prop( "disabled", false );
7082			}
7083			return;
7084		}
7085		this._resetButton();
7086	},
7087
7088	refresh: function() {
7089		//See #8237 & #8828
7090		var isDisabled = this.element.is( "input, button" ) ? this.element.is( ":disabled" ) : this.element.hasClass( "ui-button-disabled" );
7091
7092		if ( isDisabled !== this.options.disabled ) {
7093			this._setOption( "disabled", isDisabled );
7094		}
7095		if ( this.type === "radio" ) {
7096			radioGroup( this.element[0] ).each(function() {
7097				if ( $( this ).is( ":checked" ) ) {
7098					$( this ).button( "widget" )
7099						.addClass( "ui-state-active" )
7100						.attr( "aria-pressed", "true" );
7101				} else {
7102					$( this ).button( "widget" )
7103						.removeClass( "ui-state-active" )
7104						.attr( "aria-pressed", "false" );
7105				}
7106			});
7107		} else if ( this.type === "checkbox" ) {
7108			if ( this.element.is( ":checked" ) ) {
7109				this.buttonElement
7110					.addClass( "ui-state-active" )
7111					.attr( "aria-pressed", "true" );
7112			} else {
7113				this.buttonElement
7114					.removeClass( "ui-state-active" )
7115					.attr( "aria-pressed", "false" );
7116			}
7117		}
7118	},
7119
7120	_resetButton: function() {
7121		if ( this.type === "input" ) {
7122			if ( this.options.label ) {
7123				this.element.val( this.options.label );
7124			}
7125			return;
7126		}
7127		var buttonElement = this.buttonElement.removeClass( typeClasses ),
7128			buttonText = $( "<span></span>", this.document[0] )
7129				.addClass( "ui-button-text" )
7130				.html( this.options.label )
7131				.appendTo( buttonElement.empty() )
7132				.text(),
7133			icons = this.options.icons,
7134			multipleIcons = icons.primary && icons.secondary,
7135			buttonClasses = [];
7136
7137		if ( icons.primary || icons.secondary ) {
7138			if ( this.options.text ) {
7139				buttonClasses.push( "ui-button-text-icon" + ( multipleIcons ? "s" : ( icons.primary ? "-primary" : "-secondary" ) ) );
7140			}
7141
7142			if ( icons.primary ) {
7143				buttonElement.prepend( "<span class='ui-button-icon-primary ui-icon " + icons.primary + "'></span>" );
7144			}
7145
7146			if ( icons.secondary ) {
7147				buttonElement.append( "<span class='ui-button-icon-secondary ui-icon " + icons.secondary + "'></span>" );
7148			}
7149
7150			if ( !this.options.text ) {
7151				buttonClasses.push( multipleIcons ? "ui-button-icons-only" : "ui-button-icon-only" );
7152
7153				if ( !this.hasTitle ) {
7154					buttonElement.attr( "title", $.trim( buttonText ) );
7155				}
7156			}
7157		} else {
7158			buttonClasses.push( "ui-button-text-only" );
7159		}
7160		buttonElement.addClass( buttonClasses.join( " " ) );
7161	}
7162});
7163
7164$.widget( "ui.buttonset", {
7165	version: "1.9.2",
7166	options: {
7167		items: "button, input[type=button], input[type=submit], input[type=reset], input[type=checkbox], input[type=radio], a, :data(button)"
7168	},
7169
7170	_create: function() {
7171		this.element.addClass( "ui-buttonset" );
7172	},
7173
7174	_init: function() {
7175		this.refresh();
7176	},
7177
7178	_setOption: function( key, value ) {
7179		if ( key === "disabled" ) {
7180			this.buttons.button( "option", key, value );
7181		}
7182
7183		this._super( key, value );
7184	},
7185
7186	refresh: function() {
7187		var rtl = this.element.css( "direction" ) === "rtl";
7188
7189		this.buttons = this.element.find( this.options.items )
7190			.filter( ":ui-button" )
7191				.button( "refresh" )
7192			.end()
7193			.not( ":ui-button" )
7194				.button()
7195			.end()
7196			.map(function() {
7197				return $( this ).button( "widget" )[ 0 ];
7198			})
7199				.removeClass( "ui-corner-all ui-corner-left ui-corner-right" )
7200				.filter( ":first" )
7201					.addClass( rtl ? "ui-corner-right" : "ui-corner-left" )
7202				.end()
7203				.filter( ":last" )
7204					.addClass( rtl ? "ui-corner-left" : "ui-corner-right" )
7205				.end()
7206			.end();
7207	},
7208
7209	_destroy: function() {
7210		this.element.removeClass( "ui-buttonset" );
7211		this.buttons
7212			.map(function() {
7213				return $( this ).button( "widget" )[ 0 ];
7214			})
7215				.removeClass( "ui-corner-left ui-corner-right" )
7216			.end()
7217			.button( "destroy" );
7218	}
7219});
7220
7221}( jQuery ) );
7222
7223(function( $, undefined ) {
7224
7225$.extend($.ui, { datepicker: { version: "1.9.2" } });
7226
7227var PROP_NAME = 'datepicker';
7228var dpuuid = new Date().getTime();
7229var instActive;
7230
7231/* Date picker manager.
7232   Use the singleton instance of this class, $.datepicker, to interact with the date picker.
7233   Settings for (groups of) date pickers are maintained in an instance object,
7234   allowing multiple different settings on the same page. */
7235
7236function Datepicker() {
7237	this.debug = false; // Change this to true to start debugging
7238	this._curInst = null; // The current instance in use
7239	this._keyEvent = false; // If the last event was a key event
7240	this._disabledInputs = []; // List of date picker inputs that have been disabled
7241	this._datepickerShowing = false; // True if the popup picker is showing , false if not
7242	this._inDialog = false; // True if showing within a "dialog", false if not
7243	this._mainDivId = 'ui-datepicker-div'; // The ID of the main datepicker division
7244	this._inlineClass = 'ui-datepicker-inline'; // The name of the inline marker class
7245	this._appendClass = 'ui-datepicker-append'; // The name of the append marker class
7246	this._triggerClass = 'ui-datepicker-trigger'; // The name of the trigger marker class
7247	this._dialogClass = 'ui-datepicker-dialog'; // The name of the dialog marker class
7248	this._disableClass = 'ui-datepicker-disabled'; // The name of the disabled covering marker class
7249	this._unselectableClass = 'ui-datepicker-unselectable'; // The name of the unselectable cell marker class
7250	this._currentClass = 'ui-datepicker-current-day'; // The name of the current day marker class
7251	this._dayOverClass = 'ui-datepicker-days-cell-over'; // The name of the day hover marker class
7252	this.regional = []; // Available regional settings, indexed by language code
7253	this.regional[''] = { // Default regional settings
7254		closeText: 'Done', // Display text for close link
7255		prevText: 'Prev', // Display text for previous month link
7256		nextText: 'Next', // Display text for next month link
7257		currentText: 'Today', // Display text for current month link
7258		monthNames: ['January','February','March','April','May','June',
7259			'July','August','September','October','November','December'], // Names of months for drop-down and formatting
7260		monthNamesShort: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'], // For formatting
7261		dayNames: ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'], // For formatting
7262		dayNamesShort: ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'], // For formatting
vendor: 5,556 bytes, lines 7263-7360
7263		dayNamesMin: ['Su','Mo','Tu','We','Th','Fr','Sa'], // Column headings for days starting at Sunday
7264		weekHeader: 'Wk', // Column header for week of the year
7265		dateFormat: 'mm/dd/yy', // See format options on parseDate
7266		firstDay: 0, // The first day of the week, Sun = 0, Mon = 1, ...
7267		isRTL: false, // True if right-to-left language, false if left-to-right
7268		showMonthAfterYear: false, // True if the year select precedes month, false for month then year
7269		yearSuffix: '' // Additional text to append to the year in the month headers
7270	};
7271	this._defaults = { // Global defaults for all the date picker instances
7272		showOn: 'focus', // 'focus' for popup on focus,
7273			// 'button' for trigger button, or 'both' for either
7274		showAnim: 'fadeIn', // Name of jQuery animation for popup
7275		showOptions: {}, // Options for enhanced animations
7276		defaultDate: null, // Used when field is blank: actual date,
7277			// +/-number for offset from today, null for today
7278		appendText: '', // Display text following the input box, e.g. showing the format
7279		buttonText: '...', // Text for trigger button
7280		buttonImage: '', // URL for trigger button image
7281		buttonImageOnly: false, // True if the image appears alone, false if it appears on a button
7282		hideIfNoPrevNext: false, // True to hide next/previous month links
7283			// if not applicable, false to just disable them
7284		navigationAsDateFormat: false, // True if date formatting applied to prev/today/next links
7285		gotoCurrent: false, // True if today link goes back to current selection instead
7286		changeMonth: false, // True if month can be selected directly, false if only prev/next
7287		changeYear: false, // True if year can be selected directly, false if only prev/next
7288		yearRange: 'c-10:c+10', // Range of years to display in drop-down,
7289			// either relative to today's year (-nn:+nn), relative to currently displayed year
7290			// (c-nn:c+nn), absolute (nnnn:nnnn), or a combination of the above (nnnn:-n)
7291		showOtherMonths: false, // True to show dates in other months, false to leave blank
7292		selectOtherMonths: false, // True to allow selection of dates in other months, false for unselectable
7293		showWeek: false, // True to show week of the year, false to not show it
7294		calculateWeek: this.iso8601Week, // How to calculate the week of the year,
7295			// takes a Date and returns the number of the week for it
7296		shortYearCutoff: '+10', // Short year values < this are in the current century,
7297			// > this are in the previous century,
7298			// string value starting with '+' for current year + value
7299		minDate: null, // The earliest selectable date, or null for no limit
7300		maxDate: null, // The latest selectable date, or null for no limit
7301		duration: 'fast', // Duration of display/closure
7302		beforeShowDay: null, // Function that takes a date and returns an array with
7303			// [0] = true if selectable, false if not, [1] = custom CSS class name(s) or '',
7304			// [2] = cell title (optional), e.g. $.datepicker.noWeekends
7305		beforeShow: null, // Function that takes an input field and
7306			// returns a set of custom settings for the date picker
7307		onSelect: null, // Define a callback function when a date is selected
7308		onChangeMonthYear: null, // Define a callback function when the month or year is changed
7309		onClose: null, // Define a callback function when the datepicker is closed
7310		numberOfMonths: 1, // Number of months to show at a time
7311		showCurrentAtPos: 0, // The position in multipe months at which to show the current month (starting at 0)
7312		stepMonths: 1, // Number of months to step back/forward
7313		stepBigMonths: 12, // Number of months to step back/forward for the big links
7314		altField: '', // Selector for an alternate field to store selected dates into
7315		altFormat: '', // The date format to use for the alternate field
7316		constrainInput: true, // The input is constrained by the current date format
7317		showButtonPanel: false, // True to show button panel, false to not show it
7318		autoSize: false, // True to size the input for the date format, false to leave as is
7319		disabled: false // The initial disabled state
7320	};
7321	$.extend(this._defaults, this.regional['']);
7322	this.dpDiv = bindHover($('<div id="' + this._mainDivId + '" class="ui-datepicker ui-widget ui-widget-content ui-helper-clearfix ui-corner-all"></div>'));
7323}
7324
7325$.extend(Datepicker.prototype, {
7326	/* Class name added to elements to indicate already configured with a date picker. */
7327	markerClassName: 'hasDatepicker',
7328
7329	//Keep track of the maximum number of rows displayed (see #7043)
7330	maxRows: 4,
7331
7332	/* Debug logging (if enabled). */
7333	log: function () {
7334		if (this.debug)
7335			console.log.apply('', arguments);
7336	},
7337
7338	// TODO rename to "widget" when switching to widget factory
7339	_widgetDatepicker: function() {
7340		return this.dpDiv;
7341	},
7342
7343	/* Override the default settings for all instances of the date picker.
7344	   @param  settings  object - the new settings to use as defaults (anonymous object)
7345	   @return the manager object */
7346	setDefaults: function(settings) {
7347		extendRemove(this._defaults, settings || {});
7348		return this;
7349	},
7350
7351	/* Attach the date picker to a jQuery selection.
7352	   @param  target    element - the target input field or division or span
7353	   @param  settings  object - the new settings to use for this date picker instance (anonymous) */
7354	_attachDatepicker: function(target, settings) {
7355		// check for settings on the control itself - in namespace 'date:'
7356		var inlineSettings = null;
7357		for (var attrName in this._defaults) {
7358			var attrValue = target.getAttribute('date:' + attrName);
7359			if (attrValue) {
7360				inlineSettings = inlineSettings || {};
7361				try {
7362					inlineSettings[attrName] = eval(attrValue);
7363				} catch (err) {
7364					inlineSettings[attrName] = attrValue;
7365				}
7366			}
7367		}
7368		var nodeName = target.nodeName.toLowerCase();
7369		var inline = (nodeName == 'div' || nodeName == 'span');
7370		if (!target.id) {
7371			this.uuid += 1;
7372			target.id = 'dp' + this.uuid;
7373		}
7374		var inst = this._newInst($(target), inline);
7375		inst.settings = $.extend({}, settings || {}, inlineSettings || {});
7376		if (nodeName == 'input') {
7377			this._connectDatepicker(target, inst);
7378		} else if (inline) {
7379			this._inlineDatepicker(target, inst);
7380		}
7381	},
7382
7383	/* Create a new instance object. */
7384	_newInst: function(target, inline) {
7385		var id = target[0].id.replace(/([^A-Za-z0-9_-])/g, '\\\\$1'); // escape jQuery meta chars
7386		return {id: id, input: target, // associated target
7387			selectedDay: 0, selectedMonth: 0, selectedYear: 0, // current selection
7388			drawMonth: 0, drawYear: 0, // month being drawn
7389			inline: inline, // is datepicker inline or not
7390			dpDiv: (!inline ? this.dpDiv : // presentation div
7391			bindHover($('<div class="' + this._inlineClass + ' ui-datepicker ui-widget ui-widget-content ui-helper-clearfix ui-corner-all"></div>')))};
7392	},
7393
7394	/* Attach the date picker to an input field. */
7395	_connectDatepicker: function(target, inst) {
7396		var input = $(target);
7397		inst.append = $([]);
7398		inst.trigger = $([]);
7399		if (input.hasClass(this.markerClassName))
7400			return;
7401		this._attachments(input, inst);
7402		input.addClass(this.markerClassName).keydown(this._doKeyDown).
7403			keypress(this._doKeyPress).keyup(this._doKeyUp).
7404			bind("setData.datepicker", function(event, key, value) {
7405				inst.settings[key] = value;
7406			}).bind("getData.datepicker", function(event, key) {
7407				return this._get(inst, key);
7408			});
7409		this._autoSize(inst);
7410		$.data(target, PROP_NAME, inst);
7411		//If disabled option is true, disable the datepicker once it has been attached to the input (see ticket #5665)
7412		if( inst.settings.disabled ) {
7413			this._disableDatepicker( target );
7414		}
7415	},
7416
7417	/* Make attachments based on settings. */
7418	_attachments: function(input, inst) {
7419		var appendText = this._get(inst, 'appendText');
7420		var isRTL = this._get(inst, 'isRTL');
7421		if (inst.append)
7422			inst.append.remove();
7423		if (appendText) {
7424			inst.append = $('<span class="' + this._appendClass + '">' + appendText + '</span>');
7425			input[isRTL ? 'before' : 'after'](inst.append);
7426		}
7427		input.unbind('focus', this._showDatepicker);
7428		if (inst.trigger)
7429			inst.trigger.remove();
7430		var showOn = this._get(inst, 'showOn');
7431		if (showOn == 'focus' || showOn == 'both') // pop-up date picker when in the marked field
7432			input.focus(this._showDatepicker);
7433		if (showOn == 'button' || showOn == 'both') { // pop-up date picker when button clicked
7434			var buttonText = this._get(inst, 'buttonText');
7435			var buttonImage = this._get(inst, 'buttonImage');
7436			inst.trigger = $(this._get(inst, 'buttonImageOnly') ?
7437				$('<img/>').addClass(this._triggerClass).
7438					attr({ src: buttonImage, alt: buttonText, title: buttonText }) :
7439				$('<button type="button"></button>').addClass(this._triggerClass).
7440					html(buttonImage == '' ? buttonText : $('<img/>').attr(
7441					{ src:buttonImage, alt:buttonText, title:buttonText })));
7442			input[isRTL ? 'before' : 'after'](inst.trigger);
7443			inst.trigger.click(function() {
7444				if ($.datepicker._datepickerShowing && $.datepicker._lastInput == input[0])
7445					$.datepicker._hideDatepicker();
7446				else if ($.datepicker._datepickerShowing && $.datepicker._lastInput != input[0]) {
7447					$.datepicker._hideDatepicker();
7448					$.datepicker._showDatepicker(input[0]);
7449				} else
7450					$.datepicker._showDatepicker(input[0]);
7451				return false;
7452			});
7453		}
7454	},
7455
7456	/* Apply the maximum length for the date format. */
7457	_autoSize: function(inst) {
7458		if (this._get(inst, 'autoSize') && !inst.inline) {
7459			var date = new Date(2009, 12 - 1, 20); // Ensure double digits
7460			var dateFormat = this._get(inst, 'dateFormat');
7461			if (dateFormat.match(/[DM]/)) {
7462				var findMax = function(names) {
7463					var max = 0;
7464					var maxI = 0;
7465					for (var i = 0; i < names.length; i++) {
7466						if (names[i].length > max) {
7467							max = names[i].length;
7468							maxI = i;
7469						}
7470					}
vendor: 4,711 bytes, lines 7471-7586
7471					return maxI;
7472				};
7473				date.setMonth(findMax(this._get(inst, (dateFormat.match(/MM/) ?
7474					'monthNames' : 'monthNamesShort'))));
7475				date.setDate(findMax(this._get(inst, (dateFormat.match(/DD/) ?
7476					'dayNames' : 'dayNamesShort'))) + 20 - date.getDay());
7477			}
7478			inst.input.attr('size', this._formatDate(inst, date).length);
7479		}
7480	},
7481
7482	/* Attach an inline date picker to a div. */
7483	_inlineDatepicker: function(target, inst) {
7484		var divSpan = $(target);
7485		if (divSpan.hasClass(this.markerClassName))
7486			return;
7487		divSpan.addClass(this.markerClassName).append(inst.dpDiv).
7488			bind("setData.datepicker", function(event, key, value){
7489				inst.settings[key] = value;
7490			}).bind("getData.datepicker", function(event, key){
7491				return this._get(inst, key);
7492			});
7493		$.data(target, PROP_NAME, inst);
7494		this._setDate(inst, this._getDefaultDate(inst), true);
7495		this._updateDatepicker(inst);
7496		this._updateAlternate(inst);
7497		//If disabled option is true, disable the datepicker before showing it (see ticket #5665)
7498		if( inst.settings.disabled ) {
7499			this._disableDatepicker( target );
7500		}
7501		// Set display:block in place of inst.dpDiv.show() which won't work on disconnected elements
7502		// http://bugs.jqueryui.com/ticket/7552 - A Datepicker created on a detached div has zero height
7503		inst.dpDiv.css( "display", "block" );
7504	},
7505
7506	/* Pop-up the date picker in a "dialog" box.
7507	   @param  input     element - ignored
7508	   @param  date      string or Date - the initial date to display
7509	   @param  onSelect  function - the function to call when a date is selected
7510	   @param  settings  object - update the dialog date picker instance's settings (anonymous object)
7511	   @param  pos       int[2] - coordinates for the dialog's position within the screen or
7512	                     event - with x/y coordinates or
7513	                     leave empty for default (screen centre)
7514	   @return the manager object */
7515	_dialogDatepicker: function(input, date, onSelect, settings, pos) {
7516		var inst = this._dialogInst; // internal instance
7517		if (!inst) {
7518			this.uuid += 1;
7519			var id = 'dp' + this.uuid;
7520			this._dialogInput = $('<input type="text" id="' + id +
7521				'" style="position: absolute; top: -100px; width: 0px;"/>');
7522			this._dialogInput.keydown(this._doKeyDown);
7523			$('body').append(this._dialogInput);
7524			inst = this._dialogInst = this._newInst(this._dialogInput, false);
7525			inst.settings = {};
7526			$.data(this._dialogInput[0], PROP_NAME, inst);
7527		}
7528		extendRemove(inst.settings, settings || {});
7529		date = (date && date.constructor == Date ? this._formatDate(inst, date) : date);
7530		this._dialogInput.val(date);
7531
7532		this._pos = (pos ? (pos.length ? pos : [pos.pageX, pos.pageY]) : null);
7533		if (!this._pos) {
7534			var browserWidth = document.documentElement.clientWidth;
7535			var browserHeight = document.documentElement.clientHeight;
7536			var scrollX = document.documentElement.scrollLeft || document.body.scrollLeft;
7537			var scrollY = document.documentElement.scrollTop || document.body.scrollTop;
7538			this._pos = // should use actual width/height below
7539				[(browserWidth / 2) - 100 + scrollX, (browserHeight / 2) - 150 + scrollY];
7540		}
7541
7542		// move input on screen for focus, but hidden behind dialog
7543		this._dialogInput.css('left', (this._pos[0] + 20) + 'px').css('top', this._pos[1] + 'px');
7544		inst.settings.onSelect = onSelect;
7545		this._inDialog = true;
7546		this.dpDiv.addClass(this._dialogClass);
7547		this._showDatepicker(this._dialogInput[0]);
7548		if ($.blockUI)
7549			$.blockUI(this.dpDiv);
7550		$.data(this._dialogInput[0], PROP_NAME, inst);
7551		return this;
7552	},
7553
7554	/* Detach a datepicker from its control.
7555	   @param  target    element - the target input field or division or span */
7556	_destroyDatepicker: function(target) {
7557		var $target = $(target);
7558		var inst = $.data(target, PROP_NAME);
7559		if (!$target.hasClass(this.markerClassName)) {
7560			return;
7561		}
7562		var nodeName = target.nodeName.toLowerCase();
7563		$.removeData(target, PROP_NAME);
7564		if (nodeName == 'input') {
7565			inst.append.remove();
7566			inst.trigger.remove();
7567			$target.removeClass(this.markerClassName).
7568				unbind('focus', this._showDatepicker).
7569				unbind('keydown', this._doKeyDown).
7570				unbind('keypress', this._doKeyPress).
7571				unbind('keyup', this._doKeyUp);
7572		} else if (nodeName == 'div' || nodeName == 'span')
7573			$target.removeClass(this.markerClassName).empty();
7574	},
7575
7576	/* Enable the date picker to a jQuery selection.
7577	   @param  target    element - the target input field or division or span */
7578	_enableDatepicker: function(target) {
7579		var $target = $(target);
7580		var inst = $.data(target, PROP_NAME);
7581		if (!$target.hasClass(this.markerClassName)) {
7582			return;
7583		}
7584		var nodeName = target.nodeName.toLowerCase();
7585		if (nodeName == 'input') {
7586			target.disabled = false;
7587			inst.trigger.filter('button').
7588				each(function() { this.disabled = false; }).end().
7589				filter('img').css({opacity: '1.0', cursor: ''});
7590		}
7591		else if (nodeName == 'div' || nodeName == 'span') {
7592			var inline = $target.children('.' + this._inlineClass);
7593			inline.children().removeClass('ui-state-disabled');
7594			inline.find("select.ui-datepicker-month, select.ui-datepicker-year").
7595				prop("disabled", false);
7596		}
7597		this._disabledInputs = $.map(this._disabledInputs,
7598			function(value) { return (value == target ? null : value); }); // delete entry
7599	},
7600
7601	/* Disable the date picker to a jQuery selection.
7602	   @param  target    element - the target input field or division or span */
7603	_disableDatepicker: function(target) {
7604		var $target = $(target);
7605		var inst = $.data(target, PROP_NAME);
7606		if (!$target.hasClass(this.markerClassName)) {
7607			return;
7608		}
7609		var nodeName = target.nodeName.toLowerCase();
7610		if (nodeName == 'input') {
7611			target.disabled = true;
7612			inst.trigger.filter('button').
7613				each(function() { this.disabled = true; }).end().
7614				filter('img').css({opacity: '0.5', cursor: 'default'});
7615		}
7616		else if (nodeName == 'div' || nodeName == 'span') {
7617			var inline = $target.children('.' + this._inlineClass);
7618			inline.children().addClass('ui-state-disabled');
7619			inline.find("select.ui-datepicker-month, select.ui-datepicker-year").
7620				prop("disabled", true);
7621		}
7622		this._disabledInputs = $.map(this._disabledInputs,
7623			function(value) { return (value == target ? null : value); }); // delete entry
7624		this._disabledInputs[this._disabledInputs.length] = target;
7625	},
7626
7627	/* Is the first field in a jQuery collection disabled as a datepicker?
7628	   @param  target    element - the target input field or division or span
7629	   @return boolean - true if disabled, false if enabled */
7630	_isDisabledDatepicker: function(target) {
7631		if (!target) {
7632			return false;
7633		}
7634		for (var i = 0; i < this._disabledInputs.length; i++) {
7635			if (this._disabledInputs[i] == target)
7636				return true;
7637		}
7638		return false;
7639	},
7640
7641	/* Retrieve the instance data for the target control.
7642	   @param  target  element - the target input field or division or span
7643	   @return  object - the associated instance data
7644	   @throws  error if a jQuery problem getting data */
7645	_getInst: function(target) {
7646		try {
7647			return $.data(target, PROP_NAME);
7648		}
7649		catch (err) {
7650			throw 'Missing instance data for this datepicker';
7651		}
7652	},
7653
7654	/* Update or retrieve the settings for a date picker attached to an input field or division.
7655	   @param  target  element - the target input field or division or span
7656	   @param  name    object - the new settings to update or
7657	                   string - the name of the setting to change or retrieve,
7658	                   when retrieving also 'all' for all instance settings or
7659	                   'defaults' for all global defaults
7660	   @param  value   any - the new value for the setting
7661	                   (omit if above is an object or to retrieve a value) */
7662	_optionDatepicker: function(target, name, value) {
7663		var inst = this._getInst(target);
7664		if (arguments.length == 2 && typeof name == 'string') {
7665			return (name == 'defaults' ? $.extend({}, $.datepicker._defaults) :
7666				(inst ? (name == 'all' ? $.extend({}, inst.settings) :
7667				this._get(inst, name)) : null));
7668		}
7669		var settings = name || {};
7670		if (typeof name == 'string') {
7671			settings = {};
7672			settings[name] = value;
7673		}
7674		if (inst) {
7675			if (this._curInst == inst) {
7676				this._hideDatepicker();
7677			}
7678			var date = this._getDateDatepicker(target, true);
7679			var minDate = this._getMinMaxDate(inst, 'min');
7680			var maxDate = this._getMinMaxDate(inst, 'max');
7681			extendRemove(inst.settings, settings);
7682			// reformat the old minDate/maxDate values if dateFormat changes and a new minDate/maxDate isn't provided
7683			if (minDate !== null && settings['dateFormat'] !== undefined && settings['minDate'] === undefined)
7684				inst.settings.minDate = this._formatDate(inst, minDate);
7685			if (maxDate !== null && settings['dateFormat'] !== undefined && settings['maxDate'] === undefined)
7686				inst.settings.maxDate = this._formatDate(inst, maxDate);
7687			this._attachments($(target), inst);
7688			this._autoSize(inst);
7689			this._setDate(inst, date);
7690			this._updateAlternate(inst);
7691			this._updateDatepicker(inst);
7692		}
7693	},
7694
7695	// change method deprecated
7696	_changeDatepicker: function(target, name, value) {
7697		this._optionDatepicker(target, name, value);
7698	},
7699
7700	/* Redraw the date picker attached to an input field or division.
7701	   @param  target  element - the target input field or division or span */
7702	_refreshDatepicker: function(target) {
7703		var inst = this._getInst(target);
7704		if (inst) {
7705			this._updateDatepicker(inst);
7706		}
7707	},
7708
7709	/* Set the dates for a jQuery selection.
7710	   @param  target   element - the target input field or division or span
7711	   @param  date     Date - the new date */
7712	_setDateDatepicker: function(target, date) {
7713		var inst = this._getInst(target);
7714		if (inst) {
7715			this._setDate(inst, date);
7716			this._updateDatepicker(inst);
7717			this._updateAlternate(inst);
7718		}
7719	},
7720
7721	/* Get the date(s) for the first entry in a jQuery selection.
7722	   @param  target     element - the target input field or division or span
7723	   @param  noDefault  boolean - true if no default date is to be used
7724	   @return Date - the current date */
7725	_getDateDatepicker: function(target, noDefault) {
7726		var inst = this._getInst(target);
7727		if (inst && !inst.inline)
7728			this._setDateFromField(inst, noDefault);
7729		return (inst ? this._getDate(inst) : null);
7730	},
7731
7732	/* Handle keystrokes. */
7733	_doKeyDown: function(event) {
7734		var inst = $.datepicker._getInst(event.target);
7735		var handled = true;
7736		var isRTL = inst.dpDiv.is('.ui-datepicker-rtl');
7737		inst._keyEvent = true;
7738		if ($.datepicker._datepickerShowing)
7739			switch (event.keyCode) {
7740				case 9: $.datepicker._hideDatepicker();
7741						handled = false;
7742						break; // hide on tab out
7743				case 13: var sel = $('td.' + $.datepicker._dayOverClass + ':not(.' +
7744									$.datepicker._currentClass + ')', inst.dpDiv);
7745						if (sel[0])
7746							$.datepicker._selectDay(event.target, inst.selectedMonth, inst.selectedYear, sel[0]);
7747							var onSelect = $.datepicker._get(inst, 'onSelect');
7748							if (onSelect) {
7749								var dateStr = $.datepicker._formatDate(inst);
7750
7751								// trigger custom callback
7752								onSelect.apply((inst.input ? inst.input[0] : null), [dateStr, inst]);
7753							}
7754						else
7755							$.datepicker._hideDatepicker();
7756						return false; // don't submit the form
7757						break; // select the value on enter
7758				case 27: $.datepicker._hideDatepicker();
7759						break; // hide on escape
7760				case 33: $.datepicker._adjustDate(event.target, (event.ctrlKey ?
7761							-$.datepicker._get(inst, 'stepBigMonths') :
7762							-$.datepicker._get(inst, 'stepMonths')), 'M');
7763						break; // previous month/year on page up/+ ctrl
7764				case 34: $.datepicker._adjustDate(event.target, (event.ctrlKey ?
7765							+$.datepicker._get(inst, 'stepBigMonths') :
7766							+$.datepicker._get(inst, 'stepMonths')), 'M');
7767						break; // next month/year on page down/+ ctrl
7768				case 35: if (event.ctrlKey || event.metaKey) $.datepicker._clearDate(event.target);
7769						handled = event.ctrlKey || event.metaKey;
7770						break; // clear on ctrl or command +end
7771				case 36: if (event.ctrlKey || event.metaKey) $.datepicker._gotoToday(event.target);
7772						handled = event.ctrlKey || event.metaKey;
7773						break; // current on ctrl or command +home
7774				case 37: if (event.ctrlKey || event.metaKey) $.datepicker._adjustDate(event.target, (isRTL ? +1 : -1), 'D');
7775						handled = event.ctrlKey || event.metaKey;
7776						// -1 day on ctrl or command +left
7777						if (event.originalEvent.altKey) $.datepicker._adjustDate(event.target, (event.ctrlKey ?
7778									-$.datepicker._get(inst, 'stepBigMonths') :
7779									-$.datepicker._get(inst, 'stepMonths')), 'M');
7780						// next month/year on alt +left on Mac
7781						break;
7782				case 38: if (event.ctrlKey || event.metaKey) $.datepicker._adjustDate(event.target, -7, 'D');
7783						handled = event.ctrlKey || event.metaKey;
7784						break; // -1 week on ctrl or command +up
7785				case 39: if (event.ctrlKey || event.metaKey) $.datepicker._adjustDate(event.target, (isRTL ? -1 : +1), 'D');
7786						handled = event.ctrlKey || event.metaKey;
7787						// +1 day on ctrl or command +right
7788						if (event.originalEvent.altKey) $.datepicker._adjustDate(event.target, (event.ctrlKey ?
7789									+$.datepicker._get(inst, 'stepBigMonths') :
7790									+$.datepicker._get(inst, 'stepMonths')), 'M');
7791						// next month/year on alt +right
7792						break;
7793				case 40: if (event.ctrlKey || event.metaKey) $.datepicker._adjustDate(event.target, +7, 'D');
7794						handled = event.ctrlKey || event.metaKey;
7795						break; // +1 week on ctrl or command +down
7796				default: handled = false;
7797			}
7798		else if (event.keyCode == 36 && event.ctrlKey) // display the date picker on ctrl+home
7799			$.datepicker._showDatepicker(this);
7800		else {
7801			handled = false;
7802		}
7803		if (handled) {
7804			event.preventDefault();
7805			event.stopPropagation();
7806		}
7807	},
7808
7809	/* Filter entered characters - based on date format. */
7810	_doKeyPress: function(event) {
7811		var inst = $.datepicker._getInst(event.target);
7812		if ($.datepicker._get(inst, 'constrainInput')) {
7813			var chars = $.datepicker._possibleChars($.datepicker._get(inst, 'dateFormat'));
7814			var chr = String.fromCharCode(event.charCode == undefined ? event.keyCode : event.charCode);
7815			return event.ctrlKey || event.metaKey || (chr < ' ' || !chars || chars.indexOf(chr) > -1);
7816		}
7817	},
7818
7819	/* Synchronise manual entry and field/alternate field. */
7820	_doKeyUp: function(event) {
7821		var inst = $.datepicker._getInst(event.target);
vendor: 8,608 bytes, lines 7822-8023
7822		if (inst.input.val() != inst.lastVal) {
7823			try {
7824				var date = $.datepicker.parseDate($.datepicker._get(inst, 'dateFormat'),
7825					(inst.input ? inst.input.val() : null),
7826					$.datepicker._getFormatConfig(inst));
7827				if (date) { // only if valid
7828					$.datepicker._setDateFromField(inst);
7829					$.datepicker._updateAlternate(inst);
7830					$.datepicker._updateDatepicker(inst);
7831				}
7832			}
7833			catch (err) {
7834				$.datepicker.log(err);
7835			}
7836		}
7837		return true;
7838	},
7839
7840	/* Pop-up the date picker for a given input field.
7841	   If false returned from beforeShow event handler do not show.
7842	   @param  input  element - the input field attached to the date picker or
7843	                  event - if triggered by focus */
7844	_showDatepicker: function(input) {
7845		input = input.target || input;
7846		if (input.nodeName.toLowerCase() != 'input') // find from button/image trigger
7847			input = $('input', input.parentNode)[0];
7848		if ($.datepicker._isDisabledDatepicker(input) || $.datepicker._lastInput == input) // already here
7849			return;
7850		var inst = $.datepicker._getInst(input);
7851		if ($.datepicker._curInst && $.datepicker._curInst != inst) {
7852			$.datepicker._curInst.dpDiv.stop(true, true);
7853			if ( inst && $.datepicker._datepickerShowing ) {
7854				$.datepicker._hideDatepicker( $.datepicker._curInst.input[0] );
7855			}
7856		}
7857		var beforeShow = $.datepicker._get(inst, 'beforeShow');
7858		var beforeShowSettings = beforeShow ? beforeShow.apply(input, [input, inst]) : {};
7859		if(beforeShowSettings === false){
7860			//false
7861			return;
7862		}
7863		extendRemove(inst.settings, beforeShowSettings);
7864		inst.lastVal = null;
7865		$.datepicker._lastInput = input;
7866		$.datepicker._setDateFromField(inst);
7867		if ($.datepicker._inDialog) // hide cursor
7868			input.value = '';
7869		if (!$.datepicker._pos) { // position below input
7870			$.datepicker._pos = $.datepicker._findPos(input);
7871			$.datepicker._pos[1] += input.offsetHeight; // add the height
7872		}
7873		var isFixed = false;
7874		$(input).parents().each(function() {
7875			isFixed |= $(this).css('position') == 'fixed';
7876			return !isFixed;
7877		});
7878		var offset = {left: $.datepicker._pos[0], top: $.datepicker._pos[1]};
7879		$.datepicker._pos = null;
7880		//to avoid flashes on Firefox
7881		inst.dpDiv.empty();
7882		// determine sizing offscreen
7883		inst.dpDiv.css({position: 'absolute', display: 'block', top: '-1000px'});
7884		$.datepicker._updateDatepicker(inst);
7885		// fix width for dynamic number of date pickers
7886		// and adjust position before showing
7887		offset = $.datepicker._checkOffset(inst, offset, isFixed);
7888		inst.dpDiv.css({position: ($.datepicker._inDialog && $.blockUI ?
7889			'static' : (isFixed ? 'fixed' : 'absolute')), display: 'none',
7890			left: offset.left + 'px', top: offset.top + 'px'});
7891		if (!inst.inline) {
7892			var showAnim = $.datepicker._get(inst, 'showAnim');
7893			var duration = $.datepicker._get(inst, 'duration');
7894			var postProcess = function() {
7895				var cover = inst.dpDiv.find('iframe.ui-datepicker-cover'); // IE6- only
7896				if( !! cover.length ){
7897					var borders = $.datepicker._getBorders(inst.dpDiv);
7898					cover.css({left: -borders[0], top: -borders[1],
7899						width: inst.dpDiv.outerWidth(), height: inst.dpDiv.outerHeight()});
7900				}
7901			};
7902			inst.dpDiv.zIndex($(input).zIndex()+1);
7903			$.datepicker._datepickerShowing = true;
7904
7905			// DEPRECATED: after BC for 1.8.x $.effects[ showAnim ] is not needed
7906			if ( $.effects && ( $.effects.effect[ showAnim ] || $.effects[ showAnim ] ) )
7907				inst.dpDiv.show(showAnim, $.datepicker._get(inst, 'showOptions'), duration, postProcess);
7908			else
7909				inst.dpDiv[showAnim || 'show']((showAnim ? duration : null), postProcess);
7910			if (!showAnim || !duration)
7911				postProcess();
7912			if (inst.input.is(':visible') && !inst.input.is(':disabled'))
7913				inst.input.focus();
7914			$.datepicker._curInst = inst;
7915		}
7916	},
7917
7918	/* Generate the date picker content. */
7919	_updateDatepicker: function(inst) {
7920		this.maxRows = 4; //Reset the max number of rows being displayed (see #7043)
7921		var borders = $.datepicker._getBorders(inst.dpDiv);
7922		instActive = inst; // for delegate hover events
7923		inst.dpDiv.empty().append(this._generateHTML(inst));
7924		this._attachHandlers(inst);
7925		var cover = inst.dpDiv.find('iframe.ui-datepicker-cover'); // IE6- only
7926		if( !!cover.length ){ //avoid call to outerXXXX() when not in IE6
7927			cover.css({left: -borders[0], top: -borders[1], width: inst.dpDiv.outerWidth(), height: inst.dpDiv.outerHeight()})
7928		}
7929		inst.dpDiv.find('.' + this._dayOverClass + ' a').mouseover();
7930		var numMonths = this._getNumberOfMonths(inst);
7931		var cols = numMonths[1];
7932		var width = 17;
7933		inst.dpDiv.removeClass('ui-datepicker-multi-2 ui-datepicker-multi-3 ui-datepicker-multi-4').width('');
7934		if (cols > 1)
7935			inst.dpDiv.addClass('ui-datepicker-multi-' + cols).css('width', (width * cols) + 'em');
7936		inst.dpDiv[(numMonths[0] != 1 || numMonths[1] != 1 ? 'add' : 'remove') +
7937			'Class']('ui-datepicker-multi');
7938		inst.dpDiv[(this._get(inst, 'isRTL') ? 'add' : 'remove') +
7939			'Class']('ui-datepicker-rtl');
7940		if (inst == $.datepicker._curInst && $.datepicker._datepickerShowing && inst.input &&
7941				// #6694 - don't focus the input if it's already focused
7942				// this breaks the change event in IE
7943				inst.input.is(':visible') && !inst.input.is(':disabled') && inst.input[0] != document.activeElement)
7944			inst.input.focus();
7945		// deffered render of the years select (to avoid flashes on Firefox)
7946		if( inst.yearshtml ){
7947			var origyearshtml = inst.yearshtml;
7948			setTimeout(function(){
7949				//assure that inst.yearshtml didn't change.
7950				if( origyearshtml === inst.yearshtml && inst.yearshtml ){
7951					inst.dpDiv.find('select.ui-datepicker-year:first').replaceWith(inst.yearshtml);
7952				}
7953				origyearshtml = inst.yearshtml = null;
7954			}, 0);
7955		}
7956	},
7957
7958	/* Retrieve the size of left and top borders for an element.
7959	   @param  elem  (jQuery object) the element of interest
7960	   @return  (number[2]) the left and top borders */
7961	_getBorders: function(elem) {
7962		var convert = function(value) {
7963			return {thin: 1, medium: 2, thick: 3}[value] || value;
7964		};
7965		return [parseFloat(convert(elem.css('border-left-width'))),
7966			parseFloat(convert(elem.css('border-top-width')))];
7967	},
7968
7969	/* Check positioning to remain on screen. */
7970	_checkOffset: function(inst, offset, isFixed) {
7971		var dpWidth = inst.dpDiv.outerWidth();
7972		var dpHeight = inst.dpDiv.outerHeight();
7973		var inputWidth = inst.input ? inst.input.outerWidth() : 0;
7974		var inputHeight = inst.input ? inst.input.outerHeight() : 0;
7975		var viewWidth = document.documentElement.clientWidth + (isFixed ? 0 : $(document).scrollLeft());
7976		var viewHeight = document.documentElement.clientHeight + (isFixed ? 0 : $(document).scrollTop());
7977
7978		offset.left -= (this._get(inst, 'isRTL') ? (dpWidth - inputWidth) : 0);
7979		offset.left -= (isFixed && offset.left == inst.input.offset().left) ? $(document).scrollLeft() : 0;
7980		offset.top -= (isFixed && offset.top == (inst.input.offset().top + inputHeight)) ? $(document).scrollTop() : 0;
7981
7982		// now check if datepicker is showing outside window viewport - move to a better place if so.
7983		offset.left -= Math.min(offset.left, (offset.left + dpWidth > viewWidth && viewWidth > dpWidth) ?
7984			Math.abs(offset.left + dpWidth - viewWidth) : 0);
7985		offset.top -= Math.min(offset.top, (offset.top + dpHeight > viewHeight && viewHeight > dpHeight) ?
7986			Math.abs(dpHeight + inputHeight) : 0);
7987
7988		return offset;
7989	},
7990
7991	/* Find an object's position on the screen. */
7992	_findPos: function(obj) {
7993		var inst = this._getInst(obj);
7994		var isRTL = this._get(inst, 'isRTL');
7995		while (obj && (obj.type == 'hidden' || obj.nodeType != 1 || $.expr.filters.hidden(obj))) {
7996			obj = obj[isRTL ? 'previousSibling' : 'nextSibling'];
7997		}
7998		var position = $(obj).offset();
7999		return [position.left, position.top];
8000	},
8001
8002	/* Hide the date picker from view.
8003	   @param  input  element - the input field attached to the date picker */
8004	_hideDatepicker: function(input) {
8005		var inst = this._curInst;
8006		if (!inst || (input && inst != $.data(input, PROP_NAME)))
8007			return;
8008		if (this._datepickerShowing) {
8009			var showAnim = this._get(inst, 'showAnim');
8010			var duration = this._get(inst, 'duration');
8011			var postProcess = function() {
8012				$.datepicker._tidyDialog(inst);
8013			};
8014
8015			// DEPRECATED: after BC for 1.8.x $.effects[ showAnim ] is not needed
8016			if ( $.effects && ( $.effects.effect[ showAnim ] || $.effects[ showAnim ] ) )
8017				inst.dpDiv.hide(showAnim, $.datepicker._get(inst, 'showOptions'), duration, postProcess);
8018			else
8019				inst.dpDiv[(showAnim == 'slideDown' ? 'slideUp' :
8020					(showAnim == 'fadeIn' ? 'fadeOut' : 'hide'))]((showAnim ? duration : null), postProcess);
8021			if (!showAnim)
8022				postProcess();
8023			this._datepickerShowing = false;
8024			var onClose = this._get(inst, 'onClose');
8025			if (onClose)
8026				onClose.apply((inst.input ? inst.input[0] : null),
8027					[(inst.input ? inst.input.val() : ''), inst]);
8028			this._lastInput = null;
8029			if (this._inDialog) {
8030				this._dialogInput.css({ position: 'absolute', left: '0', top: '-100px' });
8031				if ($.blockUI) {
8032					$.unblockUI();
8033					$('body').append(this.dpDiv);
8034				}
8035			}
8036			this._inDialog = false;
8037		}
8038	},
8039
8040	/* Tidy up after a dialog display. */
8041	_tidyDialog: function(inst) {
8042		inst.dpDiv.removeClass(this._dialogClass).unbind('.ui-datepicker-calendar');
8043	},
8044
8045	/* Close date picker if clicked elsewhere. */
8046	_checkExternalClick: function(event) {
8047		if (!$.datepicker._curInst)
8048			return;
8049
8050		var $target = $(event.target),
8051			inst = $.datepicker._getInst($target[0]);
8052
8053		if ( ( ( $target[0].id != $.datepicker._mainDivId &&
8054				$target.parents('#' + $.datepicker._mainDivId).length == 0 &&
8055				!$target.hasClass($.datepicker.markerClassName) &&
8056				!$target.closest("." + $.datepicker._triggerClass).length &&
8057				$.datepicker._datepickerShowing && !($.datepicker._inDialog && $.blockUI) ) ) ||
8058			( $target.hasClass($.datepicker.markerClassName) && $.datepicker._curInst != inst ) )
8059			$.datepicker._hideDatepicker();
8060	},
8061
8062	/* Adjust one of the date sub-fields. */
8063	_adjustDate: function(id, offset, period) {
8064		var target = $(id);
8065		var inst = this._getInst(target[0]);
8066		if (this._isDisabledDatepicker(target[0])) {
8067			return;
8068		}
8069		this._adjustInstDate(inst, offset +
8070			(period == 'M' ? this._get(inst, 'showCurrentAtPos') : 0), // undo positioning
8071			period);
8072		this._updateDatepicker(inst);
8073	},
8074
8075	/* Action for current link. */
8076	_gotoToday: function(id) {
8077		var target = $(id);
8078		var inst = this._getInst(target[0]);
8079		if (this._get(inst, 'gotoCurrent') && inst.currentDay) {
8080			inst.selectedDay = inst.currentDay;
8081			inst.drawMonth = inst.selectedMonth = inst.currentMonth;
8082			inst.drawYear = inst.selectedYear = inst.currentYear;
8083		}
8084		else {
8085			var date = new Date();
8086			inst.selectedDay = date.getDate();
8087			inst.drawMonth = inst.selectedMonth = date.getMonth();
8088			inst.drawYear = inst.selectedYear = date.getFullYear();
8089		}
8090		this._notifyChange(inst);
8091		this._adjustDate(target);
8092	},
8093
8094	/* Action for selecting a new month/year. */
8095	_selectMonthYear: function(id, select, period) {
8096		var target = $(id);
8097		var inst = this._getInst(target[0]);
8098		inst['selected' + (period == 'M' ? 'Month' : 'Year')] =
8099		inst['draw' + (period == 'M' ? 'Month' : 'Year')] =
8100			parseInt(select.options[select.selectedIndex].value,10);
8101		this._notifyChange(inst);
8102		this._adjustDate(target);
8103	},
8104
8105	/* Action for selecting a day. */
8106	_selectDay: function(id, month, year, td) {
8107		var target = $(id);
8108		if ($(td).hasClass(this._unselectableClass) || this._isDisabledDatepicker(target[0])) {
8109			return;
8110		}
8111		var inst = this._getInst(target[0]);
8112		inst.selectedDay = inst.currentDay = $('a', td).html();
8113		inst.selectedMonth = inst.currentMonth = month;
8114		inst.selectedYear = inst.currentYear = year;
8115		this._selectDate(id, this._formatDate(inst,
8116			inst.currentDay, inst.currentMonth, inst.currentYear));
8117	},
8118
8119	/* Erase the input field and hide the date picker. */
8120	_clearDate: function(id) {
8121		var target = $(id);
8122		var inst = this._getInst(target[0]);
8123		this._selectDate(target, '');
8124	},
8125
8126	/* Update the input field with the selected date. */
8127	_selectDate: function(id, dateStr) {
8128		var target = $(id);
8129		var inst = this._getInst(target[0]);
8130		dateStr = (dateStr != null ? dateStr : this._formatDate(inst));
8131		if (inst.input)
8132			inst.input.val(dateStr);
8133		this._updateAlternate(inst);
8134		var onSelect = this._get(inst, 'onSelect');
8135		if (onSelect)
8136			onSelect.apply((inst.input ? inst.input[0] : null), [dateStr, inst]);  // trigger custom callback
8137		else if (inst.input)
8138			inst.input.trigger('change'); // fire the change event
8139		if (inst.inline)
8140			this._updateDatepicker(inst);
8141		else {
8142			this._hideDatepicker();
8143			this._lastInput = inst.input[0];
8144			if (typeof(inst.input[0]) != 'object')
8145				inst.input.focus(); // restore focus
8146			this._lastInput = null;
8147		}
8148	},
8149
8150	/* Update any alternate field to synchronise with the main field. */
8151	_updateAlternate: function(inst) {
8152		var altField = this._get(inst, 'altField');
8153		if (altField) { // update alternate field too
8154			var altFormat = this._get(inst, 'altFormat') || this._get(inst, 'dateFormat');
8155			var date = this._getDate(inst);
8156			var dateStr = this.formatDate(altFormat, date, this._getFormatConfig(inst));
8157			$(altField).each(function() { $(this).val(dateStr); });
8158		}
8159	},
8160
8161	/* Set as beforeShowDay function to prevent selection of weekends.
8162	   @param  date  Date - the date to customise
8163	   @return [boolean, string] - is this date selectable?, what is its CSS class? */
8164	noWeekends: function(date) {
8165		var day = date.getDay();
8166		return [(day > 0 && day < 6), ''];
8167	},
8168
8169	/* Set as calculateWeek to determine the week of the year based on the ISO 8601 definition.
8170	   @param  date  Date - the date to get the week for
8171	   @return  number - the number of the week within the year that contains this date */
8172	iso8601Week: function(date) {
8173		var checkDate = new Date(date.getTime());
8174		// Find Thursday of this week starting on Monday
8175		checkDate.setDate(checkDate.getDate() + 4 - (checkDate.getDay() || 7));
8176		var time = checkDate.getTime();
8177		checkDate.setMonth(0); // Compare with Jan 1
8178		checkDate.setDate(1);
8179		return Math.floor(Math.round((time - checkDate) / 86400000) / 7) + 1;
8180	},
8181
8182	/* Parse a string value into a date object.
8183	   See formatDate below for the possible formats.
8184
vendor: 4,158 bytes, lines 8185-8293
8185	   @param  format    string - the expected format of the date
8186	   @param  value     string - the date in the above format
8187	   @param  settings  Object - attributes include:
8188	                     shortYearCutoff  number - the cutoff year for determining the century (optional)
8189	                     dayNamesShort    string[7] - abbreviated names of the days from Sunday (optional)
8190	                     dayNames         string[7] - names of the days from Sunday (optional)
8191	                     monthNamesShort  string[12] - abbreviated names of the months (optional)
8192	                     monthNames       string[12] - names of the months (optional)
8193	   @return  Date - the extracted date value or null if value is blank */
8194	parseDate: function (format, value, settings) {
8195		if (format == null || value == null)
8196			throw 'Invalid arguments';
8197		value = (typeof value == 'object' ? value.toString() : value + '');
8198		if (value == '')
8199			return null;
8200		var shortYearCutoff = (settings ? settings.shortYearCutoff : null) || this._defaults.shortYearCutoff;
8201		shortYearCutoff = (typeof shortYearCutoff != 'string' ? shortYearCutoff :
8202				new Date().getFullYear() % 100 + parseInt(shortYearCutoff, 10));
8203		var dayNamesShort = (settings ? settings.dayNamesShort : null) || this._defaults.dayNamesShort;
8204		var dayNames = (settings ? settings.dayNames : null) || this._defaults.dayNames;
8205		var monthNamesShort = (settings ? settings.monthNamesShort : null) || this._defaults.monthNamesShort;
8206		var monthNames = (settings ? settings.monthNames : null) || this._defaults.monthNames;
8207		var year = -1;
8208		var month = -1;
8209		var day = -1;
8210		var doy = -1;
8211		var literal = false;
8212		// Check whether a format character is doubled
8213		var lookAhead = function(match) {
8214			var matches = (iFormat + 1 < format.length && format.charAt(iFormat + 1) == match);
8215			if (matches)
8216				iFormat++;
8217			return matches;
8218		};
8219		// Extract a number from the string value
8220		var getNumber = function(match) {
8221			var isDoubled = lookAhead(match);
8222			var size = (match == '@' ? 14 : (match == '!' ? 20 :
8223				(match == 'y' && isDoubled ? 4 : (match == 'o' ? 3 : 2))));
8224			var digits = new RegExp('^\\d{1,' + size + '}');
8225			var num = value.substring(iValue).match(digits);
8226			if (!num)
8227				throw 'Missing number at position ' + iValue;
8228			iValue += num[0].length;
8229			return parseInt(num[0], 10);
8230		};
8231		// Extract a name from the string value and convert to an index
8232		var getName = function(match, shortNames, longNames) {
8233			var names = $.map(lookAhead(match) ? longNames : shortNames, function (v, k) {
8234				return [ [k, v] ];
8235			}).sort(function (a, b) {
8236				return -(a[1].length - b[1].length);
8237			});
8238			var index = -1;
8239			$.each(names, function (i, pair) {
8240				var name = pair[1];
8241				if (value.substr(iValue, name.length).toLowerCase() == name.toLowerCase()) {
8242					index = pair[0];
8243					iValue += name.length;
8244					return false;
8245				}
8246			});
8247			if (index != -1)
8248				return index + 1;
8249			else
8250				throw 'Unknown name at position ' + iValue;
8251		};
8252		// Confirm that a literal character matches the string value
8253		var checkLiteral = function() {
8254			if (value.charAt(iValue) != format.charAt(iFormat))
8255				throw 'Unexpected literal at position ' + iValue;
8256			iValue++;
8257		};
8258		var iValue = 0;
8259		for (var iFormat = 0; iFormat < format.length; iFormat++) {
8260			if (literal)
8261				if (format.charAt(iFormat) == "'" && !lookAhead("'"))
8262					literal = false;
8263				else
8264					checkLiteral();
8265			else
8266				switch (format.charAt(iFormat)) {
8267					case 'd':
8268						day = getNumber('d');
8269						break;
8270					case 'D':
8271						getName('D', dayNamesShort, dayNames);
8272						break;
8273					case 'o':
8274						doy = getNumber('o');
8275						break;
8276					case 'm':
8277						month = getNumber('m');
8278						break;
8279					case 'M':
8280						month = getName('M', monthNamesShort, monthNames);
8281						break;
8282					case 'y':
8283						year = getNumber('y');
8284						break;
8285					case '@':
8286						var date = new Date(getNumber('@'));
8287						year = date.getFullYear();
8288						month = date.getMonth() + 1;
8289						day = date.getDate();
8290						break;
8291					case '!':
8292						var date = new Date((getNumber('!') - this._ticksTo1970) / 10000);
8293						year = date.getFullYear();
8294						month = date.getMonth() + 1;
8295						day = date.getDate();
8296						break;
8297					case "'":
8298						if (lookAhead("'"))
8299							checkLiteral();
8300						else
8301							literal = true;
8302						break;
8303					default:
8304						checkLiteral();
8305				}
8306		}
8307		if (iValue < value.length){
8308			var extra = value.substr(iValue);
8309			if (!/^\s+/.test(extra)) {
8310				throw "Extra/unparsed characters found in date: " + extra;
8311			}
8312		}
8313		if (year == -1)
8314			year = new Date().getFullYear();
8315		else if (year < 100)
8316			year += new Date().getFullYear() - new Date().getFullYear() % 100 +
8317				(year <= shortYearCutoff ? 0 : -100);
8318		if (doy > -1) {
8319			month = 1;
8320			day = doy;
8321			do {
8322				var dim = this._getDaysInMonth(year, month - 1);
8323				if (day <= dim)
8324					break;
8325				month++;
8326				day -= dim;
8327			} while (true);
8328		}
8329		var date = this._daylightSavingAdjust(new Date(year, month - 1, day));
8330		if (date.getFullYear() != year || date.getMonth() + 1 != month || date.getDate() != day)
8331			throw 'Invalid date'; // E.g. 31/02/00
8332		return date;
8333	},
8334
8335	/* Standard date formats. */
8336	ATOM: 'yy-mm-dd', // RFC 3339 (ISO 8601)
8337	COOKIE: 'D, dd M yy',
8338	ISO_8601: 'yy-mm-dd',
8339	RFC_822: 'D, d M y',
8340	RFC_850: 'DD, dd-M-y',
8341	RFC_1036: 'D, d M y',
8342	RFC_1123: 'D, d M yy',
8343	RFC_2822: 'D, d M yy',
8344	RSS: 'D, d M y', // RFC 822
8345	TICKS: '!',
8346	TIMESTAMP: '@',
8347	W3C: 'yy-mm-dd', // ISO 8601
8348
8349	_ticksTo1970: (((1970 - 1) * 365 + Math.floor(1970 / 4) - Math.floor(1970 / 100) +
8350		Math.floor(1970 / 400)) * 24 * 60 * 60 * 10000000),
8351
8352	/* Format a date object into a string value.
8353	   The format can be combinations of the following:
8354	   d  - day of month (no leading zero)
8355	   dd - day of month (two digit)
8356	   o  - day of year (no leading zeros)
8357	   oo - day of year (three digit)
8358	   D  - day name short
8359	   DD - day name long
8360	   m  - month of year (no leading zero)
8361	   mm - month of year (two digit)
8362	   M  - month name short
8363	   MM - month name long
8364	   y  - year (two digit)
8365	   yy - year (four digit)
8366	   @ - Unix timestamp (ms since 01/01/1970)
8367	   ! - Windows ticks (100ns since 01/01/0001)
8368	   '...' - literal text
8369	   '' - single quote
8370
8371	   @param  format    string - the desired format of the date
8372	   @param  date      Date - the date value to format
8373	   @param  settings  Object - attributes include:
8374	                     dayNamesShort    string[7] - abbreviated names of the days from Sunday (optional)
8375	                     dayNames         string[7] - names of the days from Sunday (optional)
8376	                     monthNamesShort  string[12] - abbreviated names of the months (optional)
8377	                     monthNames       string[12] - names of the months (optional)
8378	   @return  string - the date in the above format */
8379	formatDate: function (format, date, settings) {
8380		if (!date)
8381			return '';
8382		var dayNamesShort = (settings ? settings.dayNamesShort : null) || this._defaults.dayNamesShort;
8383		var dayNames = (settings ? settings.dayNames : null) || this._defaults.dayNames;
8384		var monthNamesShort = (settings ? settings.monthNamesShort : null) || this._defaults.monthNamesShort;
8385		var monthNames = (settings ? settings.monthNames : null) || this._defaults.monthNames;
8386		// Check whether a format character is doubled
8387		var lookAhead = function(match) {
8388			var matches = (iFormat + 1 < format.length && format.charAt(iFormat + 1) == match);
8389			if (matches)
8390				iFormat++;
8391			return matches;
8392		};
8393		// Format a number, with leading zero if necessary
8394		var formatNumber = function(match, value, len) {
8395			var num = '' + value;
8396			if (lookAhead(match))
8397				while (num.length < len)
8398					num = '0' + num;
8399			return num;
8400		};
8401		// Format a name, short or long as requested
8402		var formatName = function(match, value, shortNames, longNames) {
8403			return (lookAhead(match) ? longNames[value] : shortNames[value]);
8404		};
8405		var output = '';
8406		var literal = false;
8407		if (date)
8408			for (var iFormat = 0; iFormat < format.length; iFormat++) {
8409				if (literal)
8410					if (format.charAt(iFormat) == "'" && !lookAhead("'"))
8411						literal = false;
8412					else
8413						output += format.charAt(iFormat);
8414				else
8415					switch (format.charAt(iFormat)) {
8416						case 'd':
8417							output += formatNumber('d', date.getDate(), 2);
8418							break;
8419						case 'D':
8420							output += formatName('D', date.getDay(), dayNamesShort, dayNames);
8421							break;
8422						case 'o':
8423							output += formatNumber('o',
8424								Math.round((new Date(date.getFullYear(), date.getMonth(), date.getDate()).getTime() - new Date(date.getFullYear(), 0, 0).getTime()) / 86400000), 3);
8425							break;
8426						case 'm':
8427							output += formatNumber('m', date.getMonth() + 1, 2);
8428							break;
8429						case 'M':
8430							output += formatName('M', date.getMonth(), monthNamesShort, monthNames);
8431							break;
8432						case 'y':
8433							output += (lookAhead('y') ? date.getFullYear() :
8434								(date.getYear() % 100 < 10 ? '0' : '') + date.getYear() % 100);
8435							break;
8436						case '@':
8437							output += date.getTime();
8438							break;
8439						case '!':
8440							output += date.getTime() * 10000 + this._ticksTo1970;
8441							break;
vendor: 5,981 bytes, lines 8442-8623
8442						case "'":
8443							if (lookAhead("'"))
8444								output += "'";
8445							else
8446								literal = true;
8447							break;
8448						default:
8449							output += format.charAt(iFormat);
8450					}
8451			}
8452		return output;
8453	},
8454
8455	/* Extract all possible characters from the date format. */
8456	_possibleChars: function (format) {
8457		var chars = '';
8458		var literal = false;
8459		// Check whether a format character is doubled
8460		var lookAhead = function(match) {
8461			var matches = (iFormat + 1 < format.length && format.charAt(iFormat + 1) == match);
8462			if (matches)
8463				iFormat++;
8464			return matches;
8465		};
8466		for (var iFormat = 0; iFormat < format.length; iFormat++)
8467			if (literal)
8468				if (format.charAt(iFormat) == "'" && !lookAhead("'"))
8469					literal = false;
8470				else
8471					chars += format.charAt(iFormat);
8472			else
8473				switch (format.charAt(iFormat)) {
8474					case 'd': case 'm': case 'y': case '@':
8475						chars += '0123456789';
8476						break;
8477					case 'D': case 'M':
8478						return null; // Accept anything
8479					case "'":
8480						if (lookAhead("'"))
8481							chars += "'";
8482						else
8483							literal = true;
8484						break;
8485					default:
8486						chars += format.charAt(iFormat);
8487				}
8488		return chars;
8489	},
8490
8491	/* Get a setting value, defaulting if necessary. */
8492	_get: function(inst, name) {
8493		return inst.settings[name] !== undefined ?
8494			inst.settings[name] : this._defaults[name];
8495	},
8496
8497	/* Parse existing date and initialise date picker. */
8498	_setDateFromField: function(inst, noDefault) {
8499		if (inst.input.val() == inst.lastVal) {
8500			return;
8501		}
8502		var dateFormat = this._get(inst, 'dateFormat');
8503		var dates = inst.lastVal = inst.input ? inst.input.val() : null;
8504		var date, defaultDate;
8505		date = defaultDate = this._getDefaultDate(inst);
8506		var settings = this._getFormatConfig(inst);
8507		try {
8508			date = this.parseDate(dateFormat, dates, settings) || defaultDate;
8509		} catch (event) {
8510			this.log(event);
8511			dates = (noDefault ? '' : dates);
8512		}
8513		inst.selectedDay = date.getDate();
8514		inst.drawMonth = inst.selectedMonth = date.getMonth();
8515		inst.drawYear = inst.selectedYear = date.getFullYear();
8516		inst.currentDay = (dates ? date.getDate() : 0);
8517		inst.currentMonth = (dates ? date.getMonth() : 0);
8518		inst.currentYear = (dates ? date.getFullYear() : 0);
8519		this._adjustInstDate(inst);
8520	},
8521
8522	/* Retrieve the default date shown on opening. */
8523	_getDefaultDate: function(inst) {
8524		return this._restrictMinMax(inst,
8525			this._determineDate(inst, this._get(inst, 'defaultDate'), new Date()));
8526	},
8527
8528	/* A date may be specified as an exact value or a relative one. */
8529	_determineDate: function(inst, date, defaultDate) {
8530		var offsetNumeric = function(offset) {
8531			var date = new Date();
8532			date.setDate(date.getDate() + offset);
8533			return date;
8534		};
8535		var offsetString = function(offset) {
8536			try {
8537				return $.datepicker.parseDate($.datepicker._get(inst, 'dateFormat'),
8538					offset, $.datepicker._getFormatConfig(inst));
8539			}
8540			catch (e) {
8541				// Ignore
8542			}
8543			var date = (offset.toLowerCase().match(/^c/) ?
8544				$.datepicker._getDate(inst) : null) || new Date();
8545			var year = date.getFullYear();
8546			var month = date.getMonth();
8547			var day = date.getDate();
8548			var pattern = /([+-]?[0-9]+)\s*(d|D|w|W|m|M|y|Y)?/g;
8549			var matches = pattern.exec(offset);
8550			while (matches) {
8551				switch (matches[2] || 'd') {
8552					case 'd' : case 'D' :
8553						day += parseInt(matches[1],10); break;
8554					case 'w' : case 'W' :
8555						day += parseInt(matches[1],10) * 7; break;
8556					case 'm' : case 'M' :
8557						month += parseInt(matches[1],10);
8558						day = Math.min(day, $.datepicker._getDaysInMonth(year, month));
8559						break;
8560					case 'y': case 'Y' :
8561						year += parseInt(matches[1],10);
8562						day = Math.min(day, $.datepicker._getDaysInMonth(year, month));
8563						break;
8564				}
8565				matches = pattern.exec(offset);
8566			}
8567			return new Date(year, month, day);
8568		};
8569		var newDate = (date == null || date === '' ? defaultDate : (typeof date == 'string' ? offsetString(date) :
8570			(typeof date == 'number' ? (isNaN(date) ? defaultDate : offsetNumeric(date)) : new Date(date.getTime()))));
8571		newDate = (newDate && newDate.toString() == 'Invalid Date' ? defaultDate : newDate);
8572		if (newDate) {
8573			newDate.setHours(0);
8574			newDate.setMinutes(0);
8575			newDate.setSeconds(0);
8576			newDate.setMilliseconds(0);
8577		}
8578		return this._daylightSavingAdjust(newDate);
8579	},
8580
8581	/* Handle switch to/from daylight saving.
8582	   Hours may be non-zero on daylight saving cut-over:
8583	   > 12 when midnight changeover, but then cannot generate
8584	   midnight datetime, so jump to 1AM, otherwise reset.
8585	   @param  date  (Date) the date to check
8586	   @return  (Date) the corrected date */
8587	_daylightSavingAdjust: function(date) {
8588		if (!date) return null;
8589		date.setHours(date.getHours() > 12 ? date.getHours() + 2 : 0);
8590		return date;
8591	},
8592
8593	/* Set the date(s) directly. */
8594	_setDate: function(inst, date, noChange) {
8595		var clear = !date;
8596		var origMonth = inst.selectedMonth;
8597		var origYear = inst.selectedYear;
8598		var newDate = this._restrictMinMax(inst, this._determineDate(inst, date, new Date()));
8599		inst.selectedDay = inst.currentDay = newDate.getDate();
8600		inst.drawMonth = inst.selectedMonth = inst.currentMonth = newDate.getMonth();
8601		inst.drawYear = inst.selectedYear = inst.currentYear = newDate.getFullYear();
8602		if ((origMonth != inst.selectedMonth || origYear != inst.selectedYear) && !noChange)
8603			this._notifyChange(inst);
8604		this._adjustInstDate(inst);
8605		if (inst.input) {
8606			inst.input.val(clear ? '' : this._formatDate(inst));
8607		}
8608	},
8609
8610	/* Retrieve the date(s) directly. */
8611	_getDate: function(inst) {
8612		var startDate = (!inst.currentYear || (inst.input && inst.input.val() == '') ? null :
8613			this._daylightSavingAdjust(new Date(
8614			inst.currentYear, inst.currentMonth, inst.currentDay)));
8615			return startDate;
8616	},
8617
8618	/* Attach the onxxx handlers.  These are declared statically so
8619	 * they work with static code transformers like Caja.
8620	 */
8621	_attachHandlers: function(inst) {
8622		var stepMonths = this._get(inst, 'stepMonths');
8623		var id = '#' + inst.id.replace( /\\\\/g, "\\" );
8624		inst.dpDiv.find('[data-handler]').map(function () {
8625			var handler = {
8626				prev: function () {
8627					window['DP_jQuery_' + dpuuid].datepicker._adjustDate(id, -stepMonths, 'M');
8628				},
8629				next: function () {
8630					window['DP_jQuery_' + dpuuid].datepicker._adjustDate(id, +stepMonths, 'M');
8631				},
8632				hide: function () {
8633					window['DP_jQuery_' + dpuuid].datepicker._hideDatepicker();
8634				},
8635				today: function () {
8636					window['DP_jQuery_' + dpuuid].datepicker._gotoToday(id);
8637				},
8638				selectDay: function () {
8639					window['DP_jQuery_' + dpuuid].datepicker._selectDay(id, +this.getAttribute('data-month'), +this.getAttribute('data-year'), this);
8640					return false;
8641				},
8642				selectMonth: function () {
8643					window['DP_jQuery_' + dpuuid].datepicker._selectMonthYear(id, this, 'M');
8644					return false;
8645				},
8646				selectYear: function () {
8647					window['DP_jQuery_' + dpuuid].datepicker._selectMonthYear(id, this, 'Y');
8648					return false;
8649				}
8650			};
8651			$(this).bind(this.getAttribute('data-event'), handler[this.getAttribute('data-handler')]);
8652		});
8653	},
8654
8655	/* Generate the HTML for the current state of the date picker. */
8656	_generateHTML: function(inst) {
8657		var today = new Date();
8658		today = this._daylightSavingAdjust(
8659			new Date(today.getFullYear(), today.getMonth(), today.getDate())); // clear time
8660		var isRTL = this._get(inst, 'isRTL');
8661		var showButtonPanel = this._get(inst, 'showButtonPanel');
8662		var hideIfNoPrevNext = this._get(inst, 'hideIfNoPrevNext');
8663		var navigationAsDateFormat = this._get(inst, 'navigationAsDateFormat');
8664		var numMonths = this._getNumberOfMonths(inst);
8665		var showCurrentAtPos = this._get(inst, 'showCurrentAtPos');
8666		var stepMonths = this._get(inst, 'stepMonths');
8667		var isMultiMonth = (numMonths[0] != 1 || numMonths[1] != 1);
8668		var currentDate = this._daylightSavingAdjust((!inst.currentDay ? new Date(9999, 9, 9) :
8669			new Date(inst.currentYear, inst.currentMonth, inst.currentDay)));
8670		var minDate = this._getMinMaxDate(inst, 'min');
8671		var maxDate = this._getMinMaxDate(inst, 'max');
8672		var drawMonth = inst.drawMonth - showCurrentAtPos;
8673		var drawYear = inst.drawYear;
8674		if (drawMonth < 0) {
8675			drawMonth += 12;
8676			drawYear--;
8677		}
8678		if (maxDate) {
8679			var maxDraw = this._daylightSavingAdjust(new Date(maxDate.getFullYear(),
8680				maxDate.getMonth() - (numMonths[0] * numMonths[1]) + 1, maxDate.getDate()));
8681			maxDraw = (minDate && maxDraw < minDate ? minDate : maxDraw);
8682			while (this._daylightSavingAdjust(new Date(drawYear, drawMonth, 1)) > maxDraw) {
8683				drawMonth--;
8684				if (drawMonth < 0) {
8685					drawMonth = 11;
8686					drawYear--;
8687				}
8688			}
8689		}
8690		inst.drawMonth = drawMonth;
8691		inst.drawYear = drawYear;
8692		var prevText = this._get(inst, 'prevText');
8693		prevText = (!navigationAsDateFormat ? prevText : this.formatDate(prevText,
8694			this._daylightSavingAdjust(new Date(drawYear, drawMonth - stepMonths, 1)),
8695			this._getFormatConfig(inst)));
8696		var prev = (this._canAdjustMonth(inst, -1, drawYear, drawMonth) ?
8697			'<a class="ui-datepicker-prev ui-corner-all" data-handler="prev" data-event="click"' +
8698			' title="' + prevText + '"><span class="ui-icon ui-icon-circle-triangle-' + ( isRTL ? 'e' : 'w') + '">' + prevText + '</span></a>' :
8699			(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>'));
8700		var nextText = this._get(inst, 'nextText');
8701		nextText = (!navigationAsDateFormat ? nextText : this.formatDate(nextText,
8702			this._daylightSavingAdjust(new Date(drawYear, drawMonth + stepMonths, 1)),
8703			this._getFormatConfig(inst)));
8704		var next = (this._canAdjustMonth(inst, +1, drawYear, drawMonth) ?
8705			'<a class="ui-datepicker-next ui-corner-all" data-handler="next" data-event="click"' +
8706			' title="' + nextText + '"><span class="ui-icon ui-icon-circle-triangle-' + ( isRTL ? 'w' : 'e') + '">' + nextText + '</span></a>' :
8707			(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>'));
8708		var currentText = this._get(inst, 'currentText');
8709		var gotoDate = (this._get(inst, 'gotoCurrent') && inst.currentDay ? currentDate : today);
8710		currentText = (!navigationAsDateFormat ? currentText :
8711			this.formatDate(currentText, gotoDate, this._getFormatConfig(inst)));
8712		var 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">' +
8713			this._get(inst, 'closeText') + '</button>' : '');
8714		var buttonPanel = (showButtonPanel) ? '<div class="ui-datepicker-buttonpane ui-widget-content">' + (isRTL ? controls : '') +
8715			(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"' +
8716			'>' + currentText + '</button>' : '') + (isRTL ? '' : controls) + '</div>' : '';
8717		var firstDay = parseInt(this._get(inst, 'firstDay'),10);
8718		firstDay = (isNaN(firstDay) ? 0 : firstDay);
8719		var showWeek = this._get(inst, 'showWeek');
8720		var dayNames = this._get(inst, 'dayNames');
8721		var dayNamesShort = this._get(inst, 'dayNamesShort');
8722		var dayNamesMin = this._get(inst, 'dayNamesMin');
8723		var monthNames = this._get(inst, 'monthNames');
8724		var monthNamesShort = this._get(inst, 'monthNamesShort');
8725		var beforeShowDay = this._get(inst, 'beforeShowDay');
8726		var showOtherMonths = this._get(inst, 'showOtherMonths');
8727		var selectOtherMonths = this._get(inst, 'selectOtherMonths');
8728		var calculateWeek = this._get(inst, 'calculateWeek') || this.iso8601Week;
8729		var defaultDate = this._getDefaultDate(inst);
8730		var html = '';
8731		for (var row = 0; row < numMonths[0]; row++) {
8732			var group = '';
8733			this.maxRows = 4;
8734			for (var col = 0; col < numMonths[1]; col++) {
8735				var selectedDate = this._daylightSavingAdjust(new Date(drawYear, drawMonth, inst.selectedDay));
8736				var cornerClass = ' ui-corner-all';
8737				var calender = '';
8738				if (isMultiMonth) {
8739					calender += '<div class="ui-datepicker-group';
8740					if (numMonths[1] > 1)
8741						switch (col) {
8742							case 0: calender += ' ui-datepicker-group-first';
8743								cornerClass = ' ui-corner-' + (isRTL ? 'right' : 'left'); break;
8744							case numMonths[1]-1: calender += ' ui-datepicker-group-last';
8745								cornerClass = ' ui-corner-' + (isRTL ? 'left' : 'right'); break;
8746							default: calender += ' ui-datepicker-group-middle'; cornerClass = ''; break;
8747						}
8748					calender += '">';
8749				}
8750				calender += '<div class="ui-datepicker-header ui-widget-header ui-helper-clearfix' + cornerClass + '">' +
8751					(/all|left/.test(cornerClass) && row == 0 ? (isRTL ? next : prev) : '') +
8752					(/all|right/.test(cornerClass) && row == 0 ? (isRTL ? prev : next) : '') +
8753					this._generateMonthYearHeader(inst, drawMonth, drawYear, minDate, maxDate,
8754					row > 0 || col > 0, monthNames, monthNamesShort) + // draw month headers
8755					'</div><table class="ui-datepicker-calendar"><thead>' +
8756					'<tr>';
8757				var thead = (showWeek ? '<th class="ui-datepicker-week-col">' + this._get(inst, 'weekHeader') + '</th>' : '');
8758				for (var dow = 0; dow < 7; dow++) { // days of the week
8759					var day = (dow + firstDay) % 7;
8760					thead += '<th' + ((dow + firstDay + 6) % 7 >= 5 ? ' class="ui-datepicker-week-end"' : '') + '>
8760' +
8761						'<span title="' + dayNames[day] + '">' + dayNamesMin[day] + '</span></th>';
8762				}
8763				calender += thead + '</tr></thead><tbody>';
8764				var daysInMonth = this._getDaysInMonth(drawYear, drawMonth);
8765				if (drawYear == inst.selectedYear && drawMonth == inst.selectedMonth)
8766					inst.selectedDay = Math.min(inst.selectedDay, daysInMonth);
8767				var leadDays = (this._getFirstDayOfMonth(drawYear, drawMonth) - firstDay + 7) % 7;
8768				var curRows = Math.ceil((leadDays + daysInMonth) / 7); // calculate the number of rows to generate
8769				var numRows = (isMultiMonth ? this.maxRows > curRows ? this.maxRows : curRows : curRows); //If multiple months, use the higher number of rows (see #7043)
8770				this.maxRows = numRows;
8771				var printDate = this._daylightSavingAdjust(new Date(drawYear, drawMonth, 1 - leadDays));
8772				for (var dRow = 0; dRow < numRows; dRow++) { // create date picker rows
8773					calender += '<tr>';
8774					var tbody = (!showWeek ? '' : '<td class="ui-datepicker-week-col">' +
8775						this._get(inst, 'calculateWeek')(printDate) + '</td>');
8776					for (var dow = 0; dow < 7; dow++) { // create date picker days
8777						var daySettings = (beforeShowDay ?
8778							beforeShowDay.apply((inst.input ? inst.input[0] : null), [printDate]) : [true, '']);
8779						var otherMonth = (printDate.getMonth() != drawMonth);
8780						var unselectable = (otherMonth && !selectOtherMonths) || !daySettings[0] ||
8781							(minDate && printDate < minDate) || (maxDate && printDate > maxDate);
8782						tbody += '<td class="' +
8783							((dow + firstDay + 6) % 7 >= 5 ? ' ui-datepicker-week-end' : '') + // highlight weekends
8784							(otherMonth ? ' ui-datepicker-other-month' : '') + // highlight days from other months
8785							((printDate.getTime() == selectedDate.getTime() && drawMonth == inst.selectedMonth && inst._keyEvent) || // user pressed key
8786							(defaultDate.getTime() == printDate.getTime() && defaultDate.getTime() == selectedDate.getTime()) ?
8787							// or defaultDate is current printedDate and defaultDate is selectedDate
8788							' ' + this._dayOverClass : '') + // highlight selected day
8789							(unselectable ? ' ' + this._unselectableClass + ' ui-state-disabled': '') +  // highlight unselectable days
8790							(otherMonth && !showOtherMonths ? '' : ' ' + daySettings[1] + // highlight custom dates
8791							(printDate.getTime() == currentDate.getTime() ? ' ' + this._currentClass : '') + // highlight selected day
8792							(printDate.getTime() == today.getTime() ? ' ui-datepicker-today' : '')) + '"' + // highlight today (if different)
8793							((!otherMonth || showOtherMonths) && daySettings[2] ? ' title="' + daySettings[2] + '"' : '') + // cell title
8794							(unselectable ? '' : ' data-handler="selectDay" data-event="click" data-month="' + printDate.getMonth() + '" data-year="' + printDate.getFullYear() + '"') + '>' + // actions
8795							(otherMonth && !showOtherMonths ? '&#xa0;' : // display for other months
8796							(unselectable ? '<span class="ui-state-default">' + printDate.getDate() + '</span>' : '<a class="ui-state-default' +
8797							(printDate.getTime() == today.getTime() ? ' ui-state-highlight' : '') +
8798							(printDate.getTime() == currentDate.getTime() ? ' ui-state-active' : '') + // highlight selected day
8799							(otherMonth ? ' ui-priority-secondary' : '') + // distinguish dates from other months
8800							'" href="#">' + printDate.getDate() + '</a>')) + '</td>'; // display selectable date
8801						printDate.setDate(printDate.getDate() + 1);
8802						printDate = this._daylightSavingAdjust(printDate);
8803					}
8804					calender += tbody + '</tr>';
8805				}
8806				drawMonth++;
8807				if (drawMonth > 11) {
8808					drawMonth = 0;
8809					drawYear++;
8810				}
8811				calender += '</tbody></table>' + (isMultiMonth ? '</div>' +
8812							((numMonths[0] > 0 && col == numMonths[1]-1) ? '<div class="ui-datepicker-row-break"></div>' : '') : '');
8813				group += calender;
8814			}
8815			html += group;
8816		}
8817		html += buttonPanel + ($.ui.ie6 && !inst.inline ?
8818			'<iframe src="javascript:false;" class="ui-datepicker-cover" frameborder="0"></iframe>' : '');
8819		inst._keyEvent = false;
8820		return html;
8821	},
8822
8823	/* Generate the month and year header. */
8824	_generateMonthYearHeader: function(inst, drawMonth, drawYear, minDate, maxDate,
8825			secondary, monthNames, monthNamesShort) {
8826		var changeMonth = this._get(inst, 'changeMonth');
8827		var changeYear = this._get(inst, 'changeYear');
8828		var showMonthAfterYear = this._get(inst, 'showMonthAfterYear');
8829		var html = '<div class="ui-datepicker-title">';
8830		var monthHtml = '';
8831		// month selection
8832		if (secondary || !changeMonth)
8833			monthHtml += '<span class="ui-datepicker-month">' + monthNames[drawMonth] + '</span>';
8834		else {
8835			var inMinYear = (minDate && minDate.getFullYear() == drawYear);
8836			var inMaxYear = (maxDate && maxDate.getFullYear() == drawYear);
8837			monthHtml += '<select class="ui-datepicker-month" data-handler="selectMonth" data-event="change">';
8838			for (var month = 0; month < 12; month++) {
8839				if ((!inMinYear || month >= minDate.getMonth()) &&
8840						(!inMaxYear || month <= maxDate.getMonth()))
8841					monthHtml += '<option value="' + month + '"' +
8842						(month == drawMonth ? ' selected="selected"' : '') +
8843						'>' + monthNamesShort[month] + '</option>';
8844			}
8845			monthHtml += '</select>';
8846		}
8847		if (!showMonthAfterYear)
8848			html += monthHtml + (secondary || !(changeMonth && changeYear) ? '&#xa0;' : '');
8849		// year selection
8850		if ( !inst.yearshtml ) {
8851			inst.yearshtml = '';
8852			if (secondary || !changeYear)
8853				html += '<span class="ui-datepicker-year">' + drawYear + '</span>';
8854			else {
8855				// determine range of years to display
8856				var years = this._get(inst, 'yearRange').split(':');
8857				var thisYear = new Date().getFullYear();
8858				var determineYear = function(value) {
8859					var year = (value.match(/c[+-].*/) ? drawYear + parseInt(value.substring(1), 10) :
8860						(value.match(/[+-].*/) ? thisYear + parseInt(value, 10) :
8861						parseInt(value, 10)));
8862					return (isNaN(year) ? thisYear : year);
8863				};
8864				var year = determineYear(years[0]);
8865				var endYear = Math.max(year, determineYear(years[1] || ''));
8866				year = (minDate ? Math.max(year, minDate.getFullYear()) : year);
8867				endYear = (maxDate ? Math.min(endYear, maxDate.getFullYear()) : endYear);
8868				inst.yearshtml += '<select class="ui-datepicker-year" data-handler="selectYear" data-event="change">';
8869				for (; year <= endYear; year++) {
8870					inst.yearshtml += '<option value="' + year + '"' +
8871						(year == drawYear ? ' selected="selected"' : '') +
8872						'>' + year + '</option>';
8873				}
8874				inst.yearshtml += '</select>';
8875
8876				html += inst.yearshtml;
8877				inst.yearshtml = null;
8878			}
8879		}
8880		html += this._get(inst, 'yearSuffix');
8881		if (showMonthAfterYear)
8882			html += (secondary || !(changeMonth && changeYear) ? '&#xa0;' : '') + monthHtml;
8883		html += '</div>'; // Close datepicker_header
8884		return html;
8885	},
8886
8887	/* Adjust one of the date sub-fields. */
8888	_adjustInstDate: function(inst, offset, period) {
8889		var year = inst.drawYear + (period == 'Y' ? offset : 0);
8890		var month = inst.drawMonth + (period == 'M' ? offset : 0);
8891		var day = Math.min(inst.selectedDay, this._getDaysInMonth(year, month)) +
8892			(period == 'D' ? offset : 0);
8893		var date = this._restrictMinMax(inst,
8894			this._daylightSavingAdjust(new Date(year, month, day)));
8895		inst.selectedDay = date.getDate();
8896		inst.drawMonth = inst.selectedMonth = date.getMonth();
8897		inst.drawYear = inst.selectedYear = date.getFullYear();
8898		if (period == 'M' || period == 'Y')
8899			this._notifyChange(inst);
8900	},
8901
8902	/* Ensure a date is within any min/max bounds. */
8903	_restrictMinMax: function(inst, date) {
8904		var minDate = this._getMinMaxDate(inst, 'min');
8905		var maxDate = this._getMinMaxDate(inst, 'max');
8906		var newDate = (minDate && date < minDate ? minDate : date);
8907		newDate = (maxDate && newDate > maxDate ? maxDate : newDate);
8908		return newDate;
8909	},
8910
8911	/* Notify change of month/year. */
8912	_notifyChange: function(inst) {
8913		var onChange = this._get(inst, 'onChangeMonthYear');
8914		if (onChange)
8915			onChange.apply((inst.input ? inst.input[0] : null),
8916				[inst.selectedYear, inst.selectedMonth + 1, inst]);
8917	},
8918
8919	/* Determine the number of months to show. */
8920	_getNumberOfMonths: function(inst) {
8921		var numMonths = this._get(inst, 'numberOfMonths');
8922		return (numMonths == null ? [1, 1] : (typeof numMonths == 'number' ? [1, numMonths] : numMonths));
8923	},
8924
8925	/* Determine the current maximum date - ensure no time components are set. */
8926	_getMinMaxDate: function(inst, minMax) {
8927		return this._determineDate(inst, this._get(inst, minMax + 'Date'), null);
8928	},
8929
8930	/* Find the number of days in a given month. */
8931	_getDaysInMonth: function(year, month) {
8932		return 32 - this._daylightSavingAdjust(new Date(year, month, 32)).getDate();
8933	},
8934
8935	/* Find the day of the week of the first of a month. */
8936	_getFirstDayOfMonth: function(year, month) {
8937		return new Date(year, month, 1).getDay();
8938	},
8939
8940	/* Determines if we should allow a "next/prev" month display change. */
8941	_canAdjustMonth: function(inst, offset, curYear, curMonth) {
8942		var numMonths = this._getNumberOfMonths(inst);
8943		var date = this._daylightSavingAdjust(new Date(curYear,
8944			curMonth + (offset < 0 ? offset : numMonths[0] * numMonths[1]), 1));
8945		if (offset < 0)
8946			date.setDate(this._getDaysInMonth(date.getFullYear(), date.getMonth()));
8947		return this._isInRange(inst, date);
8948	},
8949
8950	/* Is the given date in the accepted range? */
8951	_isInRange: function(inst, date) {
8952		var minDate = this._getMinMaxDate(inst, 'min');
8953		var maxDate = this._getMinMaxDate(inst, 'max');
8954		return ((!minDate || date.getTime() >= minDate.getTime()) &&
8955			(!maxDate || date.getTime() <= maxDate.getTime()));
8956	},
8957
8958	/* Provide the configuration settings for formatting/parsing. */
8959	_getFormatConfig: function(inst) {
8960		var shortYearCutoff = this._get(inst, 'shortYearCutoff');
8961		shortYearCutoff = (typeof shortYearCutoff != 'string' ? shortYearCutoff :
8962			new Date().getFullYear() % 100 + parseInt(shortYearCutoff, 10));
8963		return {shortYearCutoff: shortYearCutoff,
8964			dayNamesShort: this._get(inst, 'dayNamesShort'), dayNames: this._get(inst, 'dayNames'),
8965			monthNamesShort: this._get(inst, 'monthNamesShort'), monthNames: this._get(inst, 'monthNames')};
8966	},
8967
8968	/* Format the given date for display. */
8969	_formatDate: function(inst, day, month, year) {
8970		if (!day) {
8971			inst.currentDay = inst.selectedDay;
8972			inst.currentMonth = inst.selectedMonth;
8973			inst.currentYear = inst.selectedYear;
8974		}
8975		var date = (day ? (typeof day == 'object' ? day :
8976			this._daylightSavingAdjust(new Date(year, month, day))) :
8977			this._daylightSavingAdjust(new Date(inst.currentYear, inst.currentMonth, inst.currentDay)));
8978		return this.formatDate(this._get(inst, 'dateFormat'), date, this._getFormatConfig(inst));
8979	}
8980});
8981
8982/*
8983 * Bind hover events for datepicker elements.
8984 * Done via delegate so the binding only occurs once in the lifetime of the parent div.
8985 * Global instActive, set by _updateDatepicker allows the handlers to find their way back to the active picker.
8986 */
8987function bindHover(dpDiv) {
8988	var selector = 'button, .ui-datepicker-prev, .ui-datepicker-next, .ui-datepicker-calendar td a';
8989	return dpDiv.delegate(selector, 'mouseout', function() {
8990			$(this).removeClass('ui-state-hover');
8991			if (this.className.indexOf('ui-datepicker-prev') != -1) $(this).removeClass('ui-datepicker-prev-hover');
8992			if (this.className.indexOf('ui-datepicker-next') != -1) $(this).removeClass('ui-datepicker-next-hover');
8993		})
8994		.delegate(selector, 'mouseover', function(){
8995			if (!$.datepicker._isDisabledDatepicker( instActive.inline ? dpDiv.parent()[0] : instActive.input[0])) {
8996				$(this).parents('.ui-datepicker-calendar').find('a').removeClass('ui-state-hover');
8997				$(this).addClass('ui-state-hover');
8998				if (this.className.indexOf('ui-datepicker-prev') != -1) $(this).addClass('ui-datepicker-prev-hover');
8999				if (this.className.indexOf('ui-datepicker-next') != -1) $(this).addClass('ui-datepicker-next-hover');
9000			}
9001		});
9002}
9003
9004/* jQuery extend now ignores nulls! */
9005function extendRemove(target, props) {
9006	$.extend(target, props);
9007	for (var name in props)
9008		if (props[name] == null || props[name] == undefined)
9009			target[name] = props[name];
9010	return target;
9011};
9012
9013/* Invoke the datepicker functionality.
9014   @param  options  string - a command, optionally followed by additional parameters or
9015	                Object - settings for attaching new datepicker functionality
9016   @return  jQuery object */
9017$.fn.datepicker = function(options){
9018
9019	/* Verify an empty collection wasn't passed - Fixes #6976 */
9020	if ( !this.length ) {
9021		return this;
9022	}
9023
9024	/* Initialise the date picker. */
9025	if (!$.datepicker.initialized) {
9026		$(document).mousedown($.datepicker._checkExternalClick).
9027			find(document.body).append($.datepicker.dpDiv);
9028		$.datepicker.initialized = true;
9029	}
9030
9031	var otherArgs = Array.prototype.slice.call(arguments, 1);
9032	if (typeof options == 'string' && (options == 'isDisabled' || options == 'getDate' || options == 'widget'))
9033		return $.datepicker['_' + options + 'Datepicker'].
9034			apply($.datepicker, [this[0]].concat(otherArgs));
9035	if (options == 'option' && arguments.length == 2 && typeof arguments[1] == 'string')
9036		return $.datepicker['_' + options + 'Datepicker'].
9037			apply($.datepicker, [this[0]].concat(otherArgs));
9038	return this.each(function() {
9039		typeof options == 'string' ?
9040			$.datepicker['_' + options + 'Datepicker'].
9041				apply($.datepicker, [this].concat(otherArgs)) :
9042			$.datepicker._attachDatepicker(this, options);
9043	});
9044};
9045
9046$.datepicker = new Datepicker(); // singleton instance
9047$.datepicker.initialized = false;
9048$.datepicker.uuid = new Date().getTime();
9049$.datepicker.version = "1.9.2";
9050
9051// Workaround for #4055
9052// Add another global to avoid noConflict issues with inline event handlers
9053window['DP_jQuery_' + dpuuid] = $;
9054
9055})(jQuery);
9056
9057(function( $, undefined ) {
9058
9059var uiDialogClasses = "ui-dialog ui-widget ui-widget-content ui-corner-all ",
9060	sizeRelatedOptions = {
9061		buttons: true,
9062		height: true,
9063		maxHeight: true,
9064		maxWidth: true,
9065		minHeight: true,
9066		minWidth: true,
9067		width: true
9068	},
9069	resizableRelatedOptions = {
9070		maxHeight: true,
9071		maxWidth: true,
9072		minHeight: true,
9073		minWidth: true
9074	};
9075
9076$.widget("ui.dialog", {
9077	version: "1.9.2",
9078	options: {
9079		autoOpen: true,
9080		buttons: {},
9081		closeOnEscape: true,
9082		closeText: "close",
9083		dialogClass: "",
9084		draggable: true,
9085		hide: null,
9086		height: "auto",
9087		maxHeight: false,
9088		maxWidth: false,
9089		minHeight: 150,
9090		minWidth: 150,
9091		modal: false,
9092		position: {
9093			my: "center",
9094			at: "center",
9095			of: window,
9096			collision: "fit",
9097			// ensure that the titlebar is never outside the document
9098			using: function( pos ) {
9099				var topOffset = $( this ).css( pos ).offset().top;
9100				if ( topOffset < 0 ) {
9101					$( this ).css( "top", pos.top - topOffset );
9102				}
9103			}
9104		},
9105		resizable: true,
9106		show: null,
9107		stack: true,
9108		title: "",
9109		width: 300,
9110		zIndex: 1000
9111	},
9112
9113	_create: function() {
9114		this.originalTitle = this.element.attr( "title" );
9115		// #5742 - .attr() might return a DOMElement
9116		if ( typeof this.originalTitle !== "string" ) {
9117			this.originalTitle = "";
9118		}
9119		this.oldPosition = {
9120			parent: this.element.parent(),
9121			index: this.element.parent().children().index( this.element )
9122		};
9123		this.options.title = this.options.title || this.originalTitle;
9124		var that = this,
9125			options = this.options,
9126
9127			title = options.title || "&#160;",
9128			uiDialog,
9129			uiDialogTitlebar,
9130			uiDialogTitlebarClose,
9131			uiDialogTitle,
9132			uiDialogButtonPane;
9133
9134			uiDialog = ( this.uiDialog = $( "<div>" ) )
9135				.addClass( uiDialogClasses + options.dialogClass )
9136				.css({
9137					display: "none",
9138					outline: 0, // TODO: move to stylesheet
9139					zIndex: options.zIndex
9140				})
9141				// setting tabIndex makes the div focusable
9142				.attr( "tabIndex", -1)
9143				.keydown(function( event ) {
9144					if ( options.closeOnEscape && !event.isDefaultPrevented() && event.keyCode &&
9145							event.keyCode === $.ui.keyCode.ESCAPE ) {
9146						that.close( event );
9147						event.preventDefault();
9148					}
9149				})
9150				.mousedown(function( event ) {
9151					that.moveToTop( false, event );
9152				})
9153				.appendTo( "body" );
9154
9155			this.element
9156				.show()
9157				.removeAttr( "title" )
9158				.addClass( "ui-dialog-content ui-widget-content" )
9159				.appendTo( uiDialog );
9160
9161			uiDialogTitlebar = ( this.uiDialogTitlebar = $( "<div>" ) )
9162				.addClass( "ui-dialog-titlebar  ui-widget-header  " +
9163					"ui-corner-all  ui-helper-clearfix" )
9164				.bind( "mousedown", function() {
9165					// Dialog isn't getting focus when dragging (#8063)
9166					uiDialog.focus();
9167				})
9168				.prependTo( uiDialog );
9169
9170			uiDialogTitlebarClose = $( "<a href='#'></a>" )
9171				.addClass( "ui-dialog-titlebar-close  ui-corner-all" )
9172				.attr( "role", "button" )
9173				.click(function( event ) {
9174					event.preventDefault();
9175					that.close( event );
9176				})
9177				.appendTo( uiDialogTitlebar );
9178
9179			( this.uiDialogTitlebarCloseText = $( "<span>" ) )
9180				.addClass( "ui-icon ui-icon-closethick" )
9181				.text( options.closeText )
9182				.appendTo( uiDialogTitlebarClose );
9183
9184			uiDialogTitle = $( "<span>" )
9185				.uniqueId()
9186				.addClass( "ui-dialog-title" )
9187				.html( title )
9188				.prependTo( uiDialogTitlebar );
9189
9190			uiDialogButtonPane = ( this.uiDialogButtonPane = $( "<div>" ) )
9191				.addClass( "ui-dialog-buttonpane ui-widget-content ui-helper-clearfix" );
9192
9193			( this.uiButtonSet = $( "<div>" ) )
9194				.addClass( "ui-dialog-buttonset" )
9195				.appendTo( uiDialogButtonPane );
9196
9197		uiDialog.attr({
9198			role: "dialog",
9199			"aria-labelledby": uiDialogTitle.attr( "id" )
9200		});
9201
9202		uiDialogTitlebar.find( "*" ).add( uiDialogTitlebar ).disableSelection();
9203		this._hoverable( uiDialogTitlebarClose );
9204		this._focusable( uiDialogTitlebarClose );
9205
9206		if ( options.draggable && $.fn.draggable ) {
9207			this._makeDraggable();
9208		}
9209		if ( options.resizable && $.fn.resizable ) {
9210			this._makeResizable();
9211		}
9212
9213		this._createButtons( options.buttons );
9214		this._isOpen = false;
9215
9216		if ( $.fn.bgiframe ) {
9217			uiDialog.bgiframe();
9218		}
9219
9220		// prevent tabbing out of modal dialogs
9221		this._on( uiDialog, { keydown: function( event ) {
9222			if ( !options.modal || event.keyCode !== $.ui.keyCode.TAB ) {
9223				return;
9224			}
9225
9226			var tabbables = $( ":tabbable", uiDialog ),
9227				first = tabbables.filter( ":first" ),
9228				last  = tabbables.filter( ":last" );
9229
9230			if ( event.target === last[0] && !event.shiftKey ) {
9231				first.focus( 1 );
9232				return false;
9233			} else if ( event.target === first[0] && event.shiftKey ) {
9234				last.focus( 1 );
9235				return false;
9236			}
9237		}});
9238	},
9239
9240	_init: function() {
9241		if ( this.options.autoOpen ) {
9242			this.open();
9243		}
9244	},
9245
9246	_destroy: function() {
9247		var next,
9248			oldPosition = this.oldPosition;
9249
9250		if ( this.overlay ) {
9251			this.overlay.destroy();
9252		}
9253		this.uiDialog.hide();
9254		this.element
9255			.removeClass( "ui-dialog-content ui-widget-content" )
9256			.hide()
9257			.appendTo( "body" );
9258		this.uiDialog.remove();
9259
9260		if ( this.originalTitle ) {
9261			this.element.attr( "title", this.originalTitle );
9262		}
9263
9264		next = oldPosition.parent.children().eq( oldPosition.index );
9265		// Don't try to place the dialog next to itself (#8613)
9266		if ( next.length && next[ 0 ] !== this.element[ 0 ] ) {
9267			next.before( this.element );
9268		} else {
9269			oldPosition.parent.append( this.element );
9270		}
9271	},
9272
9273	widget: function() {
9274		return this.uiDialog;
9275	},
9276
9277	close: function( event ) {
9278		var that = this,
9279			maxZ, thisZ;
9280
9281		if ( !this._isOpen ) {
9282			return;
9283		}
9284
9285		if ( false === this._trigger( "beforeClose", event ) ) {
9286			return;
9287		}
9288
9289		this._isOpen = false;
9290
9291		if ( this.overlay ) {
9292			this.overlay.destroy();
9293		}
9294
9295		if ( this.options.hide ) {
9296			this._hide( this.uiDialog, this.options.hide, function() {
9297				that._trigger( "close", event );
9298			});
9299		} else {
9300			this.uiDialog.hide();
9301			this._trigger( "close", event );
9302		}
9303
9304		$.ui.dialog.overlay.resize();
9305
9306		// adjust the maxZ to allow other modal dialogs to continue to work (see #4309)
9307		if ( this.options.modal ) {
9308			maxZ = 0;
9309			$( ".ui-dialog" ).each(function() {
9310				if ( this !== that.uiDialog[0] ) {
9311					thisZ = $( this ).css( "z-index" );
9312					if ( !isNaN( thisZ ) ) {
9313						maxZ = Math.max( maxZ, thisZ );
9314					}
9315				}
9316			});
9317			$.ui.dialog.maxZ = maxZ;
9318		}
9319
9320		return this;
9321	},
9322
9323	isOpen: function() {
9324		return this._isOpen;
9325	},
9326
9327	// the force parameter allows us to move modal dialogs to their correct
9328	// position on open
9329	moveToTop: function( force, event ) {
9330		var options = this.options,
9331			saveScroll;
9332
9333		if ( ( options.modal && !force ) ||
9334				( !options.stack && !options.modal ) ) {
9335			return this._trigger( "focus", event );
9336		}
9337
9338		if ( options.zIndex > $.ui.dialog.maxZ ) {
9339			$.ui.dialog.maxZ = options.zIndex;
9340		}
9341		if ( this.overlay ) {
9342			$.ui.dialog.maxZ += 1;
9343			$.ui.dialog.overlay.maxZ = $.ui.dialog.maxZ;
9344			this.overlay.$el.css( "z-index", $.ui.dialog.overlay.maxZ );
9345		}
9346
9347		// Save and then restore scroll
9348		// Opera 9.5+ resets when parent z-index is changed.
9349		// http://bugs.jqueryui.com/ticket/3193
9350		saveScroll = {
9351			scrollTop: this.element.scrollTop(),
9352			scrollLeft: this.element.scrollLeft()
9353		};
9354		$.ui.dialog.maxZ += 1;
9355		this.uiDialog.css( "z-index", $.ui.dialog.maxZ );
9356		this.element.attr( saveScroll );
9357		this._trigger( "focus", event );
9358
9359		return this;
9360	},
9361
9362	open: function() {
9363		if ( this._isOpen ) {
9364			return;
9365		}
9366
9367		var hasFocus,
9368			options = this.options,
9369			uiDialog = this.uiDialog;
9370
9371		this._size();
9372		this._position( options.position );
9373		uiDialog.show( options.show );
9374		this.overlay = options.modal ? new $.ui.dialog.overlay( this ) : null;
9375		this.moveToTop( true );
9376
9377		// set focus to the first tabbable element in the content area or the first button
9378		// if there are no tabbable elements, set focus on the dialog itself
9379		hasFocus = this.element.find( ":tabbable" );
9380		if ( !hasFocus.length ) {
9381			hasFocus = this.uiDialogButtonPane.find( ":tabbable" );
9382			if ( !hasFocus.length ) {
9383				hasFocus = uiDialog;
9384			}
9385		}
9386		hasFocus.eq( 0 ).focus();
9387
9388		this._isOpen = true;
9389		this._trigger( "open" );
9390
9391		return this;
9392	},
9393
9394	_createButtons: function( buttons ) {
9395		var that = this,
9396			hasButtons = false;
9397
9398		// if we already have a button pane, remove it
9399		this.uiDialogButtonPane.remove();
9400		this.uiButtonSet.empty();
9401
9402		if ( typeof buttons === "object" && buttons !== null ) {
9403			$.each( buttons, function() {
9404				return !(hasButtons = true);
9405			});
9406		}
9407		if ( hasButtons ) {
9408			$.each( buttons, function( name, props ) {
9409				var button, click;
9410				props = $.isFunction( props ) ?
9411					{ click: props, text: name } :
9412					props;
9413				// Default to a non-submitting button
9414				props = $.extend( { type: "button" }, props );
9415				// Change the context for the click callback to be the main element
9416				click = props.click;
9417				props.click = function() {
9418					click.apply( that.element[0], arguments );
9419				};
9420				button = $( "<button></button>", props )
9421					.appendTo( that.uiButtonSet );
9422				if ( $.fn.button ) {
9423					button.button();
9424				}
9425			});
9426			this.uiDialog.addClass( "ui-dialog-buttons" );
9427			this.uiDialogButtonPane.appendTo( this.uiDialog );
9428		} else {
9429			this.uiDialog.removeClass( "ui-dialog-buttons" );
9430		}
9431	},
9432
9433	_makeDraggable: function() {
9434		var that = this,
9435			options = this.options;
9436
9437		function filteredUi( ui ) {
9438			return {
9439				position: ui.position,
9440				offset: ui.offset
9441			};
9442		}
9443
9444		this.uiDialog.draggable({
9445			cancel: ".ui-dialog-content, .ui-dialog-titlebar-close",
9446			handle: ".ui-dialog-titlebar",
9447			containment: "document",
9448			start: function( event, ui ) {
9449				$( this )
9450					.addClass( "ui-dialog-dragging" );
9451				that._trigger( "dragStart", event, filteredUi( ui ) );
9452			},
9453			drag: function( event, ui ) {
9454				that._trigger( "drag", event, filteredUi( ui ) );
9455			},
9456			stop: function( event, ui ) {
9457				options.position = [
9458					ui.position.left - that.document.scrollLeft(),
9459					ui.position.top - that.document.scrollTop()
9460				];
9461				$( this )
9462					.removeClass( "ui-dialog-dragging" );
9463				that._trigger( "dragStop", event, filteredUi( ui ) );
9464				$.ui.dialog.overlay.resize();
9465			}
9466		});
9467	},
9468
9469	_makeResizable: function( handles ) {
9470		handles = (handles === undefined ? this.options.resizable : handles);
9471		var that = this,
9472			options = this.options,
9473			// .ui-resizable has position: relative defined in the stylesheet
9474			// but dialogs have to use absolute or fixed positioning
9475			position = this.uiDialog.css( "position" ),
9476			resizeHandles = typeof handles === 'string' ?
9477				handles	:
9478				"n,e,s,w,se,sw,ne,nw";
9479
9480		function filteredUi( ui ) {
9481			return {
9482				originalPosition: ui.originalPosition,
9483				originalSize: ui.originalSize,
9484				position: ui.position,
9485				size: ui.size
9486			};
9487		}
9488
9489		this.uiDialog.resizable({
9490			cancel: ".ui-dialog-content",
9491			containment: "document",
9492			alsoResize: this.element,
9493			maxWidth: options.maxWidth,
9494			maxHeight: options.maxHeight,
9495			minWidth: options.minWidth,
9496			minHeight: this._minHeight(),
9497			handles: resizeHandles,
9498			start: function( event, ui ) {
9499				$( this ).addClass( "ui-dialog-resizing" );
9500				that._trigger( "resizeStart", event, filteredUi( ui ) );
9501			},
9502			resize: function( event, ui ) {
9503				that._trigger( "resize", event, filteredUi( ui ) );
9504			},
9505			stop: function( event, ui ) {
9506				$( this ).removeClass( "ui-dialog-resizing" );
9507				options.height = $( this ).height();
9508				options.width = $( this ).width();
9509				that._trigger( "resizeStop", event, filteredUi( ui ) );
9510				$.ui.dialog.overlay.resize();
9511			}
9512		})
9513		.css( "position", position )
9514		.find( ".ui-resizable-se" )
9515			.addClass( "ui-icon ui-icon-grip-diagonal-se" );
9516	},
9517
9518	_minHeight: function() {
9519		var options = this.options;
9520
9521		if ( options.height === "auto" ) {
9522			return options.minHeight;
9523		} else {
9524			return Math.min( options.minHeight, options.height );
9525		}
9526	},
9527
9528	_position: function( position ) {
9529		var myAt = [],
9530			offset = [ 0, 0 ],
9531			isVisible;
9532
9533		if ( position ) {
9534			// deep extending converts arrays to objects in jQuery <= 1.3.2 :-(
9535	//		if (typeof position == 'string' || $.isArray(position)) {
9536	//			myAt = $.isArray(position) ? position : position.split(' ');
9537
9538			if ( typeof position === "string" || (typeof position === "object" && "0" in position ) ) {
9539				myAt = position.split ? position.split( " " ) : [ position[ 0 ], position[ 1 ] ];
9540				if ( myAt.length === 1 ) {
9541					myAt[ 1 ] = myAt[ 0 ];
9542				}
9543
9544				$.each( [ "left", "top" ], function( i, offsetPosition ) {
9545					if ( +myAt[ i ] === myAt[ i ] ) {
9546						offset[ i ] = myAt[ i ];
9547						myAt[ i ] = offsetPosition;
9548					}
9549				});
9550
9551				position = {
9552					my: myAt[0] + (offset[0] < 0 ? offset[0] : "+" + offset[0]) + " " +
9553						myAt[1] + (offset[1] < 0 ? offset[1] : "+" + offset[1]),
9554					at: myAt.join( " " )
9555				};
9556			}
9557
9558			position = $.extend( {}, $.ui.dialog.prototype.options.position, position );
9559		} else {
9560			position = $.ui.dialog.prototype.options.position;
9561		}
9562
9563		// need to show the dialog to get the actual offset in the position plugin
9564		isVisible = this.uiDialog.is( ":visible" );
9565		if ( !isVisible ) {
9566			this.uiDialog.show();
9567		}
9568		this.uiDialog.position( position );
9569		if ( !isVisible ) {
9570			this.uiDialog.hide();
9571		}
9572	},
9573
9574	_setOptions: function( options ) {
9575		var that = this,
9576			resizableOptions = {},
9577			resize = false;
9578
9579		$.each( options, function( key, value ) {
9580			that._setOption( key, value );
9581
9582			if ( key in sizeRelatedOptions ) {
9583				resize = true;
9584			}
9585			if ( key in resizableRelatedOptions ) {
9586				resizableOptions[ key ] = value;
9587			}
9588		});
9589
9590		if ( resize ) {
9591			this._size();
9592		}
9593		if ( this.uiDialog.is( ":data(resizable)" ) ) {
9594			this.uiDialog.resizable( "option", resizableOptions );
9595		}
9596	},
9597
9598	_setOption: function( key, value ) {
9599		var isDraggable, isResizable,
9600			uiDialog = this.uiDialog;
9601
9602		switch ( key ) {
9603			case "buttons":
9604				this._createButtons( value );
9605				break;
9606			case "closeText":
9607				// ensure that we always pass a string
9608				this.uiDialogTitlebarCloseText.text( "" + value );
9609				break;
9610			case "dialogClass":
9611				uiDialog
9612					.removeClass( this.options.dialogClass )
9613					.addClass( uiDialogClasses + value );
9614				break;
9615			case "disabled":
9616				if ( value ) {
9617					uiDialog.addClass( "ui-dialog-disabled" );
9618				} else {
9619					uiDialog.removeClass( "ui-dialog-disabled" );
9620				}
9621				break;
9622			case "draggable":
9623				isDraggable = uiDialog.is( ":data(draggable)" );
9624				if ( isDraggable && !value ) {
9625					uiDialog.draggable( "destroy" );
9626				}
9627
9628				if ( !isDraggable && value ) {
9629					this._makeDraggable();
9630				}
9631				break;
9632			case "position":
9633				this._position( value );
9634				break;
9635			case "resizable":
9636				// currently resizable, becoming non-resizable
9637				isResizable = uiDialog.is( ":data(resizable)" );
9638				if ( isResizable && !value ) {
9639					uiDialog.resizable( "destroy" );
9640				}
9641
9642				// currently resizable, changing handles
9643				if ( isResizable && typeof value === "string" ) {
9644					uiDialog.resizable( "option", "handles", value );
9645				}
9646
9647				// currently non-resizable, becoming resizable
9648				if ( !isResizable && value !== false ) {
9649					this._makeResizable( value );
9650				}
9651				break;
9652			case "title":
9653				// convert whatever was passed in o a string, for html() to not throw up
9654				$( ".ui-dialog-title", this.uiDialogTitlebar )
9655					.html( "" + ( value || "&#160;" ) );
9656				break;
9657		}
9658
9659		this._super( key, value );
9660	},
9661
9662	_size: function() {
9663		/* If the user has resized the dialog, the .ui-dialog and .ui-dialog-content
9664		 * divs will both have width and height set, so we need to reset them
9665		 */
9666		var nonContentHeight, minContentHeight, autoHeight,
9667			options = this.options,
9668			isVisible = this.uiDialog.is( ":visible" );
9669
9670		// reset content sizing
9671		this.element.show().css({
9672			width: "auto",
9673			minHeight: 0,
9674			height: 0
9675		});
9676
9677		if ( options.minWidth > options.width ) {
9678			options.width = options.minWidth;
9679		}
9680
9681		// reset wrapper sizing
9682		// determine the height of all the non-content elements
9683		nonContentHeight = this.uiDialog.css({
9684				height: "auto",
9685				width: options.width
9686			})
9687			.outerHeight();
9688		minContentHeight = Math.max( 0, options.minHeight - nonContentHeight );
9689
9690		if ( options.height === "auto" ) {
9691			// only needed for IE6 support
9692			if ( $.support.minHeight ) {
9693				this.element.css({
9694					minHeight: minContentHeight,
9695					height: "auto"
9696				});
9697			} else {
9698				this.uiDialog.show();
9699				autoHeight = this.element.css( "height", "auto" ).height();
9700				if ( !isVisible ) {
9701					this.uiDialog.hide();
9702				}
9703				this.element.height( Math.max( autoHeight, minContentHeight ) );
9704			}
9705		} else {
9706			this.element.height( Math.max( options.height - nonContentHeight, 0 ) );
9707		}
9708
9709		if (this.uiDialog.is( ":data(resizable)" ) ) {
9710			this.uiDialog.resizable( "option", "minHeight", this._minHeight() );
9711		}
9712	}
9713});
9714
9715$.extend($.ui.dialog, {
9716	uuid: 0,
9717	maxZ: 0,
9718
9719	getTitleId: function($el) {
9720		var id = $el.attr( "id" );
9721		if ( !id ) {
9722			this.uuid += 1;
9723			id = this.uuid;
9724		}
9725		return "ui-dialog-title-" + id;
9726	},
9727
9728	overlay: function( dialog ) {
9729		this.$el = $.ui.dialog.overlay.create( dialog );
9730	}
9731});
9732
9733$.extend( $.ui.dialog.overlay, {
9734	instances: [],
9735	// reuse old instances due to IE memory leak with alpha transparency (see #5185)
9736	oldInstances: [],
9737	maxZ: 0,
9738	events: $.map(
9739		"focus,mousedown,mouseup,keydown,keypress,click".split( "," ),
9740		function( event ) {
9741			return event + ".dialog-overlay";
9742		}
9743	).join( " " ),
9744	create: function( dialog ) {
9745		if ( this.instances.length === 0 ) {
9746			// prevent use of anchors and inputs
9747			// we use a setTimeout in case the overlay is created from an
9748			// event that we're going to be cancelling (see #2804)
9749			setTimeout(function() {
9750				// handle $(el).dialog().dialog('close') (see #4065)
9751				if ( $.ui.dialog.overlay.instances.length ) {
9752					$( document ).bind( $.ui.dialog.overlay.events, function( event ) {
9753						// stop events if the z-index of the target is < the z-index of the overlay
9754						// we cannot return true when we don't want to cancel the event (#3523)
9755						if ( $( event.target ).zIndex() < $.ui.dialog.overlay.maxZ ) {
9756							return false;
9757						}
9758					});
9759				}
9760			}, 1 );
9761
9762			// handle window resize
9763			$( window ).bind( "resize.dialog-overlay", $.ui.dialog.overlay.resize );
9764		}
9765
9766		var $el = ( this.oldInstances.pop() || $( "<div>" ).addClass( "ui-widget-overlay" ) );
9767
9768		// allow closing by pressing the escape key
9769		$( document ).bind( "keydown.dialog-overlay", function( event ) {
9770			var instances = $.ui.dialog.overlay.instances;
9771			// only react to the event if we're the top overlay
9772			if ( instances.length !== 0 && instances[ instances.length - 1 ] === $el &&
9773				dialog.options.closeOnEscape && !event.isDefaultPrevented() && event.keyCode &&
9774				event.keyCode === $.ui.keyCode.ESCAPE ) {
9775
9776				dialog.close( event );
9777				event.preventDefault();
9778			}
9779		});
9780
9781		$el.appendTo( document.body ).css({
9782			width: this.width(),
9783			height: this.height()
9784		});
9785
9786		if ( $.fn.bgiframe ) {
9787			$el.bgiframe();
9788		}
9789
9790		this.instances.push( $el );
9791		return $el;
9792	},
9793
9794	destroy: function( $el ) {
9795		var indexOf = $.inArray( $el, this.instances ),
9796			maxZ = 0;
9797
9798		if ( indexOf !== -1 ) {
9799			this.oldInstances.push( this.instances.splice( indexOf, 1 )[ 0 ] );
9800		}
9801
9802		if ( this.instances.length === 0 ) {
9803			$( [ document, window ] ).unbind( ".dialog-overlay" );
9804		}
9805
9806		$el.height( 0 ).width( 0 ).remove();
9807
9808		// adjust the maxZ to allow other modal dialogs to continue to work (see #4309)
9809		$.each( this.instances, function() {
9810			maxZ = Math.max( maxZ, this.css( "z-index" ) );
9811		});
9812		this.maxZ = maxZ;
9813	},
9814
9815	height: function() {
9816		var scrollHeight,
9817			offsetHeight;
9818		// handle IE
9819		if ( $.ui.ie ) {
9820			scrollHeight = Math.max(
9821				document.documentElement.scrollHeight,
9822				document.body.scrollHeight
9823			);
9824			offsetHeight = Math.max(
9825				document.documentElement.offsetHeight,
9826				document.body.offsetHeight
9827			);
9828
9829			if ( scrollHeight < offsetHeight ) {
9830				return $( window ).height() + "px";
9831			} else {
9832				return scrollHeight + "px";
9833			}
9834		// handle "good" browsers
9835		} else {
9836			return $( document ).height() + "px";
9837		}
9838	},
9839
9840	width: function() {
9841		var scrollWidth,
9842			offsetWidth;
9843		// handle IE
9844		if ( $.ui.ie ) {
9845			scrollWidth = Math.max(
9846				document.documentElement.scrollWidth,
9847				document.body.scrollWidth
9848			);
9849			offsetWidth = Math.max(
9850				document.documentElement.offsetWidth,
9851				document.body.offsetWidth
9852			);
9853
9854			if ( scrollWidth < offsetWidth ) {
9855				return $( window ).width() + "px";
9856			} else {
9857				return scrollWidth + "px";
9858			}
9859		// handle "good" browsers
9860		} else {
9861			return $( document ).width() + "px";
9862		}
9863	},
9864
9865	resize: function() {
9866		/* If the dialog is draggable and the user drags it past the
9867		 * right edge of the window, the document becomes wider so we
9868		 * need to stretch the overlay. If the user then drags the
9869		 * dialog back to the left, the document will become narrower,
9870		 * so we need to shrink the overlay to the appropriate size.
9871		 * This is handled by shrinking the overlay before setting it
9872		 * to the full document size.
9873		 */
9874		var $overlays = $( [] );
9875		$.each( $.ui.dialog.overlay.instances, function() {
9876			$overlays = $overlays.add( this );
9877		});
9878
9879		$overlays.css({
9880			width: 0,
9881			height: 0
9882		}).css({
9883			width: $.ui.dialog.overlay.width(),
9884			height: $.ui.dialog.overlay.height()
9885		});
9886	}
9887});
9888
9889$.extend( $.ui.dialog.overlay.prototype, {
9890	destroy: function() {
9891		$.ui.dialog.overlay.destroy( this.$el );
9892	}
9893});
9894
9895}( jQuery ) );
9896
9897(function( $, undefined ) {
9898
9899var rvertical = /up|down|vertical/,
9900	rpositivemotion = /up|left|vertical|horizontal/;
9901
9902$.effects.effect.blind = function( o, done ) {
9903	// Create element
9904	var el = $( this ),
9905		props = [ "position", "top", "bottom", "left", "right", "height", "width" ],
9906		mode = $.effects.setMode( el, o.mode || "hide" ),
9907		direction = o.direction || "up",
9908		vertical = rvertical.test( direction ),
9909		ref = vertical ? "height" : "width",
9910		ref2 = vertical ? "top" : "left",
9911		motion = rpositivemotion.test( direction ),
9912		animation = {},
9913		show = mode === "show",
9914		wrapper, distance, margin;
9915
9916	// if already wrapped, the wrapper's properties are my property. #6245
9917	if ( el.parent().is( ".ui-effects-wrapper" ) ) {
9918		$.effects.save( el.parent(), props );
9919	} else {
9920		$.effects.save( el, props );
9921	}
9922	el.show();
9923	wrapper = $.effects.createWrapper( el ).css({
9924		overflow: "hidden"
9925	});
9926
9927	distance = wrapper[ ref ]();
9928	margin = parseFloat( wrapper.css( ref2 ) ) || 0;
9929
9930	animation[ ref ] = show ? distance : 0;
9931	if ( !motion ) {
9932		el
9933			.css( vertical ? "bottom" : "right", 0 )
9934			.css( vertical ? "top" : "left", "auto" )
9935			.css({ position: "absolute" });
9936
9937		animation[ ref2 ] = show ? margin : distance + margin;
9938	}
9939
9940	// start at 0 if we are showing
9941	if ( show ) {
9942		wrapper.css( ref, 0 );
9943		if ( ! motion ) {
9944			wrapper.css( ref2, margin + distance );
9945		}
9946	}
9947
9948	// Animate
9949	wrapper.animate( animation, {
9950		duration: o.duration,
9951		easing: o.easing,
9952		queue: false,
9953		complete: function() {
9954			if ( mode === "hide" ) {
9955				el.hide();
9956			}
9957			$.effects.restore( el, props );
9958			$.effects.removeWrapper( el );
9959			done();
9960		}
9961	});
9962
9963};
9964
9965})(jQuery);
9966
9967(function( $, undefined ) {
9968
9969$.effects.effect.bounce = function( o, done ) {
9970	var el = $( this ),
9971		props = [ "position", "top", "bottom", "left", "right", "height", "width" ],
9972
9973		// defaults:
9974		mode = $.effects.setMode( el, o.mode || "effect" ),
9975		hide = mode === "hide",
9976		show = mode === "show",
9977		direction = o.direction || "up",
9978		distance = o.distance,
9979		times = o.times || 5,
9980
9981		// number of internal animations
9982		anims = times * 2 + ( show || hide ? 1 : 0 ),
9983		speed = o.duration / anims,
9984		easing = o.easing,
9985
9986		// utility:
9987		ref = ( direction === "up" || direction === "down" ) ? "top" : "left",
9988		motion = ( direction === "up" || direction === "left" ),
9989		i,
9990		upAnim,
9991		downAnim,
9992
9993		// we will need to re-assemble the queue to stack our animations in place
9994		queue = el.queue(),
9995		queuelen = queue.length;
9996
9997	// Avoid touching opacity to prevent clearType and PNG issues in IE
9998	if ( show || hide ) {
9999		props.push( "opacity" );
10000	}
10001
10002	$.effects.save( el, props );
10003	el.show();
10004	$.effects.createWrapper( el ); // Create Wrapper
10005
10006	// default distance for the BIGGEST bounce is the outer Distance / 3
10007	if ( !distance ) {
10008		distance = el[ ref === "top" ? "outerHeight" : "outerWidth" ]() / 3;
10009	}
10010
10011	if ( show ) {
10012		downAnim = { opacity: 1 };
10013		downAnim[ ref ] = 0;
10014
10015		// if we are showing, force opacity 0 and set the initial position
10016		// then do the "first" animation
10017		el.css( "opacity", 0 )
10018			.css( ref, motion ? -distance * 2 : distance * 2 )
10019			.animate( downAnim, speed, easing );
10020	}
10021
10022	// start at the smallest distance if we are hiding
10023	if ( hide ) {
10024		distance = distance / Math.pow( 2, times - 1 );
10025	}
10026
10027	downAnim = {};
10028	downAnim[ ref ] = 0;
10029	// Bounces up/down/left/right then back to 0 -- times * 2 animations happen here
10030	for ( i = 0; i < times; i++ ) {
10031		upAnim = {};
10032		upAnim[ ref ] = ( motion ? "-=" : "+=" ) + distance;
10033
10034		el.animate( upAnim, speed, easing )
10035			.animate( downAnim, speed, easing );
10036
10037		distance = hide ? distance * 2 : distance / 2;
10038	}
10039
10040	// Last Bounce when Hiding
10041	if ( hide ) {
10042		upAnim = { opacity: 0 };
10043		upAnim[ ref ] = ( motion ? "-=" : "+=" ) + distance;
10044
10045		el.animate( upAnim, speed, easing );
10046	}
10047
10048	el.queue(function() {
10049		if ( hide ) {
10050			el.hide();
10051		}
10052		$.effects.restore( el, props );
10053		$.effects.removeWrapper( el );
10054		done();
10055	});
10056
10057	// inject all the animations we just queued to be first in line (after "inprogress")
10058	if ( queuelen > 1) {
10059		queue.splice.apply( queue,
10060			[ 1, 0 ].concat( queue.splice( queuelen, anims + 1 ) ) );
10061	}
10062	el.dequeue();
10063
10064};
10065
10066})(jQuery);
10067
10068(function( $, undefined ) {
10069
10070$.effects.effect.clip = function( o, done ) {
10071	// Create element
10072	var el = $( this ),
10073		props = [ "position", "top", "bottom", "left", "right", "height", "width" ],
10074		mode = $.effects.setMode( el, o.mode || "hide" ),
10075		show = mode === "show",
10076		direction = o.direction || "vertical",
10077		vert = direction === "vertical",
10078		size = vert ? "height" : "width",
10079		position = vert ? "top" : "left",
10080		animation = {},
10081		wrapper, animate, distance;
10082
10083	// Save & Show
10084	$.effects.save( el, props );
10085	el.show();
10086
10087	// Create Wrapper
10088	wrapper = $.effects.createWrapper( el ).css({
10089		overflow: "hidden"
10090	});
10091	animate = ( el[0].tagName === "IMG" ) ? wrapper : el;
10092	distance = animate[ size ]();
10093
10094	// Shift
10095	if ( show ) {
10096		animate.css( size, 0 );
10097		animate.css( position, distance / 2 );
10098	}
10099
10100	// Create Animation Object:
10101	animation[ size ] = show ? distance : 0;
10102	animation[ position ] = show ? 0 : distance / 2;
10103
10104	// Animate
10105	animate.animate( animation, {
10106		queue: false,
10107		duration: o.duration,
10108		easing: o.easing,
vendor: 78,927 bytes, lines 10109-13051
10109		complete: function() {
10110			if ( !show ) {
10111				el.hide();
10112			}
10113			$.effects.restore( el, props );
10114			$.effects.removeWrapper( el );
10115			done();
10116		}
10117	});
10118
10119};
10120
10121})(jQuery);
10122
10123(function( $, undefined ) {
10124
10125$.effects.effect.drop = function( o, done ) {
10126
10127	var el = $( this ),
10128		props = [ "position", "top", "bottom", "left", "right", "opacity", "height", "width" ],
10129		mode = $.effects.setMode( el, o.mode || "hide" ),
10130		show = mode === "show",
10131		direction = o.direction || "left",
10132		ref = ( direction === "up" || direction === "down" ) ? "top" : "left",
10133		motion = ( direction === "up" || direction === "left" ) ? "pos" : "neg",
10134		animation = {
10135			opacity: show ? 1 : 0
10136		},
10137		distance;
10138
10139	// Adjust
10140	$.effects.save( el, props );
10141	el.show();
10142	$.effects.createWrapper( el );
10143
10144	distance = o.distance || el[ ref === "top" ? "outerHeight": "outerWidth" ]( true ) / 2;
10145
10146	if ( show ) {
10147		el
10148			.css( "opacity", 0 )
10149			.css( ref, motion === "pos" ? -distance : distance );
10150	}
10151
10152	// Animation
10153	animation[ ref ] = ( show ?
10154		( motion === "pos" ? "+=" : "-=" ) :
10155		( motion === "pos" ? "-=" : "+=" ) ) +
10156		distance;
10157
10158	// Animate
10159	el.animate( animation, {
10160		queue: false,
10161		duration: o.duration,
10162		easing: o.easing,
10163		complete: function() {
10164			if ( mode === "hide" ) {
10165				el.hide();
10166			}
10167			$.effects.restore( el, props );
10168			$.effects.removeWrapper( el );
10169			done();
10170		}
10171	});
10172};
10173
10174})(jQuery);
10175
10176(function( $, undefined ) {
10177
10178$.effects.effect.explode = function( o, done ) {
10179
10180	var rows = o.pieces ? Math.round( Math.sqrt( o.pieces ) ) : 3,
10181		cells = rows,
10182		el = $( this ),
10183		mode = $.effects.setMode( el, o.mode || "hide" ),
10184		show = mode === "show",
10185
10186		// show and then visibility:hidden the element before calculating offset
10187		offset = el.show().css( "visibility", "hidden" ).offset(),
10188
10189		// width and height of a piece
10190		width = Math.ceil( el.outerWidth() / cells ),
10191		height = Math.ceil( el.outerHeight() / rows ),
10192		pieces = [],
10193
10194		// loop
10195		i, j, left, top, mx, my;
10196
10197	// children animate complete:
10198	function childComplete() {
10199		pieces.push( this );
10200		if ( pieces.length === rows * cells ) {
10201			animComplete();
10202		}
10203	}
10204
10205	// clone the element for each row and cell.
10206	for( i = 0; i < rows ; i++ ) { // ===>
10207		top = offset.top + i * height;
10208		my = i - ( rows - 1 ) / 2 ;
10209
10210		for( j = 0; j < cells ; j++ ) { // |||
10211			left = offset.left + j * width;
10212			mx = j - ( cells - 1 ) / 2 ;
10213
10214			// Create a clone of the now hidden main element that will be absolute positioned
10215			// within a wrapper div off the -left and -top equal to size of our pieces
10216			el
10217				.clone()
10218				.appendTo( "body" )
10219				.wrap( "<div></div>" )
10220				.css({
10221					position: "absolute",
10222					visibility: "visible",
10223					left: -j * width,
10224					top: -i * height
10225				})
10226
10227			// select the wrapper - make it overflow: hidden and absolute positioned based on
10228			// where the original was located +left and +top equal to the size of pieces
10229				.parent()
10230				.addClass( "ui-effects-explode" )
10231				.css({
10232					position: "absolute",
10233					overflow: "hidden",
10234					width: width,
10235					height: height,
10236					left: left + ( show ? mx * width : 0 ),
10237					top: top + ( show ? my * height : 0 ),
10238					opacity: show ? 0 : 1
10239				}).animate({
10240					left: left + ( show ? 0 : mx * width ),
10241					top: top + ( show ? 0 : my * height ),
10242					opacity: show ? 1 : 0
10243				}, o.duration || 500, o.easing, childComplete );
10244		}
10245	}
10246
10247	function animComplete() {
10248		el.css({
10249			visibility: "visible"
10250		});
10251		$( pieces ).remove();
10252		if ( !show ) {
10253			el.hide();
10254		}
10255		done();
10256	}
10257};
10258
10259})(jQuery);
10260
10261(function( $, undefined ) {
10262
10263$.effects.effect.fade = function( o, done ) {
10264	var el = $( this ),
10265		mode = $.effects.setMode( el, o.mode || "toggle" );
10266
10267	el.animate({
10268		opacity: mode
10269	}, {
10270		queue: false,
10271		duration: o.duration,
10272		easing: o.easing,
10273		complete: done
10274	});
10275};
10276
10277})( jQuery );
10278
10279(function( $, undefined ) {
10280
10281$.effects.effect.fold = function( o, done ) {
10282
10283	// Create element
10284	var el = $( this ),
10285		props = [ "position", "top", "bottom", "left", "right", "height", "width" ],
10286		mode = $.effects.setMode( el, o.mode || "hide" ),
10287		show = mode === "show",
10288		hide = mode === "hide",
10289		size = o.size || 15,
10290		percent = /([0-9]+)%/.exec( size ),
10291		horizFirst = !!o.horizFirst,
10292		widthFirst = show !== horizFirst,
10293		ref = widthFirst ? [ "width", "height" ] : [ "height", "width" ],
10294		duration = o.duration / 2,
10295		wrapper, distance,
10296		animation1 = {},
10297		animation2 = {};
10298
10299	$.effects.save( el, props );
10300	el.show();
10301
10302	// Create Wrapper
10303	wrapper = $.effects.createWrapper( el ).css({
10304		overflow: "hidden"
10305	});
10306	distance = widthFirst ?
10307		[ wrapper.width(), wrapper.height() ] :
10308		[ wrapper.height(), wrapper.width() ];
10309
10310	if ( percent ) {
10311		size = parseInt( percent[ 1 ], 10 ) / 100 * distance[ hide ? 0 : 1 ];
10312	}
10313	if ( show ) {
10314		wrapper.css( horizFirst ? {
10315			height: 0,
10316			width: size
10317		} : {
10318			height: size,
10319			width: 0
10320		});
10321	}
10322
10323	// Animation
10324	animation1[ ref[ 0 ] ] = show ? distance[ 0 ] : size;
10325	animation2[ ref[ 1 ] ] = show ? distance[ 1 ] : 0;
10326
10327	// Animate
10328	wrapper
10329		.animate( animation1, duration, o.easing )
10330		.animate( animation2, duration, o.easing, function() {
10331			if ( hide ) {
10332				el.hide();
10333			}
10334			$.effects.restore( el, props );
10335			$.effects.removeWrapper( el );
10336			done();
10337		});
10338
10339};
10340
10341})(jQuery);
10342
10343(function( $, undefined ) {
10344
10345$.effects.effect.highlight = function( o, done ) {
10346	var elem = $( this ),
10347		props = [ "backgroundImage", "backgroundColor", "opacity" ],
10348		mode = $.effects.setMode( elem, o.mode || "show" ),
10349		animation = {
10350			backgroundColor: elem.css( "backgroundColor" )
10351		};
10352
10353	if (mode === "hide") {
10354		animation.opacity = 0;
10355	}
10356
10357	$.effects.save( elem, props );
10358
10359	elem
10360		.show()
10361		.css({
10362			backgroundImage: "none",
10363			backgroundColor: o.color || "#ffff99"
10364		})
10365		.animate( animation, {
10366			queue: false,
10367			duration: o.duration,
10368			easing: o.easing,
10369			complete: function() {
10370				if ( mode === "hide" ) {
10371					elem.hide();
10372				}
10373				$.effects.restore( elem, props );
10374				done();
10375			}
10376		});
10377};
10378
10379})(jQuery);
10380
10381(function( $, undefined ) {
10382
10383$.effects.effect.pulsate = function( o, done ) {
10384	var elem = $( this ),
10385		mode = $.effects.setMode( elem, o.mode || "show" ),
10386		show = mode === "show",
10387		hide = mode === "hide",
10388		showhide = ( show || mode === "hide" ),
10389
10390		// showing or hiding leaves of the "last" animation
10391		anims = ( ( o.times || 5 ) * 2 ) + ( showhide ? 1 : 0 ),
10392		duration = o.duration / anims,
10393		animateTo = 0,
10394		queue = elem.queue(),
10395		queuelen = queue.length,
10396		i;
10397
10398	if ( show || !elem.is(":visible")) {
10399		elem.css( "opacity", 0 ).show();
10400		animateTo = 1;
10401	}
10402
10403	// anims - 1 opacity "toggles"
10404	for ( i = 1; i < anims; i++ ) {
10405		elem.animate({
10406			opacity: animateTo
10407		}, duration, o.easing );
10408		animateTo = 1 - animateTo;
10409	}
10410
10411	elem.animate({
10412		opacity: animateTo
10413	}, duration, o.easing);
10414
10415	elem.queue(function() {
10416		if ( hide ) {
10417			elem.hide();
10418		}
10419		done();
10420	});
10421
10422	// We just queued up "anims" animations, we need to put them next in the queue
10423	if ( queuelen > 1 ) {
10424		queue.splice.apply( queue,
10425			[ 1, 0 ].concat( queue.splice( queuelen, anims + 1 ) ) );
10426	}
10427	elem.dequeue();
10428};
10429
10430})(jQuery);
10431
10432(function( $, undefined ) {
10433
10434$.effects.effect.puff = function( o, done ) {
10435	var elem = $( this ),
10436		mode = $.effects.setMode( elem, o.mode || "hide" ),
10437		hide = mode === "hide",
10438		percent = parseInt( o.percent, 10 ) || 150,
10439		factor = percent / 100,
10440		original = {
10441			height: elem.height(),
10442			width: elem.width(),
10443			outerHeight: elem.outerHeight(),
10444			outerWidth: elem.outerWidth()
10445		};
10446
10447	$.extend( o, {
10448		effect: "scale",
10449		queue: false,
10450		fade: true,
10451		mode: mode,
10452		complete: done,
10453		percent: hide ? percent : 100,
10454		from: hide ?
10455			original :
10456			{
10457				height: original.height * factor,
10458				width: original.width * factor,
10459				outerHeight: original.outerHeight * factor,
10460				outerWidth: original.outerWidth * factor
10461			}
10462	});
10463
10464	elem.effect( o );
10465};
10466
10467$.effects.effect.scale = function( o, done ) {
10468
10469	// Create element
10470	var el = $( this ),
10471		options = $.extend( true, {}, o ),
10472		mode = $.effects.setMode( el, o.mode || "effect" ),
10473		percent = parseInt( o.percent, 10 ) ||
10474			( parseInt( o.percent, 10 ) === 0 ? 0 : ( mode === "hide" ? 0 : 100 ) ),
10475		direction = o.direction || "both",
10476		origin = o.origin,
10477		original = {
10478			height: el.height(),
10479			width: el.width(),
10480			outerHeight: el.outerHeight(),
10481			outerWidth: el.outerWidth()
10482		},
10483		factor = {
10484			y: direction !== "horizontal" ? (percent / 100) : 1,
10485			x: direction !== "vertical" ? (percent / 100) : 1
10486		};
10487
10488	// We are going to pass this effect to the size effect:
10489	options.effect = "size";
10490	options.queue = false;
10491	options.complete = done;
10492
10493	// Set default origin and restore for show/hide
10494	if ( mode !== "effect" ) {
10495		options.origin = origin || ["middle","center"];
10496		options.restore = true;
10497	}
10498
10499	options.from = o.from || ( mode === "show" ? {
10500		height: 0,
10501		width: 0,
10502		outerHeight: 0,
10503		outerWidth: 0
10504	} : original );
10505	options.to = {
10506		height: original.height * factor.y,
10507		width: original.width * factor.x,
10508		outerHeight: original.outerHeight * factor.y,
10509		outerWidth: original.outerWidth * factor.x
10510	};
10511
10512	// Fade option to support puff
10513	if ( options.fade ) {
10514		if ( mode === "show" ) {
10515			options.from.opacity = 0;
10516			options.to.opacity = 1;
10517		}
10518		if ( mode === "hide" ) {
10519			options.from.opacity = 1;
10520			options.to.opacity = 0;
10521		}
10522	}
10523
10524	// Animate
10525	el.effect( options );
10526
10527};
10528
10529$.effects.effect.size = function( o, done ) {
10530
10531	// Create element
10532	var original, baseline, factor,
10533		el = $( this ),
10534		props0 = [ "position", "top", "bottom", "left", "right", "width", "height", "overflow", "opacity" ],
10535
10536		// Always restore
10537		props1 = [ "position", "top", "bottom", "left", "right", "overflow", "opacity" ],
10538
10539		// Copy for children
10540		props2 = [ "width", "height", "overflow" ],
10541		cProps = [ "fontSize" ],
10542		vProps = [ "borderTopWidth", "borderBottomWidth", "paddingTop", "paddingBottom" ],
10543		hProps = [ "borderLeftWidth", "borderRightWidth", "paddingLeft", "paddingRight" ],
10544
10545		// Set options
10546		mode = $.effects.setMode( el, o.mode || "effect" ),
10547		restore = o.restore || mode !== "effect",
10548		scale = o.scale || "both",
10549		origin = o.origin || [ "middle", "center" ],
10550		position = el.css( "position" ),
10551		props = restore ? props0 : props1,
10552		zero = {
10553			height: 0,
10554			width: 0,
10555			outerHeight: 0,
10556			outerWidth: 0
10557		};
10558
10559	if ( mode === "show" ) {
10560		el.show();
10561	}
10562	original = {
10563		height: el.height(),
10564		width: el.width(),
10565		outerHeight: el.outerHeight(),
10566		outerWidth: el.outerWidth()
10567	};
10568
10569	if ( o.mode === "toggle" && mode === "show" ) {
10570		el.from = o.to || zero;
10571		el.to = o.from || original;
10572	} else {
10573		el.from = o.from || ( mode === "show" ? zero : original );
10574		el.to = o.to || ( mode === "hide" ? zero : original );
10575	}
10576
10577	// Set scaling factor
10578	factor = {
10579		from: {
10580			y: el.from.height / original.height,
10581			x: el.from.width / original.width
10582		},
10583		to: {
10584			y: el.to.height / original.height,
10585			x: el.to.width / original.width
10586		}
10587	};
10588
10589	// Scale the css box
10590	if ( scale === "box" || scale === "both" ) {
10591
10592		// Vertical props scaling
10593		if ( factor.from.y !== factor.to.y ) {
10594			props = props.concat( vProps );
10595			el.from = $.effects.setTransition( el, vProps, factor.from.y, el.from );
10596			el.to = $.effects.setTransition( el, vProps, factor.to.y, el.to );
10597		}
10598
10599		// Horizontal props scaling
10600		if ( factor.from.x !== factor.to.x ) {
10601			props = props.concat( hProps );
10602			el.from = $.effects.setTransition( el, hProps, factor.from.x, el.from );
10603			el.to = $.effects.setTransition( el, hProps, factor.to.x, el.to );
10604		}
10605	}
10606
10607	// Scale the content
10608	if ( scale === "content" || scale === "both" ) {
10609
10610		// Vertical props scaling
10611		if ( factor.from.y !== factor.to.y ) {
10612			props = props.concat( cProps ).concat( props2 );
10613			el.from = $.effects.setTransition( el, cProps, factor.from.y, el.from );
10614			el.to = $.effects.setTransition( el, cProps, factor.to.y, el.to );
10615		}
10616	}
10617
10618	$.effects.save( el, props );
10619	el.show();
10620	$.effects.createWrapper( el );
10621	el.css( "overflow", "hidden" ).css( el.from );
10622
10623	// Adjust
10624	if (origin) { // Calculate baseline shifts
10625		baseline = $.effects.getBaseline( origin, original );
10626		el.from.top = ( original.outerHeight - el.outerHeight() ) * baseline.y;
10627		el.from.left = ( original.outerWidth - el.outerWidth() ) * baseline.x;
10628		el.to.top = ( original.outerHeight - el.to.outerHeight ) * baseline.y;
10629		el.to.left = ( original.outerWidth - el.to.outerWidth ) * baseline.x;
10630	}
10631	el.css( el.from ); // set top & left
10632
10633	// Animate
10634	if ( scale === "content" || scale === "both" ) { // Scale the children
10635
10636		// Add margins/font-size
10637		vProps = vProps.concat([ "marginTop", "marginBottom" ]).concat(cProps);
10638		hProps = hProps.concat([ "marginLeft", "marginRight" ]);
10639		props2 = props0.concat(vProps).concat(hProps);
10640
10641		el.find( "*[width]" ).each( function(){
10642			var child = $( this ),
10643				c_original = {
10644					height: child.height(),
10645					width: child.width(),
10646					outerHeight: child.outerHeight(),
10647					outerWidth: child.outerWidth()
10648				};
10649			if (restore) {
10650				$.effects.save(child, props2);
10651			}
10652
10653			child.from = {
10654				height: c_original.height * factor.from.y,
10655				width: c_original.width * factor.from.x,
10656				outerHeight: c_original.outerHeight * factor.from.y,
10657				outerWidth: c_original.outerWidth * factor.from.x
10658			};
10659			child.to = {
10660				height: c_original.height * factor.to.y,
10661				width: c_original.width * factor.to.x,
10662				outerHeight: c_original.height * factor.to.y,
10663				outerWidth: c_original.width * factor.to.x
10664			};
10665
10666			// Vertical props scaling
10667			if ( factor.from.y !== factor.to.y ) {
10668				child.from = $.effects.setTransition( child, vProps, factor.from.y, child.from );
10669				child.to = $.effects.setTransition( child, vProps, factor.to.y, child.to );
10670			}
10671
10672			// Horizontal props scaling
10673			if ( factor.from.x !== factor.to.x ) {
10674				child.from = $.effects.setTransition( child, hProps, factor.from.x, child.from );
10675				child.to = $.effects.setTransition( child, hProps, factor.to.x, child.to );
10676			}
10677
10678			// Animate children
10679			child.css( child.from );
10680			child.animate( child.to, o.duration, o.easing, function() {
10681
10682				// Restore children
10683				if ( restore ) {
10684					$.effects.restore( child, props2 );
10685				}
10686			});
10687		});
10688	}
10689
10690	// Animate
10691	el.animate( el.to, {
10692		queue: false,
10693		duration: o.duration,
10694		easing: o.easing,
10695		complete: function() {
10696			if ( el.to.opacity === 0 ) {
10697				el.css( "opacity", el.from.opacity );
10698			}
10699			if( mode === "hide" ) {
10700				el.hide();
10701			}
10702			$.effects.restore( el, props );
10703			if ( !restore ) {
10704
10705				// we need to calculate our new positioning based on the scaling
10706				if ( position === "static" ) {
10707					el.css({
10708						position: "relative",
10709						top: el.to.top,
10710						left: el.to.left
10711					});
10712				} else {
10713					$.each([ "top", "left" ], function( idx, pos ) {
10714						el.css( pos, function( _, str ) {
10715							var val = parseInt( str, 10 ),
10716								toRef = idx ? el.to.left : el.to.top;
10717
10718							// if original was "auto", recalculate the new value from wrapper
10719							if ( str === "auto" ) {
10720								return toRef + "px";
10721							}
10722
10723							return val + toRef + "px";
10724						});
10725					});
10726				}
10727			}
10728
10729			$.effects.removeWrapper( el );
10730			done();
10731		}
10732	});
10733
10734};
10735
10736})(jQuery);
10737
10738(function( $, undefined ) {
10739
10740$.effects.effect.shake = function( o, done ) {
10741
10742	var el = $( this ),
10743		props = [ "position", "top", "bottom", "left", "right", "height", "width" ],
10744		mode = $.effects.setMode( el, o.mode || "effect" ),
10745		direction = o.direction || "left",
10746		distance = o.distance || 20,
10747		times = o.times || 3,
10748		anims = times * 2 + 1,
10749		speed = Math.round(o.duration/anims),
10750		ref = (direction === "up" || direction === "down") ? "top" : "left",
10751		positiveMotion = (direction === "up" || direction === "left"),
10752		animation = {},
10753		animation1 = {},
10754		animation2 = {},
10755		i,
10756
10757		// we will need to re-assemble the queue to stack our animations in place
10758		queue = el.queue(),
10759		queuelen = queue.length;
10760
10761	$.effects.save( el, props );
10762	el.show();
10763	$.effects.createWrapper( el );
10764
10765	// Animation
10766	animation[ ref ] = ( positiveMotion ? "-=" : "+=" ) + distance;
10767	animation1[ ref ] = ( positiveMotion ? "+=" : "-=" ) + distance * 2;
10768	animation2[ ref ] = ( positiveMotion ? "-=" : "+=" ) + distance * 2;
10769
10770	// Animate
10771	el.animate( animation, speed, o.easing );
10772
10773	// Shakes
10774	for ( i = 1; i < times; i++ ) {
10775		el.animate( animation1, speed, o.easing ).animate( animation2, speed, o.easing );
10776	}
10777	el
10778		.animate( animation1, speed, o.easing )
10779		.animate( animation, speed / 2, o.easing )
10780		.queue(function() {
10781			if ( mode === "hide" ) {
10782				el.hide();
10783			}
10784			$.effects.restore( el, props );
10785			$.effects.removeWrapper( el );
10786			done();
10787		});
10788
10789	// inject all the animations we just queued to be first in line (after "inprogress")
10790	if ( queuelen > 1) {
10791		queue.splice.apply( queue,
10792			[ 1, 0 ].concat( queue.splice( queuelen, anims + 1 ) ) );
10793	}
10794	el.dequeue();
10795
10796};
10797
10798})(jQuery);
10799
10800(function( $, undefined ) {
10801
10802$.effects.effect.slide = function( o, done ) {
10803
10804	// Create element
10805	var el = $( this ),
10806		props = [ "position", "top", "bottom", "left", "right", "width", "height" ],
10807		mode = $.effects.setMode( el, o.mode || "show" ),
10808		show = mode === "show",
10809		direction = o.direction || "left",
10810		ref = (direction === "up" || direction === "down") ? "top" : "left",
10811		positiveMotion = (direction === "up" || direction === "left"),
10812		distance,
10813		animation = {};
10814
10815	// Adjust
10816	$.effects.save( el, props );
10817	el.show();
10818	distance = o.distance || el[ ref === "top" ? "outerHeight" : "outerWidth" ]( true );
10819
10820	$.effects.createWrapper( el ).css({
10821		overflow: "hidden"
10822	});
10823
10824	if ( show ) {
10825		el.css( ref, positiveMotion ? (isNaN(distance) ? "-" + distance : -distance) : distance );
10826	}
10827
10828	// Animation
10829	animation[ ref ] = ( show ?
10830		( positiveMotion ? "+=" : "-=") :
10831		( positiveMotion ? "-=" : "+=")) +
10832		distance;
10833
10834	// Animate
10835	el.animate( animation, {
10836		queue: false,
10837		duration: o.duration,
10838		easing: o.easing,
10839		complete: function() {
10840			if ( mode === "hide" ) {
10841				el.hide();
10842			}
10843			$.effects.restore( el, props );
10844			$.effects.removeWrapper( el );
10845			done();
10846		}
10847	});
10848};
10849
10850})(jQuery);
10851
10852(function( $, undefined ) {
10853
10854$.effects.effect.transfer = function( o, done ) {
10855	var elem = $( this ),
10856		target = $( o.to ),
10857		targetFixed = target.css( "position" ) === "fixed",
10858		body = $("body"),
10859		fixTop = targetFixed ? body.scrollTop() : 0,
10860		fixLeft = targetFixed ? body.scrollLeft() : 0,
10861		endPosition = target.offset(),
10862		animation = {
10863			top: endPosition.top - fixTop ,
10864			left: endPosition.left - fixLeft ,
10865			height: target.innerHeight(),
10866			width: target.innerWidth()
10867		},
10868		startPosition = elem.offset(),
10869		transfer = $( '<div class="ui-effects-transfer"></div>' )
10870			.appendTo( document.body )
10871			.addClass( o.className )
10872			.css({
10873				top: startPosition.top - fixTop ,
10874				left: startPosition.left - fixLeft ,
10875				height: elem.innerHeight(),
10876				width: elem.innerWidth(),
10877				position: targetFixed ? "fixed" : "absolute"
10878			})
10879			.animate( animation, o.duration, o.easing, function() {
10880				transfer.remove();
10881				done();
10882			});
10883};
10884
10885})(jQuery);
10886
10887(function( $, undefined ) {
10888
10889var mouseHandled = false;
10890
10891$.widget( "ui.menu", {
10892	version: "1.9.2",
10893	defaultElement: "<ul>",
10894	delay: 300,
10895	options: {
10896		icons: {
10897			submenu: "ui-icon-carat-1-e"
10898		},
10899		menus: "ul",
10900		position: {
10901			my: "left top",
10902			at: "right top"
10903		},
10904		role: "menu",
10905
10906		// callbacks
10907		blur: null,
10908		focus: null,
10909		select: null
10910	},
10911
10912	_create: function() {
10913		this.activeMenu = this.element;
10914		this.element
10915			.uniqueId()
10916			.addClass( "ui-menu ui-widget ui-widget-content ui-corner-all" )
10917			.toggleClass( "ui-menu-icons", !!this.element.find( ".ui-icon" ).length )
10918			.attr({
10919				role: this.options.role,
10920				tabIndex: 0
10921			})
10922			// need to catch all clicks on disabled menu
10923			// not possible through _on
10924			.bind( "click" + this.eventNamespace, $.proxy(function( event ) {
10925				if ( this.options.disabled ) {
10926					event.preventDefault();
10927				}
10928			}, this ));
10929
10930		if ( this.options.disabled ) {
10931			this.element
10932				.addClass( "ui-state-disabled" )
10933				.attr( "aria-disabled", "true" );
10934		}
10935
10936		this._on({
10937			// Prevent focus from sticking to links inside menu after clicking
10938			// them (focus should always stay on UL during navigation).
10939			"mousedown .ui-menu-item > a": function( event ) {
10940				event.preventDefault();
10941			},
10942			"click .ui-state-disabled > a": function( event ) {
10943				event.preventDefault();
10944			},
10945			"click .ui-menu-item:has(a)": function( event ) {
10946				var target = $( event.target ).closest( ".ui-menu-item" );
10947				if ( !mouseHandled && target.not( ".ui-state-disabled" ).length ) {
10948					mouseHandled = true;
10949
10950					this.select( event );
10951					// Open submenu on click
10952					if ( target.has( ".ui-menu" ).length ) {
10953						this.expand( event );
10954					} else if ( !this.element.is( ":focus" ) ) {
10955						// Redirect focus to the menu
10956						this.element.trigger( "focus", [ true ] );
10957
10958						// If the active item is on the top level, let it stay active.
10959						// Otherwise, blur the active item since it is no longer visible.
10960						if ( this.active && this.active.parents( ".ui-menu" ).length === 1 ) {
10961							clearTimeout( this.timer );
10962						}
10963					}
10964				}
10965			},
10966			"mouseenter .ui-menu-item": function( event ) {
10967				var target = $( event.currentTarget );
10968				// Remove ui-state-active class from siblings of the newly focused menu item
10969				// to avoid a jump caused by adjacent elements both having a class with a border
10970				target.siblings().children( ".ui-state-active" ).removeClass( "ui-state-active" );
10971				this.focus( event, target );
10972			},
10973			mouseleave: "collapseAll",
10974			"mouseleave .ui-menu": "collapseAll",
10975			focus: function( event, keepActiveItem ) {
10976				// If there's already an active item, keep it active
10977				// If not, activate the first item
10978				var item = this.active || this.element.children( ".ui-menu-item" ).eq( 0 );
10979
10980				if ( !keepActiveItem ) {
10981					this.focus( event, item );
10982				}
10983			},
10984			blur: function( event ) {
10985				this._delay(function() {
10986					if ( !$.contains( this.element[0], this.document[0].activeElement ) ) {
10987						this.collapseAll( event );
10988					}
10989				});
10990			},
10991			keydown: "_keydown"
10992		});
10993
10994		this.refresh();
10995
10996		// Clicks outside of a menu collapse any open menus
10997		this._on( this.document, {
10998			click: function( event ) {
10999				if ( !$( event.target ).closest( ".ui-menu" ).length ) {
11000					this.collapseAll( event );
11001				}
11002
11003				// Reset the mouseHandled flag
11004				mouseHandled = false;
11005			}
11006		});
11007	},
11008
11009	_destroy: function() {
11010		// Destroy (sub)menus
11011		this.element
11012			.removeAttr( "aria-activedescendant" )
11013			.find( ".ui-menu" ).andSelf()
11014				.removeClass( "ui-menu ui-widget ui-widget-content ui-corner-all ui-menu-icons" )
11015				.removeAttr( "role" )
11016				.removeAttr( "tabIndex" )
11017				.removeAttr( "aria-labelledby" )
11018				.removeAttr( "aria-expanded" )
11019				.removeAttr( "aria-hidden" )
11020				.removeAttr( "aria-disabled" )
11021				.removeUniqueId()
11022				.show();
11023
11024		// Destroy menu items
11025		this.element.find( ".ui-menu-item" )
11026			.removeClass( "ui-menu-item" )
11027			.removeAttr( "role" )
11028			.removeAttr( "aria-disabled" )
11029			.children( "a" )
11030				.removeUniqueId()
11031				.removeClass( "ui-corner-all ui-state-hover" )
11032				.removeAttr( "tabIndex" )
11033				.removeAttr( "role" )
11034				.removeAttr( "aria-haspopup" )
11035				.children().each( function() {
11036					var elem = $( this );
11037					if ( elem.data( "ui-menu-submenu-carat" ) ) {
11038						elem.remove();
11039					}
11040				});
11041
11042		// Destroy menu dividers
11043		this.element.find( ".ui-menu-divider" ).removeClass( "ui-menu-divider ui-widget-content" );
11044	},
11045
11046	_keydown: function( event ) {
11047		var match, prev, character, skip, regex,
11048			preventDefault = true;
11049
11050		function escape( value ) {
11051			return value.replace( /[\-\[\]{}()*+?.,\\\^$|#\s]/g, "\\$&" );
11052		}
11053
11054		switch ( event.keyCode ) {
11055		case $.ui.keyCode.PAGE_UP:
11056			this.previousPage( event );
11057			break;
11058		case $.ui.keyCode.PAGE_DOWN:
11059			this.nextPage( event );
11060			break;
11061		case $.ui.keyCode.HOME:
11062			this._move( "first", "first", event );
11063			break;
11064		case $.ui.keyCode.END:
11065			this._move( "last", "last", event );
11066			break;
11067		case $.ui.keyCode.UP:
11068			this.previous( event );
11069			break;
11070		case $.ui.keyCode.DOWN:
11071			this.next( event );
11072			break;
11073		case $.ui.keyCode.LEFT:
11074			this.collapse( event );
11075			break;
11076		case $.ui.keyCode.RIGHT:
11077			if ( this.active && !this.active.is( ".ui-state-disabled" ) ) {
11078				this.expand( event );
11079			}
11080			break;
11081		case $.ui.keyCode.ENTER:
11082		case $.ui.keyCode.SPACE:
11083			this._activate( event );
11084			break;
11085		case $.ui.keyCode.ESCAPE:
11086			this.collapse( event );
11087			break;
11088		default:
11089			preventDefault = false;
11090			prev = this.previousFilter || "";
11091			character = String.fromCharCode( event.keyCode );
11092			skip = false;
11093
11094			clearTimeout( this.filterTimer );
11095
11096			if ( character === prev ) {
11097				skip = true;
11098			} else {
11099				character = prev + character;
11100			}
11101
11102			regex = new RegExp( "^" + escape( character ), "i" );
11103			match = this.activeMenu.children( ".ui-menu-item" ).filter(function() {
11104				return regex.test( $( this ).children( "a" ).text() );
11105			});
11106			match = skip && match.index( this.active.next() ) !== -1 ?
11107				this.active.nextAll( ".ui-menu-item" ) :
11108				match;
11109
11110			// If no matches on the current filter, reset to the last character pressed
11111			// to move down the menu to the first item that starts with that character
11112			if ( !match.length ) {
11113				character = String.fromCharCode( event.keyCode );
11114				regex = new RegExp( "^" + escape( character ), "i" );
11115				match = this.activeMenu.children( ".ui-menu-item" ).filter(function() {
11116					return regex.test( $( this ).children( "a" ).text() );
11117				});
11118			}
11119
11120			if ( match.length ) {
11121				this.focus( event, match );
11122				if ( match.length > 1 ) {
11123					this.previousFilter = character;
11124					this.filterTimer = this._delay(function() {
11125						delete this.previousFilter;
11126					}, 1000 );
11127				} else {
11128					delete this.previousFilter;
11129				}
11130			} else {
11131				delete this.previousFilter;
11132			}
11133		}
11134
11135		if ( preventDefault ) {
11136			event.preventDefault();
11137		}
11138	},
11139
11140	_activate: function( event ) {
11141		if ( !this.active.is( ".ui-state-disabled" ) ) {
11142			if ( this.active.children( "a[aria-haspopup='true']" ).length ) {
11143				this.expand( event );
11144			} else {
11145				this.select( event );
11146			}
11147		}
11148	},
11149
11150	refresh: function() {
11151		var menus,
11152			icon = this.options.icons.submenu,
11153			submenus = this.element.find( this.options.menus );
11154
11155		// Initialize nested menus
11156		submenus.filter( ":not(.ui-menu)" )
11157			.addClass( "ui-menu ui-widget ui-widget-content ui-corner-all" )
11158			.hide()
11159			.attr({
11160				role: this.options.role,
11161				"aria-hidden": "true",
11162				"aria-expanded": "false"
11163			})
11164			.each(function() {
11165				var menu = $( this ),
11166					item = menu.prev( "a" ),
11167					submenuCarat = $( "<span>" )
11168						.addClass( "ui-menu-icon ui-icon " + icon )
11169						.data( "ui-menu-submenu-carat", true );
11170
11171				item
11172					.attr( "aria-haspopup", "true" )
11173					.prepend( submenuCarat );
11174				menu.attr( "aria-labelledby", item.attr( "id" ) );
11175			});
11176
11177		menus = submenus.add( this.element );
11178
11179		// Don't refresh list items that are already adapted
11180		menus.children( ":not(.ui-menu-item):has(a)" )
11181			.addClass( "ui-menu-item" )
11182			.attr( "role", "presentation" )
11183			.children( "a" )
11184				.uniqueId()
11185				.addClass( "ui-corner-all" )
11186				.attr({
11187					tabIndex: -1,
11188					role: this._itemRole()
11189				});
11190
11191		// Initialize unlinked menu-items containing spaces and/or dashes only as dividers
11192		menus.children( ":not(.ui-menu-item)" ).each(function() {
11193			var item = $( this );
11194			// hyphen, em dash, en dash
11195			if ( !/[^\-—–\s]/.test( item.text() ) ) {
11196				item.addClass( "ui-widget-content ui-menu-divider" );
11197			}
11198		});
11199
11200		// Add aria-disabled attribute to any disabled menu item
11201		menus.children( ".ui-state-disabled" ).attr( "aria-disabled", "true" );
11202
11203		// If the active item has been removed, blur the menu
11204		if ( this.active && !$.contains( this.element[ 0 ], this.active[ 0 ] ) ) {
11205			this.blur();
11206		}
11207	},
11208
11209	_itemRole: function() {
11210		return {
11211			menu: "menuitem",
11212			listbox: "option"
11213		}[ this.options.role ];
11214	},
11215
11216	focus: function( event, item ) {
11217		var nested, focused;
11218		this.blur( event, event && event.type === "focus" );
11219
11220		this._scrollIntoView( item );
11221
11222		this.active = item.first();
11223		focused = this.active.children( "a" ).addClass( "ui-state-focus" );
11224		// Only update aria-activedescendant if there's a role
11225		// otherwise we assume focus is managed elsewhere
11226		if ( this.options.role ) {
11227			this.element.attr( "aria-activedescendant", focused.attr( "id" ) );
11228		}
11229
11230		// Highlight active parent menu item, if any
11231		this.active
11232			.parent()
11233			.closest( ".ui-menu-item" )
11234			.children( "a:first" )
11235			.addClass( "ui-state-active" );
11236
11237		if ( event && event.type === "keydown" ) {
11238			this._close();
11239		} else {
11240			this.timer = this._delay(function() {
11241				this._close();
11242			}, this.delay );
11243		}
11244
11245		nested = item.children( ".ui-menu" );
11246		if ( nested.length && ( /^mouse/.test( event.type ) ) ) {
11247			this._startOpening(nested);
11248		}
11249		this.activeMenu = item.parent();
11250
11251		this._trigger( "focus", event, { item: item } );
11252	},
11253
11254	_scrollIntoView: function( item ) {
11255		var borderTop, paddingTop, offset, scroll, elementHeight, itemHeight;
11256		if ( this._hasScroll() ) {
11257			borderTop = parseFloat( $.css( this.activeMenu[0], "borderTopWidth" ) ) || 0;
11258			paddingTop = parseFloat( $.css( this.activeMenu[0], "paddingTop" ) ) || 0;
11259			offset = item.offset().top - this.activeMenu.offset().top - borderTop - paddingTop;
11260			scroll = this.activeMenu.scrollTop();
11261			elementHeight = this.activeMenu.height();
11262			itemHeight = item.height();
11263
11264			if ( offset < 0 ) {
11265				this.activeMenu.scrollTop( scroll + offset );
11266			} else if ( offset + itemHeight > elementHeight ) {
11267				this.activeMenu.scrollTop( scroll + offset - elementHeight + itemHeight );
11268			}
11269		}
11270	},
11271
11272	blur: function( event, fromFocus ) {
11273		if ( !fromFocus ) {
11274			clearTimeout( this.timer );
11275		}
11276
11277		if ( !this.active ) {
11278			return;
11279		}
11280
11281		this.active.children( "a" ).removeClass( "ui-state-focus" );
11282		this.active = null;
11283
11284		this._trigger( "blur", event, { item: this.active } );
11285	},
11286
11287	_startOpening: function( submenu ) {
11288		clearTimeout( this.timer );
11289
11290		// Don't open if already open fixes a Firefox bug that caused a .5 pixel
11291		// shift in the submenu position when mousing over the carat icon
11292		if ( submenu.attr( "aria-hidden" ) !== "true" ) {
11293			return;
11294		}
11295
11296		this.timer = this._delay(function() {
11297			this._close();
11298			this._open( submenu );
11299		}, this.delay );
11300	},
11301
11302	_open: function( submenu ) {
11303		var position = $.extend({
11304			of: this.active
11305		}, this.options.position );
11306
11307		clearTimeout( this.timer );
11308		this.element.find( ".ui-menu" ).not( submenu.parents( ".ui-menu" ) )
11309			.hide()
11310			.attr( "aria-hidden", "true" );
11311
11312		submenu
11313			.show()
11314			.removeAttr( "aria-hidden" )
11315			.attr( "aria-expanded", "true" )
11316			.position( position );
11317	},
11318
11319	collapseAll: function( event, all ) {
11320		clearTimeout( this.timer );
11321		this.timer = this._delay(function() {
11322			// If we were passed an event, look for the submenu that contains the event
11323			var currentMenu = all ? this.element :
11324				$( event && event.target ).closest( this.element.find( ".ui-menu" ) );
11325
11326			// If we found no valid submenu ancestor, use the main menu to close all sub menus anyway
11327			if ( !currentMenu.length ) {
11328				currentMenu = this.element;
11329			}
11330
11331			this._close( currentMenu );
11332
11333			this.blur( event );
11334			this.activeMenu = currentMenu;
11335		}, this.delay );
11336	},
11337
11338	// With no arguments, closes the currently active menu - if nothing is active
11339	// it closes all menus.  If passed an argument, it will search for menus BELOW
11340	_close: function( startMenu ) {
11341		if ( !startMenu ) {
11342			startMenu = this.active ? this.active.parent() : this.element;
11343		}
11344
11345		startMenu
11346			.find( ".ui-menu" )
11347				.hide()
11348				.attr( "aria-hidden", "true" )
11349				.attr( "aria-expanded", "false" )
11350			.end()
11351			.find( "a.ui-state-active" )
11352				.removeClass( "ui-state-active" );
11353	},
11354
11355	collapse: function( event ) {
11356		var newItem = this.active &&
11357			this.active.parent().closest( ".ui-menu-item", this.element );
11358		if ( newItem && newItem.length ) {
11359			this._close();
11360			this.focus( event, newItem );
11361		}
11362	},
11363
11364	expand: function( event ) {
11365		var newItem = this.active &&
11366			this.active
11367				.children( ".ui-menu " )
11368				.children( ".ui-menu-item" )
11369				.first();
11370
11371		if ( newItem && newItem.length ) {
11372			this._open( newItem.parent() );
11373
11374			// Delay so Firefox will not hide activedescendant change in expanding submenu from AT
11375			this._delay(function() {
11376				this.focus( event, newItem );
11377			});
11378		}
11379	},
11380
11381	next: function( event ) {
11382		this._move( "next", "first", event );
11383	},
11384
11385	previous: function( event ) {
11386		this._move( "prev", "last", event );
11387	},
11388
11389	isFirstItem: function() {
11390		return this.active && !this.active.prevAll( ".ui-menu-item" ).length;
11391	},
11392
11393	isLastItem: function() {
11394		return this.active && !this.active.nextAll( ".ui-menu-item" ).length;
11395	},
11396
11397	_move: function( direction, filter, event ) {
11398		var next;
11399		if ( this.active ) {
11400			if ( direction === "first" || direction === "last" ) {
11401				next = this.active
11402					[ direction === "first" ? "prevAll" : "nextAll" ]( ".ui-menu-item" )
11403					.eq( -1 );
11404			} else {
11405				next = this.active
11406					[ direction + "All" ]( ".ui-menu-item" )
11407					.eq( 0 );
11408			}
11409		}
11410		if ( !next || !next.length || !this.active ) {
11411			next = this.activeMenu.children( ".ui-menu-item" )[ filter ]();
11412		}
11413
11414		this.focus( event, next );
11415	},
11416
11417	nextPage: function( event ) {
11418		var item, base, height;
11419
11420		if ( !this.active ) {
11421			this.next( event );
11422			return;
11423		}
11424		if ( this.isLastItem() ) {
11425			return;
11426		}
11427		if ( this._hasScroll() ) {
11428			base = this.active.offset().top;
11429			height = this.element.height();
11430			this.active.nextAll( ".ui-menu-item" ).each(function() {
11431				item = $( this );
11432				return item.offset().top - base - height < 0;
11433			});
11434
11435			this.focus( event, item );
11436		} else {
11437			this.focus( event, this.activeMenu.children( ".ui-menu-item" )
11438				[ !this.active ? "first" : "last" ]() );
11439		}
11440	},
11441
11442	previousPage: function( event ) {
11443		var item, base, height;
11444		if ( !this.active ) {
11445			this.next( event );
11446			return;
11447		}
11448		if ( this.isFirstItem() ) {
11449			return;
11450		}
11451		if ( this._hasScroll() ) {
11452			base = this.active.offset().top;
11453			height = this.element.height();
11454			this.active.prevAll( ".ui-menu-item" ).each(function() {
11455				item = $( this );
11456				return item.offset().top - base + height > 0;
11457			});
11458
11459			this.focus( event, item );
11460		} else {
11461			this.focus( event, this.activeMenu.children( ".ui-menu-item" ).first() );
11462		}
11463	},
11464
11465	_hasScroll: function() {
11466		return this.element.outerHeight() < this.element.prop( "scrollHeight" );
11467	},
11468
11469	select: function( event ) {
11470		// TODO: It should never be possible to not have an active item at this
11471		// point, but the tests don't trigger mouseenter before click.
11472		this.active = this.active || $( event.target ).closest( ".ui-menu-item" );
11473		var ui = { item: this.active };
11474		if ( !this.active.has( ".ui-menu" ).length ) {
11475			this.collapseAll( event, true );
11476		}
11477		this._trigger( "select", event, ui );
11478	}
11479});
11480
11481}( jQuery ));
11482
11483(function( $, undefined ) {
11484
11485$.ui = $.ui || {};
11486
11487var cachedScrollbarWidth,
11488	max = Math.max,
11489	abs = Math.abs,
11490	round = Math.round,
11491	rhorizontal = /left|center|right/,
11492	rvertical = /top|center|bottom/,
11493	roffset = /[\+\-]\d+%?/,
11494	rposition = /^\w+/,
11495	rpercent = /%$/,
11496	_position = $.fn.position;
11497
11498function getOffsets( offsets, width, height ) {
11499	return [
11500		parseInt( offsets[ 0 ], 10 ) * ( rpercent.test( offsets[ 0 ] ) ? width / 100 : 1 ),
11501		parseInt( offsets[ 1 ], 10 ) * ( rpercent.test( offsets[ 1 ] ) ? height / 100 : 1 )
11502	];
11503}
11504function parseCss( element, property ) {
11505	return parseInt( $.css( element, property ), 10 ) || 0;
11506}
11507
11508$.position = {
11509	scrollbarWidth: function() {
11510		if ( cachedScrollbarWidth !== undefined ) {
11511			return cachedScrollbarWidth;
11512		}
11513		var w1, w2,
11514			div = $( "<div style='display:block;width:50px;height:50px;overflow:hidden;'><div style='height:100px;width:auto;'></div></div>" ),
11515			innerDiv = div.children()[0];
11516
11517		$( "body" ).append( div );
11518		w1 = innerDiv.offsetWidth;
11519		div.css( "overflow", "scroll" );
11520
11521		w2 = innerDiv.offsetWidth;
11522
11523		if ( w1 === w2 ) {
11524			w2 = div[0].clientWidth;
11525		}
11526
11527		div.remove();
11528
11529		return (cachedScrollbarWidth = w1 - w2);
11530	},
11531	getScrollInfo: function( within ) {
11532		var overflowX = within.isWindow ? "" : within.element.css( "overflow-x" ),
11533			overflowY = within.isWindow ? "" : within.element.css( "overflow-y" ),
11534			hasOverflowX = overflowX === "scroll" ||
11535				( overflowX === "auto" && within.width < within.element[0].scrollWidth ),
11536			hasOverflowY = overflowY === "scroll" ||
11537				( overflowY === "auto" && within.height < within.element[0].scrollHeight );
11538		return {
11539			width: hasOverflowX ? $.position.scrollbarWidth() : 0,
11540			height: hasOverflowY ? $.position.scrollbarWidth() : 0
11541		};
11542	},
11543	getWithinInfo: function( element ) {
11544		var withinElement = $( element || window ),
11545			isWindow = $.isWindow( withinElement[0] );
11546		return {
11547			element: withinElement,
11548			isWindow: isWindow,
11549			offset: withinElement.offset() || { left: 0, top: 0 },
11550			scrollLeft: withinElement.scrollLeft(),
11551			scrollTop: withinElement.scrollTop(),
11552			width: isWindow ? withinElement.width() : withinElement.outerWidth(),
11553			height: isWindow ? withinElement.height() : withinElement.outerHeight()
11554		};
11555	}
11556};
11557
11558$.fn.position = function( options ) {
11559	if ( !options || !options.of ) {
11560		return _position.apply( this, arguments );
11561	}
11562
11563	// make a copy, we don't want to modify arguments
11564	options = $.extend( {}, options );
11565
11566	var atOffset, targetWidth, targetHeight, targetOffset, basePosition,
11567		target = $( options.of ),
11568		within = $.position.getWithinInfo( options.within ),
11569		scrollInfo = $.position.getScrollInfo( within ),
11570		targetElem = target[0],
11571		collision = ( options.collision || "flip" ).split( " " ),
11572		offsets = {};
11573
11574	if ( targetElem.nodeType === 9 ) {
11575		targetWidth = target.width();
11576		targetHeight = target.height();
11577		targetOffset = { top: 0, left: 0 };
11578	} else if ( $.isWindow( targetElem ) ) {
11579		targetWidth = target.width();
11580		targetHeight = target.height();
11581		targetOffset = { top: target.scrollTop(), left: target.scrollLeft() };
11582	} else if ( targetElem.preventDefault ) {
11583		// force left top to allow flipping
11584		options.at = "left top";
11585		targetWidth = targetHeight = 0;
11586		targetOffset = { top: targetElem.pageY, left: targetElem.pageX };
11587	} else {
11588		targetWidth = target.outerWidth();
11589		targetHeight = target.outerHeight();
11590		targetOffset = target.offset();
11591	}
11592	// clone to reuse original targetOffset later
11593	basePosition = $.extend( {}, targetOffset );
11594
11595	// force my and at to have valid horizontal and vertical positions
11596	// if a value is missing or invalid, it will be converted to center
11597	$.each( [ "my", "at" ], function() {
11598		var pos = ( options[ this ] || "" ).split( " " ),
11599			horizontalOffset,
11600			verticalOffset;
11601
11602		if ( pos.length === 1) {
11603			pos = rhorizontal.test( pos[ 0 ] ) ?
11604				pos.concat( [ "center" ] ) :
11605				rvertical.test( pos[ 0 ] ) ?
11606					[ "center" ].concat( pos ) :
11607					[ "center", "center" ];
11608		}
11609		pos[ 0 ] = rhorizontal.test( pos[ 0 ] ) ? pos[ 0 ] : "center";
11610		pos[ 1 ] = rvertical.test( pos[ 1 ] ) ? pos[ 1 ] : "center";
11611
11612		// calculate offsets
11613		horizontalOffset = roffset.exec( pos[ 0 ] );
11614		verticalOffset = roffset.exec( pos[ 1 ] );
11615		offsets[ this ] = [
11616			horizontalOffset ? horizontalOffset[ 0 ] : 0,
11617			verticalOffset ? verticalOffset[ 0 ] : 0
11618		];
11619
11620		// reduce to just the positions without the offsets
11621		options[ this ] = [
11622			rposition.exec( pos[ 0 ] )[ 0 ],
11623			rposition.exec( pos[ 1 ] )[ 0 ]
11624		];
11625	});
11626
11627	// normalize collision option
11628	if ( collision.length === 1 ) {
11629		collision[ 1 ] = collision[ 0 ];
11630	}
11631
11632	if ( options.at[ 0 ] === "right" ) {
11633		basePosition.left += targetWidth;
11634	} else if ( options.at[ 0 ] === "center" ) {
11635		basePosition.left += targetWidth / 2;
11636	}
11637
11638	if ( options.at[ 1 ] === "bottom" ) {
11639		basePosition.top += targetHeight;
11640	} else if ( options.at[ 1 ] === "center" ) {
11641		basePosition.top += targetHeight / 2;
11642	}
11643
11644	atOffset = getOffsets( offsets.at, targetWidth, targetHeight );
11645	basePosition.left += atOffset[ 0 ];
11646	basePosition.top += atOffset[ 1 ];
11647
11648	return this.each(function() {
11649		var collisionPosition, using,
11650			elem = $( this ),
11651			elemWidth = elem.outerWidth(),
11652			elemHeight = elem.outerHeight(),
11653			marginLeft = parseCss( this, "marginLeft" ),
11654			marginTop = parseCss( this, "marginTop" ),
11655			collisionWidth = elemWidth + marginLeft + parseCss( this, "marginRight" ) + scrollInfo.width,
11656			collisionHeight = elemHeight + marginTop + parseCss( this, "marginBottom" ) + scrollInfo.height,
11657			position = $.extend( {}, basePosition ),
11658			myOffset = getOffsets( offsets.my, elem.outerWidth(), elem.outerHeight() );
11659
11660		if ( options.my[ 0 ] === "right" ) {
11661			position.left -= elemWidth;
11662		} else if ( options.my[ 0 ] === "center" ) {
11663			position.left -= elemWidth / 2;
11664		}
11665
11666		if ( options.my[ 1 ] === "bottom" ) {
11667			position.top -= elemHeight;
11668		} else if ( options.my[ 1 ] === "center" ) {
11669			position.top -= elemHeight / 2;
11670		}
11671
11672		position.left += myOffset[ 0 ];
11673		position.top += myOffset[ 1 ];
11674
11675		// if the browser doesn't support fractions, then round for consistent results
11676		if ( !$.support.offsetFractions ) {
11677			position.left = round( position.left );
11678			position.top = round( position.top );
11679		}
11680
11681		collisionPosition = {
11682			marginLeft: marginLeft,
11683			marginTop: marginTop
11684		};
11685
11686		$.each( [ "left", "top" ], function( i, dir ) {
11687			if ( $.ui.position[ collision[ i ] ] ) {
11688				$.ui.position[ collision[ i ] ][ dir ]( position, {
11689					targetWidth: targetWidth,
11690					targetHeight: targetHeight,
11691					elemWidth: elemWidth,
11692					elemHeight: elemHeight,
11693					collisionPosition: collisionPosition,
11694					collisionWidth: collisionWidth,
11695					collisionHeight: collisionHeight,
11696					offset: [ atOffset[ 0 ] + myOffset[ 0 ], atOffset [ 1 ] + myOffset[ 1 ] ],
11697					my: options.my,
11698					at: options.at,
11699					within: within,
11700					elem : elem
11701				});
11702			}
11703		});
11704
11705		if ( $.fn.bgiframe ) {
11706			elem.bgiframe();
11707		}
11708
11709		if ( options.using ) {
11710			// adds feedback as second argument to using callback, if present
11711			using = function( props ) {
11712				var left = targetOffset.left - position.left,
11713					right = left + targetWidth - elemWidth,
11714					top = targetOffset.top - position.top,
11715					bottom = top + targetHeight - elemHeight,
11716					feedback = {
11717						target: {
11718							element: target,
11719							left: targetOffset.left,
11720							top: targetOffset.top,
11721							width: targetWidth,
11722							height: targetHeight
11723						},
11724						element: {
11725							element: elem,
11726							left: position.left,
11727							top: position.top,
11728							width: elemWidth,
11729							height: elemHeight
11730						},
11731						horizontal: right < 0 ? "left" : left > 0 ? "right" : "center",
11732						vertical: bottom < 0 ? "top" : top > 0 ? "bottom" : "middle"
11733					};
11734				if ( targetWidth < elemWidth && abs( left + right ) < targetWidth ) {
11735					feedback.horizontal = "center";
11736				}
11737				if ( targetHeight < elemHeight && abs( top + bottom ) < targetHeight ) {
11738					feedback.vertical = "middle";
11739				}
11740				if ( max( abs( left ), abs( right ) ) > max( abs( top ), abs( bottom ) ) ) {
11741					feedback.important = "horizontal";
11742				} else {
11743					feedback.important = "vertical";
11744				}
11745				options.using.call( this, props, feedback );
11746			};
11747		}
11748
11749		elem.offset( $.extend( position, { using: using } ) );
11750	});
11751};
11752
11753$.ui.position = {
11754	fit: {
11755		left: function( position, data ) {
11756			var within = data.within,
11757				withinOffset = within.isWindow ? within.scrollLeft : within.offset.left,
11758				outerWidth = within.width,
11759				collisionPosLeft = position.left - data.collisionPosition.marginLeft,
11760				overLeft = withinOffset - collisionPosLeft,
11761				overRight = collisionPosLeft + data.collisionWidth - outerWidth - withinOffset,
11762				newOverRight;
11763
11764			// element is wider than within
11765			if ( data.collisionWidth > outerWidth ) {
11766				// element is initially over the left side of within
11767				if ( overLeft > 0 && overRight <= 0 ) {
11768					newOverRight = position.left + overLeft + data.collisionWidth - outerWidth - withinOffset;
11769					position.left += overLeft - newOverRight;
11770				// element is initially over right side of within
11771				} else if ( overRight > 0 && overLeft <= 0 ) {
11772					position.left = withinOffset;
11773				// element is initially over both left and right sides of within
11774				} else {
11775					if ( overLeft > overRight ) {
11776						position.left = withinOffset + outerWidth - data.collisionWidth;
11777					} else {
11778						position.left = withinOffset;
11779					}
11780				}
11781			// too far left -> align with left edge
11782			} else if ( overLeft > 0 ) {
11783				position.left += overLeft;
11784			// too far right -> align with right edge
11785			} else if ( overRight > 0 ) {
11786				position.left -= overRight;
11787			// adjust based on position and margin
11788			} else {
11789				position.left = max( position.left - collisionPosLeft, position.left );
11790			}
11791		},
11792		top: function( position, data ) {
11793			var within = data.within,
11794				withinOffset = within.isWindow ? within.scrollTop : within.offset.top,
11795				outerHeight = data.within.height,
11796				collisionPosTop = position.top - data.collisionPosition.marginTop,
11797				overTop = withinOffset - collisionPosTop,
11798				overBottom = collisionPosTop + data.collisionHeight - outerHeight - withinOffset,
11799				newOverBottom;
11800
11801			// element is taller than within
11802			if ( data.collisionHeight > outerHeight ) {
11803				// element is initially over the top of within
11804				if ( overTop > 0 && overBottom <= 0 ) {
11805					newOverBottom = position.top + overTop + data.collisionHeight - outerHeight - withinOffset;
11806					position.top += overTop - newOverBottom;
11807				// element is initially over bottom of within
11808				} else if ( overBottom > 0 && overTop <= 0 ) {
11809					position.top = withinOffset;
11810				// element is initially over both top and bottom of within
11811				} else {
11812					if ( overTop > overBottom ) {
11813						position.top = withinOffset + outerHeight - data.collisionHeight;
11814					} else {
11815						position.top = withinOffset;
11816					}
11817				}
11818			// too far up -> align with top
11819			} else if ( overTop > 0 ) {
11820				position.top += overTop;
11821			// too far down -> align with bottom edge
11822			} else if ( overBottom > 0 ) {
11823				position.top -= overBottom;
11824			// adjust based on position and margin
11825			} else {
11826				position.top = max( position.top - collisionPosTop, position.top );
11827			}
11828		}
11829	},
11830	flip: {
11831		left: function( position, data ) {
11832			var within = data.within,
11833				withinOffset = within.offset.left + within.scrollLeft,
11834				outerWidth = within.width,
11835				offsetLeft = within.isWindow ? within.scrollLeft : within.offset.left,
11836				collisionPosLeft = position.left - data.collisionPosition.marginLeft,
11837				overLeft = collisionPosLeft - offsetLeft,
11838				overRight = collisionPosLeft + data.collisionWidth - outerWidth - offsetLeft,
11839				myOffset = data.my[ 0 ] === "left" ?
11840					-data.elemWidth :
11841					data.my[ 0 ] === "right" ?
11842						data.elemWidth :
11843						0,
11844				atOffset = data.at[ 0 ] === "left" ?
11845					data.targetWidth :
11846					data.at[ 0 ] === "right" ?
11847						-data.targetWidth :
11848						0,
11849				offset = -2 * data.offset[ 0 ],
11850				newOverRight,
11851				newOverLeft;
11852
11853			if ( overLeft < 0 ) {
11854				newOverRight = position.left + myOffset + atOffset + offset + data.collisionWidth - outerWidth - withinOffset;
11855				if ( newOverRight < 0 || newOverRight < abs( overLeft ) ) {
11856					position.left += myOffset + atOffset + offset;
11857				}
11858			}
11859			else if ( overRight > 0 ) {
11860				newOverLeft = position.left - data.collisionPosition.marginLeft + myOffset + atOffset + offset - offsetLeft;
11861				if ( newOverLeft > 0 || abs( newOverLeft ) < overRight ) {
11862					position.left += myOffset + atOffset + offset;
11863				}
11864			}
11865		},
11866		top: function( position, data ) {
11867			var within = data.within,
11868				withinOffset = within.offset.top + within.scrollTop,
11869				outerHeight = within.height,
11870				offsetTop = within.isWindow ? within.scrollTop : within.offset.top,
11871				collisionPosTop = position.top - data.collisionPosition.marginTop,
11872				overTop = collisionPosTop - offsetTop,
11873				overBottom = collisionPosTop + data.collisionHeight - outerHeight - offsetTop,
11874				top = data.my[ 1 ] === "top",
11875				myOffset = top ?
11876					-data.elemHeight :
11877					data.my[ 1 ] === "bottom" ?
11878						data.elemHeight :
11879						0,
11880				atOffset = data.at[ 1 ] === "top" ?
11881					data.targetHeight :
11882					data.at[ 1 ] === "bottom" ?
11883						-data.targetHeight :
11884						0,
11885				offset = -2 * data.offset[ 1 ],
11886				newOverTop,
11887				newOverBottom;
11888			if ( overTop < 0 ) {
11889				newOverBottom = position.top + myOffset + atOffset + offset + data.collisionHeight - outerHeight - withinOffset;
11890				if ( ( position.top + myOffset + atOffset + offset) > overTop && ( newOverBottom < 0 || newOverBottom < abs( overTop ) ) ) {
11891					position.top += myOffset + atOffset + offset;
11892				}
11893			}
11894			else if ( overBottom > 0 ) {
11895				newOverTop = position.top -  data.collisionPosition.marginTop + myOffset + atOffset + offset - offsetTop;
11896				if ( ( position.top + myOffset + atOffset + offset) > overBottom && ( newOverTop > 0 || abs( newOverTop ) < overBottom ) ) {
11897					position.top += myOffset + atOffset + offset;
11898				}
11899			}
11900		}
11901	},
11902	flipfit: {
11903		left: function() {
11904			$.ui.position.flip.left.apply( this, arguments );
11905			$.ui.position.fit.left.apply( this, arguments );
11906		},
11907		top: function() {
11908			$.ui.position.flip.top.apply( this, arguments );
11909			$.ui.position.fit.top.apply( this, arguments );
11910		}
11911	}
11912};
11913
11914// fraction support test
11915(function () {
11916	var testElement, testElementParent, testElementStyle, offsetLeft, i,
11917		body = document.getElementsByTagName( "body" )[ 0 ],
11918		div = document.createElement( "div" );
11919
11920	//Create a "fake body" for testing based on method used in jQuery.support
11921	testElement = document.createElement( body ? "div" : "body" );
11922	testElementStyle = {
11923		visibility: "hidden",
11924		width: 0,
11925		height: 0,
11926		border: 0,
11927		margin: 0,
11928		background: "none"
11929	};
11930	if ( body ) {
11931		$.extend( testElementStyle, {
11932			position: "absolute",
11933			left: "-1000px",
11934			top: "-1000px"
11935		});
11936	}
11937	for ( i in testElementStyle ) {
11938		testElement.style[ i ] = testElementStyle[ i ];
11939	}
11940	testElement.appendChild( div );
11941	testElementParent = body || document.documentElement;
11942	testElementParent.insertBefore( testElement, testElementParent.firstChild );
11943
11944	div.style.cssText = "position: absolute; left: 10.7432222px;";
11945
11946	offsetLeft = $( div ).offset().left;
11947	$.support.offsetFractions = offsetLeft > 10 && offsetLeft < 11;
11948
11949	testElement.innerHTML = "";
11950	testElementParent.removeChild( testElement );
11951})();
11952
11953// DEPRECATED
11954if ( $.uiBackCompat !== false ) {
11955	// offset option
11956	(function( $ ) {
11957		var _position = $.fn.position;
11958		$.fn.position = function( options ) {
11959			if ( !options || !options.offset ) {
11960				return _position.call( this, options );
11961			}
11962			var offset = options.offset.split( " " ),
11963				at = options.at.split( " " );
11964			if ( offset.length === 1 ) {
11965				offset[ 1 ] = offset[ 0 ];
11966			}
11967			if ( /^\d/.test( offset[ 0 ] ) ) {
11968				offset[ 0 ] = "+" + offset[ 0 ];
11969			}
11970			if ( /^\d/.test( offset[ 1 ] ) ) {
11971				offset[ 1 ] = "+" + offset[ 1 ];
11972			}
11973			if ( at.length === 1 ) {
11974				if ( /left|center|right/.test( at[ 0 ] ) ) {
11975					at[ 1 ] = "center";
11976				} else {
11977					at[ 1 ] = at[ 0 ];
11978					at[ 0 ] = "center";
11979				}
11980			}
11981			return _position.call( this, $.extend( options, {
11982				at: at[ 0 ] + offset[ 0 ] + " " + at[ 1 ] + offset[ 1 ],
11983				offset: undefined
11984			} ) );
11985		};
11986	}( jQuery ) );
11987}
11988
11989}( jQuery ) );
11990
11991(function( $, undefined ) {
11992
11993$.widget( "ui.progressbar", {
11994	version: "1.9.2",
11995	options: {
11996		value: 0,
11997		max: 100
11998	},
11999
12000	min: 0,
12001
12002	_create: function() {
12003		this.element
12004			.addClass( "ui-progressbar ui-widget ui-widget-content ui-corner-all" )
12005			.attr({
12006				role: "progressbar",
12007				"aria-valuemin": this.min,
12008				"aria-valuemax": this.options.max,
12009				"aria-valuenow": this._value()
12010			});
12011
12012		this.valueDiv = $( "<div class='ui-progressbar-value ui-widget-header ui-corner-left'></div>" )
12013			.appendTo( this.element );
12014
12015		this.oldValue = this._value();
12016		this._refreshValue();
12017	},
12018
12019	_destroy: function() {
12020		this.element
12021			.removeClass( "ui-progressbar ui-widget ui-widget-content ui-corner-all" )
12022			.removeAttr( "role" )
12023			.removeAttr( "aria-valuemin" )
12024			.removeAttr( "aria-valuemax" )
12025			.removeAttr( "aria-valuenow" );
12026
12027		this.valueDiv.remove();
12028	},
12029
12030	value: function( newValue ) {
12031		if ( newValue === undefined ) {
12032			return this._value();
12033		}
12034
12035		this._setOption( "value", newValue );
12036		return this;
12037	},
12038
12039	_setOption: function( key, value ) {
12040		if ( key === "value" ) {
12041			this.options.value = value;
12042			this._refreshValue();
12043			if ( this._value() === this.options.max ) {
12044				this._trigger( "complete" );
12045			}
12046		}
12047
12048		this._super( key, value );
12049	},
12050
12051	_value: function() {
12052		var val = this.options.value;
12053		// normalize invalid value
12054		if ( typeof val !== "number" ) {
12055			val = 0;
12056		}
12057		return Math.min( this.options.max, Math.max( this.min, val ) );
12058	},
12059
12060	_percentage: function() {
12061		return 100 * this._value() / this.options.max;
12062	},
12063
12064	_refreshValue: function() {
12065		var value = this.value(),
12066			percentage = this._percentage();
12067
12068		if ( this.oldValue !== value ) {
12069			this.oldValue = value;
12070			this._trigger( "change" );
12071		}
12072
12073		this.valueDiv
12074			.toggle( value > this.min )
12075			.toggleClass( "ui-corner-right", value === this.options.max )
12076			.width( percentage.toFixed(0) + "%" );
12077		this.element.attr( "aria-valuenow", value );
12078	}
12079});
12080
12081})( jQuery );
12082
12083(function( $, undefined ) {
12084
12085// number of pages in a slider
12086// (how many times can you page up/down to go through the whole range)
12087var numPages = 5;
12088
12089$.widget( "ui.slider", $.ui.mouse, {
12090	version: "1.9.2",
12091	widgetEventPrefix: "slide",
12092
12093	options: {
12094		animate: false,
12095		distance: 0,
12096		max: 100,
12097		min: 0,
12098		orientation: "horizontal",
12099		range: false,
12100		step: 1,
12101		value: 0,
12102		values: null
12103	},
12104
12105	_create: function() {
12106		var i, handleCount,
12107			o = this.options,
12108			existingHandles = this.element.find( ".ui-slider-handle" ).addClass( "ui-state-default ui-corner-all" ),
12109			handle = "<a class='ui-slider-handle ui-state-default ui-corner-all' href='#'></a>",
12110			handles = [];
12111
12112		this._keySliding = false;
12113		this._mouseSliding = false;
12114		this._animateOff = true;
12115		this._handleIndex = null;
12116		this._detectOrientation();
12117		this._mouseInit();
12118
12119		this.element
12120			.addClass( "ui-slider" +
12121				" ui-slider-" + this.orientation +
12122				" ui-widget" +
12123				" ui-widget-content" +
12124				" ui-corner-all" +
12125				( o.disabled ? " ui-slider-disabled ui-disabled" : "" ) );
12126
12127		this.range = $([]);
12128
12129		if ( o.range ) {
12130			if ( o.range === true ) {
12131				if ( !o.values ) {
12132					o.values = [ this._valueMin(), this._valueMin() ];
12133				}
12134				if ( o.values.length && o.values.length !== 2 ) {
12135					o.values = [ o.values[0], o.values[0] ];
12136				}
12137			}
12138
12139			this.range = $( "<div></div>" )
12140				.appendTo( this.element )
12141				.addClass( "ui-slider-range" +
12142				// note: this isn't the most fittingly semantic framework class for this element,
12143				// but worked best visually with a variety of themes
12144				" ui-widget-header" +
12145				( ( o.range === "min" || o.range === "max" ) ? " ui-slider-range-" + o.range : "" ) );
12146		}
12147
12148		handleCount = ( o.values && o.values.length ) || 1;
12149
12150		for ( i = existingHandles.length; i < handleCount; i++ ) {
12151			handles.push( handle );
12152		}
12153
12154		this.handles = existingHandles.add( $( handles.join( "" ) ).appendTo( this.element ) );
12155
12156		this.handle = this.handles.eq( 0 );
12157
12158		this.handles.add( this.range ).filter( "a" )
12159			.click(function( event ) {
12160				event.preventDefault();
12161			})
12162			.mouseenter(function() {
12163				if ( !o.disabled ) {
12164					$( this ).addClass( "ui-state-hover" );
12165				}
12166			})
12167			.mouseleave(function() {
12168				$( this ).removeClass( "ui-state-hover" );
12169			})
12170			.focus(function() {
12171				if ( !o.disabled ) {
12172					$( ".ui-slider .ui-state-focus" ).removeClass( "ui-state-focus" );
12173					$( this ).addClass( "ui-state-focus" );
12174				} else {
12175					$( this ).blur();
12176				}
12177			})
12178			.blur(function() {
12179				$( this ).removeClass( "ui-state-focus" );
12180			});
12181
12182		this.handles.each(function( i ) {
12183			$( this ).data( "ui-slider-handle-index", i );
12184		});
12185
12186		this._on( this.handles, {
12187			keydown: function( event ) {
12188				var allowed, curVal, newVal, step,
12189					index = $( event.target ).data( "ui-slider-handle-index" );
12190
12191				switch ( event.keyCode ) {
12192					case $.ui.keyCode.HOME:
12193					case $.ui.keyCode.END:
12194					case $.ui.keyCode.PAGE_UP:
12195					case $.ui.keyCode.PAGE_DOWN:
12196					case $.ui.keyCode.UP:
12197					case $.ui.keyCode.RIGHT:
12198					case $.ui.keyCode.DOWN:
12199					case $.ui.keyCode.LEFT:
12200						event.preventDefault();
12201						if ( !this._keySliding ) {
12202							this._keySliding = true;
12203							$( event.target ).addClass( "ui-state-active" );
12204							allowed = this._start( event, index );
12205							if ( allowed === false ) {
12206								return;
12207							}
12208						}
12209						break;
12210				}
12211
12212				step = this.options.step;
12213				if ( this.options.values && this.options.values.length ) {
12214					curVal = newVal = this.values( index );
12215				} else {
12216					curVal = newVal = this.value();
12217				}
12218
12219				switch ( event.keyCode ) {
12220					case $.ui.keyCode.HOME:
12221						newVal = this._valueMin();
12222						break;
12223					case $.ui.keyCode.END:
12224						newVal = this._valueMax();
12225						break;
12226					case $.ui.keyCode.PAGE_UP:
12227						newVal = this._trimAlignValue( curVal + ( (this._valueMax() - this._valueMin()) / numPages ) );
12228						break;
12229					case $.ui.keyCode.PAGE_DOWN:
12230						newVal = this._trimAlignValue( curVal - ( (this._valueMax() - this._valueMin()) / numPages ) );
12231						break;
12232					case $.ui.keyCode.UP:
12233					case $.ui.keyCode.RIGHT:
12234						if ( curVal === this._valueMax() ) {
12235							return;
12236						}
12237						newVal = this._trimAlignValue( curVal + step );
12238						break;
12239					case $.ui.keyCode.DOWN:
12240					case $.ui.keyCode.LEFT:
12241						if ( curVal === this._valueMin() ) {
12242							return;
12243						}
12244						newVal = this._trimAlignValue( curVal - step );
12245						break;
12246				}
12247
12248				this._slide( event, index, newVal );
12249			},
12250			keyup: function( event ) {
12251				var index = $( event.target ).data( "ui-slider-handle-index" );
12252
12253				if ( this._keySliding ) {
12254					this._keySliding = false;
12255					this._stop( event, index );
12256					this._change( event, index );
12257					$( event.target ).removeClass( "ui-state-active" );
12258				}
12259			}
12260		});
12261
12262		this._refreshValue();
12263
12264		this._animateOff = false;
12265	},
12266
12267	_destroy: function() {
12268		this.handles.remove();
12269		this.range.remove();
12270
12271		this.element
12272			.removeClass( "ui-slider" +
12273				" ui-slider-horizontal" +
12274				" ui-slider-vertical" +
12275				" ui-slider-disabled" +
12276				" ui-widget" +
12277				" ui-widget-content" +
12278				" ui-corner-all" );
12279
12280		this._mouseDestroy();
12281	},
12282
12283	_mouseCapture: function( event ) {
12284		var position, normValue, distance, closestHandle, index, allowed, offset, mouseOverHandle,
12285			that = this,
12286			o = this.options;
12287
12288		if ( o.disabled ) {
12289			return false;
12290		}
12291
12292		this.elementSize = {
12293			width: this.element.outerWidth(),
12294			height: this.element.outerHeight()
12295		};
12296		this.elementOffset = this.element.offset();
12297
12298		position = { x: event.pageX, y: event.pageY };
12299		normValue = this._normValueFromMouse( position );
12300		distance = this._valueMax() - this._valueMin() + 1;
12301		this.handles.each(function( i ) {
12302			var thisDistance = Math.abs( normValue - that.values(i) );
12303			if ( distance > thisDistance ) {
12304				distance = thisDistance;
12305				closestHandle = $( this );
12306				index = i;
12307			}
12308		});
12309
12310		// workaround for bug #3736 (if both handles of a range are at 0,
12311		// the first is always used as the one with least distance,
12312		// and moving it is obviously prevented by preventing negative ranges)
12313		if( o.range === true && this.values(1) === o.min ) {
12314			index += 1;
12315			closestHandle = $( this.handles[index] );
12316		}
12317
12318		allowed = this._start( event, index );
12319		if ( allowed === false ) {
12320			return false;
12321		}
12322		this._mouseSliding = true;
12323
12324		this._handleIndex = index;
12325
12326		closestHandle
12327			.addClass( "ui-state-active" )
12328			.focus();
12329
12330		offset = closestHandle.offset();
12331		mouseOverHandle = !$( event.target ).parents().andSelf().is( ".ui-slider-handle" );
12332		this._clickOffset = mouseOverHandle ? { left: 0, top: 0 } : {
12333			left: event.pageX - offset.left - ( closestHandle.width() / 2 ),
12334			top: event.pageY - offset.top -
12335				( closestHandle.height() / 2 ) -
12336				( parseInt( closestHandle.css("borderTopWidth"), 10 ) || 0 ) -
12337				( parseInt( closestHandle.css("borderBottomWidth"), 10 ) || 0) +
12338				( parseInt( closestHandle.css("marginTop"), 10 ) || 0)
12339		};
12340
12341		if ( !this.handles.hasClass( "ui-state-hover" ) ) {
12342			this._slide( event, index, normValue );
12343		}
12344		this._animateOff = true;
12345		return true;
12346	},
12347
12348	_mouseStart: function() {
12349		return true;
12350	},
12351
12352	_mouseDrag: function( event ) {
12353		var position = { x: event.pageX, y: event.pageY },
12354			normValue = this._normValueFromMouse( position );
12355
12356		this._slide( event, this._handleIndex, normValue );
12357
12358		return false;
12359	},
12360
12361	_mouseStop: function( event ) {
12362		this.handles.removeClass( "ui-state-active" );
12363		this._mouseSliding = false;
12364
12365		this._stop( event, this._handleIndex );
12366		this._change( event, this._handleIndex );
12367
12368		this._handleIndex = null;
12369		this._clickOffset = null;
12370		this._animateOff = false;
12371
12372		return false;
12373	},
12374
12375	_detectOrientation: function() {
12376		this.orientation = ( this.options.orientation === "vertical" ) ? "vertical" : "horizontal";
12377	},
12378
12379	_normValueFromMouse: function( position ) {
12380		var pixelTotal,
12381			pixelMouse,
12382			percentMouse,
12383			valueTotal,
12384			valueMouse;
12385
12386		if ( this.orientation === "horizontal" ) {
12387			pixelTotal = this.elementSize.width;
12388			pixelMouse = position.x - this.elementOffset.left - ( this._clickOffset ? this._clickOffset.left : 0 );
12389		} else {
12390			pixelTotal = this.elementSize.height;
12391			pixelMouse = position.y - this.elementOffset.top - ( this._clickOffset ? this._clickOffset.top : 0 );
12392		}
12393
12394		percentMouse = ( pixelMouse / pixelTotal );
12395		if ( percentMouse > 1 ) {
12396			percentMouse = 1;
12397		}
12398		if ( percentMouse < 0 ) {
12399			percentMouse = 0;
12400		}
12401		if ( this.orientation === "vertical" ) {
12402			percentMouse = 1 - percentMouse;
12403		}
12404
12405		valueTotal = this._valueMax() - this._valueMin();
12406		valueMouse = this._valueMin() + percentMouse * valueTotal;
12407
12408		return this._trimAlignValue( valueMouse );
12409	},
12410
12411	_start: function( event, index ) {
12412		var uiHash = {
12413			handle: this.handles[ index ],
12414			value: this.value()
12415		};
12416		if ( this.options.values && this.options.values.length ) {
12417			uiHash.value = this.values( index );
12418			uiHash.values = this.values();
12419		}
12420		return this._trigger( "start", event, uiHash );
12421	},
12422
12423	_slide: function( event, index, newVal ) {
12424		var otherVal,
12425			newValues,
12426			allowed;
12427
12428		if ( this.options.values && this.options.values.length ) {
12429			otherVal = this.values( index ? 0 : 1 );
12430
12431			if ( ( this.options.values.length === 2 && this.options.range === true ) &&
12432					( ( index === 0 && newVal > otherVal) || ( index === 1 && newVal < otherVal ) )
12433				) {
12434				newVal = otherVal;
12435			}
12436
12437			if ( newVal !== this.values( index ) ) {
12438				newValues = this.values();
12439				newValues[ index ] = newVal;
12440				// A slide can be canceled by returning false from the slide callback
12441				allowed = this._trigger( "slide", event, {
12442					handle: this.handles[ index ],
12443					value: newVal,
12444					values: newValues
12445				} );
12446				otherVal = this.values( index ? 0 : 1 );
12447				if ( allowed !== false ) {
12448					this.values( index, newVal, true );
12449				}
12450			}
12451		} else {
12452			if ( newVal !== this.value() ) {
12453				// A slide can be canceled by returning false from the slide callback
12454				allowed = this._trigger( "slide", event, {
12455					handle: this.handles[ index ],
12456					value: newVal
12457				} );
12458				if ( allowed !== false ) {
12459					this.value( newVal );
12460				}
12461			}
12462		}
12463	},
12464
12465	_stop: function( event, index ) {
12466		var uiHash = {
12467			handle: this.handles[ index ],
12468			value: this.value()
12469		};
12470		if ( this.options.values && this.options.values.length ) {
12471			uiHash.value = this.values( index );
12472			uiHash.values = this.values();
12473		}
12474
12475		this._trigger( "stop", event, uiHash );
12476	},
12477
12478	_change: function( event, index ) {
12479		if ( !this._keySliding && !this._mouseSliding ) {
12480			var uiHash = {
12481				handle: this.handles[ index ],
12482				value: this.value()
12483			};
12484			if ( this.options.values && this.options.values.length ) {
12485				uiHash.value = this.values( index );
12486				uiHash.values = this.values();
12487			}
12488
12489			this._trigger( "change", event, uiHash );
12490		}
12491	},
12492
12493	value: function( newValue ) {
12494		if ( arguments.length ) {
12495			this.options.value = this._trimAlignValue( newValue );
12496			this._refreshValue();
12497			this._change( null, 0 );
12498			return;
12499		}
12500
12501		return this._value();
12502	},
12503
12504	values: function( index, newValue ) {
12505		var vals,
12506			newValues,
12507			i;
12508
12509		if ( arguments.length > 1 ) {
12510			this.options.values[ index ] = this._trimAlignValue( newValue );
12511			this._refreshValue();
12512			this._change( null, index );
12513			return;
12514		}
12515
12516		if ( arguments.length ) {
12517			if ( $.isArray( arguments[ 0 ] ) ) {
12518				vals = this.options.values;
12519				newValues = arguments[ 0 ];
12520				for ( i = 0; i < vals.length; i += 1 ) {
12521					vals[ i ] = this._trimAlignValue( newValues[ i ] );
12522					this._change( null, i );
12523				}
12524				this._refreshValue();
12525			} else {
12526				if ( this.options.values && this.options.values.length ) {
12527					return this._values( index );
12528				} else {
12529					return this.value();
12530				}
12531			}
12532		} else {
12533			return this._values();
12534		}
12535	},
12536
12537	_setOption: function( key, value ) {
12538		var i,
12539			valsLength = 0;
12540
12541		if ( $.isArray( this.options.values ) ) {
12542			valsLength = this.options.values.length;
12543		}
12544
12545		$.Widget.prototype._setOption.apply( this, arguments );
12546
12547		switch ( key ) {
12548			case "disabled":
12549				if ( value ) {
12550					this.handles.filter( ".ui-state-focus" ).blur();
12551					this.handles.removeClass( "ui-state-hover" );
12552					this.handles.prop( "disabled", true );
12553					this.element.addClass( "ui-disabled" );
12554				} else {
12555					this.handles.prop( "disabled", false );
12556					this.element.removeClass( "ui-disabled" );
12557				}
12558				break;
12559			case "orientation":
12560				this._detectOrientation();
12561				this.element
12562					.removeClass( "ui-slider-horizontal ui-slider-vertical" )
12563					.addClass( "ui-slider-" + this.orientation );
12564				this._refreshValue();
12565				break;
12566			case "value":
12567				this._animateOff = true;
12568				this._refreshValue();
12569				this._change( null, 0 );
12570				this._animateOff = false;
12571				break;
12572			case "values":
12573				this._animateOff = true;
12574				this._refreshValue();
12575				for ( i = 0; i < valsLength; i += 1 ) {
12576					this._change( null, i );
12577				}
12578				this._animateOff = false;
12579				break;
12580			case "min":
12581			case "max":
12582				this._animateOff = true;
12583				this._refreshValue();
12584				this._animateOff = false;
12585				break;
12586		}
12587	},
12588
12589	//internal value getter
12590	// _value() returns value trimmed by min and max, aligned by step
12591	_value: function() {
12592		var val = this.options.value;
12593		val = this._trimAlignValue( val );
12594
12595		return val;
12596	},
12597
12598	//internal values getter
12599	// _values() returns array of values trimmed by min and max, aligned by step
12600	// _values( index ) returns single value trimmed by min and max, aligned by step
12601	_values: function( index ) {
12602		var val,
12603			vals,
12604			i;
12605
12606		if ( arguments.length ) {
12607			val = this.options.values[ index ];
12608			val = this._trimAlignValue( val );
12609
12610			return val;
12611		} else {
12612			// .slice() creates a copy of the array
12613			// this copy gets trimmed by min and max and then returned
12614			vals = this.options.values.slice();
12615			for ( i = 0; i < vals.length; i+= 1) {
12616				vals[ i ] = this._trimAlignValue( vals[ i ] );
12617			}
12618
12619			return vals;
12620		}
12621	},
12622
12623	// returns the step-aligned value that val is closest to, between (inclusive) min and max
12624	_trimAlignValue: function( val ) {
12625		if ( val <= this._valueMin() ) {
12626			return this._valueMin();
12627		}
12628		if ( val >= this._valueMax() ) {
12629			return this._valueMax();
12630		}
12631		var step = ( this.options.step > 0 ) ? this.options.step : 1,
12632			valModStep = (val - this._valueMin()) % step,
12633			alignValue = val - valModStep;
12634
12635		if ( Math.abs(valModStep) * 2 >= step ) {
12636			alignValue += ( valModStep > 0 ) ? step : ( -step );
12637		}
12638
12639		// Since JavaScript has problems with large floats, round
12640		// the final value to 5 digits after the decimal point (see #4124)
12641		return parseFloat( alignValue.toFixed(5) );
12642	},
12643
12644	_valueMin: function() {
12645		return this.options.min;
12646	},
12647
12648	_valueMax: function() {
12649		return this.options.max;
12650	},
12651
12652	_refreshValue: function() {
12653		var lastValPercent, valPercent, value, valueMin, valueMax,
12654			oRange = this.options.range,
12655			o = this.options,
12656			that = this,
12657			animate = ( !this._animateOff ) ? o.animate : false,
12658			_set = {};
12659
12660		if ( this.options.values && this.options.values.length ) {
12661			this.handles.each(function( i ) {
12662				valPercent = ( that.values(i) - that._valueMin() ) / ( that._valueMax() - that._valueMin() ) * 100;
12663				_set[ that.orientation === "horizontal" ? "left" : "bottom" ] = valPercent + "%";
12664				$( this ).stop( 1, 1 )[ animate ? "animate" : "css" ]( _set, o.animate );
12665				if ( that.options.range === true ) {
12666					if ( that.orientation === "horizontal" ) {
12667						if ( i === 0 ) {
12668							that.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { left: valPercent + "%" }, o.animate );
12669						}
12670						if ( i === 1 ) {
12671							that.range[ animate ? "animate" : "css" ]( { width: ( valPercent - lastValPercent ) + "%" }, { queue: false, duration: o.animate } );
12672						}
12673					} else {
12674						if ( i === 0 ) {
12675							that.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { bottom: ( valPercent ) + "%" }, o.animate );
12676						}
12677						if ( i === 1 ) {
12678							that.range[ animate ? "animate" : "css" ]( { height: ( valPercent - lastValPercent ) + "%" }, { queue: false, duration: o.animate } );
12679						}
12680					}
12681				}
12682				lastValPercent = valPercent;
12683			});
12684		} else {
12685			value = this.value();
12686			valueMin = this._valueMin();
12687			valueMax = this._valueMax();
12688			valPercent = ( valueMax !== valueMin ) ?
12689					( value - valueMin ) / ( valueMax - valueMin ) * 100 :
12690					0;
12691			_set[ this.orientation === "horizontal" ? "left" : "bottom" ] = valPercent + "%";
12692			this.handle.stop( 1, 1 )[ animate ? "animate" : "css" ]( _set, o.animate );
12693
12694			if ( oRange === "min" && this.orientation === "horizontal" ) {
12695				this.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { width: valPercent + "%" }, o.animate );
12696			}
12697			if ( oRange === "max" && this.orientation === "horizontal" ) {
12698				this.range[ animate ? "animate" : "css" ]( { width: ( 100 - valPercent ) + "%" }, { queue: false, duration: o.animate } );
12699			}
12700			if ( oRange === "min" && this.orientation === "vertical" ) {
12701				this.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { height: valPercent + "%" }, o.animate );
12702			}
12703			if ( oRange === "max" && this.orientation === "vertical" ) {
12704				this.range[ animate ? "animate" : "css" ]( { height: ( 100 - valPercent ) + "%" }, { queue: false, duration: o.animate } );
12705			}
12706		}
12707	}
12708
12709});
12710
12711}(jQuery));
12712
12713(function( $ ) {
12714
12715function modifier( fn ) {
12716	return function() {
12717		var previous = this.element.val();
12718		fn.apply( this, arguments );
12719		this._refresh();
12720		if ( previous !== this.element.val() ) {
12721			this._trigger( "change" );
12722		}
12723	};
12724}
12725
12726$.widget( "ui.spinner", {
12727	version: "1.9.2",
12728	defaultElement: "<input>",
12729	widgetEventPrefix: "spin",
12730	options: {
12731		culture: null,
12732		icons: {
12733			down: "ui-icon-triangle-1-s",
12734			up: "ui-icon-triangle-1-n"
12735		},
12736		incremental: true,
12737		max: null,
12738		min: null,
12739		numberFormat: null,
12740		page: 10,
12741		step: 1,
12742
12743		change: null,
12744		spin: null,
12745		start: null,
12746		stop: null
12747	},
12748
12749	_create: function() {
12750		// handle string values that need to be parsed
12751		this._setOption( "max", this.options.max );
12752		this._setOption( "min", this.options.min );
12753		this._setOption( "step", this.options.step );
12754
12755		// format the value, but don't constrain
12756		this._value( this.element.val(), true );
12757
12758		this._draw();
12759		this._on( this._events );
12760		this._refresh();
12761
12762		// turning off autocomplete prevents the browser from remembering the
12763		// value when navigating through history, so we re-enable autocomplete
12764		// if the page is unloaded before the widget is destroyed. #7790
12765		this._on( this.window, {
12766			beforeunload: function() {
12767				this.element.removeAttr( "autocomplete" );
12768			}
12769		});
12770	},
12771
12772	_getCreateOptions: function() {
12773		var options = {},
12774			element = this.element;
12775
12776		$.each( [ "min", "max", "step" ], function( i, option ) {
12777			var value = element.attr( option );
12778			if ( value !== undefined && value.length ) {
12779				options[ option ] = value;
12780			}
12781		});
12782
12783		return options;
12784	},
12785
12786	_events: {
12787		keydown: function( event ) {
12788			if ( this._start( event ) && this._keydown( event ) ) {
12789				event.preventDefault();
12790			}
12791		},
12792		keyup: "_stop",
12793		focus: function() {
12794			this.previous = this.element.val();
12795		},
12796		blur: function( event ) {
12797			if ( this.cancelBlur ) {
12798				delete this.cancelBlur;
12799				return;
12800			}
12801
12802			this._refresh();
12803			if ( this.previous !== this.element.val() ) {
12804				this._trigger( "change", event );
12805			}
12806		},
12807		mousewheel: function( event, delta ) {
12808			if ( !delta ) {
12809				return;
12810			}
12811			if ( !this.spinning && !this._start( event ) ) {
12812				return false;
12813			}
12814
12815			this._spin( (delta > 0 ? 1 : -1) * this.options.step, event );
12816			clearTimeout( this.mousewheelTimer );
12817			this.mousewheelTimer = this._delay(function() {
12818				if ( this.spinning ) {
12819					this._stop( event );
12820				}
12821			}, 100 );
12822			event.preventDefault();
12823		},
12824		"mousedown .ui-spinner-button": function( event ) {
12825			var previous;
12826
12827			// We never want the buttons to have focus; whenever the user is
12828			// interacting with the spinner, the focus should be on the input.
12829			// If the input is focused then this.previous is properly set from
12830			// when the input first received focus. If the input is not focused
12831			// then we need to set this.previous based on the value before spinning.
12832			previous = this.element[0] === this.document[0].activeElement ?
12833				this.previous : this.element.val();
12834			function checkFocus() {
12835				var isActive = this.element[0] === this.document[0].activeElement;
12836				if ( !isActive ) {
12837					this.element.focus();
12838					this.previous = previous;
12839					// support: IE
12840					// IE sets focus asynchronously, so we need to check if focus
12841					// moved off of the input because the user clicked on the button.
12842					this._delay(function() {
12843						this.previous = previous;
12844					});
12845				}
12846			}
12847
12848			// ensure focus is on (or stays on) the text field
12849			event.preventDefault();
12850			checkFocus.call( this );
12851
12852			// support: IE
12853			// IE doesn't prevent moving focus even with event.preventDefault()
12854			// so we set a flag to know when we should ignore the blur event
12855			// and check (again) if focus moved off of the input.
12856			this.cancelBlur = true;
12857			this._delay(function() {
12858				delete this.cancelBlur;
12859				checkFocus.call( this );
12860			});
12861
12862			if ( this._start( event ) === false ) {
12863				return;
12864			}
12865
12866			this._repeat( null, $( event.currentTarget ).hasClass( "ui-spinner-up" ) ? 1 : -1, event );
12867		},
12868		"mouseup .ui-spinner-button": "_stop",
12869		"mouseenter .ui-spinner-button": function( event ) {
12870			// button will add ui-state-active if mouse was down while mouseleave and kept down
12871			if ( !$( event.currentTarget ).hasClass( "ui-state-active" ) ) {
12872				return;
12873			}
12874
12875			if ( this._start( event ) === false ) {
12876				return false;
12877			}
12878			this._repeat( null, $( event.currentTarget ).hasClass( "ui-spinner-up" ) ? 1 : -1, event );
12879		},
12880		// TODO: do we really want to consider this a stop?
12881		// shouldn't we just stop the repeater and wait until mouseup before
12882		// we trigger the stop event?
12883		"mouseleave .ui-spinner-button": "_stop"
12884	},
12885
12886	_draw: function() {
12887		var uiSpinner = this.uiSpinner = this.element
12888			.addClass( "ui-spinner-input" )
12889			.attr( "autocomplete", "off" )
12890			.wrap( this._uiSpinnerHtml() )
12891			.parent()
12892				// add buttons
12893				.append( this._buttonHtml() );
12894
12895		this.element.attr( "role", "spinbutton" );
12896
12897		// button bindings
12898		this.buttons = uiSpinner.find( ".ui-spinner-button" )
12899			.attr( "tabIndex", -1 )
12900			.button()
12901			.removeClass( "ui-corner-all" );
12902
12903		// IE 6 doesn't understand height: 50% for the buttons
12904		// unless the wrapper has an explicit height
12905		if ( this.buttons.height() > Math.ceil( uiSpinner.height() * 0.5 ) &&
12906				uiSpinner.height() > 0 ) {
12907			uiSpinner.height( uiSpinner.height() );
12908		}
12909
12910		// disable spinner if element was already disabled
12911		if ( this.options.disabled ) {
12912			this.disable();
12913		}
12914	},
12915
12916	_keydown: function( event ) {
12917		var options = this.options,
12918			keyCode = $.ui.keyCode;
12919
12920		switch ( event.keyCode ) {
12921		case keyCode.UP:
12922			this._repeat( null, 1, event );
12923			return true;
12924		case keyCode.DOWN:
12925			this._repeat( null, -1, event );
12926			return true;
12927		case keyCode.PAGE_UP:
12928			this._repeat( null, options.page, event );
12929			return true;
12930		case keyCode.PAGE_DOWN:
12931			this._repeat( null, -options.page, event );
12932			return true;
12933		}
12934
12935		return false;
12936	},
12937
12938	_uiSpinnerHtml: function() {
12939		return "<span class='ui-spinner ui-widget ui-widget-content ui-corner-all'></span>";
12940	},
12941
12942	_buttonHtml: function() {
12943		return "" +
12944			"<a class='ui-spinner-button ui-spinner-up ui-corner-tr'>" +
12945				"<span class='ui-icon " + this.options.icons.up + "'>&#9650;</span>" +
12946			"</a>" +
12947			"<a class='ui-spinner-button ui-spinner-down ui-corner-br'>" +
12948				"<span class='ui-icon " + this.options.icons.down + "'>&#9660;</span>" +
12949			"</a>";
12950	},
12951
12952	_start: function( event ) {
12953		if ( !this.spinning && this._trigger( "start", event ) === false ) {
12954			return false;
12955		}
12956
12957		if ( !this.counter ) {
12958			this.counter = 1;
12959		}
12960		this.spinning = true;
12961		return true;
12962	},
12963
12964	_repeat: function( i, steps, event ) {
12965		i = i || 500;
12966
12967		clearTimeout( this.timer );
12968		this.timer = this._delay(function() {
12969			this._repeat( 40, steps, event );
12970		}, i );
12971
12972		this._spin( steps * this.options.step, event );
12973	},
12974
12975	_spin: function( step, event ) {
12976		var value = this.value() || 0;
12977
12978		if ( !this.counter ) {
12979			this.counter = 1;
12980		}
12981
12982		value = this._adjustValue( value + step * this._increment( this.counter ) );
12983
12984		if ( !this.spinning || this._trigger( "spin", event, { value: value } ) !== false) {
12985			this._value( value );
12986			this.counter++;
12987		}
12988	},
12989
12990	_increment: function( i ) {
12991		var incremental = this.options.incremental;
12992
12993		if ( incremental ) {
12994			return $.isFunction( incremental ) ?
12995				incremental( i ) :
12996				Math.floor( i*i*i/50000 - i*i/500 + 17*i/200 + 1 );
12997		}
12998
12999		return 1;
13000	},
13001
13002	_precision: function() {
13003		var precision = this._precisionOf( this.options.step );
13004		if ( this.options.min !== null ) {
13005			precision = Math.max( precision, this._precisionOf( this.options.min ) );
13006		}
13007		return precision;
13008	},
13009
13010	_precisionOf: function( num ) {
13011		var str = num.toString(),
13012			decimal = str.indexOf( "." );
13013		return decimal === -1 ? 0 : str.length - decimal - 1;
13014	},
13015
13016	_adjustValue: function( value ) {
13017		var base, aboveMin,
13018			options = this.options;
13019
13020		// make sure we're at a valid step
13021		// - find out where we are relative to the base (min or 0)
13022		base = options.min !== null ? options.min : 0;
13023		aboveMin = value - base;
13024		// - round to the nearest step
13025		aboveMin = Math.round(aboveMin / options.step) * options.step;
13026		// - rounding is based on 0, so adjust back to our base
13027		value = base + aboveMin;
13028
13029		// fix precision from bad JS floating point math
13030		value = parseFloat( value.toFixed( this._precision() ) );
13031
13032		// clamp the value
13033		if ( options.max !== null && value > options.max) {
13034			return options.max;
13035		}
13036		if ( options.min !== null && value < options.min ) {
13037			return options.min;
13038		}
13039
13040		return value;
13041	},
13042
13043	_stop: function( event ) {
13044		if ( !this.spinning ) {
13045			return;
13046		}
13047
13048		clearTimeout( this.timer );
13049		clearTimeout( this.mousewheelTimer );
13050		this.counter = 0;
13051		this.spinning = false;
13052		this._trigger( "stop", event );
13053	},
13054
13055	_setOption: function( key, value ) {
13056		if ( key === "culture" || key === "numberFormat" ) {
13057			var prevValue = this._parse( this.element.val() );
13058			this.options[ key ] = value;
13059			this.element.val( this._format( prevValue ) );
13060			return;
13061		}
13062
13063		if ( key === "max" || key === "min" || key === "step" ) {
13064			if ( typeof value === "string" ) {
13065				value = this._parse( value );
13066			}
13067		}
13068
13069		this._super( key, value );
13070
13071		if ( key === "disabled" ) {
13072			if ( value ) {
13073				this.element.prop( "disabled", true );
13074				this.buttons.button( "disable" );
13075			} else {
13076				this.element.prop( "disabled", false );
13077				this.buttons.button( "enable" );
13078			}
13079		}
13080	},
13081
13082	_setOptions: modifier(function( options ) {
13083		this._super( options );
13084		this._value( this.element.val() );
13085	}),
13086
13087	_parse: function( val ) {
13088		if ( typeof val === "string" && val !== "" ) {
13089			val = window.Globalize && this.options.numberFormat ?
13090				Globalize.parseFloat( val, 10, this.options.culture ) : +val;
13091		}
13092		return val === "" || isNaN( val ) ? null : val;
13093	},
13094
13095	_format: function( value ) {
13096		if ( value === "" ) {
13097			return "";
13098		}
13099		return window.Globalize && this.options.numberFormat ?
13100			Globalize.format( value, this.options.numberFormat, this.options.culture ) :
13101			value;
13102	},
13103
13104	_refresh: function() {
13105		this.element.attr({
13106			"aria-valuemin": this.options.min,
13107			"aria-valuemax": this.options.max,
13108			// TODO: what should we do with values that can't be parsed?
13109			"aria-valuenow": this._parse( this.element.val() )
13110		});
13111	},
13112
13113	// update the value without triggering change
13114	_value: function( value, allowAny ) {
13115		var parsed;
13116		if ( value !== "" ) {
13117			parsed = this._parse( value );
13118			if ( parsed !== null ) {
13119				if ( !allowAny ) {
13120					parsed = this._adjustValue( parsed );
13121				}
13122				value = this._format( parsed );
13123			}
13124		}
13125		this.element.val( value );
13126		this._refresh();
13127	},
13128
13129	_destroy: function() {
13130		this.element
13131			.removeClass( "ui-spinner-input" )
13132			.prop( "disabled", false )
13133			.removeAttr( "autocomplete" )
13134			.removeAttr( "role" )
13135			.removeAttr( "aria-valuemin" )
13136			.removeAttr( "aria-valuemax" )
13137			.removeAttr( "aria-valuenow" );
13138		this.uiSpinner.replaceWith( this.element );
13139	},
13140
13141	stepUp: modifier(function( steps ) {
13142		this._stepUp( steps );
13143	}),
13144	_stepUp: function( steps ) {
13145		this._spin( (steps || 1) * this.options.step );
13146	},
13147
13148	stepDown: modifier(function( steps ) {
13149		this._stepDown( steps );
13150	}),
13151	_stepDown: function( steps ) {
13152		this._spin( (steps || 1) * -this.options.step );
13153	},
13154
13155	pageUp: modifier(function( pages ) {
13156		this._stepUp( (pages || 1) * this.options.page );
13157	}),
13158
13159	pageDown: modifier(function( pages ) {
13160		this._stepDown( (pages || 1) * this.options.page );
13161	}),
13162
13163	value: function( newVal ) {
13164		if ( !arguments.length ) {
13165			return this._parse( this.element.val() );
13166		}
13167		modifier( this._value ).call( this, newVal );
13168	},
13169
13170	widget: function() {
13171		return this.uiSpinner;
13172	}
13173});
13174
13175}( jQuery ) );
13176
13177(function( $, undefined ) {
13178
13179var tabId = 0,
13180	rhash = /#.*$/;
13181
13182function getNextTabId() {
13183	return ++tabId;
13184}
13185
13186function isLocal( anchor ) {
13187	return anchor.hash.length > 1 &&
13188		anchor.href.replace( rhash, "" ) ===
13189			location.href.replace( rhash, "" )
13190				// support: Safari 5.1
13191				// Safari 5.1 doesn't encode spaces in window.location
13192				// but it does encode spaces from anchors (#8777)
13193				.replace( /\s/g, "%20" );
13194}
13195
13196$.widget( "ui.tabs", {
13197	version: "1.9.2",
13198	delay: 300,
13199	options: {
13200		active: null,
13201		collapsible: false,
13202		event: "click",
13203		heightStyle: "content",
13204		hide: null,
13205		show: null,
13206
13207		// callbacks
13208		activate: null,
13209		beforeActivate: null,
13210		beforeLoad: null,
13211		load: null
13212	},
13213
13214	_create: function() {
13215		var that = this,
13216			options = this.options,
13217			active = options.active,
13218			locationHash = location.hash.substring( 1 );
13219
13220		this.running = false;
13221
13222		this.element
13223			.addClass( "ui-tabs ui-widget ui-widget-content ui-corner-all" )
13224			.toggleClass( "ui-tabs-collapsible", options.collapsible )
13225			// Prevent users from focusing disabled tabs via click
13226			.delegate( ".ui-tabs-nav > li", "mousedown" + this.eventNamespace, function( event ) {
13227				if ( $( this ).is( ".ui-state-disabled" ) ) {
13228					event.preventDefault();
13229				}
13230			})
13231			// support: IE <9
13232			// Preventing the default action in mousedown doesn't prevent IE
vendor: 18,149 bytes, lines 13233-13906
13233			// from focusing the element, so if the anchor gets focused, blur.
13234			// We don't have to worry about focusing the previously focused
13235			// element since clicking on a non-focusable element should focus
13236			// the body anyway.
13237			.delegate( ".ui-tabs-anchor", "focus" + this.eventNamespace, function() {
13238				if ( $( this ).closest( "li" ).is( ".ui-state-disabled" ) ) {
13239					this.blur();
13240				}
13241			});
13242
13243		this._processTabs();
13244
13245		if ( active === null ) {
13246			// check the fragment identifier in the URL
13247			if ( locationHash ) {
13248				this.tabs.each(function( i, tab ) {
13249					if ( $( tab ).attr( "aria-controls" ) === locationHash ) {
13250						active = i;
13251						return false;
13252					}
13253				});
13254			}
13255
13256			// check for a tab marked active via a class
13257			if ( active === null ) {
13258				active = this.tabs.index( this.tabs.filter( ".ui-tabs-active" ) );
13259			}
13260
13261			// no active tab, set to false
13262			if ( active === null || active === -1 ) {
13263				active = this.tabs.length ? 0 : false;
13264			}
13265		}
13266
13267		// handle numbers: negative, out of range
13268		if ( active !== false ) {
13269			active = this.tabs.index( this.tabs.eq( active ) );
13270			if ( active === -1 ) {
13271				active = options.collapsible ? false : 0;
13272			}
13273		}
13274		options.active = active;
13275
13276		// don't allow collapsible: false and active: false
13277		if ( !options.collapsible && options.active === false && this.anchors.length ) {
13278			options.active = 0;
13279		}
13280
13281		// Take disabling tabs via class attribute from HTML
13282		// into account and update option properly.
13283		if ( $.isArray( options.disabled ) ) {
13284			options.disabled = $.unique( options.disabled.concat(
13285				$.map( this.tabs.filter( ".ui-state-disabled" ), function( li ) {
13286					return that.tabs.index( li );
13287				})
13288			) ).sort();
13289		}
13290
13291		// check for length avoids error when initializing empty list
13292		if ( this.options.active !== false && this.anchors.length ) {
13293			this.active = this._findActive( this.options.active );
13294		} else {
13295			this.active = $();
13296		}
13297
13298		this._refresh();
13299
13300		if ( this.active.length ) {
13301			this.load( options.active );
13302		}
13303	},
13304
13305	_getCreateEventData: function() {
13306		return {
13307			tab: this.active,
13308			panel: !this.active.length ? $() : this._getPanelForTab( this.active )
13309		};
13310	},
13311
13312	_tabKeydown: function( event ) {
13313		var focusedTab = $( this.document[0].activeElement ).closest( "li" ),
13314			selectedIndex = this.tabs.index( focusedTab ),
13315			goingForward = true;
13316
13317		if ( this._handlePageNav( event ) ) {
13318			return;
13319		}
13320
13321		switch ( event.keyCode ) {
13322			case $.ui.keyCode.RIGHT:
13323			case $.ui.keyCode.DOWN:
13324				selectedIndex++;
13325				break;
13326			case $.ui.keyCode.UP:
13327			case $.ui.keyCode.LEFT:
13328				goingForward = false;
13329				selectedIndex--;
13330				break;
13331			case $.ui.keyCode.END:
13332				selectedIndex = this.anchors.length - 1;
13333				break;
13334			case $.ui.keyCode.HOME:
13335				selectedIndex = 0;
13336				break;
13337			case $.ui.keyCode.SPACE:
13338				// Activate only, no collapsing
13339				event.preventDefault();
13340				clearTimeout( this.activating );
13341				this._activate( selectedIndex );
13342				return;
13343			case $.ui.keyCode.ENTER:
13344				// Toggle (cancel delayed activation, allow collapsing)
13345				event.preventDefault();
13346				clearTimeout( this.activating );
13347				// Determine if we should collapse or activate
13348				this._activate( selectedIndex === this.options.active ? false : selectedIndex );
13349				return;
13350			default:
13351				return;
13352		}
13353
13354		// Focus the appropriate tab, based on which key was pressed
13355		event.preventDefault();
13356		clearTimeout( this.activating );
13357		selectedIndex = this._focusNextTab( selectedIndex, goingForward );
13358
13359		// Navigating with control key will prevent automatic activation
13360		if ( !event.ctrlKey ) {
13361			// Update aria-selected immediately so that AT think the tab is already selected.
13362			// Otherwise AT may confuse the user by stating that they need to activate the tab,
13363			// but the tab will already be activated by the time the announcement finishes.
13364			focusedTab.attr( "aria-selected", "false" );
13365			this.tabs.eq( selectedIndex ).attr( "aria-selected", "true" );
13366
13367			this.activating = this._delay(function() {
13368				this.option( "active", selectedIndex );
13369			}, this.delay );
13370		}
13371	},
13372
13373	_panelKeydown: function( event ) {
13374		if ( this._handlePageNav( event ) ) {
13375			return;
13376		}
13377
13378		// Ctrl+up moves focus to the current tab
13379		if ( event.ctrlKey && event.keyCode === $.ui.keyCode.UP ) {
13380			event.preventDefault();
13381			this.active.focus();
13382		}
13383	},
13384
13385	// Alt+page up/down moves focus to the previous/next tab (and activates)
13386	_handlePageNav: function( event ) {
13387		if ( event.altKey && event.keyCode === $.ui.keyCode.PAGE_UP ) {
13388			this._activate( this._focusNextTab( this.options.active - 1, false ) );
13389			return true;
13390		}
13391		if ( event.altKey && event.keyCode === $.ui.keyCode.PAGE_DOWN ) {
13392			this._activate( this._focusNextTab( this.options.active + 1, true ) );
13393			return true;
13394		}
13395	},
13396
13397	_findNextTab: function( index, goingForward ) {
13398		var lastTabIndex = this.tabs.length - 1;
13399
13400		function constrain() {
13401			if ( index > lastTabIndex ) {
13402				index = 0;
13403			}
13404			if ( index < 0 ) {
13405				index = lastTabIndex;
13406			}
13407			return index;
13408		}
13409
13410		while ( $.inArray( constrain(), this.options.disabled ) !== -1 ) {
13411			index = goingForward ? index + 1 : index - 1;
13412		}
13413
13414		return index;
13415	},
13416
13417	_focusNextTab: function( index, goingForward ) {
13418		index = this._findNextTab( index, goingForward );
13419		this.tabs.eq( index ).focus();
13420		return index;
13421	},
13422
13423	_setOption: function( key, value ) {
13424		if ( key === "active" ) {
13425			// _activate() will handle invalid values and update this.options
13426			this._activate( value );
13427			return;
13428		}
13429
13430		if ( key === "disabled" ) {
13431			// don't use the widget factory's disabled handling
13432			this._setupDisabled( value );
13433			return;
13434		}
13435
13436		this._super( key, value);
13437
13438		if ( key === "collapsible" ) {
13439			this.element.toggleClass( "ui-tabs-collapsible", value );
13440			// Setting collapsible: false while collapsed; open first panel
13441			if ( !value && this.options.active === false ) {
13442				this._activate( 0 );
13443			}
13444		}
13445
13446		if ( key === "event" ) {
13447			this._setupEvents( value );
13448		}
13449
13450		if ( key === "heightStyle" ) {
13451			this._setupHeightStyle( value );
13452		}
13453	},
13454
13455	_tabId: function( tab ) {
13456		return tab.attr( "aria-controls" ) || "ui-tabs-" + getNextTabId();
13457	},
13458
13459	_sanitizeSelector: function( hash ) {
13460		return hash ? hash.replace( /[!"$%&'()*+,.\/:;<=>?@\[\]\^`{|}~]/g, "\\$&" ) : "";
13461	},
13462
13463	refresh: function() {
13464		var options = this.options,
13465			lis = this.tablist.children( ":has(a[href])" );
13466
13467		// get disabled tabs from class attribute from HTML
13468		// this will get converted to a boolean if needed in _refresh()
13469		options.disabled = $.map( lis.filter( ".ui-state-disabled" ), function( tab ) {
13470			return lis.index( tab );
13471		});
13472
13473		this._processTabs();
13474
13475		// was collapsed or no tabs
13476		if ( options.active === false || !this.anchors.length ) {
13477			options.active = false;
13478			this.active = $();
13479		// was active, but active tab is gone
13480		} else if ( this.active.length && !$.contains( this.tablist[ 0 ], this.active[ 0 ] ) ) {
13481			// all remaining tabs are disabled
13482			if ( this.tabs.length === options.disabled.length ) {
13483				options.active = false;
13484				this.active = $();
13485			// activate previous tab
13486			} else {
13487				this._activate( this._findNextTab( Math.max( 0, options.active - 1 ), false ) );
13488			}
13489		// was active, active tab still exists
13490		} else {
13491			// make sure active index is correct
13492			options.active = this.tabs.index( this.active );
13493		}
13494
13495		this._refresh();
13496	},
13497
13498	_refresh: function() {
13499		this._setupDisabled( this.options.disabled );
13500		this._setupEvents( this.options.event );
13501		this._setupHeightStyle( this.options.heightStyle );
13502
13503		this.tabs.not( this.active ).attr({
13504			"aria-selected": "false",
13505			tabIndex: -1
13506		});
13507		this.panels.not( this._getPanelForTab( this.active ) )
13508			.hide()
13509			.attr({
13510				"aria-expanded": "false",
13511				"aria-hidden": "true"
13512			});
13513
13514		// Make sure one tab is in the tab order
13515		if ( !this.active.length ) {
13516			this.tabs.eq( 0 ).attr( "tabIndex", 0 );
13517		} else {
13518			this.active
13519				.addClass( "ui-tabs-active ui-state-active" )
13520				.attr({
13521					"aria-selected": "true",
13522					tabIndex: 0
13523				});
13524			this._getPanelForTab( this.active )
13525				.show()
13526				.attr({
13527					"aria-expanded": "true",
13528					"aria-hidden": "false"
13529				});
13530		}
13531	},
13532
13533	_processTabs: function() {
13534		var that = this;
13535
13536		this.tablist = this._getList()
13537			.addClass( "ui-tabs-nav ui-helper-reset ui-helper-clearfix ui-widget-header ui-corner-all" )
13538			.attr( "role", "tablist" );
13539
13540		this.tabs = this.tablist.find( "> li:has(a[href])" )
13541			.addClass( "ui-state-default ui-corner-top" )
13542			.attr({
13543				role: "tab",
13544				tabIndex: -1
13545			});
13546
13547		this.anchors = this.tabs.map(function() {
13548				return $( "a", this )[ 0 ];
13549			})
13550			.addClass( "ui-tabs-anchor" )
13551			.attr({
13552				role: "presentation",
13553				tabIndex: -1
13554			});
13555
13556		this.panels = $();
13557
13558		this.anchors.each(function( i, anchor ) {
13559			var selector, panel, panelId,
13560				anchorId = $( anchor ).uniqueId().attr( "id" ),
13561				tab = $( anchor ).closest( "li" ),
13562				originalAriaControls = tab.attr( "aria-controls" );
13563
13564			// inline tab
13565			if ( isLocal( anchor ) ) {
13566				selector = anchor.hash;
13567				panel = that.element.find( that._sanitizeSelector( selector ) );
13568			// remote tab
13569			} else {
13570				panelId = that._tabId( tab );
13571				selector = "#" + panelId;
13572				panel = that.element.find( selector );
13573				if ( !panel.length ) {
13574					panel = that._createPanel( panelId );
13575					panel.insertAfter( that.panels[ i - 1 ] || that.tablist );
13576				}
13577				panel.attr( "aria-live", "polite" );
13578			}
13579
13580			if ( panel.length) {
13581				that.panels = that.panels.add( panel );
13582			}
13583			if ( originalAriaControls ) {
13584				tab.data( "ui-tabs-aria-controls", originalAriaControls );
13585			}
13586			tab.attr({
13587				"aria-controls": selector.substring( 1 ),
13588				"aria-labelledby": anchorId
13589			});
13590			panel.attr( "aria-labelledby", anchorId );
13591		});
13592
13593		this.panels
13594			.addClass( "ui-tabs-panel ui-widget-content ui-corner-bottom" )
13595			.attr( "role", "tabpanel" );
13596	},
13597
13598	// allow overriding how to find the list for rare usage scenarios (#7715)
13599	_getList: function() {
13600		return this.element.find( "ol,ul" ).eq( 0 );
13601	},
13602
13603	_createPanel: function( id ) {
13604		return $( "<div>" )
13605			.attr( "id", id )
13606			.addClass( "ui-tabs-panel ui-widget-content ui-corner-bottom" )
13607			.data( "ui-tabs-destroy", true );
13608	},
13609
13610	_setupDisabled: function( disabled ) {
13611		if ( $.isArray( disabled ) ) {
13612			if ( !disabled.length ) {
13613				disabled = false;
13614			} else if ( disabled.length === this.anchors.length ) {
13615				disabled = true;
13616			}
13617		}
13618
13619		// disable tabs
13620		for ( var i = 0, li; ( li = this.tabs[ i ] ); i++ ) {
13621			if ( disabled === true || $.inArray( i, disabled ) !== -1 ) {
13622				$( li )
13623					.addClass( "ui-state-disabled" )
13624					.attr( "aria-disabled", "true" );
13625			} else {
13626				$( li )
13627					.removeClass( "ui-state-disabled" )
13628					.removeAttr( "aria-disabled" );
13629			}
13630		}
13631
13632		this.options.disabled = disabled;
13633	},
13634
13635	_setupEvents: function( event ) {
13636		var events = {
13637			click: function( event ) {
13638				event.preventDefault();
13639			}
13640		};
13641		if ( event ) {
13642			$.each( event.split(" "), function( index, eventName ) {
13643				events[ eventName ] = "_eventHandler";
13644			});
13645		}
13646
13647		this._off( this.anchors.add( this.tabs ).add( this.panels ) );
13648		this._on( this.anchors, events );
13649		this._on( this.tabs, { keydown: "_tabKeydown" } );
13650		this._on( this.panels, { keydown: "_panelKeydown" } );
13651
13652		this._focusable( this.tabs );
13653		this._hoverable( this.tabs );
13654	},
13655
13656	_setupHeightStyle: function( heightStyle ) {
13657		var maxHeight, overflow,
13658			parent = this.element.parent();
13659
13660		if ( heightStyle === "fill" ) {
13661			// IE 6 treats height like minHeight, so we need to turn off overflow
13662			// in order to get a reliable height
13663			// we use the minHeight support test because we assume that only
13664			// browsers that don't support minHeight will treat height as minHeight
13665			if ( !$.support.minHeight ) {
13666				overflow = parent.css( "overflow" );
13667				parent.css( "overflow", "hidden");
13668			}
13669			maxHeight = parent.height();
13670			this.element.siblings( ":visible" ).each(function() {
13671				var elem = $( this ),
13672					position = elem.css( "position" );
13673
13674				if ( position === "absolute" || position === "fixed" ) {
13675					return;
13676				}
13677				maxHeight -= elem.outerHeight( true );
13678			});
13679			if ( overflow ) {
13680				parent.css( "overflow", overflow );
13681			}
13682
13683			this.element.children().not( this.panels ).each(function() {
13684				maxHeight -= $( this ).outerHeight( true );
13685			});
13686
13687			this.panels.each(function() {
13688				$( this ).height( Math.max( 0, maxHeight -
13689					$( this ).innerHeight() + $( this ).height() ) );
13690			})
13691			.css( "overflow", "auto" );
13692		} else if ( heightStyle === "auto" ) {
13693			maxHeight = 0;
13694			this.panels.each(function() {
13695				maxHeight = Math.max( maxHeight, $( this ).height( "" ).height() );
13696			}).height( maxHeight );
13697		}
13698	},
13699
13700	_eventHandler: function( event ) {
13701		var options = this.options,
13702			active = this.active,
13703			anchor = $( event.currentTarget ),
13704			tab = anchor.closest( "li" ),
13705			clickedIsActive = tab[ 0 ] === active[ 0 ],
13706			collapsing = clickedIsActive && options.collapsible,
13707			toShow = collapsing ? $() : this._getPanelForTab( tab ),
13708			toHide = !active.length ? $() : this._getPanelForTab( active ),
13709			eventData = {
13710				oldTab: active,
13711				oldPanel: toHide,
13712				newTab: collapsing ? $() : tab,
13713				newPanel: toShow
13714			};
13715
13716		event.preventDefault();
13717
13718		if ( tab.hasClass( "ui-state-disabled" ) ||
13719				// tab is already loading
13720				tab.hasClass( "ui-tabs-loading" ) ||
13721				// can't switch durning an animation
13722				this.running ||
13723				// click on active header, but not collapsible
13724				( clickedIsActive && !options.collapsible ) ||
13725				// allow canceling activation
13726				( this._trigger( "beforeActivate", event, eventData ) === false ) ) {
13727			return;
13728		}
13729
13730		options.active = collapsing ? false : this.tabs.index( tab );
13731
13732		this.active = clickedIsActive ? $() : tab;
13733		if ( this.xhr ) {
13734			this.xhr.abort();
13735		}
13736
13737		if ( !toHide.length && !toShow.length ) {
13738			$.error( "jQuery UI Tabs: Mismatching fragment identifier." );
13739		}
13740
13741		if ( toShow.length ) {
13742			this.load( this.tabs.index( tab ), event );
13743		}
13744		this._toggle( event, eventData );
13745	},
13746
13747	// handles show/hide for selecting tabs
13748	_toggle: function( event, eventData ) {
13749		var that = this,
13750			toShow = eventData.newPanel,
13751			toHide = eventData.oldPanel;
13752
13753		this.running = true;
13754
13755		function complete() {
13756			that.running = false;
13757			that._trigger( "activate", event, eventData );
13758		}
13759
13760		function show() {
13761			eventData.newTab.closest( "li" ).addClass( "ui-tabs-active ui-state-active" );
13762
13763			if ( toShow.length && that.options.show ) {
13764				that._show( toShow, that.options.show, complete );
13765			} else {
13766				toShow.show();
13767				complete();
13768			}
13769		}
13770
13771		// start out by hiding, then showing, then completing
13772		if ( toHide.length && this.options.hide ) {
13773			this._hide( toHide, this.options.hide, function() {
13774				eventData.oldTab.closest( "li" ).removeClass( "ui-tabs-active ui-state-active" );
13775				show();
13776			});
13777		} else {
13778			eventData.oldTab.closest( "li" ).removeClass( "ui-tabs-active ui-state-active" );
13779			toHide.hide();
13780			show();
13781		}
13782
13783		toHide.attr({
13784			"aria-expanded": "false",
13785			"aria-hidden": "true"
13786		});
13787		eventData.oldTab.attr( "aria-selected", "false" );
13788		// If we're switching tabs, remove the old tab from the tab order.
13789		// If we're opening from collapsed state, remove the previous tab from the tab order.
13790		// If we're collapsing, then keep the collapsing tab in the tab order.
13791		if ( toShow.length && toHide.length ) {
13792			eventData.oldTab.attr( "tabIndex", -1 );
13793		} else if ( toShow.length ) {
13794			this.tabs.filter(function() {
13795				return $( this ).attr( "tabIndex" ) === 0;
13796			})
13797			.attr( "tabIndex", -1 );
13798		}
13799
13800		toShow.attr({
13801			"aria-expanded": "true",
13802			"aria-hidden": "false"
13803		});
13804		eventData.newTab.attr({
13805			"aria-selected": "true",
13806			tabIndex: 0
13807		});
13808	},
13809
13810	_activate: function( index ) {
13811		var anchor,
13812			active = this._findActive( index );
13813
13814		// trying to activate the already active panel
13815		if ( active[ 0 ] === this.active[ 0 ] ) {
13816			return;
13817		}
13818
13819		// trying to collapse, simulate a click on the current active header
13820		if ( !active.length ) {
13821			active = this.active;
13822		}
13823
13824		anchor = active.find( ".ui-tabs-anchor" )[ 0 ];
13825		this._eventHandler({
13826			target: anchor,
13827			currentTarget: anchor,
13828			preventDefault: $.noop
13829		});
13830	},
13831
13832	_findActive: function( index ) {
13833		return index === false ? $() : this.tabs.eq( index );
13834	},
13835
13836	_getIndex: function( index ) {
13837		// meta-function to give users option to provide a href string instead of a numerical index.
13838		if ( typeof index === "string" ) {
13839			index = this.anchors.index( this.anchors.filter( "[href$='" + index + "']" ) );
13840		}
13841
13842		return index;
13843	},
13844
13845	_destroy: function() {
13846		if ( this.xhr ) {
13847			this.xhr.abort();
13848		}
13849
13850		this.element.removeClass( "ui-tabs ui-widget ui-widget-content ui-corner-all ui-tabs-collapsible" );
13851
13852		this.tablist
13853			.removeClass( "ui-tabs-nav ui-helper-reset ui-helper-clearfix ui-widget-header ui-corner-all" )
13854			.removeAttr( "role" );
13855
13856		this.anchors
13857			.removeClass( "ui-tabs-anchor" )
13858			.removeAttr( "role" )
13859			.removeAttr( "tabIndex" )
13860			.removeData( "href.tabs" )
13861			.removeData( "load.tabs" )
13862			.removeUniqueId();
13863
13864		this.tabs.add( this.panels ).each(function() {
13865			if ( $.data( this, "ui-tabs-destroy" ) ) {
13866				$( this ).remove();
13867			} else {
13868				$( this )
13869					.removeClass( "ui-state-default ui-state-active ui-state-disabled " +
13870						"ui-corner-top ui-corner-bottom ui-widget-content ui-tabs-active ui-tabs-panel" )
13871					.removeAttr( "tabIndex" )
13872					.removeAttr( "aria-live" )
13873					.removeAttr( "aria-busy" )
13874					.removeAttr( "aria-selected" )
13875					.removeAttr( "aria-labelledby" )
13876					.removeAttr( "aria-hidden" )
13877					.removeAttr( "aria-expanded" )
13878					.removeAttr( "role" );
13879			}
13880		});
13881
13882		this.tabs.each(function() {
13883			var li = $( this ),
13884				prev = li.data( "ui-tabs-aria-controls" );
13885			if ( prev ) {
13886				li.attr( "aria-controls", prev );
13887			} else {
13888				li.removeAttr( "aria-controls" );
13889			}
13890		});
13891
13892		this.panels.show();
13893
13894		if ( this.options.heightStyle !== "content" ) {
13895			this.panels.css( "height", "" );
13896		}
13897	},
13898
13899	enable: function( index ) {
13900		var disabled = this.options.disabled;
13901		if ( disabled === false ) {
13902			return;
13903		}
13904
13905		if ( index === undefined ) {
13906			disabled = false;
13907		} else {
13908			index = this._getIndex( index );
13909			if ( $.isArray( disabled ) ) {
13910				disabled = $.map( disabled, function( num ) {
13911					return num !== index ? num : null;
13912				});
13913			} else {
13914				disabled = $.map( this.tabs, function( li, num ) {
13915					return num !== index ? num : null;
13916				});
13917			}
13918		}
13919		this._setupDisabled( disabled );
13920	},
13921
13922	disable: function( index ) {
13923		var disabled = this.options.disabled;
13924		if ( disabled === true ) {
13925			return;
13926		}
13927
13928		if ( index === undefined ) {
13929			disabled = true;
13930		} else {
13931			index = this._getIndex( index );
13932			if ( $.inArray( index, disabled ) !== -1 ) {
13933				return;
13934			}
13935			if ( $.isArray( disabled ) ) {
13936				disabled = $.merge( [ index ], disabled ).sort();
13937			} else {
13938				disabled = [ index ];
13939			}
13940		}
13941		this._setupDisabled( disabled );
13942	},
13943
13944	load: function( index, event ) {
13945		index = this._getIndex( index );
13946		var that = this,
13947			tab = this.tabs.eq( index ),
13948			anchor = tab.find( ".ui-tabs-anchor" ),
13949			panel = this._getPanelForTab( tab ),
13950			eventData = {
13951				tab: tab,
13952				panel: panel
13953			};
13954
13955		// not remote
13956		if ( isLocal( anchor[ 0 ] ) ) {
13957			return;
13958		}
13959
13960		this.xhr = $.ajax( this._ajaxSettings( anchor, event, eventData ) );
13961
13962		// support: jQuery <1.8
13963		// jQuery <1.8 returns false if the request is canceled in beforeSend,
13964		// but as of 1.8, $.ajax() always returns a jqXHR object.
13965		if ( this.xhr && this.xhr.statusText !== "canceled" ) {
13966			tab.addClass( "ui-tabs-loading" );
13967			panel.attr( "aria-busy", "true" );
13968
13969			this.xhr
13970				.success(function( response ) {
13971					// support: jQuery <1.8
13972					// http://bugs.jquery.com/ticket/11778
13973					setTimeout(function() {
13974						panel.html( response );
13975						that._trigger( "load", event, eventData );
13976					}, 1 );
13977				})
13978				.complete(function( jqXHR, status ) {
13979					// support: jQuery <1.8
13980					// http://bugs.jquery.com/ticket/11778
13981					setTimeout(function() {
13982						if ( status === "abort" ) {
13983							that.panels.stop( false, true );
13984						}
13985
13986						tab.removeClass( "ui-tabs-loading" );
13987						panel.removeAttr( "aria-busy" );
13988
13989						if ( jqXHR === that.xhr ) {
13990							delete that.xhr;
13991						}
13992					}, 1 );
13993				});
13994		}
13995	},
13996
13997	// TODO: Remove this function in 1.10 when ajaxOptions is removed
13998	_ajaxSettings: function( anchor, event, eventData ) {
13999		var that = this;
14000		return {
14001			url: anchor.attr( "href" ),
14002			beforeSend: function( jqXHR, settings ) {
14003				return that._trigger( "beforeLoad", event,
14004					$.extend( { jqXHR : jqXHR, ajaxSettings: settings }, eventData ) );
14005			}
14006		};
14007	},
14008
14009	_getPanelForTab: function( tab ) {
14010		var id = $( tab ).attr( "aria-controls" );
14011		return this.element.find( this._sanitizeSelector( "#" + id ) );
14012	}
14013});
14014
14015// DEPRECATED
14016if ( $.uiBackCompat !== false ) {
14017
14018	// helper method for a lot of the back compat extensions
14019	$.ui.tabs.prototype._ui = function( tab, panel ) {
14020		return {
14021			tab: tab,
14022			panel: panel,
14023			index: this.anchors.index( tab )
14024		};
14025	};
14026
14027	// url method
14028	$.widget( "ui.tabs", $.ui.tabs, {
14029		url: function( index, url ) {
14030			this.anchors.eq( index ).attr( "href", url );
14031		}
14032	});
14033
14034	// TODO: Remove _ajaxSettings() method when removing this extension
14035	// ajaxOptions and cache options
14036	$.widget( "ui.tabs", $.ui.tabs, {
14037		options: {
14038			ajaxOptions: null,
14039			cache: false
14040		},
14041
14042		_create: function() {
14043			this._super();
14044
14045			var that = this;
14046
14047			this._on({ tabsbeforeload: function( event, ui ) {
14048				// tab is already cached
14049				if ( $.data( ui.tab[ 0 ], "cache.tabs" ) ) {
14050					event.preventDefault();
14051					return;
14052				}
14053
14054				ui.jqXHR.success(function() {
14055					if ( that.options.cache ) {
14056						$.data( ui.tab[ 0 ], "cache.tabs", true );
14057					}
14058				});
14059			}});
14060		},
14061
14062		_ajaxSettings: function( anchor, event, ui ) {
14063			var ajaxOptions = this.options.ajaxOptions;
14064			return $.extend( {}, ajaxOptions, {
14065				error: function( xhr, status ) {
14066					try {
14067						// Passing index avoid a race condition when this method is
14068						// called after the user has selected another tab.
14069						// Pass the anchor that initiated this request allows
14070						// loadError to manipulate the tab content panel via $(a.hash)
14071						ajaxOptions.error(
14072							xhr, status, ui.tab.closest( "li" ).index(), ui.tab[ 0 ] );
14073					}
14074					catch ( error ) {}
14075				}
14076			}, this._superApply( arguments ) );
14077		},
14078
14079		_setOption: function( key, value ) {
14080			// reset cache if switching from cached to not cached
14081			if ( key === "cache" && value === false ) {
14082				this.anchors.removeData( "cache.tabs" );
14083			}
14084			this._super( key, value );
14085		},
14086
14087		_destroy: function() {
14088			this.anchors.removeData( "cache.tabs" );
14089			this._super();
14090		},
14091
14092		url: function( index ){
14093			this.anchors.eq( index ).removeData( "cache.tabs" );
14094			this._superApply( arguments );
14095		}
14096	});
14097
14098	// abort method
14099	$.widget( "ui.tabs", $.ui.tabs, {
14100		abort: function() {
14101			if ( this.xhr ) {
14102				this.xhr.abort();
14103			}
14104		}
14105	});
14106
14107	// spinner
14108	$.widget( "ui.tabs", $.ui.tabs, {
14109		options: {
14110			spinner: "<em>Loading&#8230;</em>"
14111		},
14112		_create: function() {
14113			this._super();
14114			this._on({
14115				tabsbeforeload: function( event, ui ) {
14116					// Don't react to nested tabs or tabs that don't use a spinner
14117					if ( event.target !== this.element[ 0 ] ||
14118							!this.options.spinner ) {
14119						return;
14120					}
14121
14122					var span = ui.tab.find( "span" ),
14123						html = span.html();
14124					span.html( this.options.spinner );
14125					ui.jqXHR.complete(function() {
14126						span.html( html );
14127					});
14128				}
14129			});
14130		}
14131	});
14132
14133	// enable/disable events
14134	$.widget( "ui.tabs", $.ui.tabs, {
14135		options: {
14136			enable: null,
14137			disable: null
14138		},
14139
14140		enable: function( index ) {
14141			var options = this.options,
14142				trigger;
14143
14144			if ( index && options.disabled === true ||
14145					( $.isArray( options.disabled ) && $.inArray( index, options.disabled ) !== -1 ) ) {
14146				trigger = true;
14147			}
14148
14149			this._superApply( arguments );
14150
14151			if ( trigger ) {
14152				this._trigger( "enable", null, this._ui( this.anchors[ index ], this.panels[ index ] ) );
14153			}
14154		},
14155
14156		disable: function( index ) {
14157			var options = this.options,
14158				trigger;
14159
14160			if ( index && options.disabled === false ||
14161					( $.isArray( options.disabled ) && $.inArray( index, options.disabled ) === -1 ) ) {
14162				trigger = true;
14163			}
14164
14165			this._superApply( arguments );
14166
14167			if ( trigger ) {
14168				this._trigger( "disable", null, this._ui( this.anchors[ index ], this.panels[ index ] ) );
14169			}
14170		}
14171	});
14172
14173	// add/remove methods and events
14174	$.widget( "ui.tabs", $.ui.tabs, {
14175		options: {
14176			add: null,
14177			remove: null,
14178			tabTemplate: "<li><a href='#{href}'><span>#{label}</span></a></li>"
14179		},
14180
14181		add: function( url, label, index ) {
14182			if ( index === undefined ) {
14183				index = this.anchors.length;
14184			}
14185
14186			var doInsertAfter, panel,
14187				options = this.options,
14188				li = $( options.tabTemplate
14189					.replace( /#\{href\}/g, url )
14190					.replace( /#\{label\}/g, label ) ),
14191				id = !url.indexOf( "#" ) ?
14192					url.replace( "#", "" ) :
14193					this._tabId( li );
14194
14195			li.addClass( "ui-state-default ui-corner-top" ).data( "ui-tabs-destroy", true );
14196			li.attr( "aria-controls", id );
14197
14198			doInsertAfter = index >= this.tabs.length;
14199
14200			// try to find an existing element before creating a new one
14201			panel = this.element.find( "#" + id );
14202			if ( !panel.length ) {
14203				panel = this._createPanel( id );
14204				if ( doInsertAfter ) {
14205					if ( index > 0 ) {
14206						panel.insertAfter( this.panels.eq( -1 ) );
14207					} else {
14208						panel.appendTo( this.element );
14209					}
14210				} else {
14211					panel.insertBefore( this.panels[ index ] );
14212				}
14213			}
14214			panel.addClass( "ui-tabs-panel ui-widget-content ui-corner-bottom" ).hide();
14215
14216			if ( doInsertAfter ) {
14217				li.appendTo( this.tablist );
14218			} else {
14219				li.insertBefore( this.tabs[ index ] );
14220			}
14221
14222			options.disabled = $.map( options.disabled, function( n ) {
14223				return n >= index ? ++n : n;
14224			});
14225
14226			this.refresh();
14227			if ( this.tabs.length === 1 && options.active === false ) {
14228				this.option( "active", 0 );
14229			}
14230
14231			this._trigger( "add", null, this._ui( this.anchors[ index ], this.panels[ index ] ) );
14232			return this;
14233		},
14234
14235		remove: function( index ) {
14236			index = this._getIndex( index );
14237			var options = this.options,
14238				tab = this.tabs.eq( index ).remove(),
14239				panel = this._getPanelForTab( tab ).remove();
14240
14241			// If selected tab was removed focus tab to the right or
14242			// in case the last tab was removed the tab to the left.
14243			// We check for more than 2 tabs, because if there are only 2,
14244			// then when we remove this tab, there will only be one tab left
14245			// so we don't need to detect which tab to activate.
14246			if ( tab.hasClass( "ui-tabs-active" ) && this.anchors.length > 2 ) {
14247				this._activate( index + ( index + 1 < this.anchors.length ? 1 : -1 ) );
14248			}
14249
14250			options.disabled = $.map(
14251				$.grep( options.disabled, function( n ) {
14252					return n !== index;
14253				}),
14254				function( n ) {
14255					return n >= index ? --n : n;
14256				});
14257
14258			this.refresh();
14259
14260			this._trigger( "remove", null, this._ui( tab.find( "a" )[ 0 ], panel[ 0 ] ) );
14261			return this;
14262		}
14263	});
14264
14265	// length method
14266	$.widget( "ui.tabs", $.ui.tabs, {
14267		length: function() {
14268			return this.anchors.length;
14269		}
14270	});
14271
14272	// panel ids (idPrefix option + title attribute)
14273	$.widget( "ui.tabs", $.ui.tabs, {
14274		options: {
14275			idPrefix: "ui-tabs-"
14276		},
14277
14278		_tabId: function( tab ) {
14279			var a = tab.is( "li" ) ? tab.find( "a[href]" ) : tab;
14280			a = a[0];
14281			return $( a ).closest( "li" ).attr( "aria-controls" ) ||
14282				a.title && a.title.replace( /\s/g, "_" ).replace( /[^\w\u00c0-\uFFFF\-]/g, "" ) ||
14283				this.options.idPrefix + getNextTabId();
14284		}
14285	});
14286
14287	// _createPanel method
14288	$.widget( "ui.tabs", $.ui.tabs, {
14289		options: {
14290			panelTemplate: "<div></div>"
14291		},
14292
14293		_createPanel: function( id ) {
14294			return $( this.options.panelTemplate )
14295				.attr( "id", id )
14296				.addClass( "ui-tabs-panel ui-widget-content ui-corner-bottom" )
14297				.data( "ui-tabs-destroy", true );
14298		}
14299	});
14300
14301	// selected option
14302	$.widget( "ui.tabs", $.ui.tabs, {
14303		_create: function() {
14304			var options = this.options;
14305			if ( options.active === null && options.selected !== undefined ) {
14306				options.active = options.selected === -1 ? false : options.selected;
14307			}
14308			this._super();
14309			options.selected = options.active;
14310			if ( options.selected === false ) {
14311				options.selected = -1;
14312			}
14313		},
14314
14315		_setOption: function( key, value ) {
14316			if ( key !== "selected" ) {
14317				return this._super( key, value );
14318			}
14319
14320			var options = this.options;
14321			this._super( "active", value === -1 ? false : value );
14322			options.selected = options.active;
14323			if ( options.selected === false ) {
14324				options.selected = -1;
14325			}
14326		},
14327
14328		_eventHandler: function() {
14329			this._superApply( arguments );
14330			this.options.selected = this.options.active;
14331			if ( this.options.selected === false ) {
14332				this.options.selected = -1;
14333			}
14334		}
14335	});
14336
14337	// show and select event
14338	$.widget( "ui.tabs", $.ui.tabs, {
14339		options: {
14340			show: null,
14341			select: null
14342		},
14343		_create: function() {
14344			this._super();
14345			if ( this.options.active !== false ) {
14346				this._trigger( "show", null, this._ui(
14347					this.active.find( ".ui-tabs-anchor" )[ 0 ],
14348					this._getPanelForTab( this.active )[ 0 ] ) );
14349			}
14350		},
14351		_trigger: function( type, event, data ) {
14352			var tab, panel,
14353				ret = this._superApply( arguments );
14354
14355			if ( !ret ) {
14356				return false;
14357			}
14358
14359			if ( type === "beforeActivate" ) {
14360				tab = data.newTab.length ? data.newTab : data.oldTab;
14361				panel = data.newPanel.length ? data.newPanel : data.oldPanel;
14362				ret = this._super( "select", event, {
14363					tab: tab.find( ".ui-tabs-anchor" )[ 0],
14364					panel: panel[ 0 ],
14365					index: tab.closest( "li" ).index()
14366				});
14367			} else if ( type === "activate" && data.newTab.length ) {
14368				ret = this._super( "show", event, {
14369					tab: data.newTab.find( ".ui-tabs-anchor" )[ 0 ],
14370					panel: data.newPanel[ 0 ],
14371					index: data.newTab.closest( "li" ).index()
14372				});
14373			}
14374			return ret;
14375		}
14376	});
14377
14378	// select method
14379	$.widget( "ui.tabs", $.ui.tabs, {
14380		select: function( index ) {
14381			index = this._getIndex( index );
14382			if ( index === -1 ) {
14383				if ( this.options.collapsible && this.options.selected !== -1 ) {
14384					index = this.options.selected;
14385				} else {
14386					return;
14387				}
14388			}
14389			this.anchors.eq( index ).trigger( this.options.event + this.eventNamespace );
14390		}
14391	});
14392
14393	// cookie option
14394	(function() {
14395
14396	var listId = 0;
14397
14398	$.widget( "ui.tabs", $.ui.tabs, {
14399		options: {
14400			cookie: null // e.g. { expires: 7, path: '/', domain: 'jquery.com', secure: true }
14401		},
14402		_create: function() {
14403			var options = this.options,
14404				active;
14405			if ( options.active == null && options.cookie ) {
14406				active = parseInt( this._cookie(), 10 );
14407				if ( active === -1 ) {
14408					active = false;
14409				}
14410				options.active = active;
14411			}
14412			this._super();
14413		},
14414		_cookie: function( active ) {
14415			var cookie = [ this.cookie ||
14416				( this.cookie = this.options.cookie.name || "ui-tabs-" + (++listId) ) ];
14417			if ( arguments.length ) {
14418				cookie.push( active === false ? -1 : active );
14419				cookie.push( this.options.cookie );
14420			}
14421			return $.cookie.apply( null, cookie );
14422		},
14423		_refresh: function() {
14424			this._super();
14425			if ( this.options.cookie ) {
14426				this._cookie( this.options.active, this.options.cookie );
14427			}
14428		},
14429		_eventHandler: function() {
14430			this._superApply( arguments );
14431			if ( this.options.cookie ) {
14432				this._cookie( this.options.active, this.options.cookie );
14433			}
14434		},
14435		_destroy: function() {
14436			this._super();
14437			if ( this.options.cookie ) {
14438				this._cookie( null, this.options.cookie );
14439			}
14440		}
14441	});
14442
14443	})();
14444
14445	// load event
14446	$.widget( "ui.tabs", $.ui.tabs, {
14447		_trigger: function( type, event, data ) {
14448			var _data = $.extend( {}, data );
14449			if ( type === "load" ) {
14450				_data.panel = _data.panel[ 0 ];
14451				_data.tab = _data.tab.find( ".ui-tabs-anchor" )[ 0 ];
14452			}
14453			return this._super( type, event, _data );
14454		}
14455	});
14456
14457	// fx option
14458	// The new animation options (show, hide) conflict with the old show callback.
14459	// The old fx option wins over show/hide anyway (always favor back-compat).
14460	// If a user wants to use the new animation API, they must give up the old API.
14461	$.widget( "ui.tabs", $.ui.tabs, {
14462		options: {
14463			fx: null // e.g. { height: "toggle", opacity: "toggle", duration: 200 }
14464		},
14465
14466		_getFx: function() {
14467			var hide, show,
14468				fx = this.options.fx;
14469
14470			if ( fx ) {
14471				if ( $.isArray( fx ) ) {
14472					hide = fx[ 0 ];
14473					show = fx[ 1 ];
14474				} else {
14475					hide = show = fx;
14476				}
14477			}
14478
14479			return fx ? { show: show, hide: hide } : null;
14480		},
14481
14482		_toggle: function( event, eventData ) {
14483			var that = this,
14484				toShow = eventData.newPanel,
14485				toHide = eventData.oldPanel,
14486				fx = this._getFx();
14487
14488			if ( !fx ) {
14489				return this._super( event, eventData );
14490			}
14491
14492			that.running = true;
14493
14494			function complete() {
14495				that.running = false;
14496				that._trigger( "activate", event, eventData );
14497			}
14498
14499			function show() {
14500				eventData.newTab.closest( "li" ).addClass( "ui-tabs-active ui-state-active" );
14501
14502				if ( toShow.length && fx.show ) {
14503					toShow
14504						.animate( fx.show, fx.show.duration, function() {
14505							complete();
14506						});
14507				} else {
14508					toShow.show();
14509					complete();
14510				}
14511			}
14512
14513			// start out by hiding, then showing, then completing
14514			if ( toHide.length && fx.hide ) {
14515				toHide.animate( fx.hide, fx.hide.duration, function() {
14516					eventData.oldTab.closest( "li" ).removeClass( "ui-tabs-active ui-state-active" );
14517					show();
14518				});
14519			} else {
14520				eventData.oldTab.closest( "li" ).removeClass( "ui-tabs-active ui-state-active" );
14521				toHide.hide();
14522				show();
14523			}
14524		}
14525	});
14526}
14527
14528})( jQuery );
14529
14530(function( $ ) {
14531
14532var increments = 0;
14533
14534function addDescribedBy( elem, id ) {
14535	var describedby = (elem.attr( "aria-describedby" ) || "").split( /\s+/ );
14536	describedby.push( id );
14537	elem
14538		.data( "ui-tooltip-id", id )
14539		.attr( "aria-describedby", $.trim( describedby.join( " " ) ) );
14540}
14541
14542function removeDescribedBy( elem ) {
14543	var id = elem.data( "ui-tooltip-id" ),
vendor: 9,870 bytes, lines 14544-14912
14544		describedby = (elem.attr( "aria-describedby" ) || "").split( /\s+/ ),
14545		index = $.inArray( id, describedby );
14546	if ( index !== -1 ) {
14547		describedby.splice( index, 1 );
14548	}
14549
14550	elem.removeData( "ui-tooltip-id" );
14551	describedby = $.trim( describedby.join( " " ) );
14552	if ( describedby ) {
14553		elem.attr( "aria-describedby", describedby );
14554	} else {
14555		elem.removeAttr( "aria-describedby" );
14556	}
14557}
14558
14559$.widget( "ui.tooltip", {
14560	version: "1.9.2",
14561	options: {
14562		content: function() {
14563			return $( this ).attr( "title" );
14564		},
14565		hide: true,
14566		// Disabled elements have inconsistent behavior across browsers (#8661)
14567		items: "[title]:not([disabled])",
14568		position: {
14569			my: "left top+15",
14570			at: "left bottom",
14571			collision: "flipfit flip"
14572		},
14573		show: true,
14574		tooltipClass: null,
14575		track: false,
14576
14577		// callbacks
14578		close: null,
14579		open: null
14580	},
14581
14582	_create: function() {
14583		this._on({
14584			mouseover: "open",
14585			focusin: "open"
14586		});
14587
14588		// IDs of generated tooltips, needed for destroy
14589		this.tooltips = {};
14590		// IDs of parent tooltips where we removed the title attribute
14591		this.parents = {};
14592
14593		if ( this.options.disabled ) {
14594			this._disable();
14595		}
14596	},
14597
14598	_setOption: function( key, value ) {
14599		var that = this;
14600
14601		if ( key === "disabled" ) {
14602			this[ value ? "_disable" : "_enable" ]();
14603			this.options[ key ] = value;
14604			// disable element style changes
14605			return;
14606		}
14607
14608		this._super( key, value );
14609
14610		if ( key === "content" ) {
14611			$.each( this.tooltips, function( id, element ) {
14612				that._updateContent( element );
14613			});
14614		}
14615	},
14616
14617	_disable: function() {
14618		var that = this;
14619
14620		// close open tooltips
14621		$.each( this.tooltips, function( id, element ) {
14622			var event = $.Event( "blur" );
14623			event.target = event.currentTarget = element[0];
14624			that.close( event, true );
14625		});
14626
14627		// remove title attributes to prevent native tooltips
14628		this.element.find( this.options.items ).andSelf().each(function() {
14629			var element = $( this );
14630			if ( element.is( "[title]" ) ) {
14631				element
14632					.data( "ui-tooltip-title", element.attr( "title" ) )
14633					.attr( "title", "" );
14634			}
14635		});
14636	},
14637
14638	_enable: function() {
14639		// restore title attributes
14640		this.element.find( this.options.items ).andSelf().each(function() {
14641			var element = $( this );
14642			if ( element.data( "ui-tooltip-title" ) ) {
14643				element.attr( "title", element.data( "ui-tooltip-title" ) );
14644			}
14645		});
14646	},
14647
14648	open: function( event ) {
14649		var that = this,
14650			target = $( event ? event.target : this.element )
14651				// we need closest here due to mouseover bubbling,
14652				// but always pointing at the same event target
14653				.closest( this.options.items );
14654
14655		// No element to show a tooltip for or the tooltip is already open
14656		if ( !target.length || target.data( "ui-tooltip-id" ) ) {
14657			return;
14658		}
14659
14660		if ( target.attr( "title" ) ) {
14661			target.data( "ui-tooltip-title", target.attr( "title" ) );
14662		}
14663
14664		target.data( "ui-tooltip-open", true );
14665
14666		// kill parent tooltips, custom or native, for hover
14667		if ( event && event.type === "mouseover" ) {
14668			target.parents().each(function() {
14669				var parent = $( this ),
14670					blurEvent;
14671				if ( parent.data( "ui-tooltip-open" ) ) {
14672					blurEvent = $.Event( "blur" );
14673					blurEvent.target = blurEvent.currentTarget = this;
14674					that.close( blurEvent, true );
14675				}
14676				if ( parent.attr( "title" ) ) {
14677					parent.uniqueId();
14678					that.parents[ this.id ] = {
14679						element: this,
14680						title: parent.attr( "title" )
14681					};
14682					parent.attr( "title", "" );
14683				}
14684			});
14685		}
14686
14687		this._updateContent( target, event );
14688	},
14689
14690	_updateContent: function( target, event ) {
14691		var content,
14692			contentOption = this.options.content,
14693			that = this,
14694			eventType = event ? event.type : null;
14695
14696		if ( typeof contentOption === "string" ) {
14697			return this._open( event, target, contentOption );
14698		}
14699
14700		content = contentOption.call( target[0], function( response ) {
14701			// ignore async response if tooltip was closed already
14702			if ( !target.data( "ui-tooltip-open" ) ) {
14703				return;
14704			}
14705			// IE may instantly serve a cached response for ajax requests
14706			// delay this call to _open so the other call to _open runs first
14707			that._delay(function() {
14708				// jQuery creates a special event for focusin when it doesn't
14709				// exist natively. To improve performance, the native event
14710				// object is reused and the type is changed. Therefore, we can't
14711				// rely on the type being correct after the event finished
14712				// bubbling, so we set it back to the previous value. (#8740)
14713				if ( event ) {
14714					event.type = eventType;
14715				}
14716				this._open( event, target, response );
14717			});
14718		});
14719		if ( content ) {
14720			this._open( event, target, content );
14721		}
14722	},
14723
14724	_open: function( event, target, content ) {
14725		var tooltip, events, delayedShow,
14726			positionOption = $.extend( {}, this.options.position );
14727
14728		if ( !content ) {
14729			return;
14730		}
14731
14732		// Content can be updated multiple times. If the tooltip already
14733		// exists, then just update the content and bail.
14734		tooltip = this._find( target );
14735		if ( tooltip.length ) {
14736			tooltip.find( ".ui-tooltip-content" ).html( content );
14737			return;
14738		}
14739
14740		// if we have a title, clear it to prevent the native tooltip
14741		// we have to check first to avoid defining a title if none exists
14742		// (we don't want to cause an element to start matching [title])
14743		//
14744		// We use removeAttr only for key events, to allow IE to export the correct
14745		// accessible attributes. For mouse events, set to empty string to avoid
14746		// native tooltip showing up (happens only when removing inside mouseover).
14747		if ( target.is( "[title]" ) ) {
14748			if ( event && event.type === "mouseover" ) {
14749				target.attr( "title", "" );
14750			} else {
14751				target.removeAttr( "title" );
14752			}
14753		}
14754
14755		tooltip = this._tooltip( target );
14756		addDescribedBy( target, tooltip.attr( "id" ) );
14757		tooltip.find( ".ui-tooltip-content" ).html( content );
14758
14759		function position( event ) {
14760			positionOption.of = event;
14761			if ( tooltip.is( ":hidden" ) ) {
14762				return;
14763			}
14764			tooltip.position( positionOption );
14765		}
14766		if ( this.options.track && event && /^mouse/.test( event.type ) ) {
14767			this._on( this.document, {
14768				mousemove: position
14769			});
14770			// trigger once to override element-relative positioning
14771			position( event );
14772		} else {
14773			tooltip.position( $.extend({
14774				of: target
14775			}, this.options.position ) );
14776		}
14777
14778		tooltip.hide();
14779
14780		this._show( tooltip, this.options.show );
14781		// Handle tracking tooltips that are shown with a delay (#8644). As soon
14782		// as the tooltip is visible, position the tooltip using the most recent
14783		// event.
14784		if ( this.options.show && this.options.show.delay ) {
14785			delayedShow = setInterval(function() {
14786				if ( tooltip.is( ":visible" ) ) {
14787					position( positionOption.of );
14788					clearInterval( delayedShow );
14789				}
14790			}, $.fx.interval );
14791		}
14792
14793		this._trigger( "open", event, { tooltip: tooltip } );
14794
14795		events = {
14796			keyup: function( event ) {
14797				if ( event.keyCode === $.ui.keyCode.ESCAPE ) {
14798					var fakeEvent = $.Event(event);
14799					fakeEvent.currentTarget = target[0];
14800					this.close( fakeEvent, true );
14801				}
14802			},
14803			remove: function() {
14804				this._removeTooltip( tooltip );
14805			}
14806		};
14807		if ( !event || event.type === "mouseover" ) {
14808			events.mouseleave = "close";
14809		}
14810		if ( !event || event.type === "focusin" ) {
14811			events.focusout = "close";
14812		}
14813		this._on( true, target, events );
14814	},
14815
14816	close: function( event ) {
14817		var that = this,
14818			target = $( event ? event.currentTarget : this.element ),
14819			tooltip = this._find( target );
14820
14821		// disabling closes the tooltip, so we need to track when we're closing
14822		// to avoid an infinite loop in case the tooltip becomes disabled on close
14823		if ( this.closing ) {
14824			return;
14825		}
14826
14827		// only set title if we had one before (see comment in _open())
14828		if ( target.data( "ui-tooltip-title" ) ) {
14829			target.attr( "title", target.data( "ui-tooltip-title" ) );
14830		}
14831
14832		removeDescribedBy( target );
14833
14834		tooltip.stop( true );
14835		this._hide( tooltip, this.options.hide, function() {
14836			that._removeTooltip( $( this ) );
14837		});
14838
14839		target.removeData( "ui-tooltip-open" );
14840		this._off( target, "mouseleave focusout keyup" );
14841		// Remove 'remove' binding only on delegated targets
14842		if ( target[0] !== this.element[0] ) {
14843			this._off( target, "remove" );
14844		}
14845		this._off( this.document, "mousemove" );
14846
14847		if ( event && event.type === "mouseleave" ) {
14848			$.each( this.parents, function( id, parent ) {
14849				$( parent.element ).attr( "title", parent.title );
14850				delete that.parents[ id ];
14851			});
14852		}
14853
14854		this.closing = true;
14855		this._trigger( "close", event, { tooltip: tooltip } );
14856		this.closing = false;
14857	},
14858
14859	_tooltip: function( element ) {
14860		var id = "ui-tooltip-" + increments++,
14861			tooltip = $( "<div>" )
14862				.attr({
14863					id: id,
14864					role: "tooltip"
14865				})
14866				.addClass( "ui-tooltip ui-widget ui-corner-all ui-widget-content " +
14867					( this.options.tooltipClass || "" ) );
14868		$( "<div>" )
14869			.addClass( "ui-tooltip-content" )
14870			.appendTo( tooltip );
14871		tooltip.appendTo( this.document[0].body );
14872		if ( $.fn.bgiframe ) {
14873			tooltip.bgiframe();
14874		}
14875		this.tooltips[ id ] = element;
14876		return tooltip;
14877	},
14878
14879	_find: function( target ) {
14880		var id = target.data( "ui-tooltip-id" );
14881		return id ? $( "#" + id ) : $();
14882	},
14883
14884	_removeTooltip: function( tooltip ) {
14885		tooltip.remove();
14886		delete this.tooltips[ tooltip.attr( "id" ) ];
14887	},
14888
14889	_destroy: function() {
14890		var that = this;
14891
14892		// close open tooltips
14893		$.each( this.tooltips, function( id, element ) {
14894			// Delegate to close method to handle common cleanup
14895			var event = $.Event( "blur" );
14896			event.target = event.currentTarget = element[0];
14897			that.close( event, true );
14898
14899			// Remove immediately; destroying an open tooltip doesn't use the
14900			// hide animation
14901			$( "#" + id ).remove();
14902
14903			// Restore the title
14904			if ( element.data( "ui-tooltip-title" ) ) {
14905				element.attr( "title", element.data( "ui-tooltip-title" ) );
14906				element.removeData( "ui-tooltip-title" );
14907			}
14908		});
14909	}
14910});
14911
14912}( 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.