PageSourceSearch

https://www.vegannews.co.kr/js/common/jquery-ui-1.9.2.custom.js

js vegannews.co.kr collected 2026-10-02 16:27:36 UTC 450,121 bytes, 14,880 lines download raw bytes

vendor: 9,149 bytes, lines 1-321
1/*! jQuery UI - v1.9.2 - 2014-02-09
2* http://jqueryui.com
3* Includes: jquery.ui.core.js, jquery.ui.widget.js, jquery.ui.mouse.js, jquery.ui.position.js, jquery.ui.draggable.js, jquery.ui.droppable.js, jquery.ui.resizable.js, jquery.ui.selectable.js, jquery.ui.sortable.js, jquery.ui.accordion.js, jquery.ui.autocomplete.js, jquery.ui.button.js, jquery.ui.datepicker.js, jquery.ui.dialog.js, jquery.ui.menu.js, jquery.ui.progressbar.js, jquery.ui.slider.js, jquery.ui.spinner.js, jquery.ui.tabs.js, jquery.ui.tooltip.js, jquery.ui.effect.js, jquery.ui.effect-blind.js, jquery.ui.effect-bounce.js, jquery.ui.effect-clip.js, jquery.ui.effect-drop.js, jquery.ui.effect-explode.js, jquery.ui.effect-fade.js, jquery.ui.effect-fold.js, jquery.ui.effect-highlight.js, jquery.ui.effect-pulsate.js, jquery.ui.effect-scale.js, jquery.ui.effect-shake.js, jquery.ui.effect-slide.js, jquery.ui.effect-transfer.js
4* Copyright 2014 jQuery Foundation and other contributors; Licensed MIT */
5
6(function( $, undefined ) {
7
8var uuid = 0,
9	runiqueId = /^ui-id-\d+$/;
10
11// 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,237 bytes, lines 322-458
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(function( $, undefined ) {
353
354var uuid = 0,
355	slice = Array.prototype.slice,
356	_cleanData = $.cleanData;
357$.cleanData = function( elems ) {
358	for ( var i = 0, elem; (elem = elems[i]) != null; i++ ) {
359		try {
360			$( elem ).triggerHandler( "remove" );
361		// http://bugs.jquery.com/ticket/8235
362		} catch( e ) {}
363	}
364	_cleanData( elems );
365};
366
367$.widget = function( name, base, prototype ) {
368	var fullName, existingConstructor, constructor, basePrototype,
369		namespace = name.split( "." )[ 0 ];
370
371	name = name.split( "." )[ 1 ];
372	fullName = namespace + "-" + name;
373
374	if ( !prototype ) {
375		prototype = base;
376		base = $.Widget;
377	}
378
379	// create selector for plugin
380	$.expr[ ":" ][ fullName.toLowerCase() ] = function( elem ) {
381		return !!$.data( elem, fullName );
382	};
383
384	$[ namespace ] = $[ namespace ] || {};
385	existingConstructor = $[ namespace ][ name ];
386	constructor = $[ namespace ][ name ] = function( options, element ) {
387		// allow instantiation without "new" keyword
388		if ( !this._createWidget ) {
389			return new constructor( options, element );
390		}
391
392		// allow instantiation without initializing for simple inheritance
393		// must use "new" keyword (the code above always passes args)
394		if ( arguments.length ) {
395			this._createWidget( options, element );
396		}
397	};
398	// extend with the existing constructor to carry over any static properties
399	$.extend( constructor, existingConstructor, {
400		version: prototype.version,
401		// copy the object used to create the prototype in case we need to
402		// redefine the widget later
403		_proto: $.extend( {}, prototype ),
404		// track widgets that inherit from this widget in case this widget is
405		// redefined after a widget inherits from it
406		_childConstructors: []
407	});
408
409	basePrototype = new base();
410	// we need to make the options hash a property directly on the new instance
411	// otherwise we'll modify the options hash on the prototype that we're
412	// inheriting from
413	basePrototype.options = $.widget.extend( {}, basePrototype.options );
414	$.each( prototype, function( prop, value ) {
415		if ( $.isFunction( value ) ) {
416			prototype[ prop ] = (function() {
417				var _super = function() {
418						return base.prototype[ prop ].apply( this, arguments );
419					},
420					_superApply = function( args ) {
421						return base.prototype[ prop ].apply( this, args );
422					};
423				return function() {
424					var __super = this._super,
425						__superApply = this._superApply,
426						returnValue;
427
428					this._super = _super;
429					this._superApply = _superApply;
430
431					returnValue = value.apply( this, arguments );
432
433					this._super = __super;
434					this._superApply = __superApply;
435
436					return returnValue;
437				};
438			})();
439		}
440	});
441	constructor.prototype = $.widget.extend( basePrototype, {
442		// TODO: remove support for widgetEventPrefix
443		// always use the name + a colon as the prefix, e.g., draggable:start
444		// don't prefix for widgets that aren't DOM-based
445		widgetEventPrefix: existingConstructor ? basePrototype.widgetEventPrefix : name
446	}, prototype, {
447		constructor: constructor,
448		namespace: namespace,
449		widgetName: name,
450		// TODO remove widgetBaseClass, see #8155
451		widgetBaseClass: fullName,
452		widgetFullName: fullName
453	});
454
455	// If this widget is being redefined then we need to find all widgets that
456	// are inheriting from it and redefine all of them so that they inherit from
457	// the new version of this widget. We're essentially trying to replace one
458	// level in the prototype chain.
vendor: 11,206 bytes, lines 459-848
459	if ( existingConstructor ) {
460		$.each( existingConstructor._childConstructors, function( i, child ) {
461			var childPrototype = child.prototype;
462
463			// redefine the child widget using the same prototype that was
464			// originally used, but inherit from the new version of the base
465			$.widget( childPrototype.namespace + "." + childPrototype.widgetName, constructor, child._proto );
466		});
467		// remove the list of existing child constructors from the old constructor
468		// so the old child constructors can be garbage collected
469		delete existingConstructor._childConstructors;
470	} else {
471		base._childConstructors.push( constructor );
472	}
473
474	$.widget.bridge( name, constructor );
475};
476
477$.widget.extend = function( target ) {
478	var input = slice.call( arguments, 1 ),
479		inputIndex = 0,
480		inputLength = input.length,
481		key,
482		value;
483	for ( ; inputIndex < inputLength; inputIndex++ ) {
484		for ( key in input[ inputIndex ] ) {
485			value = input[ inputIndex ][ key ];
486			if ( input[ inputIndex ].hasOwnProperty( key ) && value !== undefined ) {
487				// Clone objects
488				if ( $.isPlainObject( value ) ) {
489					target[ key ] = $.isPlainObject( target[ key ] ) ?
490						$.widget.extend( {}, target[ key ], value ) :
491						// Don't extend strings, arrays, etc. with objects
492						$.widget.extend( {}, value );
493				// Copy everything else by reference
494				} else {
495					target[ key ] = value;
496				}
497			}
498		}
499	}
500	return target;
501};
502
503$.widget.bridge = function( name, object ) {
504	var fullName = object.prototype.widgetFullName || name;
505	$.fn[ name ] = function( options ) {
506		var isMethodCall = typeof options === "string",
507			args = slice.call( arguments, 1 ),
508			returnValue = this;
509
510		// allow multiple hashes to be passed on init
511		options = !isMethodCall && args.length ?
512			$.widget.extend.apply( null, [ options ].concat(args) ) :
513			options;
514
515		if ( isMethodCall ) {
516			this.each(function() {
517				var methodValue,
518					instance = $.data( this, fullName );
519				if ( !instance ) {
520					return $.error( "cannot call methods on " + name + " prior to initialization; " +
521						"attempted to call method '" + options + "'" );
522				}
523				if ( !$.isFunction( instance[options] ) || options.charAt( 0 ) === "_" ) {
524					return $.error( "no such method '" + options + "' for " + name + " widget instance" );
525				}
526				methodValue = instance[ options ].apply( instance, args );
527				if ( methodValue !== instance && methodValue !== undefined ) {
528					returnValue = methodValue && methodValue.jquery ?
529						returnValue.pushStack( methodValue.get() ) :
530						methodValue;
531					return false;
532				}
533			});
534		} else {
535			this.each(function() {
536				var instance = $.data( this, fullName );
537				if ( instance ) {
538					instance.option( options || {} )._init();
539				} else {
540					$.data( this, fullName, new object( options, this ) );
541				}
542			});
543		}
544
545		return returnValue;
546	};
547};
548
549$.Widget = function( /* options, element */ ) {};
550$.Widget._childConstructors = [];
551
552$.Widget.prototype = {
553	widgetName: "widget",
554	widgetEventPrefix: "",
555	defaultElement: "<div>",
556	options: {
557		disabled: false,
558
559		// callbacks
560		create: null
561	},
562	_createWidget: function( options, element ) {
563		element = $( element || this.defaultElement || this )[ 0 ];
564		this.element = $( element );
565		this.uuid = uuid++;
566		this.eventNamespace = "." + this.widgetName + this.uuid;
567		this.options = $.widget.extend( {},
568			this.options,
569			this._getCreateOptions(),
570			options );
571
572		this.bindings = $();
573		this.hoverable = $();
574		this.focusable = $();
575
576		if ( element !== this ) {
577			// 1.9 BC for #7810
578			// TODO remove dual storage
579			$.data( element, this.widgetName, this );
580			$.data( element, this.widgetFullName, this );
581			this._on( true, this.element, {
582				remove: function( event ) {
583					if ( event.target === element ) {
584						this.destroy();
585					}
586				}
587			});
588			this.document = $( element.style ?
589				// element within the document
590				element.ownerDocument :
591				// element is window or document
592				element.document || element );
593			this.window = $( this.document[0].defaultView || this.document[0].parentWindow );
594		}
595
596		this._create();
597		this._trigger( "create", null, this._getCreateEventData() );
598		this._init();
599	},
600	_getCreateOptions: $.noop,
601	_getCreateEventData: $.noop,
602	_create: $.noop,
603	_init: $.noop,
604
605	destroy: function() {
606		this._destroy();
607		// we can probably remove the unbind calls in 2.0
608		// all event bindings should go through this._on()
609		this.element
610			.unbind( this.eventNamespace )
611			// 1.9 BC for #7810
612			// TODO remove dual storage
613			.removeData( this.widgetName )
614			.removeData( this.widgetFullName )
615			// support: jquery <1.6.3
616			// http://bugs.jquery.com/ticket/9413
617			.removeData( $.camelCase( this.widgetFullName ) );
618		this.widget()
619			.unbind( this.eventNamespace )
620			.removeAttr( "aria-disabled" )
621			.removeClass(
622				this.widgetFullName + "-disabled " +
623				"ui-state-disabled" );
624
625		// clean up events and states
626		this.bindings.unbind( this.eventNamespace );
627		this.hoverable.removeClass( "ui-state-hover" );
628		this.focusable.removeClass( "ui-state-focus" );
629	},
630	_destroy: $.noop,
631
632	widget: function() {
633		return this.element;
634	},
635
636	option: function( key, value ) {
637		var options = key,
638			parts,
639			curOption,
640			i;
641
642		if ( arguments.length === 0 ) {
643			// don't return a reference to the internal hash
644			return $.widget.extend( {}, this.options );
645		}
646
647		if ( typeof key === "string" ) {
648			// handle nested keys, e.g., "foo.bar" => { foo: { bar: ___ } }
649			options = {};
650			parts = key.split( "." );
651			key = parts.shift();
652			if ( parts.length ) {
653				curOption = options[ key ] = $.widget.extend( {}, this.options[ key ] );
654				for ( i = 0; i < parts.length - 1; i++ ) {
655					curOption[ parts[ i ] ] = curOption[ parts[ i ] ] || {};
656					curOption = curOption[ parts[ i ] ];
657				}
658				key = parts.pop();
659				if ( value === undefined ) {
660					return curOption[ key ] === undefined ? null : curOption[ key ];
661				}
662				curOption[ key ] = value;
663			} else {
664				if ( value === undefined ) {
665					return this.options[ key ] === undefined ? null : this.options[ key ];
666				}
667				options[ key ] = value;
668			}
669		}
670
671		this._setOptions( options );
672
673		return this;
674	},
675	_setOptions: function( options ) {
676		var key;
677
678		for ( key in options ) {
679			this._setOption( key, options[ key ] );
680		}
681
682		return this;
683	},
684	_setOption: function( key, value ) {
685		this.options[ key ] = value;
686
687		if ( key === "disabled" ) {
688			this.widget()
689				.toggleClass( this.widgetFullName + "-disabled ui-state-disabled", !!value )
690				.attr( "aria-disabled", value );
691			this.hoverable.removeClass( "ui-state-hover" );
692			this.focusable.removeClass( "ui-state-focus" );
693		}
694
695		return this;
696	},
697
698	enable: function() {
699		return this._setOption( "disabled", false );
700	},
701	disable: function() {
702		return this._setOption( "disabled", true );
703	},
704
705	_on: function( suppressDisabledCheck, element, handlers ) {
706		var delegateElement,
707			instance = this;
708
709		// no suppressDisabledCheck flag, shuffle arguments
710		if ( typeof suppressDisabledCheck !== "boolean" ) {
711			handlers = element;
712			element = suppressDisabledCheck;
713			suppressDisabledCheck = false;
714		}
715
716		// no element argument, shuffle and use this.element
717		if ( !handlers ) {
718			handlers = element;
719			element = this.element;
720			delegateElement = this.widget();
721		} else {
722			// accept selectors, DOM elements
723			element = delegateElement = $( element );
724			this.bindings = this.bindings.add( element );
725		}
726
727		$.each( handlers, function( event, handler ) {
728			function handlerProxy() {
729				// allow widgets to customize the disabled handling
730				// - disabled as an array instead of boolean
731				// - disabled class as method for disabling individual parts
732				if ( !suppressDisabledCheck &&
733						( instance.options.disabled === true ||
734							$( this ).hasClass( "ui-state-disabled" ) ) ) {
735					return;
736				}
737				return ( typeof handler === "string" ? instance[ handler ] : handler )
738					.apply( instance, arguments );
739			}
740
741			// copy the guid so direct unbinding works
742			if ( typeof handler !== "string" ) {
743				handlerProxy.guid = handler.guid =
744					handler.guid || handlerProxy.guid || $.guid++;
745			}
746
747			var match = event.match( /^(\w+)\s*(.*)$/ ),
748				eventName = match[1] + instance.eventNamespace,
749				selector = match[2];
750			if ( selector ) {
751				delegateElement.delegate( selector, eventName, handlerProxy );
752			} else {
753				element.bind( eventName, handlerProxy );
754			}
755		});
756	},
757
758	_off: function( element, eventName ) {
759		eventName = (eventName || "").split( " " ).join( this.eventNamespace + " " ) + this.eventNamespace;
760		element.unbind( eventName ).undelegate( eventName );
761	},
762
763	_delay: function( handler, delay ) {
764		function handlerProxy() {
765			return ( typeof handler === "string" ? instance[ handler ] : handler )
766				.apply( instance, arguments );
767		}
768		var instance = this;
769		return setTimeout( handlerProxy, delay || 0 );
770	},
771
772	_hoverable: function( element ) {
773		this.hoverable = this.hoverable.add( element );
774		this._on( element, {
775			mouseenter: function( event ) {
776				$( event.currentTarget ).addClass( "ui-state-hover" );
777			},
778			mouseleave: function( event ) {
779				$( event.currentTarget ).removeClass( "ui-state-hover" );
780			}
781		});
782	},
783
784	_focusable: function( element ) {
785		this.focusable = this.focusable.add( element );
786		this._on( element, {
787			focusin: function( event ) {
788				$( event.currentTarget ).addClass( "ui-state-focus" );
789			},
790			focusout: function( event ) {
791				$( event.currentTarget ).removeClass( "ui-state-focus" );
792			}
793		});
794	},
795
796	_trigger: function( type, event, data ) {
797		var prop, orig,
798			callback = this.options[ type ];
799
800		data = data || {};
801		event = $.Event( event );
802		event.type = ( type === this.widgetEventPrefix ?
803			type :
804			this.widgetEventPrefix + type ).toLowerCase();
805		// the original event may come from any element
806		// so we need to reset the target on the new event
807		event.target = this.element[ 0 ];
808
809		// copy original event properties over to the new event
810		orig = event.originalEvent;
811		if ( orig ) {
812			for ( prop in orig ) {
813				if ( !( prop in event ) ) {
814					event[ prop ] = orig[ prop ];
815				}
816			}
817		}
818
819		this.element.trigger( event, data );
820		return !( $.isFunction( callback ) &&
821			callback.apply( this.element[0], [ event ].concat( data ) ) === false ||
822			event.isDefaultPrevented() );
823	}
824};
825
826$.each( { show: "fadeIn", hide: "fadeOut" }, function( method, defaultEffect ) {
827	$.Widget.prototype[ "_" + method ] = function( element, options, callback ) {
828		if ( typeof options === "string" ) {
829			options = { effect: options };
830		}
831		var hasOptions,
832			effectName = !options ?
833				method :
834				options === true || typeof options === "number" ?
835					defaultEffect :
836					options.effect || defaultEffect;
837		options = options || {};
838		if ( typeof options === "number" ) {
839			options = { duration: options };
840		}
841		hasOptions = !$.isEmptyObject( options );
842		options.complete = callback;
843		if ( options.delay ) {
844			element.delay( options.delay );
845		}
846		if ( hasOptions && $.effects && ( $.effects.effect[ effectName ] || $.uiBackCompat !== false && $.effects[ effectName ] ) ) {
847			element[ method ]( options );
848		} else if ( effectName !== method && element[ effectName ] ) {
vendor: 4,170 bytes, lines 849-1003
849			element[ effectName ]( options.duration, options.easing, callback );
850		} else {
851			element.queue(function( next ) {
852				$( this )[ method ]();
853				if ( callback ) {
854					callback.call( element[ 0 ] );
855				}
856				next();
857			});
858		}
859	};
860});
861
862// DEPRECATED
863if ( $.uiBackCompat !== false ) {
864	$.Widget.prototype._getCreateOptions = function() {
865		return $.metadata && $.metadata.get( this.element[0] )[ this.widgetName ];
866	};
867}
868
869})( jQuery );
870(function( $, undefined ) {
871
872var mouseHandled = false;
873$( document ).mouseup( function( e ) {
874	mouseHandled = false;
875});
876
877$.widget("ui.mouse", {
878	version: "1.9.2",
879	options: {
880		cancel: 'input,textarea,button,select,option',
881		distance: 1,
882		delay: 0
883	},
884	_mouseInit: function() {
885		var that = this;
886
887		this.element
888			.bind('mousedown.'+this.widgetName, function(event) {
889				return that._mouseDown(event);
890			})
891			.bind('click.'+this.widgetName, function(event) {
892				if (true === $.data(event.target, that.widgetName + '.preventClickEvent')) {
893					$.removeData(event.target, that.widgetName + '.preventClickEvent');
894					event.stopImmediatePropagation();
895					return false;
896				}
897			});
898
899		this.started = false;
900	},
901
902	// TODO: make sure destroying one instance of mouse doesn't mess with
903	// other instances of mouse
904	_mouseDestroy: function() {
905		this.element.unbind('.'+this.widgetName);
906		if ( this._mouseMoveDelegate ) {
907			$(document)
908				.unbind('mousemove.'+this.widgetName, this._mouseMoveDelegate)
909				.unbind('mouseup.'+this.widgetName, this._mouseUpDelegate);
910		}
911	},
912
913	_mouseDown: function(event) {
914		// don't let more than one widget handle mouseStart
915		if( mouseHandled ) { return; }
916
917		// we may have missed mouseup (out of window)
918		(this._mouseStarted && this._mouseUp(event));
919
920		this._mouseDownEvent = event;
921
922		var that = this,
923			btnIsLeft = (event.which === 1),
924			// event.target.nodeName works around a bug in IE 8 with
925			// disabled inputs (#7620)
926			elIsCancel = (typeof this.options.cancel === "string" && event.target.nodeName ? $(event.target).closest(this.options.cancel).length : false);
927		if (!btnIsLeft || elIsCancel || !this._mouseCapture(event)) {
928			return true;
929		}
930
931		this.mouseDelayMet = !this.options.delay;
932		if (!this.mouseDelayMet) {
933			this._mouseDelayTimer = setTimeout(function() {
934				that.mouseDelayMet = true;
935			}, this.options.delay);
936		}
937
938		if (this._mouseDistanceMet(event) && this._mouseDelayMet(event)) {
939			this._mouseStarted = (this._mouseStart(event) !== false);
940			if (!this._mouseStarted) {
941				event.preventDefault();
942				return true;
943			}
944		}
945
946		// Click event may never have fired (Gecko & Opera)
947		if (true === $.data(event.target, this.widgetName + '.preventClickEvent')) {
948			$.removeData(event.target, this.widgetName + '.preventClickEvent');
949		}
950
951		// these delegates are required to keep context
952		this._mouseMoveDelegate = function(event) {
953			return that._mouseMove(event);
954		};
955		this._mouseUpDelegate = function(event) {
956			return that._mouseUp(event);
957		};
958		$(document)
959			.bind('mousemove.'+this.widgetName, this._mouseMoveDelegate)
960			.bind('mouseup.'+this.widgetName, this._mouseUpDelegate);
961
962		event.preventDefault();
963
964		mouseHandled = true;
965		return true;
966	},
967
968	_mouseMove: function(event) {
969		// IE mouseup check - mouseup happened when mouse was out of window
970		if ($.ui.ie && !(document.documentMode >= 9) && !event.button) {
971			return this._mouseUp(event);
972		}
973
974		if (this._mouseStarted) {
975			this._mouseDrag(event);
976			return event.preventDefault();
977		}
978
979		if (this._mouseDistanceMet(event) && this._mouseDelayMet(event)) {
980			this._mouseStarted =
981				(this._mouseStart(this._mouseDownEvent, event) !== false);
982			(this._mouseStarted ? this._mouseDrag(event) : this._mouseUp(event));
983		}
984
985		return !this._mouseStarted;
986	},
987
988	_mouseUp: function(event) {
989		$(document)
990			.unbind('mousemove.'+this.widgetName, this._mouseMoveDelegate)
991			.unbind('mouseup.'+this.widgetName, this._mouseUpDelegate);
992
993		if (this._mouseStarted) {
994			this._mouseStarted = false;
995
996			if (event.target === this._mouseDownEvent.target) {
997				$.data(event.target, this.widgetName + '.preventClickEvent', true);
998			}
999
1000			this._mouseStop(event);
1001		}
1002
1003		return false;
1004	},
1005
1006	_mouseDistanceMet: function(event) {
1007		return (Math.max(
1008				Math.abs(this._mouseDownEvent.pageX - event.pageX),
1009				Math.abs(this._mouseDownEvent.pageY - event.pageY)
1010			) >= this.options.distance
1011		);
1012	},
1013
1014	_mouseDelayMet: function(event) {
1015		return this.mouseDelayMet;
1016	},
1017
1018	// These are placeholder methods, to be overriden by extending plugin
1019	_mouseStart: function(event) {},
1020	_mouseDrag: function(event) {},
1021	_mouseStop: function(event) {},
1022	_mouseCapture: function(event) { return true; }
1023});
1024
1025})(jQuery);
1026(function( $, undefined ) {
1027
1028$.ui = $.ui || {};
1029
1030var cachedScrollbarWidth,
1031	max = Math.max,
1032	abs = Math.abs,
1033	round = Math.round,
1034	rhorizontal = /left|center|right/,
1035	rvertical = /top|center|bottom/,
1036	roffset = /[\+\-]\d+%?/,
1037	rposition = /^\w+/,
1038	rpercent = /%$/,
1039	_position = $.fn.position;
1040
1041function getOffsets( offsets, width, height ) {
1042	return [
1043		parseInt( offsets[ 0 ], 10 ) * ( rpercent.test( offsets[ 0 ] ) ? width / 100 : 1 ),
1044		parseInt( offsets[ 1 ], 10 ) * ( rpercent.test( offsets[ 1 ] ) ? height / 100 : 1 )
1045	];
1046}
1047function parseCss( element, property ) {
1048	return parseInt( $.css( element, property ), 10 ) || 0;
1049}
1050
1051$.position = {
1052	scrollbarWidth: function() {
1053		if ( cachedScrollbarWidth !== undefined ) {
1054			return cachedScrollbarWidth;
1055		}
1056		var w1, w2,
1057			div = $( "<div style='display:block;width:50px;height:50px;overflow:hidden;'><div style='height:100px;width:auto;'></div></div>" ),
1058			innerDiv = div.children()[0];
1059
1060		$( "body" ).append( div );
1061		w1 = innerDiv.offsetWidth;
1062		div.css( "overflow", "scroll" );
1063
1064		w2 = innerDiv.offsetWidth;
1065
1066		if ( w1 === w2 ) {
1067			w2 = div[0].clientWidth;
1068		}
1069
1070		div.remove();
1071
1072		return (cachedScrollbarWidth = w1 - w2);
1073	},
1074	getScrollInfo: function( within ) {
1075		var overflowX = within.isWindow ? "" : within.element.css( "overflow-x" ),
1076			overflowY = within.isWindow ? "" : within.element.css( "overflow-y" ),
1077			hasOverflowX = overflowX === "scroll" ||
1078				( overflowX === "auto" && within.width < within.element[0].scrollWidth ),
1079			hasOverflowY = overflowY === "scroll" ||
1080				( overflowY === "auto" && within.height < within.element[0].scrollHeight );
1081		return {
1082			width: hasOverflowX ? $.position.scrollbarWidth() : 0,
1083			height: hasOverflowY ? $.position.scrollbarWidth() : 0
1084		};
1085	},
1086	getWithinInfo: function( element ) {
1087		var withinElement = $( element || window ),
1088			isWindow = $.isWindow( withinElement[0] );
1089		return {
1090			element: withinElement,
1091			isWindow: isWindow,
1092			offset: withinElement.offset() || { left: 0, top: 0 },
1093			scrollLeft: withinElement.scrollLeft(),
1094			scrollTop: withinElement.scrollTop(),
1095			width: isWindow ? withinElement.width() : withinElement.outerWidth(),
1096			height: isWindow ? withinElement.height() : withinElement.outerHeight()
1097		};
1098	}
1099};
1100
1101$.fn.position = function( options ) {
1102	if ( !options || !options.of ) {
1103		return _position.apply( this, arguments );
1104	}
1105
1106	// make a copy, we don't want to modify arguments
1107	options = $.extend( {}, options );
1108
1109	var atOffset, targetWidth, targetHeight, targetOffset, basePosition,
1110		target = $( options.of ),
1111		within = $.position.getWithinInfo( options.within ),
1112		scrollInfo = $.position.getScrollInfo( within ),
1113		targetElem = target[0],
1114		collision = ( options.collision || "flip" ).split( " " ),
1115		offsets = {};
1116
1117	if ( targetElem.nodeType === 9 ) {
1118		targetWidth = target.width();
1119		targetHeight = target.height();
1120		targetOffset = { top: 0, left: 0 };
1121	} else if ( $.isWindow( targetElem ) ) {
1122		targetWidth = target.width();
1123		targetHeight = target.height();
1124		targetOffset = { top: target.scrollTop(), left: target.scrollLeft() };
1125	} else if ( targetElem.preventDefault ) {
1126		// force left top to allow flipping
1127		options.at = "left top";
1128		targetWidth = targetHeight = 0;
1129		targetOffset = { top: targetElem.pageY, left: targetElem.pageX };
1130	} else {
1131		targetWidth = target.outerWidth();
1132		targetHeight = target.outerHeight();
1133		targetOffset = target.offset();
1134	}
1135	// clone to reuse original targetOffset later
1136	basePosition = $.extend( {}, targetOffset );
1137
1138	// force my and at to have valid horizontal and vertical positions
1139	// if a value is missing or invalid, it will be converted to center
1140	$.each( [ "my", "at" ], function() {
1141		var pos = ( options[ this ] || "" ).split( " " ),
1142			horizontalOffset,
1143			verticalOffset;
1144
1145		if ( pos.length === 1) {
1146			pos = rhorizontal.test( pos[ 0 ] ) ?
vendor: 12,659 bytes, lines 1147-1544
1147				pos.concat( [ "center" ] ) :
1148				rvertical.test( pos[ 0 ] ) ?
1149					[ "center" ].concat( pos ) :
1150					[ "center", "center" ];
1151		}
1152		pos[ 0 ] = rhorizontal.test( pos[ 0 ] ) ? pos[ 0 ] : "center";
1153		pos[ 1 ] = rvertical.test( pos[ 1 ] ) ? pos[ 1 ] : "center";
1154
1155		// calculate offsets
1156		horizontalOffset = roffset.exec( pos[ 0 ] );
1157		verticalOffset = roffset.exec( pos[ 1 ] );
1158		offsets[ this ] = [
1159			horizontalOffset ? horizontalOffset[ 0 ] : 0,
1160			verticalOffset ? verticalOffset[ 0 ] : 0
1161		];
1162
1163		// reduce to just the positions without the offsets
1164		options[ this ] = [
1165			rposition.exec( pos[ 0 ] )[ 0 ],
1166			rposition.exec( pos[ 1 ] )[ 0 ]
1167		];
1168	});
1169
1170	// normalize collision option
1171	if ( collision.length === 1 ) {
1172		collision[ 1 ] = collision[ 0 ];
1173	}
1174
1175	if ( options.at[ 0 ] === "right" ) {
1176		basePosition.left += targetWidth;
1177	} else if ( options.at[ 0 ] === "center" ) {
1178		basePosition.left += targetWidth / 2;
1179	}
1180
1181	if ( options.at[ 1 ] === "bottom" ) {
1182		basePosition.top += targetHeight;
1183	} else if ( options.at[ 1 ] === "center" ) {
1184		basePosition.top += targetHeight / 2;
1185	}
1186
1187	atOffset = getOffsets( offsets.at, targetWidth, targetHeight );
1188	basePosition.left += atOffset[ 0 ];
1189	basePosition.top += atOffset[ 1 ];
1190
1191	return this.each(function() {
1192		var collisionPosition, using,
1193			elem = $( this ),
1194			elemWidth = elem.outerWidth(),
1195			elemHeight = elem.outerHeight(),
1196			marginLeft = parseCss( this, "marginLeft" ),
1197			marginTop = parseCss( this, "marginTop" ),
1198			collisionWidth = elemWidth + marginLeft + parseCss( this, "marginRight" ) + scrollInfo.width,
1199			collisionHeight = elemHeight + marginTop + parseCss( this, "marginBottom" ) + scrollInfo.height,
1200			position = $.extend( {}, basePosition ),
1201			myOffset = getOffsets( offsets.my, elem.outerWidth(), elem.outerHeight() );
1202
1203		if ( options.my[ 0 ] === "right" ) {
1204			position.left -= elemWidth;
1205		} else if ( options.my[ 0 ] === "center" ) {
1206			position.left -= elemWidth / 2;
1207		}
1208
1209		if ( options.my[ 1 ] === "bottom" ) {
1210			position.top -= elemHeight;
1211		} else if ( options.my[ 1 ] === "center" ) {
1212			position.top -= elemHeight / 2;
1213		}
1214
1215		position.left += myOffset[ 0 ];
1216		position.top += myOffset[ 1 ];
1217
1218		// if the browser doesn't support fractions, then round for consistent results
1219		if ( !$.support.offsetFractions ) {
1220			position.left = round( position.left );
1221			position.top = round( position.top );
1222		}
1223
1224		collisionPosition = {
1225			marginLeft: marginLeft,
1226			marginTop: marginTop
1227		};
1228
1229		$.each( [ "left", "top" ], function( i, dir ) {
1230			if ( $.ui.position[ collision[ i ] ] ) {
1231				$.ui.position[ collision[ i ] ][ dir ]( position, {
1232					targetWidth: targetWidth,
1233					targetHeight: targetHeight,
1234					elemWidth: elemWidth,
1235					elemHeight: elemHeight,
1236					collisionPosition: collisionPosition,
1237					collisionWidth: collisionWidth,
1238					collisionHeight: collisionHeight,
1239					offset: [ atOffset[ 0 ] + myOffset[ 0 ], atOffset [ 1 ] + myOffset[ 1 ] ],
1240					my: options.my,
1241					at: options.at,
1242					within: within,
1243					elem : elem
1244				});
1245			}
1246		});
1247
1248		if ( $.fn.bgiframe ) {
1249			elem.bgiframe();
1250		}
1251
1252		if ( options.using ) {
1253			// adds feedback as second argument to using callback, if present
1254			using = function( props ) {
1255				var left = targetOffset.left - position.left,
1256					right = left + targetWidth - elemWidth,
1257					top = targetOffset.top - position.top,
1258					bottom = top + targetHeight - elemHeight,
1259					feedback = {
1260						target: {
1261							element: target,
1262							left: targetOffset.left,
1263							top: targetOffset.top,
1264							width: targetWidth,
1265							height: targetHeight
1266						},
1267						element: {
1268							element: elem,
1269							left: position.left,
1270							top: position.top,
1271							width: elemWidth,
1272							height: elemHeight
1273						},
1274						horizontal: right < 0 ? "left" : left > 0 ? "right" : "center",
1275						vertical: bottom < 0 ? "top" : top > 0 ? "bottom" : "middle"
1276					};
1277				if ( targetWidth < elemWidth && abs( left + right ) < targetWidth ) {
1278					feedback.horizontal = "center";
1279				}
1280				if ( targetHeight < elemHeight && abs( top + bottom ) < targetHeight ) {
1281					feedback.vertical = "middle";
1282				}
1283				if ( max( abs( left ), abs( right ) ) > max( abs( top ), abs( bottom ) ) ) {
1284					feedback.important = "horizontal";
1285				} else {
1286					feedback.important = "vertical";
1287				}
1288				options.using.call( this, props, feedback );
1289			};
1290		}
1291
1292		elem.offset( $.extend( position, { using: using } ) );
1293	});
1294};
1295
1296$.ui.position = {
1297	fit: {
1298		left: function( position, data ) {
1299			var within = data.within,
1300				withinOffset = within.isWindow ? within.scrollLeft : within.offset.left,
1301				outerWidth = within.width,
1302				collisionPosLeft = position.left - data.collisionPosition.marginLeft,
1303				overLeft = withinOffset - collisionPosLeft,
1304				overRight = collisionPosLeft + data.collisionWidth - outerWidth - withinOffset,
1305				newOverRight;
1306
1307			// element is wider than within
1308			if ( data.collisionWidth > outerWidth ) {
1309				// element is initially over the left side of within
1310				if ( overLeft > 0 && overRight <= 0 ) {
1311					newOverRight = position.left + overLeft + data.collisionWidth - outerWidth - withinOffset;
1312					position.left += overLeft - newOverRight;
1313				// element is initially over right side of within
1314				} else if ( overRight > 0 && overLeft <= 0 ) {
1315					position.left = withinOffset;
1316				// element is initially over both left and right sides of within
1317				} else {
1318					if ( overLeft > overRight ) {
1319						position.left = withinOffset + outerWidth - data.collisionWidth;
1320					} else {
1321						position.left = withinOffset;
1322					}
1323				}
1324			// too far left -> align with left edge
1325			} else if ( overLeft > 0 ) {
1326				position.left += overLeft;
1327			// too far right -> align with right edge
1328			} else if ( overRight > 0 ) {
1329				position.left -= overRight;
1330			// adjust based on position and margin
1331			} else {
1332				position.left = max( position.left - collisionPosLeft, position.left );
1333			}
1334		},
1335		top: function( position, data ) {
1336			var within = data.within,
1337				withinOffset = within.isWindow ? within.scrollTop : within.offset.top,
1338				outerHeight = data.within.height,
1339				collisionPosTop = position.top - data.collisionPosition.marginTop,
1340				overTop = withinOffset - collisionPosTop,
1341				overBottom = collisionPosTop + data.collisionHeight - outerHeight - withinOffset,
1342				newOverBottom;
1343
1344			// element is taller than within
1345			if ( data.collisionHeight > outerHeight ) {
1346				// element is initially over the top of within
1347				if ( overTop > 0 && overBottom <= 0 ) {
1348					newOverBottom = position.top + overTop + data.collisionHeight - outerHeight - withinOffset;
1349					position.top += overTop - newOverBottom;
1350				// element is initially over bottom of within
1351				} else if ( overBottom > 0 && overTop <= 0 ) {
1352					position.top = withinOffset;
1353				// element is initially over both top and bottom of within
1354				} else {
1355					if ( overTop > overBottom ) {
1356						position.top = withinOffset + outerHeight - data.collisionHeight;
1357					} else {
1358						position.top = withinOffset;
1359					}
1360				}
1361			// too far up -> align with top
1362			} else if ( overTop > 0 ) {
1363				position.top += overTop;
1364			// too far down -> align with bottom edge
1365			} else if ( overBottom > 0 ) {
1366				position.top -= overBottom;
1367			// adjust based on position and margin
1368			} else {
1369				position.top = max( position.top - collisionPosTop, position.top );
1370			}
1371		}
1372	},
1373	flip: {
1374		left: function( position, data ) {
1375			var within = data.within,
1376				withinOffset = within.offset.left + within.scrollLeft,
1377				outerWidth = within.width,
1378				offsetLeft = within.isWindow ? within.scrollLeft : within.offset.left,
1379				collisionPosLeft = position.left - data.collisionPosition.marginLeft,
1380				overLeft = collisionPosLeft - offsetLeft,
1381				overRight = collisionPosLeft + data.collisionWidth - outerWidth - offsetLeft,
1382				myOffset = data.my[ 0 ] === "left" ?
1383					-data.elemWidth :
1384					data.my[ 0 ] === "right" ?
1385						data.elemWidth :
1386						0,
1387				atOffset = data.at[ 0 ] === "left" ?
1388					data.targetWidth :
1389					data.at[ 0 ] === "right" ?
1390						-data.targetWidth :
1391						0,
1392				offset = -2 * data.offset[ 0 ],
1393				newOverRight,
1394				newOverLeft;
1395
1396			if ( overLeft < 0 ) {
1397				newOverRight = position.left + myOffset + atOffset + offset + data.collisionWidth - outerWidth - withinOffset;
1398				if ( newOverRight < 0 || newOverRight < abs( overLeft ) ) {
1399					position.left += myOffset + atOffset + offset;
1400				}
1401			}
1402			else if ( overRight > 0 ) {
1403				newOverLeft = position.left - data.collisionPosition.marginLeft + myOffset + atOffset + offset - offsetLeft;
1404				if ( newOverLeft > 0 || abs( newOverLeft ) < overRight ) {
1405					position.left += myOffset + atOffset + offset;
1406				}
1407			}
1408		},
1409		top: function( position, data ) {
1410			var within = data.within,
1411				withinOffset = within.offset.top + within.scrollTop,
1412				outerHeight = within.height,
1413				offsetTop = within.isWindow ? within.scrollTop : within.offset.top,
1414				collisionPosTop = position.top - data.collisionPosition.marginTop,
1415				overTop = collisionPosTop - offsetTop,
1416				overBottom = collisionPosTop + data.collisionHeight - outerHeight - offsetTop,
1417				top = data.my[ 1 ] === "top",
1418				myOffset = top ?
1419					-data.elemHeight :
1420					data.my[ 1 ] === "bottom" ?
1421						data.elemHeight :
1422						0,
1423				atOffset = data.at[ 1 ] === "top" ?
1424					data.targetHeight :
1425					data.at[ 1 ] === "bottom" ?
1426						-data.targetHeight :
1427						0,
1428				offset = -2 * data.offset[ 1 ],
1429				newOverTop,
1430				newOverBottom;
1431			if ( overTop < 0 ) {
1432				newOverBottom = position.top + myOffset + atOffset + offset + data.collisionHeight - outerHeight - withinOffset;
1433				if ( ( position.top + myOffset + atOffset + offset) > overTop && ( newOverBottom < 0 || newOverBottom < abs( overTop ) ) ) {
1434					position.top += myOffset + atOffset + offset;
1435				}
1436			}
1437			else if ( overBottom > 0 ) {
1438				newOverTop = position.top -  data.collisionPosition.marginTop + myOffset + atOffset + offset - offsetTop;
1439				if ( ( position.top + myOffset + atOffset + offset) > overBottom && ( newOverTop > 0 || abs( newOverTop ) < overBottom ) ) {
1440					position.top += myOffset + atOffset + offset;
1441				}
1442			}
1443		}
1444	},
1445	flipfit: {
1446		left: function() {
1447			$.ui.position.flip.left.apply( this, arguments );
1448			$.ui.position.fit.left.apply( this, arguments );
1449		},
1450		top: function() {
1451			$.ui.position.flip.top.apply( this, arguments );
1452			$.ui.position.fit.top.apply( this, arguments );
1453		}
1454	}
1455};
1456
1457// fraction support test
1458(function () {
1459	var testElement, testElementParent, testElementStyle, offsetLeft, i,
1460		body = document.getElementsByTagName( "body" )[ 0 ],
1461		div = document.createElement( "div" );
1462
1463	//Create a "fake body" for testing based on method used in jQuery.support
1464	testElement = document.createElement( body ? "div" : "body" );
1465	testElementStyle = {
1466		visibility: "hidden",
1467		width: 0,
1468		height: 0,
1469		border: 0,
1470		margin: 0,
1471		background: "none"
1472	};
1473	if ( body ) {
1474		$.extend( testElementStyle, {
1475			position: "absolute",
1476			left: "-1000px",
1477			top: "-1000px"
1478		});
1479	}
1480	for ( i in testElementStyle ) {
1481		testElement.style[ i ] = testElementStyle[ i ];
1482	}
1483	testElement.appendChild( div );
1484	testElementParent = body || document.documentElement;
1485	testElementParent.insertBefore( testElement, testElementParent.firstChild );
1486
1487	div.style.cssText = "position: absolute; left: 10.7432222px;";
1488
1489	offsetLeft = $( div ).offset().left;
1490	$.support.offsetFractions = offsetLeft > 10 && offsetLeft < 11;
1491
1492	testElement.innerHTML = "";
1493	testElementParent.removeChild( testElement );
1494})();
1495
1496// DEPRECATED
1497if ( $.uiBackCompat !== false ) {
1498	// offset option
1499	(function( $ ) {
1500		var _position = $.fn.position;
1501		$.fn.position = function( options ) {
1502			if ( !options || !options.offset ) {
1503				return _position.call( this, options );
1504			}
1505			var offset = options.offset.split( " " ),
1506				at = options.at.split( " " );
1507			if ( offset.length === 1 ) {
1508				offset[ 1 ] = offset[ 0 ];
1509			}
1510			if ( /^\d/.test( offset[ 0 ] ) ) {
1511				offset[ 0 ] = "+" + offset[ 0 ];
1512			}
1513			if ( /^\d/.test( offset[ 1 ] ) ) {
1514				offset[ 1 ] = "+" + offset[ 1 ];
1515			}
1516			if ( at.length === 1 ) {
1517				if ( /left|center|right/.test( at[ 0 ] ) ) {
1518					at[ 1 ] = "center";
1519				} else {
1520					at[ 1 ] = at[ 0 ];
1521					at[ 0 ] = "center";
1522				}
1523			}
1524			return _position.call( this, $.extend( options, {
1525				at: at[ 0 ] + offset[ 0 ] + " " + at[ 1 ] + offset[ 1 ],
1526				offset: undefined
1527			} ) );
1528		};
1529	}( jQuery ) );
1530}
1531
1532}( jQuery ) );
1533(function( $, undefined ) {
1534
1535$.widget("ui.draggable", $.ui.mouse, {
1536	version: "1.9.2",
1537	widgetEventPrefix: "drag",
1538	options: {
1539		addClasses: true,
1540		appendTo: "parent",
1541		axis: false,
1542		connectToSortable: false,
1543		containment: false,
1544		cursor: "auto",
1545		cursorAt: false,
1546		grid: false,
1547		handle: false,
1548		helper: "original",
1549		iframeFix: false,
1550		opacity: false,
1551		refreshPositions: false,
1552		revert: false,
1553		revertDuration: 500,
1554		scope: "default",
1555		scroll: true,
1556		scrollSensitivity: 20,
1557		scrollSpeed: 20,
1558		snap: false,
1559		snapMode: "both",
1560		snapTolerance: 20,
1561		stack: false,
1562		zIndex: false
1563	},
1564	_create: function() {
1565
1566		if (this.options.helper == 'original' && !(/^(?:r|a|f)/).test(this.element.css("position")))
1567			this.element[0].style.position = 'relative';
1568
1569		(this.options.addClasses && this.element.addClass("ui-draggable"));
1570		(this.options.disabled && this.element.addClass("ui-draggable-disabled"));
1571
1572		this._mouseInit();
1573
1574	},
1575
1576	_destroy: function() {
1577		this.element.removeClass( "ui-draggable ui-draggable-dragging ui-draggable-disabled" );
1578		this._mouseDestroy();
1579	},
1580
1581	_mouseCapture: function(event) {
1582
1583		var o = this.options;
1584
1585		// among others, prevent a drag on a resizable-handle
1586		if (this.helper || o.disabled || $(event.target).is('.ui-resizable-handle'))
1587			return false;
1588
1589		//Quit if we're not on a valid handle
1590		this.handle = this._getHandle(event);
1591		if (!this.handle)
1592			return false;
1593
1594		$(o.iframeFix === true ? "iframe" : o.iframeFix).each(function() {
1595			$('<div class="ui-draggable-iframeFix" style="background: #fff;"></div>')
1596			.css({
1597				width: this.offsetWidth+"px", height: this.offsetHeight+"px",
1598				position: "absolute", opacity: "0.001", zIndex: 1000
1599			})
1600			.css($(this).offset())
1601			.appendTo("body");
1602		});
1603
1604		return true;
1605
1606	},
1607
1608	_mouseStart: function(event) {
1609
1610		var o = this.options;
1611
1612		//Create and append the visible helper
1613		this.helper = this._createHelper(event);
1614
1615		this.helper.addClass("ui-draggable-dragging");
1616
1617		//Cache the helper size
1618		this._cacheHelperProportions();
1619
1620		//If ddmanager is used for droppables, set the global draggable
1621		if($.ui.ddmanager)
1622			$.ui.ddmanager.current = this;
1623
1624		/*
1625		 * - Position generation -
1626		 * This block generates everything position related - it's the core of draggables.
1627		 */
1628
1629		//Cache the margins of the original element
1630		this._cacheMargins();
1631
1632		//Store the helper's css position
1633		this.cssPosition = this.helper.css("position");
1634		this.scrollParent = this.helper.scrollParent();
1635
1636		//The element's absolute position on the page minus margins
1637		this.offset = this.positionAbs = this.element.offset();
1638		this.offset = {
1639			top: this.offset.top - this.margins.top,
1640			left: this.offset.left - this.margins.left
1641		};
1642
1643		$.extend(this.offset, {
1644			click: { //Where the click happened, relative to the element
1645				left: event.pageX - this.offset.left,
1646				top: event.pageY - this.offset.top
1647			},
1648			parent: this._getParentOffset(),
1649			relative: this._getRelativeOffset() //This is a relative to absolute position minus the actual position calculation - only used for relative positioned helper
1650		});
1651
1652		//Generate the original position
1653		this.originalPosition = this.position = this._generatePosition(event);
1654		this.originalPageX = event.pageX;
1655		this.originalPageY = event.pageY;
1656
1657		//Adjust the mouse offset relative to the helper if 'cursorAt' is supplied
1658		(o.cursorAt && this._adjustOffsetFromHelper(o.cursorAt));
1659
1660		//Set a containment if given in the options
1661		if(o.containment)
1662			this._setContainment();
1663
1664		//Trigger event + callbacks
1665		if(this._trigger("start", event) === false) {
1666			this._clear();
1667			return false;
1668		}
1669
1670		//Recache the helper size
1671		this._cacheHelperProportions();
1672
1673		//Prepare the droppable offsets
1674		if ($.ui.ddmanager && !o.dropBehaviour)
1675			$.ui.ddmanager.prepareOffsets(this, event);
1676
1677
1678		this._mouseDrag(event, true); //Execute the drag once - this causes the helper not to be visible before getting its correct position
1679
1680		//If the ddmanager is used for droppables, inform the manager that dragging has started (see #5003)
1681		if ( $.ui.ddmanager ) $.ui.ddmanager.dragStart(this, event);
1682
1683		return true;
1684	},
1685
1686	_mouseDrag: function(event, noPropagation) {
1687
1688		//Compute the helpers position
1689		this.position = this._generatePosition(event);
1690		this.positionAbs = this._convertPositionTo("absolute");
1691
1692		//Call plugins and callbacks and use the resulting position if something is returned
1693		if (!noPropagation) {
1694			var ui = this._uiHash();
1695			if(this._trigger('drag', event, ui) === false) {
1696				this._mouseUp({});
1697				return false;
1698			}
1699			this.position = ui.position;
1700		}
1701
1702		if(!this.options.axis || this.options.axis != "y") this.helper[0].style.left = this.position.left+'px';
1703		if(!this.options.axis || this.options.axis != "x") this.helper[0].style.top = this.position.top+'px';
1704		if($.ui.ddmanager) $.ui.ddmanager.drag(this, event);
1705
1706		return false;
1707	},
1708
1709	_mouseStop: function(event) {
1710
1711		//If we are using droppables, inform the manager about the drop
1712		var dropped = false;
1713		if ($.ui.ddmanager && !this.options.dropBehaviour)
1714			dropped = $.ui.ddmanager.drop(this, event);
1715
1716		//if a drop comes from outside (a sortable)
1717		if(this.dropped) {
1718			dropped = this.dropped;
1719			this.dropped = false;
1720		}
1721
1722		//if the original element is no longer in the DOM don't bother to continue (see #8269)
1723		var element = this.element[0], elementInDom = false;
1724		while ( element && (element = element.parentNode) ) {
1725			if (element == document ) {
1726				elementInDom = true;
1727			}
1728		}
1729		if ( !elementInDom && this.options.helper === "original" )
1730			return false;
1731
1732		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))) {
1733			var that = this;
1734			$(this.helper).animate(this.originalPosition, parseInt(this.options.revertDuration, 10), function() {
1735				if(that._trigger("stop", event) !== false) {
1736					that._clear();
1737				}
1738			});
1739		} else {
1740			if(this._trigger("stop", event) !== false) {
1741				this._clear();
1742			}
1743		}
1744
1745		return false;
1746	},
1747
1748	_mouseUp: function(event) {
1749		//Remove frame helpers
1750		$("div.ui-draggable-iframeFix").each(function() {
1751			this.parentNode.removeChild(this);
1752		});
1753
1754		//If the ddmanager is used for droppables, inform the manager that dragging has stopped (see #5003)
1755		if( $.ui.ddmanager ) $.ui.ddmanager.dragStop(this, event);
1756
1757		return $.ui.mouse.prototype._mouseUp.call(this, event);
1758	},
1759
1760	cancel: function() {
1761
1762		if(this.helper.is(".ui-draggable-dragging")) {
1763			this._mouseUp({});
1764		} else {
1765			this._clear();
1766		}
1767
1768		return this;
1769
1770	},
1771
1772	_getHandle: function(event) {
1773
1774		var handle = !this.options.handle || !$(this.options.handle, this.element).length ? true : false;
1775		$(this.options.handle, this.element)
1776			.find("*")
1777			.andSelf()
1778			.each(function() {
1779				if(this == event.target) handle = true;
1780			});
1781
1782		return handle;
1783
1784	},
1785
1786	_createHelper: function(event) {
1787
1788		var o = this.options;
1789		var helper = $.isFunction(o.helper) ? $(o.helper.apply(this.element[0], [event])) : (o.helper == 'clone' ? this.element.clone().removeAttr('id') : this.element);
1790
1791		if(!helper.parents('body').length)
1792			helper.appendTo((o.appendTo == 'parent' ? this.element[0].parentNode : o.appendTo));
1793
1794		if(helper[0] != this.element[0] && !(/(fixed|absolute)/).test(helper.css("position")))
1795			helper.css("position", "absolute");
1796
1797		return helper;
1798
1799	},
1800
1801	_adjustOffsetFromHelper: function(obj) {
1802		if (typeof obj == 'string') {
1803			obj = obj.split(' ');
1804		}
1805		if ($.isArray(obj)) {
1806			obj = {left: +obj[0], top: +obj[1] || 0};
1807		}
1808		if ('left' in obj) {
1809			this.offset.click.left = obj.left + this.margins.left;
1810		}
1811		if ('right' in obj) {
1812			this.offset.click.left = this.helperProportions.width - obj.right + this.margins.left;
1813		}
1814		if ('top' in obj) {
1815			this.offset.click.top = obj.top + this.margins.top;
1816		}
1817		if ('bottom' in obj) {
1818			this.offset.click.top = this.helperProportions.height - obj.bottom + this.margins.top;
1819		}
1820	},
1821
1822	_getParentOffset: function() {
1823
1824		//Get the offsetParent and cache its position
1825		this.offsetParent = this.helper.offsetParent();
1826		var po = this.offsetParent.offset();
1827
1828		// This is a special case where we need to modify a offset calculated on start, since the following happened:
1829		// 1. The position of the helper is absolute, so it's position is calculated based on the next positioned parent
1830		// 2. The actual offset parent is a child of the scroll parent, and the scroll parent isn't the document, which means that
1831		//    the scroll is included in the initial calculation of the offset of the parent, and never recalculated upon drag
1832		if(this.cssPosition == 'absolute' && this.scrollParent[0] != document && $.contains(this.scrollParent[0], this.offsetParent[0])) {
1833			po.left += this.scrollParent.scrollLeft();
1834			po.top += this.scrollParent.scrollTop();
1835		}
1836
1837		if((this.offsetParent[0] == document.body) //This needs to be actually done for all browsers, since pageX/pageY includes this information
1838		|| (this.offsetParent[0].tagName && this.offsetParent[0].tagName.toLowerCase() == 'html' && $.ui.ie)) //Ugly IE fix
1839			po = { top: 0, left: 0 };
1840
1841		return {
1842			top: po.top + (parseInt(this.offsetParent.css("borderTopWidth"),
184210) || 0),
1843			left: po.left + (parseInt(this.offsetParent.css("borderLeftWidth"),10) || 0)
1844		};
1845
1846	},
1847
1848	_getRelativeOffset: function() {
1849
1850		if(this.cssPosition == "relative") {
1851			var p = this.element.position();
1852			return {
1853				top: p.top - (parseInt(this.helper.css("top"),10) || 0) + this.scrollParent.scrollTop(),
1854				left: p.left - (parseInt(this.helper.css("left"),10) || 0) + this.scrollParent.scrollLeft()
1855			};
1856		} else {
1857			return { top: 0, left: 0 };
1858		}
1859
1860	},
1861
1862	_cacheMargins: function() {
1863		this.margins = {
1864			left: (parseInt(this.element.css("marginLeft"),10) || 0),
1865			top: (parseInt(this.element.css("marginTop"),10) || 0),
1866			right: (parseInt(this.element.css("marginRight"),10) || 0),
1867			bottom: (parseInt(this.element.css("marginBottom"),10) || 0)
1868		};
1869	},
1870
1871	_cacheHelperProportions: function() {
1872		this.helperProportions = {
1873			width: this.helper.outerWidth(),
1874			height: this.helper.outerHeight()
1875		};
1876	},
1877
1878	_setContainment: function() {
1879
1880		var o = this.options;
1881		if(o.containment == 'parent') o.containment = this.helper[0].parentNode;
1882		if(o.containment == 'document' || o.containment == 'window') this.containment = [
1883			o.containment == 'document' ? 0 : $(window).scrollLeft() - this.offset.relative.left - this.offset.parent.left,
1884			o.containment == 'document' ? 0 : $(window).scrollTop() - this.offset.relative.top - this.offset.parent.top,
1885			(o.containment == 'document' ? 0 : $(window).scrollLeft()) + $(o.containment == 'document' ? document : window).width() - this.helperProportions.width - this.margins.left,
1886			(o.containment == 'document' ? 0 : $(window).scrollTop()) + ($(o.containment == 'document' ? document : window).height() || document.body.parentNode.scrollHeight) - this.helperProportions.height - this.margins.top
1887		];
1888
1889		if(!(/^(document|window|parent)$/).test(o.containment) && o.containment.constructor != Array) {
1890			var c = $(o.containment);
1891			var ce = c[0]; if(!ce) return;
1892			var co = c.offset();
1893			var over = ($(ce).css("overflow") != 'hidden');
1894
1895			this.containment = [
1896				(parseInt($(ce).css("borderLeftWidth"),10) || 0) + (parseInt($(ce).css("paddingLeft"),10) || 0),
1897				(parseInt($(ce).css("borderTopWidth"),10) || 0) + (parseInt($(ce).css("paddingTop"),10) || 0),
1898				(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,
1899				(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
1900			];
1901			this.relative_container = c;
1902
1903		} else if(o.containment.constructor == Array) {
1904			this.containment = o.containment;
1905		}
1906
1907	},
1908
1909	_convertPositionTo: function(d, pos) {
1910
1911		if(!pos) pos = this.position;
1912		var mod = d == "absolute" ? 1 : -1;
1913		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);
1914
1915		return {
1916			top: (
1917				pos.top																	// The absolute mouse position
1918				+ this.offset.relative.top * mod										// Only for relative positioned nodes: Relative offset from element to offset parent
1919				+ this.offset.parent.top * mod											// The offsetParent's offset without borders (offset + border)
1920				- ( ( this.cssPosition == 'fixed' ? -this.scrollParent.scrollTop() : ( scrollIsRootNode ? 0 : scroll.scrollTop() ) ) * mod)
1921			),
1922			left: (
1923				pos.left																// The absolute mouse position
1924				+ this.offset.relative.left * mod										// Only for relative positioned nodes: Relative offset from element to offset parent
1925				+ this.offset.parent.left * mod											// The offsetParent's offset without borders (offset + border)
1926				- ( ( this.cssPosition == 'fixed' ? -this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 : scroll.scrollLeft() ) * mod)
1927			)
1928		};
1929
1930	},
1931
1932	_generatePosition: function(event) {
1933
1934		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);
1935		var pageX = event.pageX;
1936		var pageY = event.pageY;
1937
1938		/*
1939		 * - Position constraining -
1940		 * Constrain the position to a mix of grid, containment.
1941		 */
1942
1943		if(this.originalPosition) { //If we are not dragging yet, we won't check for options
1944			var containment;
1945			if(this.containment) {
1946			if (this.relative_container){
1947				var co = this.relative_container.offset();
1948				containment = [ this.containment[0] + co.left,
1949					this.containment[1] + co.top,
1950					this.containment[2] + co.left,
1951					this.containment[3] + co.top ];
1952			}
1953			else {
1954				containment = this.containment;
1955			}
1956
1957				if(event.pageX - this.offset.click.left < containment[0]) pageX = containment[0] + this.offset.click.left;
1958				if(event.pageY - this.offset.click.top < containment[1]) pageY = containment[1] + this.offset.click.top;
1959				if(event.pageX - this.offset.click.left > containment[2]) pageX = containment[2] + this.offset.click.left;
1960				if(event.pageY - this.offset.click.top > containment[3]) pageY = containment[3] + this.offset.click.top;
1961			}
1962
1963			if(o.grid) {
1964				//Check for grid elements set to 0 to prevent divide by 0 error causing invalid argument errors in IE (see ticket #6950)
1965				var top = o.grid[1] ? this.originalPageY + Math.round((pageY - this.originalPageY) / o.grid[1]) * o.grid[1] : this.originalPageY;
1966				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;
1967
1968				var left = o.grid[0] ? this.originalPageX + Math.round((pageX - this.originalPageX) / o.grid[0]) * o.grid[0] : this.originalPageX;
1969				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;
1970			}
1971
1972		}
1973
1974		return {
1975			top: (
1976				pageY																// The absolute mouse position
1977				- this.offset.click.top													// Click offset (relative to the element)
1978				- this.offset.relative.top												// Only for relative positioned nodes: Relative offset from element to offset parent
1979				- this.offset.parent.top												// The offsetParent's offset without borders (offset + border)
1980				+ ( ( this.cssPosition == 'fixed' ? -this.scrollParent.scrollTop() : ( scrollIsRootNode ? 0 : scroll.scrollTop() ) ))
1981			),
1982			left: (
1983				pageX																// The absolute mouse position
1984				- this.offset.click.left												// Click offset (relative to the element)
1985				- this.offset.relative.left												// Only for relative positioned nodes: Relative offset from element to offset parent
1986				- this.offset.parent.left												// The offsetParent's offset without borders (offset + border)
1987				+ ( ( this.cssPosition == 'fixed' ? -this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 : scroll.scrollLeft() ))
1988			)
1989		};
1990
1991	},
1992
1993	_clear: function() {
1994		this.helper.removeClass("ui-draggable-dragging");
1995		if(this.helper[0] != this.element[0] && !this.cancelHelperRemoval) this.helper.remove();
1996		//if($.ui.ddmanager) $.ui.ddmanager.current = null;
1997		this.helper = null;
1998		this.cancelHelperRemoval = false;
1999	},
2000
2001	// From now on bulk stuff - mainly helpers
2002
2003	_trigger: function(type, event, ui) {
2004		ui = ui || this._uiHash();
2005		$.ui.plugin.call(this, type, [event, ui]);
2006		if(type == "drag") this.positionAbs = this._convertPositionTo("absolute"); //The absolute position has to be recalculated after plugins
2007		return $.Widget.prototype._trigger.call(this, type, event, ui);
2008	},
2009
2010	plugins: {},
2011
2012	_uiHash: function(event) {
2013		return {
2014			helper: this.helper,
2015			position: this.position,
2016			originalPosition: this.originalPosition,
2017			offset: this.positionAbs
2018		};
2019	}
2020
2021});
2022
2023$.ui.plugin.add("draggable", "connectToSortable", {
2024	start: function(event, ui) {
2025
2026		var inst = $(this).data("draggable"), o = inst.options,
2027			uiSortable = $.extend({}, ui, { item: inst.element });
2028		inst.sortables = [];
2029		$(o.connectToSortable).each(function() {
2030			var sortable = $.data(this, 'sortable');
2031			if (sortable && !sortable.options.disabled) {
2032				inst.sortables.push({
2033					instance: sortable,
2034					shouldRevert: sortable.options.revert
2035				});
2036				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).
2037				sortable._trigger("activate", event, uiSortable);
2038			}
2039		});
2040
2041	},
2042	stop: function(event, ui) {
2043
2044		//If we are still over the sortable, we fake the stop event of the sortable, but also remove helper
2045		var inst = $(this).data("draggable"),
2046			uiSortable = $.extend({}, ui, { item: inst.element });
2047
2048		$.each(inst.sortables, function() {
2049			if(this.instance.isOver) {
2050
2051				this.instance.isOver = 0;
2052
2053				inst.cancelHelperRemoval = true; //Don't remove the helper in the draggable instance
2054				this.instance.cancelHelperRemoval = false; //Remove it in the sortable instance (so sortable plugins like revert still work)
2055
2056				//The sortable revert is supported, and we have to set a temporary dropped variable on the draggable to support revert: 'valid/invalid'
2057				if(this.shouldRevert) this.instance.options.revert = true;
2058
2059				//Trigger the stop of the sortable
2060				this.instance._mouseStop(event);
2061
2062				this.instance.options.helper = this.instance.options._helper;
2063
2064				//If the helper has been the original item, restore properties in the sortable
2065				if(inst.options.helper == 'original')
2066					this.instance.currentItem.css({ top: 'auto', left: 'auto' });
2067
2068			} else {
2069				this.instance.cancelHelperRemoval = false; //Remove the helper in the sortable instance
2070				this.instance._trigger("deactivate", event, uiSortable);
2071			}
2072
2073		});
2074
2075	},
2076	drag: function(event, ui) {
2077
2078		var inst = $(this).data("draggable"), that = this;
2079
2080		var checkPos = function(o) {
2081			var dyClick = this.offset.click.top, dxClick = this.offset.click.left;
2082			var helperTop = this.positionAbs.top, helperLeft = this.positionAbs.left;
2083			var itemHeight = o.height, itemWidth = o.width;
2084			var itemTop = o.top, itemLeft = o.left;
2085
2086			return $.ui.isOver(helperTop + dyClick, helperLeft + dxClick, itemTop, itemLeft, itemHeight, itemWidth);
2087		};
2088
2089		$.each(inst.sortables, function(i) {
2090
2091			var innermostIntersecting = false;
2092			var thisSortable = this;
2093			//Copy over some variables to allow calling the sortable's native _intersectsWith
2094			this.instance.positionAbs = inst.positionAbs;
2095			this.instance.helperProportions = inst.helperProportions;
2096			this.instance.offset.click = inst.offset.click;
2097
2098			if(this.instance._intersectsWith(this.instance.containerCache)) {
2099				innermostIntersecting = true;
2100				$.each(inst.sortables, function () {
2101					this.instance.positionAbs = inst.positionAbs;
2102					this.instance.helperProportions = inst.helperProportions;
2103					this.instance.offset.click = inst.offset.click;
2104					if  (this != thisSortable
2105						&& this.instance._intersectsWith(this.instance.containerCache)
2106						&& $.ui.contains(thisSortable.instance.element[0], this.instance.element[0]))
2107						innermostIntersecting = false;
2108						return innermostIntersecting;
2109				});
2110			}
2111
2112
2113			if(innermostIntersecting) {
2114				//If it intersects, we use a little isOver variable and set it once, so our move-in stuff gets fired only once
2115				if(!this.instance.isOver) {
2116
2117					this.instance.isOver = 1;
2118					//Now we fake the start of dragging for the sortable instance,
2119					//by cloning the list group item, appending it to the sortable and using it as inst.currentItem
2120					//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)
2121					this.instance.currentItem = $(that).clone().removeAttr('id').appendTo(this.instance.element).data("sortable-item", true);
2122					this.instance.options._helper = this.instance.options.helper; //Store helper option to later restore it
2123					this.instance.options.helper = function() { return ui.helper[0]; };
2124
2125					event.target = this.instance.currentItem[0];
2126					this.instance._mouseCapture(event, true);
2127					this.instance._mouseStart(event, true, true);
2128
2129					//Because the browser event is way off the new appended portlet, we modify a couple of variables to reflect the changes
2130					this.instance.offset.click.top = inst.offset.click.top;
2131					this.instance.offset.click.left = inst.offset.click.left;
2132					this.instance.offset.parent.left -= inst.offset.parent.left - this.instance.offset.parent.left;
2133					this.instance.offset.parent.top -= inst.offset.parent.top - this.instance.offset.parent.top;
2134
2135					inst._trigger("toSortable", event);
2136					inst.dropped = this.instance.element; //draggable revert needs that
2137					//hack so receive/update callbacks work (mostly)
2138					inst.currentItem = inst.element;
2139					this.instance.fromOutside = inst;
2140
2141				}
2142
2143				//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
2144				if(this.instance.currentItem) this.instance._mouseDrag(event);
2145
2146			} else {
2147
2148				//If it doesn't intersect with the sortable, and it intersected before,
2149				//we fake the drag stop of the sortable, but make sure it doesn't remove the helper by using cancelHelperRemoval
2150				if(this.instance.isOver) {
2151
2152					this.instance.isOver = 0;
2153					this.instance.cancelHelperRemoval = true;
2154
2155					//Prevent reverting on this forced stop
2156					this.instance.options.revert = false;
2157
2158					// The out event needs to be triggered independently
2159					this.instance._trigger('out', event, this.instance._uiHash(this.instance));
2160
2161					this.instance._mouseStop(event, true);
2162					this.instance.options.helper = this.instance.options._helper;
2163
2164					//Now we remove our currentItem, the list group clone again, and the placeholder, and animate the helper back to it's original size
2165					this.instance.currentItem.remove();
2166					if(this.instance.placeholder) this.instance.placeholder.remove();
2167
2168					inst._trigger("fromSortable", event);
2169					inst.dropped = false; //draggable revert needs that
2170				}
2171
2172			};
2173
2174		});
2175
2176	}
2177});
2178
2179$.ui.plugin.add("draggable", "cursor", {
2180	start: function(event, ui) {
2181		var t = $('body'), o = $(this).data('draggable').options;
2182		if (t.css("cursor")) o._cursor = t.css("cursor");
2183		t.css("cursor", o.cursor);
2184	},
2185	stop: function(event, ui) {
2186		var o = $(this).data('draggable').options;
2187		if (o._cursor) $('body').css("cursor", o._cursor);
2188	}
2189});
2190
2191$.ui.plugin.add("draggable", "opacity", {
2192	start: function(event, ui) {
2193		var t = $(ui.helper), o = $(this).data('draggable').options;
2194		if(t.css("opacity")) o._opacity = t.css("opacity");
2195		t.css('opacity', o.opacity);
2196	},
2197	stop: function(event, ui) {
2198		var o = $(this).data('draggable').options;
2199		if(o._opacity) $(ui.helper).css('opacity', o._opacity);
2200	}
2201});
2202
2203$.ui.plugin.add("draggable", "scroll", {
2204	start: function(event, ui) {
2205		var i = $(this).data("draggable");
2206		if(i.scrollParent[0] != document && i.scrollParent[0].tagName != 'HTML') i.overflowOffset = i.scrollParent.offset();
2207	},
2208	drag: function(event, ui) {
2209
2210		var i = $(this).data("draggable"), o = i.options, scrolled = false;
2211
2212		if(i.scrollParent[0] != document && i.scrollParent[0].tagName != 'HTML') {
2213
2214			if(!o.axis || o.axis != 'x') {
2215				if((i.overflowOffset.top + i.scrollParent[0].offsetHeight) - event.pageY < o.scrollSensitivity)
2216					i.scrollParent[0].scrollTop = scrolled = i.scrollParent[0].scrollTop + o.scrollSpeed;
2217				else if(event.pageY - i.overflowOffset.top < o.scrollSensitivity)
2218					i.scrollParent[0].scrollTop = scrolled = i.scrollParent[0].scrollTop - o.scrollSpeed;
2219			}
2220
2221			if(!o.axis || o.axis != 'y') {
2222				if((i.overflowOffset.left + i.scrollParent[0].offsetWidth) - event.pageX < o.scrollSensitivity)
2223					i.scrollParent[0].scrollLeft = scrolled = i.scrollParent[0].scrollLeft + o.scrollSpeed;
2224				else if(event.pageX - i.overflowOffset.left < o.scrollSensitivity)
2225					i.scrollParent[0].scrollLeft = scrolled = i.scrollParent[0].scrollLeft - o.scrollSpeed;
2226			}
2227
2228		} else {
2229
2230			if(!o.axis || o.axis != 'x') {
2231				if(event.pageY - $(document).scrollTop() < o.scrollSensitivity)
2232					scrolled = $(document).scrollTop($(document).scrollTop() - o.scrollSpeed);
2233				else if($(window).height() - (event.pageY - $(document).scrollTop()) < o.scrollSensitivity)
2234					scrolled = $(document).scrollTop($(document).scrollTop() + o.scrollSpeed);
2235			}
2236
2237			if(!o.axis || o.axis != 'y') {
2238				if(event.pageX - $(document).scrollLeft() < o.scrollSensitivity)
2239					scrolled = $(document).scrollLeft($(document).scrollLeft() - o.scrollSpeed);
2240				else if($(window).width() - (event.pageX - $(document).scrollLeft()) < o.scrollSensitivity)
2241					scrolled = $(document).scrollLeft($(document).scrollLeft() + o.scrollSpeed);
2242			}
2243
2244		}
2245
2246		if(scrolled !== false && $.ui.ddmanager && !o.dropBehaviour)
2247			$.ui.ddmanager.prepareOffsets(i, event);
2248
2249	}
2250});
2251
2252$.ui.plugin.add("draggable", "snap", {
2253	start: function(event, ui) {
2254
2255		var i = $(this).data("draggable"), o = i.options;
2256		i.snapElements = [];
2257
2258		$(o.snap.constructor != String ? ( o.snap.items || ':data(draggable)' ) : o.snap).each(function() {
2259			var $t = $(this); var $o = $t.offset();
2260			if(this != i.element[0]) i.snapElements.push({
2261				item: this,
2262				width: $t.outerWidth(), height: $t.outerHeight(),
2263				top: $o.top, left: $o.left
2264			});
2265		});
2266
2267	},
2268	drag: function(event, ui) {
2269
2270		var inst = $(this).data("draggable"), o = inst.options;
2271		var d = o.snapTolerance;
2272
2273		var x1 = ui.offset.left, x2 = x1 + inst.helperProportions.width,
2274			y1 = ui.offset.top, y2 = y1 + inst.helperProportions.height;
2275
2276		for (var i = inst.snapElements.length - 1; i >= 0; i--){
2277
2278			var l = inst.snapElements[i].left, r = l + inst.snapElements[i].width,
2279				t = inst.snapElements[i].top, b = t + inst.snapElements[i].height;
2280
2281			//Yes, I know, this is insane ;)
2282			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))) {
2283				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 })));
2284				inst.snapElements[i].snapping = false;
2285				continue;
2286			}
2287
2288			if(o.snapMode != 'inner') {
2289				var ts = Math.abs(t - y2) <= d;
2290				var bs = Math.abs(b - y1) <= d;
2291				var ls = Math.abs(l - x2) <= d;
2292				var rs = Math.abs(r - x1) <= d;
2293				if(ts) ui.position.top = inst._convertPositionTo("relative", { top: t - inst.helperProportions.height, left: 0 }).top - inst.margins.top;
2294				if(bs) ui.position.top = inst._convertPositionTo("relative", { top: b, left: 0 }).top - inst.margins.top;
2295				if(ls) ui.position.left = inst._convertPositionTo("relative", { top: 0, left: l - inst.helperProportions.width }).left - inst.margins.left;
2296				if(rs) ui.position.left = inst._convertPositionTo("relative", { top: 0, left: r }).left - inst.margins.left;
2297			}
2298
2299			var first = (ts || bs || ls || rs);
2300
2301			if(o.snapMode != 'outer') {
2302				var ts = Math.abs(t - y1) <= d;
2303				var bs = Math.abs(b - y2) <= d;
2304				var ls = Math.abs(l - x1) <= d;
2305				var rs = Math.abs(r - x2) <= d;
2306				if(ts) ui.position.top = inst._convertPositionTo("relative", { top: t, left: 0 }).top - inst.margins.top;
2307				if(bs) ui.position.top = inst._convertPositionTo("relative", { top: b - inst.helperProportions.height, left: 0 }).top - inst.margins.top;
2308				if(ls) ui.position.left = inst._convertPositionTo("relative", { top: 0, left: l }).left - inst.margins.left;
2309				if(rs) ui.position.left = inst._convertPositionTo("relative", { top: 0, left: r - inst.helperProportions.width }).left - inst.margins.left;
2310			}
2311
2312			if(!inst.snapElements[i].snapping && (ts || bs || ls || rs || first))
2313				(inst.options.snap.snap && inst.options.snap.snap.call(inst.element, event, $.extend(inst._uiHash(), { snapItem: inst.snapElements[i].item })));
2314			inst.snapElements[i].snapping = (ts || bs || ls || rs || first);
2315
2316		};
2317
2318	}
2319});
2320
2321$.ui.plugin.add("draggable", "stack", {
2322	start: function(event, ui) {
2323
2324		var o = $(this).data("draggable").options;
2325
2326		var group = $.makeArray($(o.stack)).sort(function(a,b) {
2327			return (parseInt($(a).css("zIndex"),10) || 0) - (parseInt($(b).css("zIndex"),10) || 0);
2328		});
2329		if (!group.length) { return; }
2330
2331		var min = parseInt(group[0].style.zIndex) || 0;
2332		$(group).each(function(i) {
2333			this.style.zIndex = min + i;
2334		});
2335
2336		this[0].style.zIndex = min + group.length;
2337
2338	}
2339});
2340
2341$.ui.plugin.add("draggable", "zIndex", {
2342	start: function(event, ui) {
2343		var t = $(ui.helper), o = $(this).data("draggable").options;
2344		if(t.css("zIndex")) o._zIndex = t.css("zIndex");
2345		t.css('zIndex', o.zIndex);
2346	},
2347	stop: function(event, ui) {
2348		var o = $(this).data("draggable").options;
2349		if(o._zIndex) $(ui.helper).css('zIndex', o._zIndex);
2350	}
2351});
2352
2353})(jQuery);
2354(function( $, undefined ) {
2355
2356$.widget("ui.droppable", {
2357	version: "1.9.2",
2358	widgetEventPrefix: "drop",
2359	options: {
2360		accept: '*',
2361		activeClass: false,
2362		addClasses: true,
2363		greedy: false,
2364		hoverClass: false,
2365		scope: 'default',
2366		tolerance: 'intersect'
2367	},
2368	_create: function() {
2369
2370		var o = this.options, accept = o.accept;
2371		this.isover = 0; this.isout = 1;
2372
2373		this.accept = $.isFunction(accept) ? accept : function(d) {
2374			return d.is(accept);
2375		};
2376
2377		//Store the droppable's proportions
2378		this.proportions = { width: this.element[0].offsetWidth, height: this.element[0].offsetHeight };
2379
2380		// Add the reference and positions to the manager
2381		$.ui.ddmanager.droppables[o.scope] = $.ui.ddmanager.droppables[o.scope] || [];
2382		$.ui.ddmanager.droppables[o.scope].push(this);
2383
2384		(o.addClasses && this.element.addClass("ui-droppable"));
2385
2386	},
2387
2388	_destroy: function() {
2389		var drop = $.ui.ddmanager.droppables[this.options.scope];
2390		for ( var i = 0; i < drop.length; i++ )
2391			if ( drop[i] == this )
2392				drop.splice(i, 1);
2393
2394		this.element.removeClass("ui-droppable ui-droppable-disabled");
2395	},
2396
2397	_setOption: function(key, value) {
2398
2399		if(key == 'accept') {
2400			this.accept = $.isFunction(value) ? value : function(d) {
2401				return d.is(value);
2402			};
2403		}
2404		$.Widget.prototype._setOption.apply(this, arguments);
2405	},
2406
2407	_activate: function(event) {
2408		var draggable = $.ui.ddmanager.current;
2409		if(this.options.activeClass) this.element.addClass(this.options.activeClass);
2410		(draggable && this._trigger('activate', event, this.ui(draggable)));
2411	},
2412
2413	_deactivate: function(event) {
2414		var draggable = $.ui.ddmanager.current;
2415		if(this.options.activeClass) this.element.removeClass(this.options.activeClass);
2416		(draggable && this._trigger('deactivate', event, this.ui(draggable)));
2417	},
2418
2419	_over: function(event) {
2420
2421		var draggable = $.ui.ddmanager.current;
2422		if (!draggable || (draggable.currentItem || draggable.element)[0] == this.element[0]) return; // Bail if draggable and droppable are same element
2423
2424		if (this.accept.call(this.element[0],(draggable.currentItem || draggable.element))) {
2425			if(this.options.hoverClass) this.element.addClass(this.options.hoverClass);
2426			this._trigger('over', event, this.ui(draggable));
2427		}
2428
2429	},
2430
2431	_out: function(event) {
2432
2433		var draggable = $.ui.ddmanager.current;
2434		if (!draggable || (draggable.currentItem || draggable.element)[0] == this.element[0]) return; // Bail if draggable and droppable are same element
2435
2436		if (this.accept.call(this.element[0],(draggable.currentItem || draggable.element))) {
2437			if(this.options.hoverClass) this.element.removeClass(this.options.hoverClass);
2438			this._trigger('out', event, this.ui(draggable));
2439		}
2440
2441	},
2442
2443	_drop: function(event,custom) {
2444
2445		var draggable = custom || $.ui.ddmanager.current;
2446		if (!draggable || (draggable.currentItem || draggable.element)[0] == this.element[0]) return false; // Bail if draggable and droppable are same element
2447
2448		var childrenIntersection = false;
2449		this.element.find(":data(droppable)").not(".ui-draggable-dragging").each(function() {
2450			var inst = $.data(this, 'droppable');
2451			if(
2452				inst.options.greedy
2453				&& !inst.options.disabled
2454				&& inst.options.scope == draggable.options.scope
2455				&& inst.accept.call(inst.element[0], (draggable.currentItem || draggable.element))
2456				&& $.ui.intersect(draggable, $.extend(inst, { offset: inst.element.offset() }), inst.options.tolerance)
2457			) { childrenIntersection = true; return false; }
2458		});
2459		if(childrenIntersection) return false;
2460
2461		if(this.accept.call(this.element[0],(draggable.currentItem || draggable.element))) {
2462			if(this.options.activeClass) this.element.removeClass(this.options.activeClass);
2463			if(this.options.hoverClass) this.element.removeClass(this.options.hoverClass);
2464			this._trigger('drop', event, this.ui(draggable));
2465			return this.element;
2466		}
2467
2468		return false;
2469
2470	},
2471
2472	ui: function(c) {
2473		return {
2474			draggable: (c.currentItem || c.element),
2475			helper: c.helper,
2476			position: c.position,
2477			offset: c.positionAbs
2478		};
2479	}
2480
2481});
2482
2483$.ui.intersect = function(draggable, droppable, toleranceMode) {
2484
2485	if (!droppable.offset) return false;
2486
2487	var x1 = (draggable.positionAbs || draggable.position.absolute).left, x2 = x1 + draggable.helperProportions.width,
2488		y1 = (draggable.positionAbs || draggable.position.absolute).top, y2 = y1 + draggable.helperProportions.height;
2489	var l = droppable.offset.left, r = l + droppable.proportions.width,
2490		t = droppable.offset.top, b = t + droppable.proportions.height;
2491
2492	switch (toleranceMode) {
2493		case 'fit':
2494			return (l <= x1 && x2 <= r
2495				&& t <= y1 && y2 <= b);
2496			break;
2497		case 'intersect':
2498			return (l < x1 + (draggable.helperProportions.width / 2) // Right Half
2499				&& x2 - (draggable.helperProportions.width / 2) < r // Left Half
2500				&& t < y1 + (draggable.helperProportions.height / 2) // Bottom Half
2501				&& y2 - (draggable.helperProportions.height / 2) < b ); // Top Half
2502			break;
2503		case 'pointer':
2504			var draggableLeft = ((draggable.positionAbs || draggable.position.absolute).left + (draggable.clickOffset || draggable.offset.click).left),
2505				draggableTop = ((draggable.positionAbs || draggable.position.absolute).top + (draggable.clickOffset || draggable.offset.click).top),
2506				isOver = $.ui.isOver(draggableTop, draggableLeft, t, l, droppable.proportions.height, droppable.proportions.width);
2507			return isOver;
2508			break;
2509		case 'touch':
2510			return (
2511					(y1 >= t && y1 <= b) ||	// Top edge touching
2512					(y2 >= t && y2 <= b) ||	// Bottom edge touching
2513					(y1 < t && y2 > b)		// Surrounded vertically
2514				) && (
2515					(x1 >= l && x1 <= r) ||	// Left edge touching
2516					(x2 >= l && x2 <= r) ||	// Right edge touching
2517					(x1 < l && x2 > r)		// Surrounded horizontally
2518				);
2519			break;
2520		default:
2521			return false;
2522			break;
2523		}
2524
2525};
2526
2527/*
2528	This manager tracks offsets of draggables and droppables
2529*/
2530$.ui.ddmanager = {
2531	current: null,
2532	droppables: { 'default': [] },
2533	prepareOffsets: function(t, event) {
2534
2535		var m = $.ui.ddmanager.droppables[t.options.scope] || [];
2536		var type = event ? event.type : null; // workaround for #2317
2537		var list = (t.currentItem || t.element).find(":data(droppable)").andSelf();
2538
2539		droppablesLoop: for (var i = 0; i < m.length; i++) {
2540
2541			if(m[i].options.disabled || (t && !m[i].accept.call(m[i].element[0],(t.currentItem || t.element)))) continue;	//No disabled and non-accepted
2542			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
2543			m[i].visible = m[i].element.css("display") != "none"; if(!m[i].visible) continue; 									//If the element is not visible, continue
2544
2545			if(type == "mousedown") m[i]._activate.call(m[i], event); //Activate the droppable if used directly from draggables
2546
2547			m[i].offset = m[i].element.offset();
2548			m[i].proportions = { width: m[i].element[0].offsetWidth, height: m[i].element[0].offsetHeight };
2549
2550		}
2551
2552	},
2553	drop: function(draggable, event) {
2554
2555		var dropped = false;
2556		$.each($.ui.ddmanager.droppables[draggable.options.scope] || [], function() {
2557
2558			if(!this.options) return;
2559			if (!this.options.disabled && this.visible && $.ui.intersect(draggable, this, this.options.tolerance))
2560				dropped = this._drop.call(this, event) || dropped;
2561
2562			if (!this.options.disabled && this.visible && this.accept.call(this.element[0],(draggable.currentItem || draggable.element))) {
2563				this.isout = 1; this.isover = 0;
2564				this._deactivate.call(this, event);
2565			}
2566
2567		});
2568		return dropped;
2569
2570	},
2571	dragStart: function( draggable, event ) {
2572		//Listen for scrolling so that if the dragging causes scrolling the position of the droppables can be recalculated (see #5003)
2573		draggable.element.parentsUntil( "body" ).bind( "scroll.droppable", function() {
2574			if( !draggable.options.refreshPositions ) $.ui.ddmanager.prepareOffsets( draggable, event );
2575		});
2576	},
2577	drag: function(draggable, event) {
2578
2579		//If you have a highly dynamic page, you might try this option. It renders positions every time you move the mouse.
2580		if(draggable.options.refreshPositions) $.ui.ddmanager.prepareOffsets(draggable, event);
2581
2582		//Run through all droppables and check their positions based on specific tolerance options
2583		$.each($.ui.ddmanager.droppables[draggable.options.scope] || [], function() {
2584
2585			if(this.options.disabled || this.greedyChild || !this.visible) return;
2586			var intersects = $.ui.intersect(draggable, this, this.options.tolerance);
2587
2588			var c = !intersects && this.isover == 1 ? 'isout' : (intersects && this.isover == 0 ? 'isover' : null);
2589			if(!c) return;
2590
2591			var parentInstance;
2592			if (this.options.greedy) {
2593				// find droppable parents with same scope
2594				var scope = this.options.scope;
2595				var parent = this.element.parents(':data(droppable)').filter(function () {
2596					return $.data(this, 'droppable').options.scope === scope;
2597				});
2598
2599				if (parent.length) {
2600					parentInstance = $.data(parent[0], 'droppable');
2601					parentInstance.greedyChild = (c == 'isover' ? 1 : 0);
2602				}
2603			}
2604
2605			// we just moved into a greedy child
2606			if (parentInstance && c == 'isover') {
2607				parentInstance['isover'] = 0;
2608				parentInstance['isout'] = 1;
2609				parentInstance._out.call(parentInstance, event);
2610			}
2611
2612			this[c] = 1; this[c == 'isout' ? 'isover' : 'isout'] = 0;
2613			this[c == "isover" ? "_over" : "_out"].call(this, event);
2614
2615			// we just moved out of a greedy child
2616			if (parentInstance && c == 'isout') {
2617				parentInstance['isout'] = 0;
2618				parentInstance['isover'] = 1;
2619				parentInstance._over.call(parentInstance, event);
2620			}
2621		});
2622
2623	},
2624	dragStop: function( draggable, event ) {
2625		draggable.element.parentsUntil( "body" ).unbind( "scroll.droppable" );
2626		//Call prepareOffsets one final time since IE does not fire return scroll events when overflow was caused by drag (see #5003)
2627		if( !draggable.options.refreshPositions ) $.ui.ddmanager.prepareOffsets( draggable, event );
2628	}
2629};
2630
2631})(jQuery);
2632(function( $, undefined ) {
2633
2634$.widget("ui.resizable", $.ui.mouse, {
2635	version: "1.9.2",
2636	widgetEventPrefix: "resize",
2637	options: {
2638		alsoResize: false,
2639		animate: false,
2640		animateDuration: "slow",
2641		animateEasing: "swing",
2642		aspectRatio: false,
2643		autoHide: false,
2644		containment: false,
2645		ghost: false,
2646		grid: false,
2647		handles: "e,s,se",
2648		helper: false,
2649		maxHeight: null,
2650		maxWidth: null,
2651		minHeight: 10,
2652		minWidth: 10,
2653		zIndex: 1000
2654	},
2655	_create: function() {
2656
2657		var that = this, o = this.options;
2658		this.element.addClass("ui-resizable");
2659
2660		$.extend(this, {
2661			_aspectRatio: !!(o.aspectRatio),
2662			aspectRatio: o.aspectRatio,
2663			originalElement: this.element,
2664			_proportionallyResizeElements: [],
2665			_helper: o.helper || o.ghost || o.animate ? o.helper || 'ui-resizable-helper' : null
2666		});
2667
2668		//Wrap the element if it cannot hold child nodes
2669		if(this.element[0].nodeName.match(/canvas|textarea|input|select|button|img/i)) {
2670
2671			//Create a wrapper element and set the wrapper to the new current internal element
2672			this.element.wrap(
2673				$('<div class="ui-wrapper" style="overflow: hidden;"></div>').css({
2674					position: this.element.css('position'),
2675					width: this.element.outerWidth(),
2676					height: this.element.outerHeight(),
2677					top: this.element.css('top'),
2678					left: this.element.css('left')
2679				})
2680			);
2681
2682			//Overwrite the original this.element
2683			this.element = this.element.parent().data(
2684				"resizable", this.element.data('resizable')
2685			);
2686
2687			this.elementIsWrapper = true;
2688
2689			//Move margins to the wrapper
2690			this.element.css({ marginLeft: this.originalElement.css("marginLeft"), marginTop: this.originalElement.css("marginTop"), marginRight: this.originalElement.css("marginRight"), marginBottom: this.originalElement.css("marginBottom") });
2691			this.originalElement.css({ marginLeft: 0, marginTop: 0, marginRight: 0, marginBottom: 0});
2692
2693			//Prevent Safari textarea resize
2694			this.originalResizeStyle = this.originalElement.css('resize');
2695			this.originalElement.css('resize', 'none');
2696
2697			//Push the actual element to our proportionallyResize internal array
2698			this._proportionallyResizeElements.push(this.originalElement.css({ position: 'static', zoom: 1, display: 'block' }));
2699
2700			// avoid IE jump (hard set the margin)
2701			this.originalElement.css({ margin: this.originalElement.css('margin') });
2702
2703			// fix handlers offset
2704			this._proportionallyResize();
2705
2706		}
2707
2708		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' });
2709		if(this.handles.constructor == String) {
2710
2711			if(this.handles == 'all') this.handles = 'n,e,s,w,se,sw,ne,nw';
2712			var n = this.handles.split(","); this.handles = {};
2713
2714			for(var i = 0; i < n.length; i++) {
2715
2716				var handle = $.trim(n[i]), hname = 'ui-resizable-'+handle;
2717				var axis = $('<div class="ui-resizable-handle ' + hname + '"></div>');
2718
2719				// Apply zIndex to all handles - see #7960
2720				axis.css({ zIndex: o.zIndex });
2721
2722				//TODO : What's going on here?
2723				if ('se' == handle) {
2724					axis.addClass('ui-icon ui-icon-gripsmall-diagonal-se');
2725				};
2726
2727				//Insert into internal handles object and append to element
2728				this.handles[handle] = '.ui-resizable-'+handle;
2729				this.element.append(axis);
2730			}
2731
2732		}
2733
2734		this._renderAxis = function(target) {
2735
2736			target = target || this.element;
2737
2738			for(var i in this.handles) {
2739
2740				if(this.handles[i].constructor == String)
2741					this.handles[i] = $(this.handles[i], this.element).show();
2742
2743				//Apply pad to wrapper element, needed to fix axis position (textarea, inputs, scrolls)
2744				if (this.elementIsWrapper && this.originalElement[0].nodeName.match(/textarea|input|select|button/i)) {
2745
2746					var axis = $(this.handles[i], this.element), padWrapper = 0;
2747
2748					//Checking the correct pad and border
2749					padWrapper = /sw|ne|nw|se|n|s/.test(i) ? axis.outerHeight() : axis.outerWidth();
2750
2751					//The padding type i have to apply...
2752					var padPos = [ 'padding',
2753						/ne|nw|n/.test(i) ? 'Top' :
2754						/se|sw|s/.test(i) ? 'Bottom' :
2755						/^e$/.test(i) ? 'Right' : 'Left' ].join("");
2756
2757					target.css(padPos, padWrapper);
2758
2759					this._proportionallyResize();
2760
2761				}
2762
2763				//TODO: What's that good for? There's not anything to be executed left
2764				if(!$(this.handles[i]).length)
2765					continue;
2766
2767			}
2768		};
2769
2770		//TODO: make renderAxis a prototype function
2771		this._renderAxis(this.element);
2772
2773		this._handles = $('.ui-resizable-handle', this.element)
2774			.disableSelection();
2775
2776		//Matching axis name
2777		this._handles.mouseover(function() {
2778			if (!that.resizing) {
2779				if (this.className)
2780					var axis = this.className.match(/ui-resizable-(se|sw|ne|nw|n|e|s|w)/i);
2781				//Axis, default = se
2782				that.axis = axis && axis[1] ? axis[1] : 'se';
2783			}
2784		});
2785
2786		//If we want to auto hide the elements
2787		if (o.autoHide) {
2788			this._handles.hide();
2789			$(this.element)
2790				.addClass("ui-resizable-autohide")
2791				.mouseenter(function() {
2792					if (o.disabled) return;
2793					$(this).removeClass("ui-resizable-autohide");
2794					that._handles.show();
2795				})
2796				.mouseleave(function(){
2797					if (o.disabled) return;
2798					if (!that.resizing) {
2799						$(this).addClass("ui-resizable-autohide");
2800						that._handles.hide();
2801					}
2802				});
2803		}
2804
2805		//Initialize the mouse interaction
2806		this._mouseInit();
2807
2808	},
2809
2810	_destroy: function() {
2811
2812		this._mouseDestroy();
2813
2814		var _destroy = function(exp) {
2815			$(exp).removeClass("ui-resizable ui-resizable-disabled ui-resizable-resizing")
2816				.removeData("resizable").removeData("ui-resizable").unbind(".resizable").find('.ui-resizable-handle').remove();
2817		};
2818
2819		//TODO: Unwrap at same DOM position
2820		if (this.elementIsWrapper) {
2821			_destroy(this.element);
2822			var wrapper = this.element;
2823			this.originalElement.css({
2824				position: wrapper.css('position'),
2825				width: wrapper.outerWidth(),
2826				height: wrapper.outerHeight(),
2827				top: wrapper.css('top'),
2828				left: wrapper.css('left')
2829			}).insertAfter( wrapper );
2830			wrapper.remove();
2831		}
2832
2833		this.originalElement.css('resize', this.originalResizeStyle);
2834		_destroy(this.originalElement);
2835
2836		return this;
2837	},
2838
2839	_mouseCapture: function(event) {
2840		var handle = false;
2841		for (var i in this.handles) {
2842			if ($(this.handles[i])[0] == event.target) {
2843				handle = true;
2844			}
2845		}
2846
2847		return !this.options.disabled && handle;
2848	},
2849
2850	_mouseStart: function(event) {
2851
2852		var o = this.options, iniPos = this.element.position(), el = this.element;
2853
2854		this.resizing = true;
2855		this.documentScroll = { top: $(document).scrollTop(), left: $(document).scrollLeft() };
2856
2857		// bugfix for http://dev.jquery.com/ticket/1749
2858		if (el.is('.ui-draggable') || (/absolute/).test(el.css('position'))) {
2859			el.css({ position: 'absolute', top: iniPos.top, left: iniPos.left });
2860		}
2861
2862		this._renderProxy();
2863
2864		var curleft = num(this.helper.css('left')), curtop = num(this.helper.css('top'));
2865
2866		if (o.containment) {
2867			curleft += $(o.containment).scrollLeft() || 0;
2868			curtop += $(o.containment).scrollTop() || 0;
2869		}
2870
2871		//Store needed variables
2872		this.offset = this.helper.offset();
2873		this.position = { left: curleft, top: curtop };
2874		this.size = this._helper ? { width: el.outerWidth(), height: el.outerHeight() } : { width: el.width(), height: el.height() };
2875		this.originalSize = this._helper ? { width: el.outerWidth(), height: el.outerHeight() } : { width: el.width(), height: el.height() };
2876		this.originalPosition = { left: curleft, top: curtop };
2877		this.sizeDiff = { width: el.outerWidth() - el.width(), height: el.outerHeight() - el.height() };
2878		this.originalMousePosition = { left: event.pageX, top: event.pageY };
2879
2880		//Aspect Ratio
2881		this.aspectRatio = (typeof o.aspectRatio == 'number') ? o.aspectRatio : ((this.originalSize.width / this.originalSize.height) || 1);
2882
2883		var cursor = $('.ui-resizable-' + this.axis).css('cursor');
2884		$('body').css('cursor', cursor == 'auto' ? this.axis + '-resize' : cursor);
2885
2886		el.addClass("ui-resizable-resizing");
2887		this._propagate("start", event);
2888		return true;
2889	},
2890
2891	_mouseDrag: function(event) {
2892
2893		//Increase performance, avoid regex
2894		var el = this.helper, o = this.options, props = {},
2895			that = this, smp = this.originalMousePosition, a = this.axis;
2896
2897		var dx = (event.pageX-smp.left)||0, dy = (event.pageY-smp.top)||0;
2898		var trigger = this._change[a];
2899		if (!trigger) return false;
2900
2901		// Calculate the attrs that will be change
2902		var data = trigger.apply(this, [event, dx, dy]);
2903
2904		// Put this in the mouseDrag handler since the user can start pressing shift while resizing
2905		this._updateVirtualBoundaries(event.shiftKey);
2906		if (this._aspectRatio || event.shiftKey)
2907			data = this._updateRatio(data, event);
2908
2909		data = this._respectSize(data, event);
2910
2911		// plugins callbacks need to be called first
2912		this._propagate("resize", event);
2913
2914		el.css({
2915			top: this.position.top + "px", left: this.position.left + "px",
2916			width: this.size.width + "px", height: this.size.height + "px"
2917		});
2918
2919		if (!this._helper && this._proportionallyResizeElements.length)
2920			this._proportionallyResize();
2921
2922		this._updateCache(data);
2923
2924		// calling the user callback at the end
2925		this._trigger('resize', event, this.ui());
2926
2927		return false;
2928	},
2929
2930	_mouseStop: function(event) {
2931
2932		this.resizing = false;
2933		var o = this.options, that = this;
2934
2935		if(this._helper) {
2936			var pr = this._proportionallyResizeElements, ista = pr.length && (/textarea/i).test(pr[0].nodeName),
2937				soffseth = ista && $.ui.hasScroll(pr[0], 'left') /* TODO - jump height */ ? 0 : that.sizeDiff.height,
2938				soffsetw = ista ? 0 : that.sizeDiff.width;
2939
2940			var s = { width: (that.helper.width()  - soffsetw), height: (that.helper.height() - soffseth) },
2941				left = (parseInt(that.element.css('left'), 10) + (that.position.left - that.originalPosition.left)) || null,
2942				top = (parseInt(that.element.css('top'), 10) + (that.position.top - that.originalPosition.top)) || null;
2943
2944			if (!o.animate)
2945				this.element.css($.extend(s, { top: top, left: left }));
2946
2947			that.helper.height(that.size.height);
2948			that.helper.width(that.size.width);
2949
2950			if (this._helper && !o.animate) this._proportionallyResize();
2951		}
2952
2953		$('body').css('cursor', 'auto');
2954
2955		this.element.removeClass("ui-resizable-resizing");
2956
2957		this._propagate("stop", event);
2958
2959		if (this._helper) this.helper.remove();
2960		return false;
2961
2962	},
2963
2964	_updateVirtualBoundaries: function(forceAspectRatio) {
2965		var o = this.options, pMinWidth, pMaxWidth, pMinHeight, pMaxHeight, b;
2966
2967		b = {
2968			minWidth: isNumber(o.minWidth) ? o.minWidth : 0,
2969			maxWidth: isNumber(o.maxWidth) ? o.maxWidth : Infinity,
2970			minHeight: isNumber(o.minHeight) ? o.minHeight : 0,
2971			maxHeight: isNumber(o.maxHeight) ? o.maxHeight : Infinity
2972		};
2973
2974		if(this._aspectRatio || forceAspectRatio) {
2975			// We want to create an enclosing box whose aspect ration is the requested one
2976			// First, compute the "projected" size for each dimension based on the aspect ratio and other dimension
2977			pMinWidth = b.minHeight * this.aspectRatio;
2978			pMinHeight = b.minWidth / this.aspectRatio;
2979			pMaxWidth = b.maxHeight * this.aspectRatio;
2980			pMaxHeight = b.maxWidth / this.aspectRatio;
2981
2982			if(pMinWidth > b.minWidth) b.minWidth = pMinWidth;
2983			if(pMinHeight > b.minHeight) b.minHeight = pMinHeight;
2984			if(pMaxWidth < b.maxWidth) b.maxWidth = pMaxWidth;
2985			if(pMaxHeight < b.maxHeight) b.maxHeight = pMaxHeight;
2986		}
2987		this._vBoundaries = b;
2988	},
2989
2990	_updateCache: function(data) {
2991		var o = this.options;
2992		this.offset = this.helper.offset();
2993		if (isNumber(data.left)) this.position.left = data.left;
2994		if (isNumber(data.top)) this.position.top = data.top;
2995		if (isNumber(data.height)) this.size.height = data.height;
2996		if (isNumber(data.width)) this.size.width = data.width;
2997	},
2998
2999	_updateRatio: function(data, event) {
3000
3001		var o = this.options, cpos = this.position, csize = this.size, a = this.axis;
3002
3003		if (isNumber(data.height)) data.width = (data.height * this.aspectRatio);
3004		else if (isNumber(data.width)) data.height = (data.width / this.aspectRatio);
3005
3006		if (a == 'sw') {
3007			data.left = cpos.left + (csize.width - data.width);
3008			data.top = null;
3009		}
3010		if (a == 'nw') {
3011			data.top = cpos.top + (csize.height - data.height);
3012			data.left = cpos.left + (csize.width - data.width);
3013		}
3014
3015		return data;
3016	},
3017
3018	_respectSize: function(data, event) {
3019
3020		var el = this.helper, o = this._vBoundaries, pRatio = this._aspectRatio || event.shiftKey, a = this.axis,
3021				ismaxw = isNumber(data.width) && o.maxWidth && (o.maxWidth < data.width), ismaxh = isNumber(data.height) && o.maxHeight && (o.maxHeight < data.height),
3022					isminw = isNumber(data.width) && o.minWidth && (o.minWidth > data.width), isminh = isNumber(data.height) && o.minHeight && (o.minHeight > data.height);
3023
3024		if (isminw) data.width = o.minWidth;
3025		if (isminh) data.height = o.minHeight;
3026		if (ismaxw) data.width = o.maxWidth;
3027		if (ismaxh) data.height = o.maxHeight;
3028
3029		var dw = this.originalPosition.left + this.originalSize.width, dh = this.position.top + this.size.height;
3030		var cw = /sw|nw|w/.test(a), ch = /nw|ne|n/.test(a);
3031
3032		if (isminw && cw) data.left = dw - o.minWidth;
3033		if (ismaxw && cw) data.left = dw - o.maxWidth;
3034		if (isminh && ch)	data.top = dh - o.minHeight;
3035		if (ismaxh && ch)	data.top = dh - o.maxHeight;
3036
3037		// fixing jump error on top/left - bug #2330
3038		var isNotwh = !data.width && !data.height;
3039		if (isNotwh && !data.left && data.top) data.top = null;
3040		else if (isNotwh && !data.top && data.left) data.left = null;
3041
3042		return data;
3043	},
3044
3045	_proportionallyResize: function() {
3046
3047		var o = this.options;
3048		if (!this._proportionallyResizeElements.length) return;
3049		var element = this.helper || this.element;
3050
3051		for (var i=0; i < this._proportionallyResizeElements.length; i++) {
3052
3053			var prel = this._proportionallyResizeElements[i];
3054
3055			if (!this.borderDif) {
3056				var b = [prel.css('borderTopWidth'), prel.css('borderRightWidth'), prel.css('borderBottomWidth'), prel.css('borderLeftWidth')],
3057					p = [prel.css('paddingTop'), prel.css('paddingRight'), prel.css('paddingBottom'), prel.css('paddingLeft')];
3058
3059				this.borderDif = $.map(b, function(v, i) {
3060					var border = parseInt(v,10)||0, padding = parseInt(p[i],10)||0;
3061					return border + padding;
3062				});
3063			}
3064
3065			prel.css({
3066				height: (element.height() - this.borderDif[0] - this.borderDif[2]) || 0,
3067				width: (element.width() - this.borderDif[1] - this.borderDif[3]) || 0
3068			});
3069
3070		};
3071
3072	},
3073
3074	_renderProxy: function() {
3075
3076		var el = this.element, o = this.options;
3077		this.elementOffset = el.offset();
3078
3079		if(this._helper) {
3080
3081			this.helper = this.helper || $('<div style="overflow:hidden;"></div>');
3082
3083			// fix ie6 offset TODO: This seems broken
3084			var ie6offset = ($.ui.ie6 ? 1 : 0),
3085			pxyoffset = ( $.ui.ie6 ? 2 : -1 );
3086
3087			this.helper.addClass(this._helper).css({
3088				width: this.element.outerWidth() + pxyoffset,
3089				height: this.element.outerHeight() + pxyoffset,
3090				position: 'absolute',
3091				left: this.elementOffset.left - ie6offset +'px',
3092				top: this.elementOffset.top - ie6offset +'px',
3093				zIndex: ++o.zIndex //TODO: Don't modify option
3094			});
3095
3096			this.helper
3097				.appendTo("body")
3098				.disableSelection();
3099
3100		} else {
3101			this.helper = this.element;
3102		}
3103
3104	},
3105
3106	_change: {
3107		e: function(event, dx, dy) {
3108			return { width: this.originalSize.width + dx };
3109		},
3110		w: function(event, dx, dy) {
3111			var o = this.options, cs = this.originalSize, sp = this.originalPosition;
3112			return { left: sp.left + dx, width: cs.width - dx };
3113		},
3114		n: function(event, dx, dy) {
3115			var o = this.options, cs = this.originalSize, sp = this.originalPosition;
3116			return { top: sp.top + dy, height: cs.height - dy };
3117		},
3118		s: function(event, dx, dy) {
3119			return { height: this.originalSize.height + dy };
3120		},
3121		se: function(event, dx, dy) {
3122			return $.extend(this._change.s.apply(this, arguments), this._change.e.apply(this, [event, dx, dy]));
3123		},
3124		sw: function(event, dx, dy) {
3125			return $.extend(this._change.s.apply(this, arguments), this._change.w.apply(this, [event, dx, dy]));
3126		},
3127		ne: function(event, dx, dy) {
3128			return $.extend(this._change.n.apply(this, arguments), this._change.e.apply(this, [event, dx, dy]));
3129		},
3130		nw: function(event, dx, dy) {
3131			return $.extend(this._change.n.apply(this, arguments), this._change.w.apply(this, [event, dx, dy]));
3132		}
3133	},
3134
3135	_propagate: function(n, event) {
3136		$.ui.plugin.call(this, n, [event, this.ui()]);
3137		(n != "resize" && this._trigger(n, event, this.ui()));
3138	},
3139
3140	plugins: {},
3141
3142	ui: function() {
3143		return {
3144			originalElement: this.originalElement,
3145			element: this.element,
3146			helper: this.helper,
3147			position: this.position,
3148			size: this.size,
3149			originalSize: this.originalSize,
3150			originalPosition: this.originalPosition
3151		};
3152	}
3153
3154});
3155
3156/*
3157 * Resizable Extensions
3158 */
3159
3160$.ui.plugin.add("resizable", "alsoResize", {
3161
3162	start: function (event, ui) {
3163		var that = $(this).data("resizable"), o = that.options;
3164
3165		var _store = function (exp) {
3166			$(exp).each(function() {
3167				var el = $(this);
3168				el.data("resizable-alsoresize", {
3169					width: parseInt(el.width(), 10), height: parseInt(el.height(), 10),
3170					left: parseInt(el.css('left'), 10), top: parseInt(el.css('top'), 10)
3171				});
3172			});
3173		};
3174
3175		if (typeof(o.alsoResize) == 'object' && !o.alsoResize.parentNode) {
3176			if (o.alsoResize.length) { o.alsoResize = o.alsoResize[0]; _store(o.alsoResize); }
3177			else { $.each(o.alsoResize, function (exp) { _store(exp); }); }
3178		}else{
3179			_store(o.alsoResize);
3180		}
3181	},
3182
3183	resize: function (event, ui) {
3184		var that = $(this).data("resizable"), o = that.options, os = that.originalSize, op = that.originalPosition;
3185
3186		var delta = {
3187			height: (that.size.height - os.height) || 0, width: (that.size.width - os.width) || 0,
3188			top: (that.position.top - op.top) || 0, left: (that.position.left - op.left) || 0
3189		},
3190
3191		_alsoResize = function (exp, c) {
3192			$(exp).each(function() {
3193				var el = $(this), start = $(this).data("resizable-alsoresize"), style = {},
3194					css = c && c.length ? c : el.parents(ui.originalElement[0]).length ? ['width', 'height'] : ['width', 'height', 'top', 'left'];
3195
3196				$.each(css, function (i, prop) {
3197					var sum = (start[prop]||0) + (delta[prop]||0);
3198					if (sum && sum >= 0)
3199						style[prop] = sum || null;
3200				});
3201
3202				el.css(style);
3203			});
3204		};
3205
3206		if (typeof(o.alsoResize) == 'object' && !o.alsoResize.nodeType) {
3207			$.each(o.alsoResize, function (exp, c) { _alsoResize(exp, c); });
3208		}else{
3209			_alsoResize(o.alsoResize);
3210		}
3211	},
3212
3213	stop: function (event, ui) {
3214		$(this).removeData("resizable-alsoresize");
3215	}
3216});
3217
3218$.ui.plugin.add("resizable", "animate", {
3219
3220	stop: function(event, ui) {
3221		var that = $(this).data("resizable"), o = that.options;
3222
3223		var pr = that._proportionallyResizeElements, ista = pr.length && (/textarea/i).test(pr[0].nodeName),
3224					soffseth = ista && $.ui.hasScroll(pr[0], 'left') /* TODO - jump height */ ? 0 : that.sizeDiff.height,
3225						soffsetw = ista ? 0 : that.sizeDiff.width;
3226
3227		var style = { width: (that.size.width - soffsetw), height: (that.size.height - soffseth) },
3228					left = (parseInt(that.element.css('left'), 10) + (that.position.left - that.originalPosition.left)) || null,
3229						top = (parseInt(that.element.css('top'), 10) + (that.position.top - that.originalPosition.top)) || null;
3230
3231		that.element.animate(
3232			$.extend(style, top && left ? { top: top, left: left } : {}), {
3233				duration: o.animateDuration,
3234				easing: o.animateEasing,
3235				step: function() {
3236
3237					var data = {
3238						width: parseInt(that.element.css('width'), 10),
3239						height: parseInt(that.element.css('height'), 10),
3240						top: parseInt(that.element.css('top'), 10),
3241						left: parseInt(that.element.css('left'), 10)
3242					};
3243
3244					if (pr && pr.length) $(pr[0]).css({ width: data.width, height: data.height });
3245
3246					// propagating resize, and updating values for each animation step
3247					that._updateCache(data);
3248					that._propagate("resize", event);
3249
3250				}
3251			}
3252		);
3253	}
3254
3255});
3256
3257$.ui.plugin.add("resizable", "containment", {
3258
3259	start: function(event, ui) {
3260		var that = $(this).data("resizable"), o = that.options, el = that.element;
3261		var oc = o.containment,	ce = (oc instanceof $) ? oc.get(0) : (/parent/.test(oc)) ? el.parent().get(0) : oc;
3262		if (!ce) return;
3263
3264		that.containerElement = $(ce);
3265
3266		if (/document/.test(oc) || oc == document) {
3267			that.containerOffset = { left: 0, top: 0 };
3268			that.containerPosition = { left: 0, top: 0 };
3269
3270			that.parentData = {
3271				element: $(document), left: 0, top: 0,
3272				width: $(document).width(), height: $(document).height() || document.body.parentNode.scrollHeight
3273			};
3274		}
3275
3276		// i'm a node, so compute top, left, right, bottom
3277		else {
3278			var element = $(ce), p = [];
3279			$([ "Top", "Right", "Left", "Bottom" ]).each(function(i, name) { p[i] = num(element.css("padding" + name)); });
3280
3281			that.containerOffset = element.offset();
3282			that.containerPosition = element.position();
3283			that.containerSize = { height: (element.innerHeight() - p[3]), width: (element.innerWidth() - p[1]) };
3284
3285			var co = that.containerOffset, ch = that.containerSize.height,	cw = that.containerSize.width,
3286						width = ($.ui.hasScroll(ce, "left") ? ce.scrollWidth : cw ), height = ($.ui.hasScroll(ce) ? ce.scrollHeight : ch);
3287
3288			that.parentData = {
3289				element: ce, left: co.left, top: co.top, width: width, height: height
3290			};
3291		}
3292	},
3293
3294	resize: function(event, ui) {
3295		var that = $(this).data("resizable"), o = that.options,
3296				ps = that.containerSize, co = that.containerOffset, cs = that.size, cp = that.position,
3297				pRatio = that._aspectRatio || event.shiftKey, cop = { top:0, left:0 }, ce = that.containerElement;
3298
3299		if (ce[0] != document && (/static/).test(ce.css('position'))) cop = co;
3300
3301		if (cp.left < (that._helper ? co.left : 0)) {
3302			that.size.width = that.size.width + (that._helper ? (that.position.left - co.left) : (that.position.left - cop.left));
3303			if (pRatio) that.size.height = that.size.width / that.aspectRatio;
3304			that.position.left = o.helper ? co.left : 0;
3305		}
3306
3307		if (cp.top < (that._helper ? co.top : 0)) {
3308			that.size.height = that.size.height + (that._helper ? (that.position.top - co.top) : that.position.top);
3309			if (pRatio) that.size.width = that.size.height * that.aspectRatio;
3310			that.position.top = that._helper ? co.top : 0;
3311		}
3312
3313		that.offset.left = that.parentData.left+that.position.left;
3314		that.offset.top = that.parentData.top+that.position.top;
3315
3316		var woset = Math.abs( (that._helper ? that.offset.left - cop.left : (that.offset.left - cop.left)) + that.sizeDiff.width ),
3317					hoset = Math.abs( (that._helper ? that.offset.top - cop.top : (that.offset.top - co.top)) + that.sizeDiff.height );
3318
3319		var isParent = that.containerElement.get(0) == that.element.parent().get(0),
3320			isOffsetRelative = /relative|absolute/.test(that.containerElement.css('position'));
3321
3322		if(isParent && isOffsetRelative) woset -= that.parentData.left;
3323
3324		if (woset + that.size.width >= that.parentData.width) {
3325			that.size.width = that.parentData.width - woset;
3326			if (pRatio) that.size.height = that.size.width / that.aspectRatio;
3327		}
3328
3329		if (hoset + that.size.height >= that.parentData.height) {
3330			that.size.height = that.parentData.height - hoset;
3331			if (pRatio) that.size.width = that.size.height * that.aspectRatio;
3332		}
3333	},
3334
3335	stop: function(event, ui){
3336		var that = $(this).data("resizable"), o = that.options, cp = that.position,
3337				co = that.containerOffset, cop = that.containerPosition, ce = that.containerElement;
3338
3339		var helper = $(that.helper), ho = helper.offset(), w = helper.outerWidth() - that.sizeDiff.width, h = helper.outerHeight() - that.sizeDiff.height;
3340
3341		if (that._helper && !o.animate && (/relative/).test(ce.css('position')))
3342			$(this).css({ left: ho.left - cop.left - co.left, width: w, height: h });
3343
3344		if (that._helper && !o.animate && (/static/).test(ce.css('position')))
3345			$(this).css({ left: ho.left - cop.left - co.left, width: w, height: h });
3346
3347	}
3348});
3349
3350$.ui.plugin.add("resizable", "ghost", {
3351
3352	start: function(event, ui) {
3353
3354		var that = $(this).data("resizable"), o = that.options, cs = that.size;
3355
3356		that.ghost = that.originalElement.clone();
3357		that.ghost
3358			.css({ opacity: .25, display: 'block', position: 'relative', height: cs.height, width: cs.width, margin: 0, left: 0, top: 0 })
3359			.addClass('ui-resizable-ghost')
3360			.addClass(typeof o.ghost == 'string' ? o.ghost : '');
3361
3362		that.ghost.appendTo(that.helper);
3363
3364	},
3365
3366	resize: function(event, ui){
3367		var that = $(this).data("resizable"), o = that.options;
3368		if (that.ghost) that.ghost.css({ position: 'relative', height: that.size.height, width: that.size.width });
3369	},
3370
3371	stop: function(event, ui){
3372		var that = $(this).data("resizable"), o = that.options;
3373		if (that.ghost && that.helper) that.helper.get(0).removeChild(that.ghost.get(0));
3374	}
3375
3376});
3377
3378$.ui.plugin.add("resizable", "grid", {
3379
3380	resize: function(event, ui) {
3381		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;
3382		o.grid = typeof o.grid == "number" ? [o.grid, o.grid] : o.grid;
3383		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);
3384
3385		if (/^(se|s|e)$/.test(a)) {
3386			that.size.width = os.width + ox;
3387			that.size.height = os.height + oy;
3388		}
3389		else if (/^(ne)$/.test(a)) {
3390			that.size.width = os.width + ox;
3391			that.size.height = os.height + oy;
3392			that.position.top = op.top - oy;
3393		}
3394		else if (/^(sw)$/.test(a)) {
3395			that.size.width = os.width + ox;
3396			that.size.height = os.height + oy;
3397			that.position.left = op.left - ox;
3398		}
3399		else {
3400			that.size.width = os.width + ox;
3401			that.size.height = os.height + oy;
3402			that.position.top = op.top - oy;
3403			that.position.left = op.left - ox;
3404		}
3405	}
3406
3407});
3408
3409var num = function(v) {
3410	return parseInt(v, 10) || 0;
3411};
3412
3413var isNumber = function(value) {
3414	return !isNaN(parseInt(value, 10));
3415};
3416
3417})(jQuery);
3418(function( $, undefined ) {
3419
3420$.widget("ui.selectable", $.ui.mouse, {
3421	version: "1.9.2",
3422	options: {
3423		appendTo: 'body',
3424		autoRefresh: true,
3425		distance: 0,
3426		filter: '*',
3427		tolerance: 'touch'
3428	},
3429	_create: function() {
3430		var that = this;
3431
3432		this.element.addClass("ui-selectable");
3433
3434		this.dragged = false;
3435
3436		// cache selectee children based on filter
3437		var selectees;
3438		this.refresh = function() {
3439			selectees = $(that.options.filter, that.element[0]);
3440			selectees.addClass("ui-selectee");
3441			selectees.each(function() {
3442				var $this = $(this);
3443				var pos = $this.offset();
3444				$.data(this, "selectable-item", {
3445					element: this,
3446					$element: $this,
3447					left: pos.left,
3448					top: pos.top,
3449					right: pos.left + $this.outerWidth(),
3450					bottom: pos.top + $this.outerHeight(),
3451					startselected: false,
3452					selected: $this.hasClass('ui-selected'),
3453					selecting: $this.hasClass('ui-selecting'),
3454					unselecting: $this.hasClass('ui-unselecting')
3455				});
3456			});
3457		};
3458		this.refresh();
3459
3460		this.selectees = selectees.addClass("ui-selectee");
3461
3462		this._mouseInit();
3463
3464		this.helper = $("<div class='ui-selectable-helper'></div>");
3465	},
3466
3467	_destroy: function() {
3468		this.selectees
3469			.removeClass("ui-selectee")
3470			.removeData("selectable-item");
3471		this.element
3472			.removeClass("ui-selectable ui-selectable-disabled");
3473		this._mouseDestroy();
3474	},
3475
3476	_mouseStart: function(event) {
3477		var that = this;
3478
3479		this.opos = [event.pageX, event.pageY];
3480
3481		if (this.options.disabled)
3482			return;
3483
3484		var options = this.options;
3485
3486		this.selectees = $(options.filter, this.element[0]);
3487
3488		this._trigger("start", event);
3489
3490		$(options.appendTo).append(this.helper);
3491		// position helper (lasso)
3492		this.helper.css({
3493			"left": event.clientX,
3494			"top": event.clientY,
3495			"width": 0,
3496			"height": 0
3497		});
3498
3499		if (options.autoRefresh) {
3500			this.refresh();
3501		}
3502
3503		this.selectees.filter('.ui-selected').each(function() {
3504			var selectee = $.data(this, "selectable-item");
3505			selectee.startselected = true;
3506			if (!event.metaKey && !event.ctrlKey) {
3507				selectee.$element.removeClass('ui-selected');
3508				selectee.selected = false;
vendor: 4,195 bytes, lines 3509-3647
3509				selectee.$element.addClass('ui-unselecting');
3510				selectee.unselecting = true;
3511				// selectable UNSELECTING callback
3512				that._trigger("unselecting", event, {
3513					unselecting: selectee.element
3514				});
3515			}
3516		});
3517
3518		$(event.target).parents().andSelf().each(function() {
3519			var selectee = $.data(this, "selectable-item");
3520			if (selectee) {
3521				var doSelect = (!event.metaKey && !event.ctrlKey) || !selectee.$element.hasClass('ui-selected');
3522				selectee.$element
3523					.removeClass(doSelect ? "ui-unselecting" : "ui-selected")
3524					.addClass(doSelect ? "ui-selecting" : "ui-unselecting");
3525				selectee.unselecting = !doSelect;
3526				selectee.selecting = doSelect;
3527				selectee.selected = doSelect;
3528				// selectable (UN)SELECTING callback
3529				if (doSelect) {
3530					that._trigger("selecting", event, {
3531						selecting: selectee.element
3532					});
3533				} else {
3534					that._trigger("unselecting", event, {
3535						unselecting: selectee.element
3536					});
3537				}
3538				return false;
3539			}
3540		});
3541
3542	},
3543
3544	_mouseDrag: function(event) {
3545		var that = this;
3546		this.dragged = true;
3547
3548		if (this.options.disabled)
3549			return;
3550
3551		var options = this.options;
3552
3553		var x1 = this.opos[0], y1 = this.opos[1], x2 = event.pageX, y2 = event.pageY;
3554		if (x1 > x2) { var tmp = x2; x2 = x1; x1 = tmp; }
3555		if (y1 > y2) { var tmp = y2; y2 = y1; y1 = tmp; }
3556		this.helper.css({left: x1, top: y1, width: x2-x1, height: y2-y1});
3557
3558		this.selectees.each(function() {
3559			var selectee = $.data(this, "selectable-item");
3560			//prevent helper from being selected if appendTo: selectable
3561			if (!selectee || selectee.element == that.element[0])
3562				return;
3563			var hit = false;
3564			if (options.tolerance == 'touch') {
3565				hit = ( !(selectee.left > x2 || selectee.right < x1 || selectee.top > y2 || selectee.bottom < y1) );
3566			} else if (options.tolerance == 'fit') {
3567				hit = (selectee.left > x1 && selectee.right < x2 && selectee.top > y1 && selectee.bottom < y2);
3568			}
3569
3570			if (hit) {
3571				// SELECT
3572				if (selectee.selected) {
3573					selectee.$element.removeClass('ui-selected');
3574					selectee.selected = false;
3575				}
3576				if (selectee.unselecting) {
3577					selectee.$element.removeClass('ui-unselecting');
3578					selectee.unselecting = false;
3579				}
3580				if (!selectee.selecting) {
3581					selectee.$element.addClass('ui-selecting');
3582					selectee.selecting = true;
3583					// selectable SELECTING callback
3584					that._trigger("selecting", event, {
3585						selecting: selectee.element
3586					});
3587				}
3588			} else {
3589				// UNSELECT
3590				if (selectee.selecting) {
3591					if ((event.metaKey || event.ctrlKey) && selectee.startselected) {
3592						selectee.$element.removeClass('ui-selecting');
3593						selectee.selecting = false;
3594						selectee.$element.addClass('ui-selected');
3595						selectee.selected = true;
3596					} else {
3597						selectee.$element.removeClass('ui-selecting');
3598						selectee.selecting = false;
3599						if (selectee.startselected) {
3600							selectee.$element.addClass('ui-unselecting');
3601							selectee.unselecting = true;
3602						}
3603						// selectable UNSELECTING callback
3604						that._trigger("unselecting", event, {
3605							unselecting: selectee.element
3606						});
3607					}
3608				}
3609				if (selectee.selected) {
3610					if (!event.metaKey && !event.ctrlKey && !selectee.startselected) {
3611						selectee.$element.removeClass('ui-selected');
3612						selectee.selected = false;
3613
3614						selectee.$element.addClass('ui-unselecting');
3615						selectee.unselecting = true;
3616						// selectable UNSELECTING callback
3617						that._trigger("unselecting", event, {
3618							unselecting: selectee.element
3619						});
3620					}
3621				}
3622			}
3623		});
3624
3625		return false;
3626	},
3627
3628	_mouseStop: function(event) {
3629		var that = this;
3630
3631		this.dragged = false;
3632
3633		var options = this.options;
3634
3635		$('.ui-unselecting', this.element[0]).each(function() {
3636			var selectee = $.data(this, "selectable-item");
3637			selectee.$element.removeClass('ui-unselecting');
3638			selectee.unselecting = false;
3639			selectee.startselected = false;
3640			that._trigger("unselected", event, {
3641				unselected: selectee.element
3642			});
3643		});
3644		$('.ui-selecting', this.element[0]).each(function() {
3645			var selectee = $.data(this, "selectable-item");
3646			selectee.$element.removeClass('ui-selecting').addClass('ui-selected');
3647			selectee.selecting = false;
3648			selectee.selected = true;
3649			selectee.startselected = true;
3650			that._trigger("selected", event, {
3651				selected: selectee.element
3652			});
3653		});
3654		this._trigger("stop", event);
3655
3656		this.helper.remove();
3657
3658		return false;
3659	}
3660
3661});
3662
3663})(jQuery);
3664(function( $, undefined ) {
3665
3666$.widget("ui.sortable", $.ui.mouse, {
3667	version: "1.9.2",
3668	widgetEventPrefix: "sort",
3669	ready: false,
3670	options: {
3671		appendTo: "parent",
3672		axis: false,
3673		connectWith: false,
3674		containment: false,
3675		cursor: 'auto',
3676		cursorAt: false,
3677		dropOnEmpty: true,
3678		forcePlaceholderSize: false,
3679		forceHelperSize: false,
3680		grid: false,
3681		handle: false,
3682		helper: "original",
3683		items: '> *',
3684		opacity: false,
3685		placeholder: false,
3686		revert: false,
3687		scroll: true,
3688		scrollSensitivity: 20,
3689		scrollSpeed: 20,
3690		scope: "default",
3691		tolerance: "intersect",
3692		zIndex: 1000
3693	},
3694	_create: function() {
3695
3696		var o = this.options;
3697		this.containerCache = {};
3698		this.element.addClass("ui-sortable");
3699
3700		//Get the items
3701		this.refresh();
3702
3703		//Let's determine if the items are being displayed horizontally
3704		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;
3705
3706		//Let's determine the parent's offset
3707		this.offset = this.element.offset();
3708
3709		//Initialize mouse events for interaction
3710		this._mouseInit();
3711
3712		//We're ready to go
3713		this.ready = true
3714
3715	},
3716
3717	_destroy: function() {
3718		this.element
3719			.removeClass("ui-sortable ui-sortable-disabled");
3720		this._mouseDestroy();
3721
3722		for ( var i = this.items.length - 1; i >= 0; i-- )
3723			this.items[i].item.removeData(this.widgetName + "-item");
3724
3725		return this;
3726	},
3727
3728	_setOption: function(key, value){
3729		if ( key === "disabled" ) {
3730			this.options[ key ] = value;
3731
3732			this.widget().toggleClass( "ui-sortable-disabled", !!value );
3733		} else {
3734			// Don't call widget base _setOption for disable as it adds ui-state-disabled class
3735			$.Widget.prototype._setOption.apply(this, arguments);
3736		}
3737	},
3738
3739	_mouseCapture: function(event, overrideHandle) {
3740		var that = this;
3741
3742		if (this.reverting) {
3743			return false;
3744		}
3745
3746		if(this.options.disabled || this.options.type == 'static') return false;
3747
3748		//We have to refresh the items data once first
3749		this._refreshItems(event);
3750
3751		//Find out if the clicked node (or one of its parents) is a actual item in this.items
3752		var currentItem = null, nodes = $(event.target).parents().each(function() {
3753			if($.data(this, that.widgetName + '-item') == that) {
3754				currentItem = $(this);
3755				return false;
3756			}
3757		});
3758		if($.data(event.target, that.widgetName + '-item') == that) currentItem = $(event.target);
3759
3760		if(!currentItem) return false;
3761		if(this.options.handle && !overrideHandle) {
3762			var validHandle = false;
3763
3764			$(this.options.handle, currentItem).find("*").andSelf().each(function() { if(this == event.target) validHandle = true; });
3765			if(!validHandle) return false;
3766		}
3767
3768		this.currentItem = currentItem;
3769		this._removeCurrentsFromItems();
3770		return true;
3771
3772	},
3773
3774	_mouseStart: function(event, overrideHandle, noActivation) {
3775
3776		var o = this.options;
3777		this.currentContainer = this;
3778
3779		//We only need to call refreshPositions, because the refreshItems call has been moved to mouseCapture
3780		this.refreshPositions();
3781
3782		//Create and append the visible helper
3783		this.helper = this._createHelper(event);
3784
3785		//Cache the helper size
3786		this._cacheHelperProportions();
3787
3788		/*
3789		 * - Position generation -
3790		 * This block generates everything position related - it's the core of draggables.
3791		 */
3792
3793		//Cache the margins of the original element
3794		this._cacheMargins();
3795
3796		//Get the next scrolling parent
3797		this.scrollParent = this.helper.scrollParent();
3798
3799		//The element's absolute position on the page minus margins
3800		this.offset = this.currentItem.offset();
3801		this.offset = {
3802			top: this.offset.top - this.margins.top,
3803			left: this.offset.left - this.margins.left
3804		};
3805
3806		$.extend(this.offset, {
3807			click: { //Where the click happened, relative to the element
3808				left: event.pageX - this.offset.left,
3809				top: event.pageY - this.offset.top
3810			},
3811			parent: this._getParentOffset(),
3812			relative: this._getRelativeOffset() //This is a relative to absolute position minus the actual position calculation - only used for relative positioned helper
3813		});
3814
3815		// Only after we got the offset, we can change the helper's position to absolute
3816		// TODO: Still need to figure out a way to make relative sorting possible
3817		this.helper.css("position", "absolute");
3818		this.cssPosition = this.helper.css("position");
3819
3820		//Generate the original position
3821		this.originalPosition = this._generatePosition(event);
3822		this.originalPageX = event.pageX;
3823		this.originalPageY = event.pageY;
3824
3825		//Adjust the mouse offset relative to the helper if 'cursorAt' is supplied
3826		(o.cursorAt && this._adjustOffsetFromHelper(o.cursorAt));
3827
3828		//Cache the former DOM position
3829		this.domPosition = { prev: this.currentItem.prev()[0], parent: this.currentItem.parent()[0] };
3830
3831		//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
3832		if(this.helper[0] != this.currentItem[0]) {
3833			this.currentItem.hide();
3834		}
3835
3836		//Create the placeholder
3837		this._createPlaceholder();
3838
3839		//Set a containment if given in the options
3840		if(o.containment)
3841			this._setContainment();
3842
3843		if(o.cursor) { // cursor option
3844			if ($('body').css("cursor")) this._storedCursor = $('body').css("cursor");
3845			$('body').css("cursor", o.cursor);
3846		}
3847
3848		if(o.opacity) { // opacity option
3849			if (this.helper.css("opacity")) this._storedOpacity = this.helper.css("opacity");
3850			this.helper.css("opacity", o.opacity);
3851		}
3852
3853		if(o.zIndex) { // zIndex option
3854			if (this.helper.css("zIndex")) this._storedZIndex = this.helper.css("zIndex");
3855			this.helper.css("zIndex", o.zIndex);
3856		}
3857
3858		//Prepare scrolling
3859		if(this.scrollParent[0] != document && this.scrollParent[0].tagName != 'HTML')
3860			this.overflowOffset = this.scrollParent.offset();
3861
3862		//Call callbacks
3863		this._trigger("start", event, this._uiHash());
3864
3865		//Recache the helper size
3866		if(!this._preserveHelperProportions)
3867			this._cacheHelperProportions();
3868
3869
3870		//Post 'activate' events to possible containers
3871		if(!noActivation) {
3872			 for (var i = this.containers.length - 1; i >= 0; i--) { this.containers[i]._trigger("activate", event, this._uiHash(this)); }
3873		}
3874
3875		//Prepare possible droppables
3876		if($.ui.ddmanager)
3877			$.ui.ddmanager.current = this;
3878
3879		if ($.ui.ddmanager && !o.dropBehaviour)
3880			$.ui.ddmanager.prepareOffsets(this, event);
3881
3882		this.dragging = true;
3883
3884		this.helper.addClass("ui-sortable-helper");
3885		this._mouseDrag(event); //Execute the drag once - this causes the helper not to be visible before getting its correct position
3886		return true;
3887
3888	},
3889
3890	_mouseDrag: function(event) {
3891
3892		//Compute the helpers position
3893		this.position = this._generatePosition(event);
3894		this.positionAbs = this._convertPositionTo("absolute");
3895
3896		if (!this.lastPositionAbs) {
3897			this.lastPositionAbs = this.positionAbs;
3898		}
3899
3900		//Do scrolling
3901		if(this.options.scroll) {
3902			var o = this.options, scrolled = false;
3903			if(this.scrollParent[0] != document && this.scrollParent[0].tagName != 'HTML') {
3904
3905				if((this.overflowOffset.top + this.scrollParent[0].offsetHeight) - event.pageY < o.scrollSensitivity)
3906					this.scrollParent[0].scrollTop = scrolled = this.scrollParent[0].scrollTop + o.scrollSpeed;
3907				else if(event.pageY - this.overflowOffset.top < o.scrollSensitivity)
3908					this.scrollParent[0].scrollTop = scrolled = this.scrollParent[0].scrollTop - o.scrollSpeed;
3909
3910				if((this.overflowOffset.left + this.scrollParent[0].offsetWidth) - event.pageX < o.scrollSensitivity)
3911					this.scrollParent[0].scrollLeft = scrolled = this.scrollParent[0].scrollLeft + o.scrollSpeed;
3912				else if(event.pageX - this.overflowOffset.left < o.scrollSensitivity)
3913					this.scrollParent[0].scrollLeft = scrolled = this.scrollParent[0].scrollLeft - o.scrollSpeed;
3914
3915			} else {
3916
3917				if(event.pageY - $(document).scrollTop() < o.scrollSensitivity)
3918					scrolled = $(document).scrollTop($(document).scrollTop() - o.scrollSpeed);
3919				else if($(window).height() - (event.pageY - $(document).scrollTop()) < o.scrollSensitivity)
3920					scrolled = $(document).scrollTop($(document).scrollTop() + o.scrollSpeed);
3921
3922				if(event.pageX - $(document).scrollLeft() < o.scrollSensitivity)
3923					scrolled = $(document).scrollLeft($(document).scrollLeft() - o.scrollSpeed);
3924				else if($(window).width() - (event.pageX - $(document).scrollLeft()) < o.scrollSensitivity)
3925					scrolled = $(document).scrollLeft($(document).scrollLeft() + o.scrollSpeed);
3926
3927			}
3928
3929			if(scrolled !== false && $.ui.ddmanager && !o.dropBehaviour)
3930				$.ui.ddmanager.prepareOffsets(this, event);
3931		}
3932
3933		//Regenerate the absolute position used for position checks
3934		this.positionAbs = this._convertPositionTo("absolute");
3935
3936		//Set the helper position
3937		if(!this.options.axis || this.options.axis != "y") this.helper[0].style.left = this.position.left+'px';
3938		if(!this.options.axis || this.options.axis != "x") this.helper[0].style.top = this.position.top+'px';
3939
3940		//Rearrange
3941		for (var i = this.items.length - 1; i >= 0; i--) {
3942
3943			//Cache variables and intersection, continue if no intersection
3944			var item = this.items[i], itemElement = item.item[0], intersection = this._intersectsWithPointer(item);
3945			if (!intersection) continue;
3946
3947			// Only put the placeholder inside the current Container, skip all
3948			// items form other containers. This works because when moving
3949			// an item from one container to another the
3950			// currentContainer is switched before the placeholder is moved.
3951			//
3952			// Without this moving items in "sub-sortables" can cause the placeholder to jitter
3953			// beetween the outer and inner container.
3954			if (item.instance !== this.currentContainer) continue;
3955
3956			if (itemElement != this.currentItem[0] //cannot intersect with itself
3957				&&	this.placeholder[intersection == 1 ? "next" : "prev"]()[0] != itemElement //no useless actions that have been done before
3958				&&	!$.contains(this.placeholder[0], itemElement) //no action if the item moved is the parent of the item checked
3959				&& (this.options.type == 'semi-dynamic' ? !$.contains(this.element[0], itemElement) : true)
3960				//&& itemElement.parentNode == this.placeholder[0].parentNode // only rearrange items within the same container
3961			) {
3962
3963				this.direction = intersection == 1 ? "down" : "up";
3964
3965				if (this.options.tolerance == "pointer" || this._intersectsWithSides(item)) {
3966					this._rearrange(event, item);
3967				} else {
3968					break;
3969				}
3970
3971				this._trigger("change", event, this._uiHash());
3972				break;
3973			}
3974		}
3975
3976		//Post events to containers
3977		this._contactContainers(event);
3978
3979		//Interconnect with droppables
3980		if($.ui.ddmanager) $.ui.ddmanager.drag(this, event);
3981
3982		//Call callbacks
3983		this._trigger('sort', event, this._uiHash());
3984
3985		this.lastPositionAbs = this.positionAbs;
3986		return false;
3987
3988	},
3989
3990	_mouseStop: function(event, noPropagation) {
3991
3992		if(!event) return;
3993
3994		//If we are using droppables, inform the manager about the drop
3995		if ($.ui.ddmanager && !this.options.dropBehaviour)
3996			$.ui.ddmanager.drop(this, event);
3997
3998		if(this.options.revert) {
3999			var that = this;
4000			var cur = this.placeholder.offset();
4001
4002			this.reverting = true;
4003
4004			$(this.helper).animate({
4005				left: cur.left - this.offset.parent.left - this.margins.left + (this.offsetParent[0] == document.body ? 0 : this.offsetParent[0].scrollLeft),
4006				top: cur.top - this.offset.parent.top - this.margins.top + (this.offsetParent[0] == document.body ? 0 : this.offsetParent[0].scrollTop)
4007			}, parseInt(this.options.revert, 10) || 500, function() {
4008				that._clear(event);
4009			});
4010		} else {
4011			this._clear(event, noPropagation);
4012		}
4013
4014		return false;
4015
4016	},
4017
4018	cancel: function() {
4019
4020		if(this.dragging) {
4021
4022			this._mouseUp({ target: null });
4023
4024			if(this.options.helper == "original")
4025				this.currentItem.css(this._storedCSS).removeClass("ui-sortable-helper");
4026			else
4027				this.currentItem.show();
4028
4029			//Post deactivating events to containers
4030			for (var i = this.containers.length - 1; i >= 0; i--){
4031				this.containers[i]._trigger("deactivate", null, this._uiHash(this));
4032				if(this.containers[i].containerCache.over) {
4033					this.containers[i]._trigger("out", null, this._uiHash(this));
4034					this.containers[i].containerCache.over = 0;
4035				}
4036			}
4037
4038		}
4039
4040		if (this.placeholder) {
4041			//$(this.placeholder[0]).remove(); would have been the jQuery way - unfortunately, it unbinds ALL events from the original node!
4042			if(this.placeholder[0].parentNode) this.placeholder[0].parentNode.removeChild(this.placeholder[0]);
4043			if(this.options.helper != "original" && this.helper && this.helper[0].parentNode) this.helper.remove();
4044
4045			$.extend(this, {
4046				helper: null,
4047				dragging: false,
4048				reverting: false,
4049				_noFinalSort: null
4050			});
4051
4052			if(this.domPosition.prev) {
4053				$(this.domPosition.prev).after(this.currentItem);
4054			} else {
4055				$(this.domPosition.parent).prepend(this.currentItem);
4056			}
4057		}
4058
4059		return this;
4060
4061	},
4062
4063	serialize: function(o) {
4064
4065		var items = this._getItemsAsjQuery(o && o.connected);
4066		var str = []; o = o || {};
4067
4068		$(items).each(function() {
4069			var res = ($(o.item || this).attr(o.attribute || 'id') || '').match(o.expression || (/(.+)[-=_](.+)/));
4070			if(res) str.push((o.key || res[1]+'[]')+'='+(o.key && o.expression ? res[1] : res[2]));
4071		});
4072
4073		if(!str.length && o.key) {
4074			str.push(o.key + '=');
4075		}
4076
4077		return str.join('&');
4078
4079	},
4080
4081	toArray: function(o) {
4082
4083		var items = this._getItemsAsjQuery(o && o.connected);
4084		var ret = []; o = o || {};
4085
4086		items.each(function() { ret.push($(o.item || this).attr(o.attribute || 'id') || ''); });
4087		return ret;
4088
4089	},
4090
4091	/* Be careful with the following core functions */
4092	_intersectsWith: function(item) {
4093
4094		var x1 = this.positionAbs.left,
4095			x2 = x1 + this.helperProportions.width,
4096			y1 = this.positionAbs.top,
4097			y2 = y1 + this.helperProportions.height;
4098
4099		var l = item.left,
4100			r = l + item.width,
4101			t = item.top,
4102			b = t + item.height;
4103
4104		var dyClick = this.offset.click.top,
4105			dxClick = this.offset.click.left;
4106
4107		var isOverElement = (y1 + dyClick) > t && (y1 + dyClick) < b && (x1 + dxClick) > l && (x1 + dxClick) < r;
4108
4109		if(	   this.options.tolerance == "pointer"
4110			|| this.options.forcePointerForContainers
4111			|| (this.options.tolerance != "pointer" && this.helperProportions[this.floating ? 'width' : 'height'] > item[this.floating ? 'width' : 'height'])
4112		) {
4113			return isOverElement;
4114		} else {
4115
4116			return (l < x1 + (this.helperProportions.width / 2) // Right Half
4117				&& x2 - (this.helperProportions.width / 2) < r // Left Half
4118				&& t < y1 + (this.helperProportions.height / 2) // Bottom Half
4119				&& y2 - (this.helperProportions.height / 2) < b ); // Top Half
4120
4121		}
4122	},
4123
4124	_intersectsWithPointer: function(item) {
4125
4126		var isOverElementHeight = (this.options.axis === 'x') || $.ui.isOverAxis(this.positionAbs.top + this.offset.click.top, item.top, item.height),
4127			isOverElementWidth = (this.options.axis === 'y') || $.ui.isOverAxis(this.positionAbs.left + this.offset.click.left, item.left, item.width),
4128			isOverElement = isOverElementHeight && isOverElementWidth,
4129			verticalDirection = this._getDragVerticalDirection(),
4130			horizontalDirection = this._getDragHorizontalDirection();
4131
4132		if (!isOverElement)
4133			return false;
4134
4135		return this.floating ?
4136			( ((horizontalDirection && horizontalDirection == "right") || verticalDirection == "down") ? 2 : 1 )
4137			: ( verticalDirection && (verticalDirection == "down" ? 2 : 1) );
4138
4139	},
4140
4141	_intersectsWithSides: function(item) {
4142
4143		var isOverBottomHalf = $.ui.isOverAxis(this.positionAbs.top + this.offset.click.top, item.top + (item.height/2), item.height),
4144			isOverRightHalf = $.ui.isOverAxis(this.positionAbs.left + this.offset.click.left, item.left + (item.width/2), item.width),
4145			verticalDirection = this._getDragVerticalDirection(),
4146			horizontalDirection = this._getDragHorizontalDirection();
4147
4148		if (this.floating && horizontalDirection) {
4149			return ((horizontalDirection == "right" && isOverRightHalf) || (horizontalDirection == "left" && !isOverRightHalf));
4150		} else {
4151			return verticalDirection && ((verticalDirection == "down" && isOverBottomHalf) || (verticalDirection == "up" && !isOverBottomHalf));
4152		}
4153
4154	},
4155
4156	_getDragVerticalDirection: function() {
4157		var delta = this.positionAbs.top - this.lastPositionAbs.top;
4158		return delta != 0 && (delta > 0 ? "down" : "up");
4159	},
4160
4161	_getDragHorizontalDirection: function() {
4162		var delta = this.positionAbs.left - this.lastPositionAbs.left;
4163		return delta != 0 && (delta > 0 ? "right" : "left");
4164	},
4165
4166	refresh: function(event) {
4167		this._refreshItems(event);
4168		this.refreshPositions();
4169		return this;
4170	},
4171
4172	_connectWith: function() {
4173		var options = this.options;
4174		return options.connectWith.constructor == String
4175			? [options.connectWith]
4176			: options.connectWith;
4177	},
4178
4179	_getItemsAsjQuery: function(connected) {
4180
4181		var items = [];
4182		var queries = [];
4183		var connectWith = this._connectWith();
4184
4185		if(connectWith && connected) {
4186			for (var i = connectWith.length - 1; i >= 0; i--){
4187				var cur = $(connectWith[i]);
4188				for (var j = cur.length - 1; j >= 0; j--){
4189					var inst = $.data(cur[j], this.widgetName);
4190					if(inst && inst != this && !inst.options.disabled) {
4191						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]);
4192					}
4193				};
4194			};
4195		}
4196
4197		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]);
4198
4199		for (var i = queries.length - 1; i >= 0; i--){
4200			queries[i][0].each(function() {
4201				items.push(this);
4202			});
4203		};
4204
4205		return $(items);
4206
4207	},
4208
4209	_removeCurrentsFromItems: function() {
4210
4211		var list = this.currentItem.find(":data(" + this.widgetName + "-item)");
4212
4213		this.items = $.grep(this.items, function (item) {
4214			for (var j=0; j < list.length; j++) {
4215				if(list[j] == item.item[0])
4216					return false;
4217			};
4218			return true;
4219		});
4220
4221	},
4222
4223	_refreshItems: function(event) {
4224
4225		this.items = [];
4226		this.containers = [this];
4227		var items = this.items;
4228		var queries = [[$.isFunction(this.options.items) ? this.options.items.call(this.element[0], event, { item: this.currentItem }) : $(this.options.items, this.element), this]];
4229		var connectWith = this._connectWith();
4230
4231		if(connectWith && this.ready) { //Shouldn't be run the first time through due to massive slow-down
4232			for (var i = connectWith.length - 1; i >= 0; i--){
4233				var cur = $(connectWith[i]);
4234				for (var j = cur.length - 1; j >= 0; j--){
4235					var inst = $.data(cur[j], this.widgetName);
4236					if(inst && inst != this && !inst.options.disabled) {
4237						queries.push([$.isFunction(inst.options.items) ? inst.options.items.call(inst.element[0], event, { item: this.currentItem }) : $(inst.options.items, inst.element), inst]);
4238						this.containers.push(inst);
4239					}
4240				};
4241			};
4242		}
4243
4244		for (var i = queries.length - 1; i >= 0; i--) {
4245			var targetData = queries[i][1];
4246			var _queries = queries[i][0];
4247
4248			for (var j=0, queriesLength = _queries.length; j < queriesLength; j++) {
4249				var item = $(_queries[j]);
4250
4251				item.data(this.widgetName + '-item', targetData); // Data for target checking (mouse manager)
4252
4253				items.push({
4254					item: item,
4255					instance: targetData,
4256					width: 0, height: 0,
4257					left: 0, top: 0
4258				});
4259			};
4260		};
4261
4262	},
4263
4264	refreshPositions: function(fast) {
4265
4266		//This has to be redone because due to the item being moved out/into the offsetParent, the offsetParent's position will change
4267		if(this.offsetParent && this.helper) {
4268			this.offset.parent = this._getParentOffset();
4269		}
4270
4271		for (var i = this.items.length - 1; i >= 0; i--){
4272			var item = this.items[i];
4273
4274			//We ignore calculating positions of all connected containers when we're not over them
4275			if(item.instance != this.currentContainer && this.currentContainer && item.item[0] != this.currentItem[0])
4276				continue;
4277
4278			var t = this.options.toleranceElement ? $(this.options.toleranceElement, item.item) : item.item;
4279
4280			if (!fast) {
4281				item.width = t.outerWidth();
4282				item.height = t.outerHeight();
4283			}
4284
4285			var p = t.offset();
4286			item.left = p.left;
4287			item.top = p.top;
4288		};
4289
4290		if(this.options.custom && this.options.custom.refreshContainers
4290) {
4291			this.options.custom.refreshContainers.call(this);
4292		} else {
4293			for (var i = this.containers.length - 1; i >= 0; i--){
4294				var p = this.containers[i].element.offset();
4295				this.containers[i].containerCache.left = p.left;
4296				this.containers[i].containerCache.top = p.top;
4297				this.containers[i].containerCache.width	= this.containers[i].element.outerWidth();
4298				this.containers[i].containerCache.height = this.containers[i].element.outerHeight();
4299			};
4300		}
4301
4302		return this;
4303	},
4304
4305	_createPlaceholder: function(that) {
4306		that = that || this;
4307		var o = that.options;
4308
4309		if(!o.placeholder || o.placeholder.constructor == String) {
4310			var className = o.placeholder;
4311			o.placeholder = {
4312				element: function() {
4313
4314					var el = $(document.createElement(that.currentItem[0].nodeName))
4315						.addClass(className || that.currentItem[0].className+" ui-sortable-placeholder")
4316						.removeClass("ui-sortable-helper")[0];
4317
4318					if(!className)
4319						el.style.visibility = "hidden";
4320
4321					return el;
4322				},
4323				update: function(container, p) {
4324
4325					// 1. If a className is set as 'placeholder option, we don't force sizes - the class is responsible for that
4326					// 2. The option 'forcePlaceholderSize can be enabled to force it even if a class name is specified
4327					if(className && !o.forcePlaceholderSize) return;
4328
4329					//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
4330					if(!p.height()) { p.height(that.currentItem.innerHeight() - parseInt(that.currentItem.css('paddingTop')||0, 10) - parseInt(that.currentItem.css('paddingBottom')||0, 10)); };
4331					if(!p.width()) { p.width(that.currentItem.innerWidth() - parseInt(that.currentItem.css('paddingLeft')||0, 10) - parseInt(that.currentItem.css('paddingRight')||0, 10)); };
4332				}
4333			};
4334		}
4335
4336		//Create the placeholder
4337		that.placeholder = $(o.placeholder.element.call(that.element, that.currentItem));
4338
4339		//Append it after the actual current item
4340		that.currentItem.after(that.placeholder);
4341
4342		//Update the size of the placeholder (TODO: Logic to fuzzy, see line 316/317)
4343		o.placeholder.update(that, that.placeholder);
4344
4345	},
4346
4347	_contactContainers: function(event) {
4348
4349		// get innermost container that intersects with item
4350		var innermostContainer = null, innermostIndex = null;
4351
4352
4353		for (var i = this.containers.length - 1; i >= 0; i--){
4354
4355			// never consider a container that's located within the item itself
4356			if($.contains(this.currentItem[0], this.containers[i].element[0]))
4357				continue;
4358
4359			if(this._intersectsWith(this.containers[i].containerCache)) {
4360
4361				// if we've already found a container and it's more "inner" than this, then continue
4362				if(innermostContainer && $.contains(this.containers[i].element[0], innermostContainer.element[0]))
4363					continue;
4364
4365				innermostContainer = this.containers[i];
4366				innermostIndex = i;
4367
4368			} else {
4369				// container doesn't intersect. trigger "out" event if necessary
4370				if(this.containers[i].containerCache.over) {
4371					this.containers[i]._trigger("out", event, this._uiHash(this));
4372					this.containers[i].containerCache.over = 0;
4373				}
4374			}
4375
4376		}
4377
4378		// if no intersecting containers found, return
4379		if(!innermostContainer) return;
4380
4381		// move the item into the container if it's not there already
4382		if(this.containers.length === 1) {
4383			this.containers[innermostIndex]._trigger("over", event, this._uiHash(this));
4384			this.containers[innermostIndex].containerCache.over = 1;
4385		} else {
4386
4387			//When entering a new container, we will find the item with the least distance and append our item near it
4388			var dist = 10000; var itemWithLeastDistance = null;
4389			var posProperty = this.containers[innermostIndex].floating ? 'left' : 'top';
4390			var sizeProperty = this.containers[innermostIndex].floating ? 'width' : 'height';
4391			var base = this.positionAbs[posProperty] + this.offset.click[posProperty];
4392			for (var j = this.items.length - 1; j >= 0; j--) {
4393				if(!$.contains(this.containers[innermostIndex].element[0], this.items[j].item[0])) continue;
4394				if(this.items[j].item[0] == this.currentItem[0]) continue;
4395				var cur = this.items[j].item.offset()[posProperty];
4396				var nearBottom = false;
4397				if(Math.abs(cur - base) > Math.abs(cur + this.items[j][sizeProperty] - base)){
4398					nearBottom = true;
4399					cur += this.items[j][sizeProperty];
4400				}
4401
4402				if(Math.abs(cur - base) < dist) {
4403					dist = Math.abs(cur - base); itemWithLeastDistance = this.items[j];
4404					this.direction = nearBottom ? "up": "down";
4405				}
4406			}
4407
4408			if(!itemWithLeastDistance && !this.options.dropOnEmpty) //Check if dropOnEmpty is enabled
4409				return;
4410
4411			this.currentContainer = this.containers[innermostIndex];
4412			itemWithLeastDistance ? this._rearrange(event, itemWithLeastDistance, null, true) : this._rearrange(event, null, this.containers[innermostIndex].element, true);
4413			this._trigger("change", event, this._uiHash());
4414			this.containers[innermostIndex]._trigger("change", event, this._uiHash(this));
4415
4416			//Update the placeholder
4417			this.options.placeholder.update(this.currentContainer, this.placeholder);
4418
4419			this.containers[innermostIndex]._trigger("over", event, this._uiHash(this));
4420			this.containers[innermostIndex].containerCache.over = 1;
4421		}
4422
4423
4424	},
4425
4426	_createHelper: function(event) {
4427
4428		var o = this.options;
4429		var helper = $.isFunction(o.helper) ? $(o.helper.apply(this.element[0], [event, this.currentItem])) : (o.helper == 'clone' ? this.currentItem.clone() : this.currentItem);
4430
4431		if(!helper.parents('body').length) //Add the helper to the DOM if that didn't happen already
4432			$(o.appendTo != 'parent' ? o.appendTo : this.currentItem[0].parentNode)[0].appendChild(helper[0]);
4433
4434		if(helper[0] == this.currentItem[0])
4435			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
4435: this.currentItem.css("left") };
4436
4437		if(helper[0].style.width == '' || o.forceHelperSize) helper.width(this.currentItem.width());
4438		if(helper[0].style.height == '' || o.forceHelperSize) helper.height(this.currentItem.height());
4439
4440		return helper;
4441
4442	},
4443
4444	_adjustOffsetFromHelper: function(obj) {
4445		if (typeof obj == 'string') {
4446			obj = obj.split(' ');
4447		}
4448		if ($.isArray(obj)) {
4449			obj = {left: +obj[0], top: +obj[1] || 0};
4450		}
4451		if ('left' in obj) {
4452			this.offset.click.left = obj.left + this.margins.left;
4453		}
4454		if ('right' in obj) {
4455			this.offset.click.left = this.helperProportions.width - obj.right + this.margins.left;
4456		}
4457		if ('top' in obj) {
4458			this.offset.click.top = obj.top + this.margins.top;
4459		}
4460		if ('bottom' in obj) {
4461			this.offset.click.top = this.helperProportions.height - obj.bottom + this.margins.top;
4462		}
4463	},
4464
4465	_getParentOffset: function() {
4466
4467
4468		//Get the offsetParent and cache its position
4469		this.offsetParent = this.helper.offsetParent();
4470		var po = this.offsetParent.offset();
4471
4472		// This is a special case where we need to modify a offset calculated on start, since the following happened:
4473		// 1. The position of the helper is absolute, so it's position is calculated based on the next positioned parent
4474		// 2. The actual offset parent is a child of the scroll parent, and the scroll parent isn't the document, which means that
4475		//    the scroll is included in the initial calculation of the offset of the parent, and never recalculated upon drag
4476		if(this.cssPosition == 'absolute' && this.scrollParent[0] != document && $.contains(this.scrollParent[0], this.offsetParent[0])) {
4477			po.left += this.scrollParent.scrollLeft();
4478			po.top += this.scrollParent.scrollTop();
4479		}
4480
4481		if((this.offsetParent[0] == document.body) //This needs to be actually done for all browsers, since pageX/pageY includes this information
4482		|| (this.offsetParent[0].tagName && this.offsetParent[0].tagName.toLowerCase() == 'html' && $.ui.ie)) //Ugly IE fix
4483			po = { top: 0, left: 0 };
4484
4485		return {
4486			top: po.top + (parseInt(this.offsetParent.css("borderTopWidth"),10) || 0),
4487			left: po.left + (parseInt(this.offsetParent.css("borderLeftWidth"),10) || 0)
4488		};
4489
4490	},
4491
4492	_getRelativeOffset: function() {
4493
4494		if(this.cssPosition == "relative") {
4495			var p = this.currentItem.position();
4496			return {
4497				top: p.top - (parseInt(this.helper.css("top"),10) || 0) + this.scrollParent.scrollTop(),
4498				left: p.left - (parseInt(this.helper.css("left"),10) || 0) + this.scrollParent.scrollLeft()
4499			};
4500		} else {
4501			return { top: 0, left: 0 };
4502		}
4503
4504	},
4505
4506	_cacheMargins: function() {
4507		this.margins = {
4508			left: (parseInt(this.currentItem.css("marginLeft"),10) || 0),
4509			top: (parseInt(this.currentItem.css("marginTop"),10) || 0)
4510		};
4511	},
4512
4513	_cacheHelperProportions: function() {
4514		this.helperProportions = {
4515			width: this.helper.outerWidth(),
4516			height: this.helper.outerHeight()
4517		};
4518	},
4519
4520	_setContainment: function() {
4521
4522		var o = this.options;
4523		if(o.containment == 'parent') o.containment = this.helper[0].parentNode;
4524		if(o.containment == 'document' || o.containment == 'window') this.containment = [
4525			0 - this.offset.relative.left - this.offset.parent.left,
4526			0 - this.offset.relative.top - this.offset.parent.top,
4527			$(o.containment == 'document' ? document : window).width() - this.helperProportions.width - this.margins.left,
4528			($(o.containment == 'document' ? document : window).height() || document.body.parentNode.scrollHeight) - this.helperProportions.height - this.margins.top
4529		];
4530
4531		if(!(/^(document|window|parent)$/).test(o.containment)) {
4532			var ce = $(o.containment)[0];
4533			var co = $(o.containment).offset();
4534			var over = ($(ce).css("overflow") != 'hidden');
4535
4536			this.containment = [
4537				co.left + (parseInt($(ce).css("borderLeftWidth"),10) || 0) + (parseInt($(ce).css("paddingLeft"),10) || 0) - this.margins.left,
4538				co.top + (parseInt($(ce).css("borderTopWidth"),10) || 0) + (parseInt($(ce).css("paddingTop"),10) || 0) - this.margins.top,
4539				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,
4540				co.top+(over ? Math.max(ce.scrollHeight,ce.offsetHeight) : ce.offsetHeight) - (parseInt($(ce).css("borderTopWidth"),
454010) || 0) - (parseInt($(ce).css("paddingBottom"),10) || 0) - this.helperProportions.height - this.margins.top
4541			];
4542		}
4543
4544	},
4545
4546	_convertPositionTo: function(d, pos) {
4547
4548		if(!pos) pos = this.position;
4549		var mod = d == "absolute" ? 1 : -1;
4550		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);
4551
4552		return {
4553			top: (
4554				pos.top																	// The absolute mouse position
4555				+ this.offset.relative.top * mod										// Only for relative positioned nodes: Relative offset from element to offset parent
4556				+ this.offset.parent.top * mod											// The offsetParent's offset without borders (offset + border)
4557				- ( ( this.cssPosition == 'fixed' ? -this.scrollParent.scrollTop() : ( scrollIsRootNode ? 0 : scroll.scrollTop() ) ) * mod)
4558			),
4559			left: (
4560				pos.left																// The absolute mouse position
4561				+ this.offset.relative.left * mod										// Only for relative positioned nodes: Relative offset from element to offset parent
4562				+ this.offset.parent.left * mod											// The offsetParent's offset without borders (offset + border)
4563				- ( ( this.cssPosition == 'fixed' ? -this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 : scroll.scrollLeft() ) * mod)
4564			)
4565		};
4566
4567	},
4568
4569	_generatePosition: function(event) {
4570
4571		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);
4572
4573		// This is another very weird special case that only happens for relative elements:
4574		// 1. If the css position is relative
4575		// 2. and the scroll parent is the document or similar to the offset parent
4576		// we have to refresh the relative offset during the scroll so there are no jumps
4577		if(this.cssPosition == 'relative' && !(this.scrollParent[0] != document && this.scrollParent[0] != this.offsetParent[0])) {
4578			this.offset.relative = this._getRelativeOffset();
4579		}
4580
4581		var pageX = event.pageX;
4582		var pageY = event.pageY;
4583
4584		/*
4585		 * - Position constraining -
4586		 * Constrain the position to a mix of grid, containment.
4587		 */
4588
4589		if(this.originalPosition) { //If we are not dragging yet, we won't check for options
4590
4591			if(this.containment) {
4592				if(event.pageX - this.offset.click.left < this.containment[0]) pageX = this.containment[0] + this.offset.click.left;
4593				if(event.pageY - this.offset.click.top < this.containment[1]) pageY = this.containment[1] + this.offset.click.top;
4594				if(event.pageX - this.offset.click.left > this.containment[2]) pageX = this.containment[2] + this.offset.click.left;
4595				if(event.pageY - this.offset.click.top > this.containment[3]) pageY = this.containment[3] + this.offset.click.top;
4596			}
4597
4598			if(o.grid) {
4599				var top = this.originalPageY + Math.round((pageY - this.originalPageY) / o.grid[1]) * o.grid[1];
4600				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;
4601
4602				var left = this.originalPageX + Math.round((pageX - this.originalPageX) / o.grid[0]) * o.grid[0];
4603				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;
4604			}
4605
4606		}
4607
4608		return {
4609			top: (
4610				pageY																// The absolute mouse position
4611				- this.offset.click.top													// Click offset (relative to the element)
4612				- this.offset.relative.top												// Only for relative positioned nodes: Relative offset from element to offset parent
4613				- this.offset.parent.top												// The offsetParent's offset without borders (offset + border)
4614				+ ( ( this.cssPosition == 'fixed' ? -this.scrollParent.scrollTop() : ( scrollIsRootNode ? 0 : scroll.scrollTop() ) ))
4615			),
4616			left: (
4617				pageX																// The absolute mouse position
4618				- this.offset.click.left												// Click offset (relative to the element)
4619				- this.offset.relative.left												// Only for relative positioned nodes: Relative offset from element to offset parent
4620				- this.offset.parent.left												// The offsetParent's offset without borders (offset + border)
4621				+ ( ( this.cssPosition == 'fixed' ? -this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 : scroll.scrollLeft() ))
4622			)
4623		};
4624
4625	},
4626
4627	_rearrange: function(event, i, a, hardRefresh) {
4628
4629		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));
4630
4631		//Various things done here to improve the performance:
4632		// 1. we create a setTimeout, that calls refreshPositions
4633		// 2. on the instance, we have a counter variable, that get's higher after every append
4634		// 3. on the local scope, we copy the counter variable, and check in the timeout, if it's still the same
4635		// 4. this lets only the last addition to the timeout stack through
4636		this.counter = this.counter ? ++this.counter : 1;
4637		var counter = this.counter;
4638
4639		this._delay(function() {
4640			if(counter == this.counter) this.refreshPositions(!hardRefresh); //Precompute after each DOM insertion, NOT on mousemove
4641		});
4642
4643	},
4644
4645	_clear: function(event, noPropagation) {
4646
4647		this.reverting = false;
4648		// We delay all events that have to be triggered to after the point where the placeholder has been removed and
4649		// everything else normalized again
4650		var delayedTriggers = [];
4651
4652		// We first have to update the dom position of the actual currentItem
4653		// Note: don't do it if the current item is already removed (by a user), or it gets reappended (see #4088)
4654		if(!this._noFinalSort && this.currentItem.parent().length) this.placeholder.before(this.currentItem);
4655		this._noFinalSort = null;
4656
4657		if(this.helper[0] == this.currentItem[0]) {
4658			for(var i in this._storedCSS) {
4659				if(this._storedCSS[i] == 'auto' || this._storedCSS[i] == 'static') this._storedCSS[i] = '';
4660			}
4661			this.currentItem.css(this._storedCSS).removeClass("ui-sortable-helper");
4662		} else {
4663			this.currentItem.show();
4664		}
4665
4666		if(this.fromOutside && !noPropagation) delayedTriggers.push(function(event) { this._trigger("receive", event, this._uiHash(this.fromOutside)); });
4667		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
4668
4669		// Check if the items Container has Changed and trigger appropriate
4670		// events.
4671		if (this !== this.currentContainer) {
4672			if(!noPropagation) {
4673				delayedTriggers.push(function(event) { this._trigger("remove", event, this._uiHash()); });
4674				delayedTriggers.push((function(c) { return function(event) { c._trigger("receive", event, this._uiHash(this)); };  }).call(this, this.currentContainer));
4675				delayedTriggers.push((function(c) { return function(event) { c._trigger("update", event, this._uiHash(this));  }; }).call(this, this.currentContainer));
4676			}
4677		}
4678
4679
4680		//Post events to containers
4681		for (var i = this.containers.length - 1; i >= 0; i--){
4682			if(!noPropagation) delayedTriggers.push((function(c) { return function(event) { c._trigger("deactivate", event, this._uiHash(this)); };  }).call(this, this.containers[i]));
4683			if(this.containers[i].containerCache.over) {
4684				delayedTriggers.push((function(c) { return function(event) { c._trigger("out", event, this._uiHash(this)); };  }).call(this, this.containers[i]));
4685				this.containers[i].containerCache.over = 0;
4686			}
4687		}
4688
4689		//Do what was originally in plugins
4690		if(this._storedCursor) $('body').css("cursor", this._storedCursor); //Reset cursor
4691		if(this._storedOpacity) this.helper.css("opacity", this._storedOpacity); //Reset opacity
4692		if(this._storedZIndex) this.helper.css("zIndex", this._storedZIndex == 'auto' ? '' : this._storedZIndex); //Reset z-index
4693
4694		this.dragging = false;
4695		if(this.cancelHelperRemoval) {
4696			if(!noPropagation) {
4697				this._trigger("beforeStop", event, this._uiHash());
4698				for (var i=0; i < delayedTriggers.length; i++) { delayedTriggers[i].call(this, event); }; //Trigger all delayed events
4699				this._trigger("stop", event, this._uiHash());
4700			}
4701
4702			this.fromOutside = false;
vendor: 11,425 bytes, lines 4703-5134
4703			return false;
4704		}
4705
4706		if(!noPropagation) this._trigger("beforeStop", event, this._uiHash());
4707
4708		//$(this.placeholder[0]).remove(); would have been the jQuery way - unfortunately, it unbinds ALL events from the original node!
4709		this.placeholder[0].parentNode.removeChild(this.placeholder[0]);
4710
4711		if(this.helper[0] != this.currentItem[0]) this.helper.remove(); this.helper = null;
4712
4713		if(!noPropagation) {
4714			for (var i=0; i < delayedTriggers.length; i++) { delayedTriggers[i].call(this, event); }; //Trigger all delayed events
4715			this._trigger("stop", event, this._uiHash());
4716		}
4717
4718		this.fromOutside = false;
4719		return true;
4720
4721	},
4722
4723	_trigger: function() {
4724		if ($.Widget.prototype._trigger.apply(this, arguments) === false) {
4725			this.cancel();
4726		}
4727	},
4728
4729	_uiHash: function(_inst) {
4730		var inst = _inst || this;
4731		return {
4732			helper: inst.helper,
4733			placeholder: inst.placeholder || $([]),
4734			position: inst.position,
4735			originalPosition: inst.originalPosition,
4736			offset: inst.positionAbs,
4737			item: inst.currentItem,
4738			sender: _inst ? _inst.element : null
4739		};
4740	}
4741
4742});
4743
4744})(jQuery);
4745(function( $, undefined ) {
4746
4747var uid = 0,
4748	hideProps = {},
4749	showProps = {};
4750
4751hideProps.height = hideProps.paddingTop = hideProps.paddingBottom =
4752	hideProps.borderTopWidth = hideProps.borderBottomWidth = "hide";
4753showProps.height = showProps.paddingTop = showProps.paddingBottom =
4754	showProps.borderTopWidth = showProps.borderBottomWidth = "show";
4755
4756$.widget( "ui.accordion", {
4757	version: "1.9.2",
4758	options: {
4759		active: 0,
4760		animate: {},
4761		collapsible: false,
4762		event: "click",
4763		header: "> li > :first-child,> :not(li):even",
4764		heightStyle: "auto",
4765		icons: {
4766			activeHeader: "ui-icon-triangle-1-s",
4767			header: "ui-icon-triangle-1-e"
4768		},
4769
4770		// callbacks
4771		activate: null,
4772		beforeActivate: null
4773	},
4774
4775	_create: function() {
4776		var accordionId = this.accordionId = "ui-accordion-" +
4777				(this.element.attr( "id" ) || ++uid),
4778			options = this.options;
4779
4780		this.prevShow = this.prevHide = $();
4781		this.element.addClass( "ui-accordion ui-widget ui-helper-reset" );
4782
4783		this.headers = this.element.find( options.header )
4784			.addClass( "ui-accordion-header ui-helper-reset ui-state-default ui-corner-all" );
4785		this._hoverable( this.headers );
4786		this._focusable( this.headers );
4787
4788		this.headers.next()
4789			.addClass( "ui-accordion-content ui-helper-reset ui-widget-content ui-corner-bottom" )
4790			.hide();
4791
4792		// don't allow collapsible: false and active: false / null
4793		if ( !options.collapsible && (options.active === false || options.active == null) ) {
4794			options.active = 0;
4795		}
4796		// handle negative values
4797		if ( options.active < 0 ) {
4798			options.active += this.headers.length;
4799		}
4800		this.active = this._findActive( options.active )
4801			.addClass( "ui-accordion-header-active ui-state-active" )
4802			.toggleClass( "ui-corner-all ui-corner-top" );
4803		this.active.next()
4804			.addClass( "ui-accordion-content-active" )
4805			.show();
4806
4807		this._createIcons();
4808		this.refresh();
4809
4810		// ARIA
4811		this.element.attr( "role", "tablist" );
4812
4813		this.headers
4814			.attr( "role", "tab" )
4815			.each(function( i ) {
4816				var header = $( this ),
4817					headerId = header.attr( "id" ),
4818					panel = header.next(),
4819					panelId = panel.attr( "id" );
4820				if ( !headerId ) {
4821					headerId = accordionId + "-header-" + i;
4822					header.attr( "id", headerId );
4823				}
4824				if ( !panelId ) {
4825					panelId = accordionId + "-panel-" + i;
4826					panel.attr( "id", panelId );
4827				}
4828				header.attr( "aria-controls", panelId );
4829				panel.attr( "aria-labelledby", headerId );
4830			})
4831			.next()
4832				.attr( "role", "tabpanel" );
4833
4834		this.headers
4835			.not( this.active )
4836			.attr({
4837				"aria-selected": "false",
4838				tabIndex: -1
4839			})
4840			.next()
4841				.attr({
4842					"aria-expanded": "false",
4843					"aria-hidden": "true"
4844				})
4845				.hide();
4846
4847		// make sure at least one header is in the tab order
4848		if ( !this.active.length ) {
4849			this.headers.eq( 0 ).attr( "tabIndex", 0 );
4850		} else {
4851			this.active.attr({
4852				"aria-selected": "true",
4853				tabIndex: 0
4854			})
4855			.next()
4856				.attr({
4857					"aria-expanded": "true",
4858					"aria-hidden": "false"
4859				});
4860		}
4861
4862		this._on( this.headers, { keydown: "_keydown" });
4863		this._on( this.headers.next(), { keydown: "_panelKeyDown" });
4864		this._setupEvents( options.event );
4865	},
4866
4867	_getCreateEventData: function() {
4868		return {
4869			header: this.active,
4870			content: !this.active.length ? $() : this.active.next()
4871		};
4872	},
4873
4874	_createIcons: function() {
4875		var icons = this.options.icons;
4876		if ( icons ) {
4877			$( "<span>" )
4878				.addClass( "ui-accordion-header-icon ui-icon " + icons.header )
4879				.prependTo( this.headers );
4880			this.active.children( ".ui-accordion-header-icon" )
4881				.removeClass( icons.header )
4882				.addClass( icons.activeHeader );
4883			this.headers.addClass( "ui-accordion-icons" );
4884		}
4885	},
4886
4887	_destroyIcons: function() {
4888		this.headers
4889			.removeClass( "ui-accordion-icons" )
4890			.children( ".ui-accordion-header-icon" )
4891				.remove();
4892	},
4893
4894	_destroy: function() {
4895		var contents;
4896
4897		// clean up main element
4898		this.element
4899			.removeClass( "ui-accordion ui-widget ui-helper-reset" )
4900			.removeAttr( "role" );
4901
4902		// clean up headers
4903		this.headers
4904			.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" )
4905			.removeAttr( "role" )
4906			.removeAttr( "aria-selected" )
4907			.removeAttr( "aria-controls" )
4908			.removeAttr( "tabIndex" )
4909			.each(function() {
4910				if ( /^ui-accordion/.test( this.id ) ) {
4911					this.removeAttribute( "id" );
4912				}
4913			});
4914		this._destroyIcons();
4915
4916		// clean up content panels
4917		contents = this.headers.next()
4918			.css( "display", "" )
4919			.removeAttr( "role" )
4920			.removeAttr( "aria-expanded" )
4921			.removeAttr( "aria-hidden" )
4922			.removeAttr( "aria-labelledby" )
4923			.removeClass( "ui-helper-reset ui-widget-content ui-corner-bottom ui-accordion-content ui-accordion-content-active ui-state-disabled" )
4924			.each(function() {
4925				if ( /^ui-accordion/.test( this.id ) ) {
4926					this.removeAttribute( "id" );
4927				}
4928			});
4929		if ( this.options.heightStyle !== "content" ) {
4930			contents.css( "height", "" );
4931		}
4932	},
4933
4934	_setOption: function( key, value ) {
4935		if ( key === "active" ) {
4936			// _activate() will handle invalid values and update this.options
4937			this._activate( value );
4938			return;
4939		}
4940
4941		if ( key === "event" ) {
4942			if ( this.options.event ) {
4943				this._off( this.headers, this.options.event );
4944			}
4945			this._setupEvents( value );
4946		}
4947
4948		this._super( key, value );
4949
4950		// setting collapsible: false while collapsed; open first panel
4951		if ( key === "collapsible" && !value && this.options.active === false ) {
4952			this._activate( 0 );
4953		}
4954
4955		if ( key === "icons" ) {
4956			this._destroyIcons();
4957			if ( value ) {
4958				this._createIcons();
4959			}
4960		}
4961
4962		// #5332 - opacity doesn't cascade to positioned elements in IE
4963		// so we need to add the disabled class to the headers and panels
4964		if ( key === "disabled" ) {
4965			this.headers.add( this.headers.next() )
4966				.toggleClass( "ui-state-disabled", !!value );
4967		}
4968	},
4969
4970	_keydown: function( event ) {
4971		if ( event.altKey || event.ctrlKey ) {
4972			return;
4973		}
4974
4975		var keyCode = $.ui.keyCode,
4976			length = this.headers.length,
4977			currentIndex = this.headers.index( event.target ),
4978			toFocus = false;
4979
4980		switch ( event.keyCode ) {
4981			case keyCode.RIGHT:
4982			case keyCode.DOWN:
4983				toFocus = this.headers[ ( currentIndex + 1 ) % length ];
4984				break;
4985			case keyCode.LEFT:
4986			case keyCode.UP:
4987				toFocus = this.headers[ ( currentIndex - 1 + length ) % length ];
4988				break;
4989			case keyCode.SPACE:
4990			case keyCode.ENTER:
4991				this._eventHandler( event );
4992				break;
4993			case keyCode.HOME:
4994				toFocus = this.headers[ 0 ];
4995				break;
4996			case keyCode.END:
4997				toFocus = this.headers[ length - 1 ];
4998				break;
4999		}
5000
5001		if ( toFocus ) {
5002			$( event.target ).attr( "tabIndex", -1 );
5003			$( toFocus ).attr( "tabIndex", 0 );
5004			toFocus.focus();
5005			event.preventDefault();
5006		}
5007	},
5008
5009	_panelKeyDown : function( event ) {
5010		if ( event.keyCode === $.ui.keyCode.UP && event.ctrlKey ) {
5011			$( event.currentTarget ).prev().focus();
5012		}
5013	},
5014
5015	refresh: function() {
5016		var maxHeight, overflow,
5017			heightStyle = this.options.heightStyle,
5018			parent = this.element.parent();
5019
5020
5021		if ( heightStyle === "fill" ) {
5022			// IE 6 treats height like minHeight, so we need to turn off overflow
5023			// in order to get a reliable height
5024			// we use the minHeight support test because we assume that only
5025			// browsers that don't support minHeight will treat height as minHeight
5026			if ( !$.support.minHeight ) {
5027				overflow = parent.css( "overflow" );
5028				parent.css( "overflow", "hidden");
5029			}
5030			maxHeight = parent.height();
5031			this.element.siblings( ":visible" ).each(function() {
5032				var elem = $( this ),
5033					position = elem.css( "position" );
5034
5035				if ( position === "absolute" || position === "fixed" ) {
5036					return;
5037				}
5038				maxHeight -= elem.outerHeight( true );
5039			});
5040			if ( overflow ) {
5041				parent.css( "overflow", overflow );
5042			}
5043
5044			this.headers.each(function() {
5045				maxHeight -= $( this ).outerHeight( true );
5046			});
5047
5048			this.headers.next()
5049				.each(function() {
5050					$( this ).height( Math.max( 0, maxHeight -
5051						$( this ).innerHeight() + $( this ).height() ) );
5052				})
5053				.css( "overflow", "auto" );
5054		} else if ( heightStyle === "auto" ) {
5055			maxHeight = 0;
5056			this.headers.next()
5057				.each(function() {
5058					maxHeight = Math.max( maxHeight, $( this ).css( "height", "" ).height() );
5059				})
5060				.height( maxHeight );
5061		}
5062	},
5063
5064	_activate: function( index ) {
5065		var active = this._findActive( index )[ 0 ];
5066
5067		// trying to activate the already active panel
5068		if ( active === this.active[ 0 ] ) {
5069			return;
5070		}
5071
5072		// trying to collapse, simulate a click on the currently active header
5073		active = active || this.active[ 0 ];
5074
5075		this._eventHandler({
5076			target: active,
5077			currentTarget: active,
5078			preventDefault: $.noop
5079		});
5080	},
5081
5082	_findActive: function( selector ) {
5083		return typeof selector === "number" ? this.headers.eq( selector ) : $();
5084	},
5085
5086	_setupEvents: function( event ) {
5087		var events = {};
5088		if ( !event ) {
5089			return;
5090		}
5091		$.each( event.split(" "), function( index, eventName ) {
5092			events[ eventName ] = "_eventHandler";
5093		});
5094		this._on( this.headers, events );
5095	},
5096
5097	_eventHandler: function( event ) {
5098		var options = this.options,
5099			active = this.active,
5100			clicked = $( event.currentTarget ),
5101			clickedIsActive = clicked[ 0 ] === active[ 0 ],
5102			collapsing = clickedIsActive && options.collapsible,
5103			toShow = collapsing ? $() : clicked.next(),
5104			toHide = active.next(),
5105			eventData = {
5106				oldHeader: active,
5107				oldPanel: toHide,
5108				newHeader: collapsing ? $() : clicked,
5109				newPanel: toShow
5110			};
5111
5112		event.preventDefault();
5113
5114		if (
5115				// click on active header, but not collapsible
5116				( clickedIsActive && !options.collapsible ) ||
5117				// allow canceling activation
5118				( this._trigger( "beforeActivate", event, eventData ) === false ) ) {
5119			return;
5120		}
5121
5122		options.active = collapsing ? false : this.headers.index( clicked );
5123
5124		// when the call to ._toggle() comes after the class changes
5125		// it causes a very odd bug in IE 8 (see #6720)
5126		this.active = clickedIsActive ? $() : clicked;
5127		this._toggle( eventData );
5128
5129		// switch classes
5130		// corner classes on the previously active header stay after the animation
5131		active.removeClass( "ui-accordion-header-active ui-state-active" );
5132		if ( options.icons ) {
5133			active.children( ".ui-accordion-header-icon" )
5134				.removeClass( options.icons.activeHeader )
5135				.addClass( options.icons.header );
5136		}
5137
5138		if ( !clickedIsActive ) {
5139			clicked
5140				.removeClass( "ui-corner-all" )
5141				.addClass( "ui-accordion-header-active ui-state-active ui-corner-top" );
5142			if ( options.icons ) {
5143				clicked.children( ".ui-accordion-header-icon" )
5144					.removeClass( options.icons.header )
5145					.addClass( options.icons.activeHeader );
5146			}
5147
5148			clicked
5149				.next()
5150				.addClass( "ui-accordion-content-active" );
5151		}
5152	},
5153
5154	_toggle: function( data ) {
5155		var toShow = data.newPanel,
5156			toHide = this.prevShow.length ? this.prevShow : data.oldPanel;
5157
5158		// handle activating a panel during the animation for another activation
5159		this.prevShow.add( this.prevHide ).stop( true, true );
5160		this.prevShow = toShow;
5161		this.prevHide = toHide;
5162
5163		if ( this.options.animate ) {
5164			this._animate( toShow, toHide, data );
5165		} else {
5166			toHide.hide();
5167			toShow.show();
5168			this._toggleComplete( data );
5169		}
5170
5171		toHide.attr({
5172			"aria-expanded": "false",
5173			"aria-hidden": "true"
5174		});
5175		toHide.prev().attr( "aria-selected", "false" );
5176		// if we're switching panels, remove the old header from the tab order
5177		// if we're opening from collapsed state, remove the previous header from the tab order
5178		// if we're collapsing, then keep the collapsing header in the tab order
5179		if ( toShow.length && toHide.length ) {
5180			toHide.prev().attr( "tabIndex", -1 );
5181		} else if ( toShow.length ) {
5182			this.headers.filter(function() {
5183				return $( this ).attr( "tabIndex" ) === 0;
5184			})
5185			.attr( "tabIndex", -1 );
5186		}
5187
5188		toShow
5189			.attr({
5190				"aria-expanded": "true",
5191				"aria-hidden": "false"
5192			})
5193			.prev()
5194				.attr({
5195					"aria-selected": "true",
5196					tabIndex: 0
5197				});
5198	},
5199
5200	_animate: function( toShow, toHide, data ) {
5201		var total, easing, duration,
5202			that = this,
5203			adjust = 0,
5204			down = toShow.length &&
5205				( !toHide.length || ( toShow.index() < toHide.index() ) ),
5206			animate = this.options.animate || {},
5207			options = down && animate.down || animate,
5208			complete = function() {
5209				that._toggleComplete( data );
5210			};
5211
5212		if ( typeof options === "number" ) {
5213			duration = options;
5214		}
5215		if ( typeof options === "string" ) {
5216			easing = options;
5217		}
5218		// fall back from options to animation in case of partial down settings
5219		easing = easing || options.easing || animate.easing;
5220		duration = duration || options.duration || animate.duration;
5221
5222		if ( !toHide.length ) {
5223			return toShow.animate( showProps, duration, easing, complete );
5224		}
5225		if ( !toShow.length ) {
5226			return toHide.animate( hideProps, duration, easing, complete );
5227		}
5228
5229		total = toShow.show().outerHeight();
5230		toHide.animate( hideProps, {
5231			duration: duration,
5232			easing: easing,
5233			step: function( now, fx ) {
5234				fx.now = Math.round( now );
5235			}
5236		});
5237		toShow
5238			.hide()
5239			.animate( showProps, {
5240				duration: duration,
5241				easing: easing,
5242				complete: complete,
5243				step: function( now, fx ) {
5244					fx.now = Math.round( now );
5245					if ( fx.prop !== "height" ) {
5246						adjust += fx.now;
5247					} else if ( that.options.heightStyle !== "content" ) {
5248						fx.now = Math.round( total - toHide.outerHeight() - adjust );
5249						adjust = 0;
5250					}
5251				}
5252			});
5253	},
5254
5255	_toggleComplete: function( data ) {
5256		var toHide = data.oldPanel;
5257
5258		toHide
5259			.removeClass( "ui-accordion-content-active" )
5260			.prev()
5261				.removeClass( "ui-corner-top" )
5262				.addClass( "ui-corner-all" );
5263
5264		// Work around for rendering bug in IE (#5421)
5265		if ( toHide.length ) {
5266			toHide.parent()[0].className = toHide.parent()[0].className;
5267		}
5268
5269		this._trigger( "activate", null, data );
5270	}
5271});
5272
5273
5274
5275// DEPRECATED
5276if ( $.uiBackCompat !== false ) {
5277	// navigation options
5278	(function( $, prototype ) {
5279		$.extend( prototype.options, {
5280			navigation: false,
5281			navigationFilter: function() {
5282				return this.href.toLowerCase() === location.href.toLowerCase();
5283			}
5284		});
5285
5286		var _create = prototype._create;
5287		prototype._create = function() {
5288			if ( this.options.navigation ) {
5289				var that = this,
5290					headers = this.element.find( this.options.header ),
5291					content = headers.next(),
5292					current = headers.add( content )
5293						.find( "a" )
5294						.filter( this.options.navigationFilter )
5295						[ 0 ];
5296				if ( current ) {
5297					headers.add( content ).each( function( index ) {
5298						if ( $.contains( this, current ) ) {
5299							that.options.active = Math.floor( index / 2 );
5300							return false;
5301						}
5302					});
5303				}
5304			}
5305			_create.call( this );
5306		};
5307	}( jQuery, jQuery.ui.accordion.prototype ) );
5308
5309	// height options
5310	(function( $, prototype ) {
5311		$.extend( prototype.options, {
5312			heightStyle: null, // remove default so we fall back to old values
5313			autoHeight: true, // use heightStyle: "auto"
5314			clearStyle: false, // use heightStyle: "content"
5315			fillSpace: false // use heightStyle: "fill"
5316		});
5317
5318		var _create = prototype._create,
5319			_setOption = prototype._setOption;
5320
5321		$.extend( prototype, {
5322			_create: function() {
5323				this.options.heightStyle = this.options.heightStyle ||
5324					this._mergeHeightStyle();
5325
5326				_create.call( this );
5327			},
5328
5329			_setOption: function( key ) {
5330				if ( key === "autoHeight" || key === "clearStyle" || key === "fillSpace" ) {
5331					this.options.heightStyle = this._mergeHeightStyle();
5332				}
5333				_setOption.apply( this, arguments );
5334			},
5335
5336			_mergeHeightStyle: function() {
5337				var options = this.options;
5338
5339				if ( options.fillSpace ) {
5340					return "fill";
5341				}
5342
5343				if ( options.clearStyle ) {
5344					return "content";
5345				}
5346
5347				if ( options.autoHeight ) {
5348					return "auto";
5349				}
5350			}
5351		});
5352	}( jQuery, jQuery.ui.accordion.prototype ) );
5353
5354	// icon options
5355	(function( $, prototype ) {
5356		$.extend( prototype.options.icons, {
5357			activeHeader: null, // remove default so we fall back to old values
5358			headerSelected: "ui-icon-triangle-1-s"
5359		});
5360
5361		var _createIcons = prototype._createIcons;
5362		prototype._createIcons = function() {
5363			if ( this.options.icons ) {
5364				this.options.icons.activeHeader = this.options.icons.activeHeader ||
5365					this.options.icons.headerSelected;
5366			}
5367			_createIcons.call( this );
5368		};
5369	}( jQuery, jQuery.ui.accordion.prototype ) );
5370
5371	// expanded active option, activate method
5372	(function( $, prototype ) {
5373		prototype.activate = prototype._activate;
5374
5375		var _findActive = prototype._findActive;
5376		prototype._findActive = function( index ) {
5377			if ( index === -1 ) {
5378				index = false;
5379			}
5380			if ( index && typeof index !== "number" ) {
5381				index = this.headers.index( this.headers.filter( index ) );
5382				if ( index === -1 ) {
5383					index = false;
5384				}
5385			}
5386			return _findActive.call( this, index );
5387		};
5388	}( jQuery, jQuery.ui.accordion.prototype ) );
5389
5390	// resize method
5391	jQuery.ui.accordion.prototype.resize = jQuery.ui.accordion.prototype.refresh;
5392
5393	// change events
5394	(function( $, prototype ) {
5395		$.extend( prototype.options, {
5396			change: null,
5397			changestart: null
5398		});
5399
5400		var _trigger = prototype._trigger;
5401		prototype._trigger = function( type, event, data ) {
5402			var ret = _trigger.apply( this, arguments );
5403			if ( !ret ) {
5404				return false;
5405			}
5406
5407			if ( type === "beforeActivate" ) {
5408				ret = _trigger.call( this, "changestart", event, {
5409					oldHeader: data.oldHeader,
5410					oldContent: data.oldPanel,
5411					newHeader: data.newHeader,
5412					newContent: data.newPanel
5413				});
5414			} else if ( type === "activate" ) {
5415				ret = _trigger.call( this, "change", event, {
5416					oldHeader: data.oldHeader,
5417					oldContent: data.oldPanel,
5418					newHeader: data.newHeader,
5419					newContent: data.newPanel
5420				});
5421			}
5422			return ret;
5423		};
5424	}( jQuery, jQuery.ui.accordion.prototype ) );
5425
5426	// animated option
5427	// NOTE: this only provides support for "slide", "bounceslide", and easings
5428	// not the full $.ui.accordion.animations API
5429	(function( $, prototype ) {
5430		$.extend( prototype.options, {
5431			animate: null,
5432			animated: "slide"
5433		});
5434
5435		var _create = prototype._create;
5436		prototype._create = function() {
5437			var options = this.options;
5438			if ( options.animate === null ) {
5439				if ( !options.animated ) {
5440					options.animate = false;
5441				} else if ( options.animated === "slide" ) {
5442					options.animate = 300;
5443				} else if ( options.animated === "bounceslide" ) {
5444					options.animate = {
5445						duration: 200,
5446						down: {
5447							easing: "easeOutBounce",
5448							duration: 1000
5449						}
5450					};
5451				} else {
5452					options.animate = options.animated;
5453				}
5454			}
5455
5456			_create.call( this );
5457		};
5458	}( jQuery, jQuery.ui.accordion.prototype ) );
5459}
5460
5461})( jQuery );
5462(function( $, undefined ) {
5463
5464// used to prevent race conditions with remote data sources
5465var requestIndex = 0;
5466
5467$.widget( "ui.autocomplete", {
5468	version: "1.9.2",
5469	defaultElement: "<input>",
5470	options: {
5471		appendTo: "body",
5472		autoFocus: false,
5473		delay: 300,
5474		minLength: 1,
5475		position: {
5476			my: "left top",
5477			at: "left bottom",
5478			collision: "none"
5479		},
5480		source: null,
5481
5482		// callbacks
5483		change: null,
5484		close: null,
5485		focus: null,
5486		open: null,
5487		response: null,
5488		search: null,
5489		select: null
5490	},
5491
5492	pending: 0,
5493
5494	_create: function() {
5495		// Some browsers only repeat keydown events, not keypress events,
5496		// so we use the suppressKeyPress flag to determine if we've already
5497		// handled the keydown event. #7269
5498		// Unfortunately the code for & in keypress is the same as the up arrow,
5499		// so we use the suppressKeyPressRepeat flag to avoid handling keypress
5500		// events when we know the keydown event was used to modify the
5501		// search term. #7799
5502		var suppressKeyPress, suppressKeyPressRepeat, suppressInput;
5503
5504		this.isMultiLine = this._isMultiLine();
5505		this.valueMethod = this.element[ this.element.is( "input,textarea" ) ? "val" : "text" ];
5506		this.isNewMenu = true;
5507
5508		this.element
5509			.addClass( "ui-autocomplete-input" )
5510			.attr( "autocomplete", "off" );
5511
5512		this._on( this.element, {
5513			keydown: function( event ) {
5514				if ( this.element.prop( "readOnly" ) ) {
5515					suppressKeyPress = true;
5516					suppressInput = true;
5517					suppressKeyPressRepeat = true;
5518					return;
5519				}
5520
5521				suppressKeyPress = false;
vendor: 21,656 bytes, lines 5522-6300
5522				suppressInput = false;
5523				suppressKeyPressRepeat = false;
5524				var keyCode = $.ui.keyCode;
5525				switch( event.keyCode ) {
5526				case keyCode.PAGE_UP:
5527					suppressKeyPress = true;
5528					this._move( "previousPage", event );
5529					break;
5530				case keyCode.PAGE_DOWN:
5531					suppressKeyPress = true;
5532					this._move( "nextPage", event );
5533					break;
5534				case keyCode.UP:
5535					suppressKeyPress = true;
5536					this._keyEvent( "previous", event );
5537					break;
5538				case keyCode.DOWN:
5539					suppressKeyPress = true;
5540					this._keyEvent( "next", event );
5541					break;
5542				case keyCode.ENTER:
5543				case keyCode.NUMPAD_ENTER:
5544					// when menu is open and has focus
5545					if ( this.menu.active ) {
5546						// #6055 - Opera still allows the keypress to occur
5547						// which causes forms to submit
5548						suppressKeyPress = true;
5549						event.preventDefault();
5550						this.menu.select( event );
5551					}
5552					break;
5553				case keyCode.TAB:
5554					if ( this.menu.active ) {
5555						this.menu.select( event );
5556					}
5557					break;
5558				case keyCode.ESCAPE:
5559					if ( this.menu.element.is( ":visible" ) ) {
5560						this._value( this.term );
5561						this.close( event );
5562						// Different browsers have different default behavior for escape
5563						// Single press can mean undo or clear
5564						// Double press in IE means clear the whole form
5565						event.preventDefault();
5566					}
5567					break;
5568				default:
5569					suppressKeyPressRepeat = true;
5570					// search timeout should be triggered before the input value is changed
5571					this._searchTimeout( event );
5572					break;
5573				}
5574			},
5575			keypress: function( event ) {
5576				if ( suppressKeyPress ) {
5577					suppressKeyPress = false;
5578					event.preventDefault();
5579					return;
5580				}
5581				if ( suppressKeyPressRepeat ) {
5582					return;
5583				}
5584
5585				// replicate some key handlers to allow them to repeat in Firefox and Opera
5586				var keyCode = $.ui.keyCode;
5587				switch( event.keyCode ) {
5588				case keyCode.PAGE_UP:
5589					this._move( "previousPage", event );
5590					break;
5591				case keyCode.PAGE_DOWN:
5592					this._move( "nextPage", event );
5593					break;
5594				case keyCode.UP:
5595					this._keyEvent( "previous", event );
5596					break;
5597				case keyCode.DOWN:
5598					this._keyEvent( "next", event );
5599					break;
5600				}
5601			},
5602			input: function( event ) {
5603				if ( suppressInput ) {
5604					suppressInput = false;
5605					event.preventDefault();
5606					return;
5607				}
5608				this._searchTimeout( event );
5609			},
5610			focus: function() {
5611				this.selectedItem = null;
5612				this.previous = this._value();
5613			},
5614			blur: function( event ) {
5615				if ( this.cancelBlur ) {
5616					delete this.cancelBlur;
5617					return;
5618				}
5619
5620				clearTimeout( this.searching );
5621				this.close( event );
5622				this._change( event );
5623			}
5624		});
5625
5626		this._initSource();
5627		this.menu = $( "<ul>" )
5628			.addClass( "ui-autocomplete" )
5629			.appendTo( this.document.find( this.options.appendTo || "body" )[ 0 ] )
5630			.menu({
5631				// custom key handling for now
5632				input: $(),
5633				// disable ARIA support, the live region takes care of that
5634				role: null
5635			})
5636			.zIndex( this.element.zIndex() + 1 )
5637			.hide()
5638			.data( "menu" );
5639
5640		this._on( this.menu.element, {
5641			mousedown: function( event ) {
5642				// prevent moving focus out of the text field
5643				event.preventDefault();
5644
5645				// IE doesn't prevent moving focus even with event.preventDefault()
5646				// so we set a flag to know when we should ignore the blur event
5647				this.cancelBlur = true;
5648				this._delay(function() {
5649					delete this.cancelBlur;
5650				});
5651
5652				// clicking on the scrollbar causes focus to shift to the body
5653				// but we can't detect a mouseup or a click immediately afterward
5654				// so we have to track the next mousedown and close the menu if
5655				// the user clicks somewhere outside of the autocomplete
5656				var menuElement = this.menu.element[ 0 ];
5657				if ( !$( event.target ).closest( ".ui-menu-item" ).length ) {
5658					this._delay(function() {
5659						var that = this;
5660						this.document.one( "mousedown", function( event ) {
5661							if ( event.target !== that.element[ 0 ] &&
5662									event.target !== menuElement &&
5663									!$.contains( menuElement, event.target ) ) {
5664								that.close();
5665							}
5666						});
5667					});
5668				}
5669			},
5670			menufocus: function( event, ui ) {
5671				// #7024 - Prevent accidental activation of menu items in Firefox
5672				if ( this.isNewMenu ) {
5673					this.isNewMenu = false;
5674					if ( event.originalEvent && /^mouse/.test( event.originalEvent.type ) ) {
5675						this.menu.blur();
5676
5677						this.document.one( "mousemove", function() {
5678							$( event.target ).trigger( event.originalEvent );
5679						});
5680
5681						return;
5682					}
5683				}
5684
5685				// back compat for _renderItem using item.autocomplete, via #7810
5686				// TODO remove the fallback, see #8156
5687				var item = ui.item.data( "ui-autocomplete-item" ) || ui.item.data( "item.autocomplete" );
5688				if ( false !== this._trigger( "focus", event, { item: item } ) ) {
5689					// use value to match what will end up in the input, if it was a key event
5690					if ( event.originalEvent && /^key/.test( event.originalEvent.type ) ) {
5691						this._value( item.value );
5692					}
5693				} else {
5694					// Normally the input is populated with the item's value as the
5695					// menu is navigated, causing screen readers to notice a change and
5696					// announce the item. Since the focus event was canceled, this doesn't
5697					// happen, so we update the live region so that screen readers can
5698					// still notice the change and announce it.
5699					this.liveRegion.text( item.value );
5700				}
5701			},
5702			menuselect: function( event, ui ) {
5703				// back compat for _renderItem using item.autocomplete, via #7810
5704				// TODO remove the fallback, see #8156
5705				var item = ui.item.data( "ui-autocomplete-item" ) || ui.item.data( "item.autocomplete" ),
5706					previous = this.previous;
5707
5708				// only trigger when focus was lost (click on menu)
5709				if ( this.element[0] !== this.document[0].activeElement ) {
5710					this.element.focus();
5711					this.previous = previous;
5712					// #6109 - IE triggers two focus events and the second
5713					// is asynchronous, so we need to reset the previous
5714					// term synchronously and asynchronously :-(
5715					this._delay(function() {
5716						this.previous = previous;
5717						this.selectedItem = item;
5718					});
5719				}
5720
5721				if ( false !== this._trigger( "select", event, { item: item } ) ) {
5722					this._value( item.value );
5723				}
5724				// reset the term after the select event
5725				// this allows custom select handling to work properly
5726				this.term = this._value();
5727
5728				this.close( event );
5729				this.selectedItem = item;
5730			}
5731		});
5732
5733		this.liveRegion = $( "<span>", {
5734				role: "status",
5735				"aria-live": "polite"
5736			})
5737			.addClass( "ui-helper-hidden-accessible" )
5738			.insertAfter( this.element );
5739
5740		if ( $.fn.bgiframe ) {
5741			this.menu.element.bgiframe();
5742		}
5743
5744		// turning off autocomplete prevents the browser from remembering the
5745		// value when navigating through history, so we re-enable autocomplete
5746		// if the page is unloaded before the widget is destroyed. #7790
5747		this._on( this.window, {
5748			beforeunload: function() {
5749				this.element.removeAttr( "autocomplete" );
5750			}
5751		});
5752	},
5753
5754	_destroy: function() {
5755		clearTimeout( this.searching );
5756		this.element
5757			.removeClass( "ui-autocomplete-input" )
5758			.removeAttr( "autocomplete" );
5759		this.menu.element.remove();
5760		this.liveRegion.remove();
5761	},
5762
5763	_setOption: function( key, value ) {
5764		this._super( key, value );
5765		if ( key === "source" ) {
5766			this._initSource();
5767		}
5768		if ( key === "appendTo" ) {
5769			this.menu.element.appendTo( this.document.find( value || "body" )[0] );
5770		}
5771		if ( key === "disabled" && value && this.xhr ) {
5772			this.xhr.abort();
5773		}
5774	},
5775
5776	_isMultiLine: function() {
5777		// Textareas are always multi-line
5778		if ( this.element.is( "textarea" ) ) {
5779			return true;
5780		}
5781		// Inputs are always single-line, even if inside a contentEditable element
5782		// IE also treats inputs as contentEditable
5783		if ( this.element.is( "input" ) ) {
5784			return false;
5785		}
5786		// All other element types are determined by whether or not they're contentEditable
5787		return this.element.prop( "isContentEditable" );
5788	},
5789
5790	_initSource: function() {
5791		var array, url,
5792			that = this;
5793		if ( $.isArray(this.options.source) ) {
5794			array = this.options.source;
5795			this.source = function( request, response ) {
5796				response( $.ui.autocomplete.filter( array, request.term ) );
5797			};
5798		} else if ( typeof this.options.source === "string" ) {
5799			url = this.options.source;
5800			this.source = function( request, response ) {
5801				if ( that.xhr ) {
5802					that.xhr.abort();
5803				}
5804				that.xhr = $.ajax({
5805					url: url,
5806					data: request,
5807					dataType: "json",
5808					success: function( data ) {
5809						response( data );
5810					},
5811					error: function() {
5812						response( [] );
5813					}
5814				});
5815			};
5816		} else {
5817			this.source = this.options.source;
5818		}
5819	},
5820
5821	_searchTimeout: function( event ) {
5822		clearTimeout( this.searching );
5823		this.searching = this._delay(function() {
5824			// only search if the value has changed
5825			if ( this.term !== this._value() ) {
5826				this.selectedItem = null;
5827				this.search( null, event );
5828			}
5829		}, this.options.delay );
5830	},
5831
5832	search: function( value, event ) {
5833		value = value != null ? value : this._value();
5834
5835		// always save the actual value, not the one passed as an argument
5836		this.term = this._value();
5837
5838		if ( value.length < this.options.minLength ) {
5839			return this.close( event );
5840		}
5841
5842		if ( this._trigger( "search", event ) === false ) {
5843			return;
5844		}
5845
5846		return this._search( value );
5847	},
5848
5849	_search: function( value ) {
5850		this.pending++;
5851		this.element.addClass( "ui-autocomplete-loading" );
5852		this.cancelSearch = false;
5853
5854		this.source( { term: value }, this._response() );
5855	},
5856
5857	_response: function() {
5858		var that = this,
5859			index = ++requestIndex;
5860
5861		return function( content ) {
5862			if ( index === requestIndex ) {
5863				that.__response( content );
5864			}
5865
5866			that.pending--;
5867			if ( !that.pending ) {
5868				that.element.removeClass( "ui-autocomplete-loading" );
5869			}
5870		};
5871	},
5872
5873	__response: function( content ) {
5874		if ( content ) {
5875			content = this._normalize( content );
5876		}
5877		this._trigger( "response", null, { content: content } );
5878		if ( !this.options.disabled && content && content.length && !this.cancelSearch ) {
5879			this._suggest( content );
5880			this._trigger( "open" );
5881		} else {
5882			// use ._close() instead of .close() so we don't cancel future searches
5883			this._close();
5884		}
5885	},
5886
5887	close: function( event ) {
5888		this.cancelSearch = true;
5889		this._close( event );
5890	},
5891
5892	_close: function( event ) {
5893		if ( this.menu.element.is( ":visible" ) ) {
5894			this.menu.element.hide();
5895			this.menu.blur();
5896			this.isNewMenu = true;
5897			this._trigger( "close", event );
5898		}
5899	},
5900
5901	_change: function( event ) {
5902		if ( this.previous !== this._value() ) {
5903			this._trigger( "change", event, { item: this.selectedItem } );
5904		}
5905	},
5906
5907	_normalize: function( items ) {
5908		// assume all items have the right format when the first item is complete
5909		if ( items.length && items[0].label && items[0].value ) {
5910			return items;
5911		}
5912		return $.map( items, function( item ) {
5913			if ( typeof item === "string" ) {
5914				return {
5915					label: item,
5916					value: item
5917				};
5918			}
5919			return $.extend({
5920				label: item.label || item.value,
5921				value: item.value || item.label
5922			}, item );
5923		});
5924	},
5925
5926	_suggest: function( items ) {
5927		var ul = this.menu.element
5928			.empty()
5929			.zIndex( this.element.zIndex() + 1 );
5930		this._renderMenu( ul, items );
5931		this.menu.refresh();
5932
5933		// size and position menu
5934		ul.show();
5935		this._resizeMenu();
5936		ul.position( $.extend({
5937			of: this.element
5938		}, this.options.position ));
5939
5940		if ( this.options.autoFocus ) {
5941			this.menu.next();
5942		}
5943	},
5944
5945	_resizeMenu: function() {
5946		var ul = this.menu.element;
5947		ul.outerWidth( Math.max(
5948			// Firefox wraps long text (possibly a rounding bug)
5949			// so we add 1px to avoid the wrapping (#7513)
5950			ul.width( "" ).outerWidth() + 1,
5951			this.element.outerWidth()
5952		) );
5953	},
5954
5955	_renderMenu: function( ul, items ) {
5956		var that = this;
5957		$.each( items, function( index, item ) {
5958			that._renderItemData( ul, item );
5959		});
5960	},
5961
5962	_renderItemData: function( ul, item ) {
5963		return this._renderItem( ul, item ).data( "ui-autocomplete-item", item );
5964	},
5965
5966	_renderItem: function( ul, item ) {
5967		return $( "<li>" )
5968			.append( $( "<a>" ).text( item.label ) )
5969			.appendTo( ul );
5970	},
5971
5972	_move: function( direction, event ) {
5973		if ( !this.menu.element.is( ":visible" ) ) {
5974			this.search( null, event );
5975			return;
5976		}
5977		if ( this.menu.isFirstItem() && /^previous/.test( direction ) ||
5978				this.menu.isLastItem() && /^next/.test( direction ) ) {
5979			this._value( this.term );
5980			this.menu.blur();
5981			return;
5982		}
5983		this.menu[ direction ]( event );
5984	},
5985
5986	widget: function() {
5987		return this.menu.element;
5988	},
5989
5990	_value: function() {
5991		return this.valueMethod.apply( this.element, arguments );
5992	},
5993
5994	_keyEvent: function( keyEvent, event ) {
5995		if ( !this.isMultiLine || this.menu.element.is( ":visible" ) ) {
5996			this._move( keyEvent, event );
5997
5998			// prevents moving cursor to beginning/end of the text field in some browsers
5999			event.preventDefault();
6000		}
6001	}
6002});
6003
6004$.extend( $.ui.autocomplete, {
6005	escapeRegex: function( value ) {
6006		return value.replace(/[\-\[\]{}()*+?.,\\\^$|#\s]/g, "\\$&");
6007	},
6008	filter: function(array, term) {
6009		var matcher = new RegExp( $.ui.autocomplete.escapeRegex(term), "i" );
6010		return $.grep( array, function(value) {
6011			return matcher.test( value.label || value.value || value );
6012		});
6013	}
6014});
6015
6016
6017// live region extension, adding a `messages` option
6018// NOTE: This is an experimental API. We are still investigating
6019// a full solution for string manipulation and internationalization.
6020$.widget( "ui.autocomplete", $.ui.autocomplete, {
6021	options: {
6022		messages: {
6023			noResults: "No search results.",
6024			results: function( amount ) {
6025				return amount + ( amount > 1 ? " results are" : " result is" ) +
6026					" available, use up and down arrow keys to navigate.";
6027			}
6028		}
6029	},
6030
6031	__response: function( content ) {
6032		var message;
6033		this._superApply( arguments );
6034		if ( this.options.disabled || this.cancelSearch ) {
6035			return;
6036		}
6037		if ( content && content.length ) {
6038			message = this.options.messages.results( content.length );
6039		} else {
6040			message = this.options.messages.noResults;
6041		}
6042		this.liveRegion.text( message );
6043	}
6044});
6045
6046
6047}( jQuery ));
6048(function( $, undefined ) {
6049
6050var lastActive, startXPos, startYPos, clickDragged,
6051	baseClasses = "ui-button ui-widget ui-state-default ui-corner-all",
6052	stateClasses = "ui-state-hover ui-state-active ",
6053	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",
6054	formResetHandler = function() {
6055		var buttons = $( this ).find( ":ui-button" );
6056		setTimeout(function() {
6057			buttons.button( "refresh" );
6058		}, 1 );
6059	},
6060	radioGroup = function( radio ) {
6061		var name = radio.name,
6062			form = radio.form,
6063			radios = $( [] );
6064		if ( name ) {
6065			if ( form ) {
6066				radios = $( form ).find( "[name='" + name + "']" );
6067			} else {
6068				radios = $( "[name='" + name + "']", radio.ownerDocument )
6069					.filter(function() {
6070						return !this.form;
6071					});
6072			}
6073		}
6074		return radios;
6075	};
6076
6077$.widget( "ui.button", {
6078	version: "1.9.2",
6079	defaultElement: "<button>",
6080	options: {
6081		disabled: null,
6082		text: true,
6083		label: null,
6084		icons: {
6085			primary: null,
6086			secondary: null
6087		}
6088	},
6089	_create: function() {
6090		this.element.closest( "form" )
6091			.unbind( "reset" + this.eventNamespace )
6092			.bind( "reset" + this.eventNamespace, formResetHandler );
6093
6094		if ( typeof this.options.disabled !== "boolean" ) {
6095			this.options.disabled = !!this.element.prop( "disabled" );
6096		} else {
6097			this.element.prop( "disabled", this.options.disabled );
6098		}
6099
6100		this._determineButtonType();
6101		this.hasTitle = !!this.buttonElement.attr( "title" );
6102
6103		var that = this,
6104			options = this.options,
6105			toggleButton = this.type === "checkbox" || this.type === "radio",
6106			activeClass = !toggleButton ? "ui-state-active" : "",
6107			focusClass = "ui-state-focus";
6108
6109		if ( options.label === null ) {
6110			options.label = (this.type === "input" ? this.buttonElement.val() : this.buttonElement.html());
6111		}
6112
6113		this._hoverable( this.buttonElement );
6114
6115		this.buttonElement
6116			.addClass( baseClasses )
6117			.attr( "role", "button" )
6118			.bind( "mouseenter" + this.eventNamespace, function() {
6119				if ( options.disabled ) {
6120					return;
6121				}
6122				if ( this === lastActive ) {
6123					$( this ).addClass( "ui-state-active" );
6124				}
6125			})
6126			.bind( "mouseleave" + this.eventNamespace, function() {
6127				if ( options.disabled ) {
6128					return;
6129				}
6130				$( this ).removeClass( activeClass );
6131			})
6132			.bind( "click" + this.eventNamespace, function( event ) {
6133				if ( options.disabled ) {
6134					event.preventDefault();
6135					event.stopImmediatePropagation();
6136				}
6137			});
6138
6139		this.element
6140			.bind( "focus" + this.eventNamespace, function() {
6141				// no need to check disabled, focus won't be triggered anyway
6142				that.buttonElement.addClass( focusClass );
6143			})
6144			.bind( "blur" + this.eventNamespace, function() {
6145				that.buttonElement.removeClass( focusClass );
6146			});
6147
6148		if ( toggleButton ) {
6149			this.element.bind( "change" + this.eventNamespace, function() {
6150				if ( clickDragged ) {
6151					return;
6152				}
6153				that.refresh();
6154			});
6155			// if mouse moves between mousedown and mouseup (drag) set clickDragged flag
6156			// prevents issue where button state changes but checkbox/radio checked state
6157			// does not in Firefox (see ticket #6970)
6158			this.buttonElement
6159				.bind( "mousedown" + this.eventNamespace, function( event ) {
6160					if ( options.disabled ) {
6161						return;
6162					}
6163					clickDragged = false;
6164					startXPos = event.pageX;
6165					startYPos = event.pageY;
6166				})
6167				.bind( "mouseup" + this.eventNamespace, function( event ) {
6168					if ( options.disabled ) {
6169						return;
6170					}
6171					if ( startXPos !== event.pageX || startYPos !== event.pageY ) {
6172						clickDragged = true;
6173					}
6174			});
6175		}
6176
6177		if ( this.type === "checkbox" ) {
6178			this.buttonElement.bind( "click" + this.eventNamespace, function() {
6179				if ( options.disabled || clickDragged ) {
6180					return false;
6181				}
6182				$( this ).toggleClass( "ui-state-active" );
6183				that.buttonElement.attr( "aria-pressed", that.element[0].checked );
6184			});
6185		} else if ( this.type === "radio" ) {
6186			this.buttonElement.bind( "click" + this.eventNamespace, function() {
6187				if ( options.disabled || clickDragged ) {
6188					return false;
6189				}
6190				$( this ).addClass( "ui-state-active" );
6191				that.buttonElement.attr( "aria-pressed", "true" );
6192
6193				var radio = that.element[ 0 ];
6194				radioGroup( radio )
6195					.not( radio )
6196					.map(function() {
6197						return $( this ).button( "widget" )[ 0 ];
6198					})
6199					.removeClass( "ui-state-active" )
6200					.attr( "aria-pressed", "false" );
6201			});
6202		} else {
6203			this.buttonElement
6204				.bind( "mousedown" + this.eventNamespace, function() {
6205					if ( options.disabled ) {
6206						return false;
6207					}
6208					$( this ).addClass( "ui-state-active" );
6209					lastActive = this;
6210					that.document.one( "mouseup", function() {
6211						lastActive = null;
6212					});
6213				})
6214				.bind( "mouseup" + this.eventNamespace, function() {
6215					if ( options.disabled ) {
6216						return false;
6217					}
6218					$( this ).removeClass( "ui-state-active" );
6219				})
6220				.bind( "keydown" + this.eventNamespace, function(event) {
6221					if ( options.disabled ) {
6222						return false;
6223					}
6224					if ( event.keyCode === $.ui.keyCode.SPACE || event.keyCode === $.ui.keyCode.ENTER ) {
6225						$( this ).addClass( "ui-state-active" );
6226					}
6227				})
6228				.bind( "keyup" + this.eventNamespace, function() {
6229					$( this ).removeClass( "ui-state-active" );
6230				});
6231
6232			if ( this.buttonElement.is("a") ) {
6233				this.buttonElement.keyup(function(event) {
6234					if ( event.keyCode === $.ui.keyCode.SPACE ) {
6235						// TODO pass through original event correctly (just as 2nd argument doesn't work)
6236						$( this ).click();
6237					}
6238				});
6239			}
6240		}
6241
6242		// TODO: pull out $.Widget's handling for the disabled option into
6243		// $.Widget.prototype._setOptionDisabled so it's easy to proxy and can
6244		// be overridden by individual plugins
6245		this._setOption( "disabled", options.disabled );
6246		this._resetButton();
6247	},
6248
6249	_determineButtonType: function() {
6250		var ancestor, labelSelector, checked;
6251
6252		if ( this.element.is("[type=checkbox]") ) {
6253			this.type = "checkbox";
6254		} else if ( this.element.is("[type=radio]") ) {
6255			this.type = "radio";
6256		} else if ( this.element.is("input") ) {
6257			this.type = "input";
6258		} else {
6259			this.type = "button";
6260		}
6261
6262		if ( this.type === "checkbox" || this.type === "radio" ) {
6263			// we don't search against the document in case the element
6264			// is disconnected from the DOM
6265			ancestor = this.element.parents().last();
6266			labelSelector = "label[for='" + this.element.attr("id") + "']";
6267			this.buttonElement = ancestor.find( labelSelector );
6268			if ( !this.buttonElement.length ) {
6269				ancestor = ancestor.length ? ancestor.siblings() : this.element.siblings();
6270				this.buttonElement = ancestor.filter( labelSelector );
6271				if ( !this.buttonElement.length ) {
6272					this.buttonElement = ancestor.find( labelSelector );
6273				}
6274			}
6275			this.element.addClass( "ui-helper-hidden-accessible" );
6276
6277			checked = this.element.is( ":checked" );
6278			if ( checked ) {
6279				this.buttonElement.addClass( "ui-state-active" );
6280			}
6281			this.buttonElement.prop( "aria-pressed", checked );
6282		} else {
6283			this.buttonElement = this.element;
6284		}
6285	},
6286
6287	widget: function() {
6288		return this.buttonElement;
6289	},
6290
6291	_destroy: function() {
6292		this.element
6293			.removeClass( "ui-helper-hidden-accessible" );
6294		this.buttonElement
6295			.removeClass( baseClasses + " " + stateClasses + " " + typeClasses )
6296			.removeAttr( "role" )
6297			.removeAttr( "aria-pressed" )
6298			.html( this.buttonElement.find(".ui-button-text").html() );
6299
6300		if ( !this.hasTitle ) {
vendor: 7,201 bytes, lines 6301-6502
6301			this.buttonElement.removeAttr( "title" );
6302		}
6303	},
6304
6305	_setOption: function( key, value ) {
6306		this._super( key, value );
6307		if ( key === "disabled" ) {
6308			if ( value ) {
6309				this.element.prop( "disabled", true );
6310			} else {
6311				this.element.prop( "disabled", false );
6312			}
6313			return;
6314		}
6315		this._resetButton();
6316	},
6317
6318	refresh: function() {
6319		//See #8237 & #8828
6320		var isDisabled = this.element.is( "input, button" ) ? this.element.is( ":disabled" ) : this.element.hasClass( "ui-button-disabled" );
6321
6322		if ( isDisabled !== this.options.disabled ) {
6323			this._setOption( "disabled", isDisabled );
6324		}
6325		if ( this.type === "radio" ) {
6326			radioGroup( this.element[0] ).each(function() {
6327				if ( $( this ).is( ":checked" ) ) {
6328					$( this ).button( "widget" )
6329						.addClass( "ui-state-active" )
6330						.attr( "aria-pressed", "true" );
6331				} else {
6332					$( this ).button( "widget" )
6333						.removeClass( "ui-state-active" )
6334						.attr( "aria-pressed", "false" );
6335				}
6336			});
6337		} else if ( this.type === "checkbox" ) {
6338			if ( this.element.is( ":checked" ) ) {
6339				this.buttonElement
6340					.addClass( "ui-state-active" )
6341					.attr( "aria-pressed", "true" );
6342			} else {
6343				this.buttonElement
6344					.removeClass( "ui-state-active" )
6345					.attr( "aria-pressed", "false" );
6346			}
6347		}
6348	},
6349
6350	_resetButton: function() {
6351		if ( this.type === "input" ) {
6352			if ( this.options.label ) {
6353				this.element.val( this.options.label );
6354			}
6355			return;
6356		}
6357		var buttonElement = this.buttonElement.removeClass( typeClasses ),
6358			buttonText = $( "<span></span>", this.document[0] )
6359				.addClass( "ui-button-text" )
6360				.html( this.options.label )
6361				.appendTo( buttonElement.empty() )
6362				.text(),
6363			icons = this.options.icons,
6364			multipleIcons = icons.primary && icons.secondary,
6365			buttonClasses = [];
6366
6367		if ( icons.primary || icons.secondary ) {
6368			if ( this.options.text ) {
6369				buttonClasses.push( "ui-button-text-icon" + ( multipleIcons ? "s" : ( icons.primary ? "-primary" : "-secondary" ) ) );
6370			}
6371
6372			if ( icons.primary ) {
6373				buttonElement.prepend( "<span class='ui-button-icon-primary ui-icon " + icons.primary + "'></span>" );
6374			}
6375
6376			if ( icons.secondary ) {
6377				buttonElement.append( "<span class='ui-button-icon-secondary ui-icon " + icons.secondary + "'></span>" );
6378			}
6379
6380			if ( !this.options.text ) {
6381				buttonClasses.push( multipleIcons ? "ui-button-icons-only" : "ui-button-icon-only" );
6382
6383				if ( !this.hasTitle ) {
6384					buttonElement.attr( "title", $.trim( buttonText ) );
6385				}
6386			}
6387		} else {
6388			buttonClasses.push( "ui-button-text-only" );
6389		}
6390		buttonElement.addClass( buttonClasses.join( " " ) );
6391	}
6392});
6393
6394$.widget( "ui.buttonset", {
6395	version: "1.9.2",
6396	options: {
6397		items: "button, input[type=button], input[type=submit], input[type=reset], input[type=checkbox], input[type=radio], a, :data(button)"
6398	},
6399
6400	_create: function() {
6401		this.element.addClass( "ui-buttonset" );
6402	},
6403
6404	_init: function() {
6405		this.refresh();
6406	},
6407
6408	_setOption: function( key, value ) {
6409		if ( key === "disabled" ) {
6410			this.buttons.button( "option", key, value );
6411		}
6412
6413		this._super( key, value );
6414	},
6415
6416	refresh: function() {
6417		var rtl = this.element.css( "direction" ) === "rtl";
6418
6419		this.buttons = this.element.find( this.options.items )
6420			.filter( ":ui-button" )
6421				.button( "refresh" )
6422			.end()
6423			.not( ":ui-button" )
6424				.button()
6425			.end()
6426			.map(function() {
6427				return $( this ).button( "widget" )[ 0 ];
6428			})
6429				.removeClass( "ui-corner-all ui-corner-left ui-corner-right" )
6430				.filter( ":first" )
6431					.addClass( rtl ? "ui-corner-right" : "ui-corner-left" )
6432				.end()
6433				.filter( ":last" )
6434					.addClass( rtl ? "ui-corner-left" : "ui-corner-right" )
6435				.end()
6436			.end();
6437	},
6438
6439	_destroy: function() {
6440		this.element.removeClass( "ui-buttonset" );
6441		this.buttons
6442			.map(function() {
6443				return $( this ).button( "widget" )[ 0 ];
6444			})
6445				.removeClass( "ui-corner-left ui-corner-right" )
6446			.end()
6447			.button( "destroy" );
6448	}
6449});
6450
6451}( jQuery ) );
6452(function( $, undefined ) {
6453
6454$.extend($.ui, { datepicker: { version: "1.9.2" } });
6455
6456var PROP_NAME = 'datepicker';
6457var dpuuid = new Date().getTime();
6458var instActive;
6459
6460/* Date picker manager.
6461   Use the singleton instance of this class, $.datepicker, to interact with the date picker.
6462   Settings for (groups of) date pickers are maintained in an instance object,
6463   allowing multiple different settings on the same page. */
6464
6465function Datepicker() {
6466	this.debug = false; // Change this to true to start debugging
6467	this._curInst = null; // The current instance in use
6468	this._keyEvent = false; // If the last event was a key event
6469	this._disabledInputs = []; // List of date picker inputs that have been disabled
6470	this._datepickerShowing = false; // True if the popup picker is showing , false if not
6471	this._inDialog = false; // True if showing within a "dialog", false if not
6472	this._mainDivId = 'ui-datepicker-div'; // The ID of the main datepicker division
6473	this._inlineClass = 'ui-datepicker-inline'; // The name of the inline marker class
6474	this._appendClass = 'ui-datepicker-append'; // The name of the append marker class
6475	this._triggerClass = 'ui-datepicker-trigger'; // The name of the trigger marker class
6476	this._dialogClass = 'ui-datepicker-dialog'; // The name of the dialog marker class
6477	this._disableClass = 'ui-datepicker-disabled'; // The name of the disabled covering marker class
6478	this._unselectableClass = 'ui-datepicker-unselectable'; // The name of the unselectable cell marker class
6479	this._currentClass = 'ui-datepicker-current-day'; // The name of the current day marker class
6480	this._dayOverClass = 'ui-datepicker-days-cell-over'; // The name of the day hover marker class
6481	this.regional = []; // Available regional settings, indexed by language code
6482	this.regional[''] = { // Default regional settings
6483		closeText: 'Done', // Display text for close link
6484		prevText: 'Prev', // Display text for previous month link
6485		nextText: 'Next', // Display text for next month link
6486		currentText: 'Today', // Display text for current month link
6487		monthNames: ['1월','2월','3월','4월','5월','6월',
6488			'7월','8월','9월','10월','11월','12월'], // Names of months for drop-down and formatting
6489		monthNamesShort: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'], // For formatting
6490		dayNames: ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'], // For formatting
6491		dayNamesShort: ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'], // For formatting
6492		dayNamesMin: ['일','월','화','수','목','금','토'], // Column headings for days starting at Sunday
6493		weekHeader: 'Wk', // Column header for week of the year
6494		dateFormat: 'yy-mm-dd', // See format options on parseDate
6495		firstDay: 0, // The first day of the week, Sun = 0, Mon = 1, ...
6496		isRTL: false, // True if right-to-left language, false if left-to-right
6497		showMonthAfterYear: false, // True if the year select precedes month, false for month then year
6498		yearSuffix: '' // Additional text to append to the year in the month headers
6499	};
6500	this._defaults = { // Global defaults for all the date picker instances
6501		showOn: 'focus', // 'focus' for popup on focus,
6502			// 'button' for trigger button, or 'both' for either
vendor: 4,836 bytes, lines 6503-6589
6503		showAnim: 'fadeIn', // Name of jQuery animation for popup
6504		showOptions: {}, // Options for enhanced animations
6505		defaultDate: null, // Used when field is blank: actual date,
6506			// +/-number for offset from today, null for today
6507		appendText: '', // Display text following the input box, e.g. showing the format
6508		buttonText: '...', // Text for trigger button
6509		buttonImage: '', // URL for trigger button image
6510		buttonImageOnly: false, // True if the image appears alone, false if it appears on a button
6511		hideIfNoPrevNext: false, // True to hide next/previous month links
6512			// if not applicable, false to just disable them
6513		navigationAsDateFormat: false, // True if date formatting applied to prev/today/next links
6514		gotoCurrent: false, // True if today link goes back to current selection instead
6515		changeMonth: false, // True if month can be selected directly, false if only prev/next
6516		changeYear: false, // True if year can be selected directly, false if only prev/next
6517		yearRange: 'c-10:c+10', // Range of years to display in drop-down,
6518			// either relative to today's year (-nn:+nn), relative to currently displayed year
6519			// (c-nn:c+nn), absolute (nnnn:nnnn), or a combination of the above (nnnn:-n)
6520		showOtherMonths: false, // True to show dates in other months, false to leave blank
6521		selectOtherMonths: false, // True to allow selection of dates in other months, false for unselectable
6522		showWeek: false, // True to show week of the year, false to not show it
6523		calculateWeek: this.iso8601Week, // How to calculate the week of the year,
6524			// takes a Date and returns the number of the week for it
6525		shortYearCutoff: '+10', // Short year values < this are in the current century,
6526			// > this are in the previous century,
6527			// string value starting with '+' for current year + value
6528		minDate: null, // The earliest selectable date, or null for no limit
6529		maxDate: null, // The latest selectable date, or null for no limit
6530		duration: 'fast', // Duration of display/closure
6531		beforeShowDay: null, // Function that takes a date and returns an array with
6532			// [0] = true if selectable, false if not, [1] = custom CSS class name(s) or '',
6533			// [2] = cell title (optional), e.g. $.datepicker.noWeekends
6534		beforeShow: null, // Function that takes an input field and
6535			// returns a set of custom settings for the date picker
6536		onSelect: null, // Define a callback function when a date is selected
6537		onChangeMonthYear: null, // Define a callback function when the month or year is changed
6538		onClose: null, // Define a callback function when the datepicker is closed
6539		numberOfMonths: 1, // Number of months to show at a time
6540		showCurrentAtPos: 0, // The position in multipe months at which to show the current month (starting at 0)
6541		stepMonths: 1, // Number of months to step back/forward
6542		stepBigMonths: 12, // Number of months to step back/forward for the big links
6543		altField: '', // Selector for an alternate field to store selected dates into
6544		altFormat: '', // The date format to use for the alternate field
6545		constrainInput: true, // The input is constrained by the current date format
6546		showButtonPanel: false, // True to show button panel, false to not show it
6547		autoSize: false, // True to size the input for the date format, false to leave as is
6548		disabled: false // The initial disabled state
6549	};
6550	$.extend(this._defaults, this.regional['']);
6551	this.dpDiv = bindHover($('<div id="' + this._mainDivId + '" class="ui-datepicker ui-widget ui-widget-content ui-helper-clearfix ui-corner-all"></div>'));
6552}
6553
6554$.extend(Datepicker.prototype, {
6555	/* Class name added to elements to indicate already configured with a date picker. */
6556	markerClassName: 'hasDatepicker',
6557
6558	//Keep track of the maximum number of rows displayed (see #7043)
6559	maxRows: 4,
6560
6561	/* Debug logging (if enabled). */
6562	log: function () {
6563		if (this.debug)
6564			console.log.apply('', arguments);
6565	},
6566
6567	// TODO rename to "widget" when switching to widget factory
6568	_widgetDatepicker: function() {
6569		return this.dpDiv;
6570	},
6571
6572	/* Override the default settings for all instances of the date picker.
6573	   @param  settings  object - the new settings to use as defaults (anonymous object)
6574	   @return the manager object */
6575	setDefaults: function(settings) {
6576		extendRemove(this._defaults, settings || {});
6577		return this;
6578	},
6579
6580	/* Attach the date picker to a jQuery selection.
6581	   @param  target    element - the target input field or division or span
6582	   @param  settings  object - the new settings to use for this date picker instance (anonymous) */
6583	_attachDatepicker: function(target, settings) {
6584		// check for settings on the control itself - in namespace 'date:'
6585		var inlineSettings = null;
6586		for (var attrName in this._defaults) {
6587			var attrValue = target.getAttribute('date:' + attrName);
6588			if (attrValue) {
6589				inlineSettings = inlineSettings || {};
6590				try {
6591					inlineSettings[attrName] = eval(attrValue);
6592				} catch (err) {
6593					inlineSettings[attrName] = attrValue;
6594				}
6595			}
6596		}
6597		var nodeName = target.nodeName.toLowerCase();
6598		var inline = (nodeName == 'div' || nodeName == 'span');
6599		if (!target.id) {
6600			this.uuid += 1;
6601			target.id = 'dp' + this.uuid;
6602		}
6603		var inst = this._newInst($(target), inline);
6604		inst.settings = $.extend({}, settings || {}, inlineSettings || {});
6605		if (nodeName == 'input') {
6606			this._connectDatepicker(target, inst);
6607		} else if (inline) {
6608			this._inlineDatepicker(target, inst);
6609		}
6610	},
6611
6612	/* Create a new instance object. */
6613	_newInst: function(target, inline) {
6614		var id = target[0].id.replace(/([^A-Za-z0-9_-])/g, '\\\\$1'); // escape jQuery meta chars
6615		return {id: id, input: target, // associated target
6616			selectedDay: 0, selectedMonth: 0, selectedYear: 0, // current selection
6617			drawMonth: 0, drawYear: 0, // month being drawn
6618			inline: inline, // is datepicker inline or not
6619			dpDiv: (!inline ? this.dpDiv : // presentation div
6620			bindHover($('<div class="' + this._inlineClass + ' ui-datepicker ui-widget ui-widget-content ui-helper-clearfix ui-corner-all"></div>')))};
6621	},
6622
6623	/* Attach the date picker to an input field. */
6624	_connectDatepicker: function(target, inst) {
6625		var input = $(target);
6626		inst.append = $([]);
6627		inst.trigger = $([]);
6628		if (input.hasClass(this.markerClassName))
6629			return;
6630		this._attachments(input, inst);
6631		input.addClass(this.markerClassName).keydown(this._doKeyDown).
6632			keypress(this._doKeyPress).keyup(this._doKeyUp).
6633			bind("setData.datepicker", function(event, key, value) {
6634				inst.settings[key] = value;
6635			}).bind("getData.datepicker", function(event, key) {
6636				return this._get(inst, key);
6637			});
6638		this._autoSize(inst);
6639		$.data(target, PROP_NAME, inst);
6640		//If disabled option is true, disable the datepicker once it has been attached to the input (see ticket #5665)
6641		if( inst.settings.disabled ) {
6642			this._disableDatepicker( target );
6643		}
6644	},
6645
6646	/* Make attachments based on settings. */
6647	_attachments: function(input, inst) {
6648		var appendText = this._get(inst, 'appendText');
6649		var isRTL = this._get(inst, 'isRTL');
6650		if (inst.append)
6651			inst.append.remove();
6652		if (appendText) {
6653			inst.append = $('<span class="' + this._appendClass + '">' + appendText + '</span>');
6654			input[isRTL ? 'before' : 'after'](inst.append);
6655		}
6656		input.unbind('focus', this._showDatepicker);
6657		if (inst.trigger)
6658			inst.trigger.remove();
6659		var showOn = this._get(inst, 'showOn');
6660		if (showOn == 'focus' || showOn == 'both') // pop-up date picker when in the marked field
6661			input.focus(this._showDatepicker);
6662		if (showOn == 'button' || showOn == 'both') { // pop-up date picker when button clicked
6663			var buttonText = this._get(inst, 'buttonText');
6664			var buttonImage = this._get(inst, 'buttonImage');
6665			inst.trigger = $(this._get(inst, 'buttonImageOnly') ?
6666				$('<img/>').addClass(this._triggerClass).
6667					attr({ src: buttonImage, alt: buttonText, title: buttonText }) :
6668				$('<button type="button"></button>').addClass(this._triggerClass).
6669					html(buttonImage == '' ? buttonText : $('<img/>').attr(
6670					{ src:buttonImage, alt:buttonText, title:buttonText })));
6671			input[isRTL ? 'before' : 'after'](inst.trigger);
6672			inst.trigger.click(function() {
6673				if ($.datepicker._datepickerShowing && $.datepicker._lastInput == input[0])
6674					$.datepicker._hideDatepicker();
6675				else if ($.datepicker._datepickerShowing && $.datepicker._lastInput != input[0]) {
6676					$.datepicker._hideDatepicker();
6677					$.datepicker._showDatepicker(input[0]);
6678				} else
6679					$.datepicker._showDatepicker(input[0]);
6680				return false;
6681			});
6682		}
6683	},
6684
6685	/* Apply the maximum length for the date format. */
6686	_autoSize: function(inst) {
6687		if (this._get(inst, 'autoSize') && !inst.inline) {
6688			var date = new Date(2009, 12 - 1, 20); // Ensure double digits
6689			var dateFormat = this._get(inst, 'dateFormat');
6690			if (dateFormat.match(/[DM]/)) {
6691				var findMax = function(names) {
6692					var max = 0;
6693					var maxI = 0;
6694					for (var i = 0; i < names.length; i++) {
6695						if (names[i].length > max) {
6696							max = names[i].length;
6697							maxI = i;
6698						}
6699					}
vendor: 4,711 bytes, lines 6700-6815
6700					return maxI;
6701				};
6702				date.setMonth(findMax(this._get(inst, (dateFormat.match(/MM/) ?
6703					'monthNames' : 'monthNamesShort'))));
6704				date.setDate(findMax(this._get(inst, (dateFormat.match(/DD/) ?
6705					'dayNames' : 'dayNamesShort'))) + 20 - date.getDay());
6706			}
6707			inst.input.attr('size', this._formatDate(inst, date).length);
6708		}
6709	},
6710
6711	/* Attach an inline date picker to a div. */
6712	_inlineDatepicker: function(target, inst) {
6713		var divSpan = $(target);
6714		if (divSpan.hasClass(this.markerClassName))
6715			return;
6716		divSpan.addClass(this.markerClassName).append(inst.dpDiv).
6717			bind("setData.datepicker", function(event, key, value){
6718				inst.settings[key] = value;
6719			}).bind("getData.datepicker", function(event, key){
6720				return this._get(inst, key);
6721			});
6722		$.data(target, PROP_NAME, inst);
6723		this._setDate(inst, this._getDefaultDate(inst), true);
6724		this._updateDatepicker(inst);
6725		this._updateAlternate(inst);
6726		//If disabled option is true, disable the datepicker before showing it (see ticket #5665)
6727		if( inst.settings.disabled ) {
6728			this._disableDatepicker( target );
6729		}
6730		// Set display:block in place of inst.dpDiv.show() which won't work on disconnected elements
6731		// http://bugs.jqueryui.com/ticket/7552 - A Datepicker created on a detached div has zero height
6732		inst.dpDiv.css( "display", "block" );
6733	},
6734
6735	/* Pop-up the date picker in a "dialog" box.
6736	   @param  input     element - ignored
6737	   @param  date      string or Date - the initial date to display
6738	   @param  onSelect  function - the function to call when a date is selected
6739	   @param  settings  object - update the dialog date picker instance's settings (anonymous object)
6740	   @param  pos       int[2] - coordinates for the dialog's position within the screen or
6741	                     event - with x/y coordinates or
6742	                     leave empty for default (screen centre)
6743	   @return the manager object */
6744	_dialogDatepicker: function(input, date, onSelect, settings, pos) {
6745		var inst = this._dialogInst; // internal instance
6746		if (!inst) {
6747			this.uuid += 1;
6748			var id = 'dp' + this.uuid;
6749			this._dialogInput = $('<input type="text" id="' + id +
6750				'" style="position: absolute; top: -100px; width: 0px;"/>');
6751			this._dialogInput.keydown(this._doKeyDown);
6752			$('body').append(this._dialogInput);
6753			inst = this._dialogInst = this._newInst(this._dialogInput, false);
6754			inst.settings = {};
6755			$.data(this._dialogInput[0], PROP_NAME, inst);
6756		}
6757		extendRemove(inst.settings, settings || {});
6758		date = (date && date.constructor == Date ? this._formatDate(inst, date) : date);
6759		this._dialogInput.val(date);
6760
6761		this._pos = (pos ? (pos.length ? pos : [pos.pageX, pos.pageY]) : null);
6762		if (!this._pos) {
6763			var browserWidth = document.documentElement.clientWidth;
6764			var browserHeight = document.documentElement.clientHeight;
6765			var scrollX = document.documentElement.scrollLeft || document.body.scrollLeft;
6766			var scrollY = document.documentElement.scrollTop || document.body.scrollTop;
6767			this._pos = // should use actual width/height below
6768				[(browserWidth / 2) - 100 + scrollX, (browserHeight / 2) - 150 + scrollY];
6769		}
6770
6771		// move input on screen for focus, but hidden behind dialog
6772		this._dialogInput.css('left', (this._pos[0] + 20) + 'px').css('top', this._pos[1] + 'px');
6773		inst.settings.onSelect = onSelect;
6774		this._inDialog = true;
6775		this.dpDiv.addClass(this._dialogClass);
6776		this._showDatepicker(this._dialogInput[0]);
6777		if ($.blockUI)
6778			$.blockUI(this.dpDiv);
6779		$.data(this._dialogInput[0], PROP_NAME, inst);
6780		return this;
6781	},
6782
6783	/* Detach a datepicker from its control.
6784	   @param  target    element - the target input field or division or span */
6785	_destroyDatepicker: function(target) {
6786		var $target = $(target);
6787		var inst = $.data(target, PROP_NAME);
6788		if (!$target.hasClass(this.markerClassName)) {
6789			return;
6790		}
6791		var nodeName = target.nodeName.toLowerCase();
6792		$.removeData(target, PROP_NAME);
6793		if (nodeName == 'input') {
6794			inst.append.remove();
6795			inst.trigger.remove();
6796			$target.removeClass(this.markerClassName).
6797				unbind('focus', this._showDatepicker).
6798				unbind('keydown', this._doKeyDown).
6799				unbind('keypress', this._doKeyPress).
6800				unbind('keyup', this._doKeyUp);
6801		} else if (nodeName == 'div' || nodeName == 'span')
6802			$target.removeClass(this.markerClassName).empty();
6803	},
6804
6805	/* Enable the date picker to a jQuery selection.
6806	   @param  target    element - the target input field or division or span */
6807	_enableDatepicker: function(target) {
6808		var $target = $(target);
6809		var inst = $.data(target, PROP_NAME);
6810		if (!$target.hasClass(this.markerClassName)) {
6811			return;
6812		}
6813		var nodeName = target.nodeName.toLowerCase();
6814		if (nodeName == 'input') {
6815			target.disabled = false;
6816			inst.trigger.filter('button').
6817				each(function() { this.disabled = false; }).end().
6818				filter('img').css({opacity: '1.0', cursor: ''});
6819		}
6820		else if (nodeName == 'div' || nodeName == 'span') {
6821			var inline = $target.children('.' + this._inlineClass);
6822			inline.children().removeClass('ui-state-disabled');
6823			inline.find("select.ui-datepicker-month, select.ui-datepicker-year").
6824				prop("disabled", false);
6825		}
6826		this._disabledInputs = $.map(this._disabledInputs,
6827			function(value) { return (value == target ? null : value); }); // delete entry
6828	},
6829
6830	/* Disable the date picker to a jQuery selection.
6831	   @param  target    element - the target input field or division or span */
6832	_disableDatepicker: function(target) {
6833		var $target = $(target);
6834		var inst = $.data(target, PROP_NAME);
6835		if (!$target.hasClass(this.markerClassName)) {
6836			return;
6837		}
6838		var nodeName = target.nodeName.toLowerCase();
6839		if (nodeName == 'input') {
6840			target.disabled = true;
6841			inst.trigger.filter('button').
6842				each(function() { this.disabled = true; }).end().
6843				filter('img').css({opacity: '0.5', cursor: 'default'});
6844		}
6845		else if (nodeName == 'div' || nodeName == 'span') {
6846			var inline = $target.children('.' + this._inlineClass);
6847			inline.children().addClass('ui-state-disabled');
6848			inline.find("select.ui-datepicker-month, select.ui-datepicker-year").
6849				prop("disabled", true);
6850		}
6851		this._disabledInputs = $.map(this._disabledInputs,
6852			function(value) { return (value == target ? null : value); }); // delete entry
6853		this._disabledInputs[this._disabledInputs.length] = target;
6854	},
6855
6856	/* Is the first field in a jQuery collection disabled as a datepicker?
6857	   @param  target    element - the target input field or division or span
6858	   @return boolean - true if disabled, false if enabled */
6859	_isDisabledDatepicker: function(target) {
6860		if (!target) {
6861			return false;
6862		}
6863		for (var i = 0; i < this._disabledInputs.length; i++) {
6864			if (this._disabledInputs[i] == target)
6865				return true;
6866		}
6867		return false;
6868	},
6869
6870	/* Retrieve the instance data for the target control.
6871	   @param  target  element - the target input field or division or span
6872	   @return  object - the associated instance data
6873	   @throws  error if a jQuery problem getting data */
6874	_getInst: function(target) {
6875		try {
6876			return $.data(target, PROP_NAME);
6877		}
6878		catch (err) {
6879			throw 'Missing instance data for this datepicker';
6880		}
6881	},
6882
6883	/* Update or retrieve the settings for a date picker attached to an input field or division.
6884	   @param  target  element - the target input field or division or span
6885	   @param  name    object - the new settings to update or
6886	                   string - the name of the setting to change or retrieve,
6887	                   when retrieving also 'all' for all instance settings or
6888	                   'defaults' for all global defaults
6889	   @param  value   any - the new value for the setting
6890	                   (omit if above is an object or to retrieve a value) */
6891	_optionDatepicker: function(target, name, value) {
6892		var inst = this._getInst(target);
6893		if (arguments.length == 2 && typeof name == 'string') {
6894			return (name == 'defaults' ? $.extend({}, $.datepicker._defaults) :
6895				(inst ? (name == 'all' ? $.extend({}, inst.settings) :
6896				this._get(inst, name)) : null));
6897		}
6898		var settings = name || {};
6899		if (typeof name == 'string') {
6900			settings = {};
6901			settings[name] = value;
6902		}
6903		if (inst) {
6904			if (this._curInst == inst) {
6905				this._hideDatepicker();
6906			}
6907			var date = this._getDateDatepicker(target, true);
6908			var minDate = this._getMinMaxDate(inst, 'min');
6909			var maxDate = this._getMinMaxDate(inst, 'max');
6910			extendRemove(inst.settings, settings);
6911			// reformat the old minDate/maxDate values if dateFormat changes and a new minDate/maxDate isn't provided
6912			if (minDate !== null && settings['dateFormat'] !== undefined && settings['minDate'] === undefined)
6913				inst.settings.minDate = this._formatDate(inst, minDate);
6914			if (maxDate !== null && settings['dateFormat'] !== undefined && settings['maxDate'] === undefined)
6915				inst.settings.maxDate = this._formatDate(inst, maxDate);
6916			this._attachments($(target), inst);
6917			this._autoSize(inst);
6918			this._setDate(inst, date);
6919			this._updateAlternate(inst);
6920			this._updateDatepicker(inst);
6921		}
6922	},
6923
6924	// change method deprecated
6925	_changeDatepicker: function(target, name, value) {
6926		this._optionDatepicker(target, name, value);
6927	},
6928
6929	/* Redraw the date picker attached to an input field or division.
6930	   @param  target  element - the target input field or division or span */
6931	_refreshDatepicker: function(target) {
6932		var inst = this._getInst(target);
6933		if (inst) {
6934			this._updateDatepicker(inst);
6935		}
6936	},
6937
6938	/* Set the dates for a jQuery selection.
6939	   @param  target   element - the target input field or division or span
6940	   @param  date     Date - the new date */
6941	_setDateDatepicker: function(target, date) {
6942		var inst = this._getInst(target);
6943		if (inst) {
6944			this._setDate(inst, date);
6945			this._updateDatepicker(inst);
6946			this._updateAlternate(inst);
6947		}
6948	},
6949
6950	/* Get the date(s) for the first entry in a jQuery selection.
6951	   @param  target     element - the target input field or division or span
6952	   @param  noDefault  boolean - true if no default date is to be used
6953	   @return Date - the current date */
6954	_getDateDatepicker: function(target, noDefault) {
6955		var inst = this._getInst(target);
6956		if (inst && !inst.inline)
6957			this._setDateFromField(inst, noDefault);
6958		return (inst ? this._getDate(inst) : null);
6959	},
6960
6961	/* Handle keystrokes. */
6962	_doKeyDown: function(event) {
6963		var inst = $.datepicker._getInst(event.target);
6964		var handled = true;
6965		var isRTL = inst.dpDiv.is('.ui-datepicker-rtl');
6966		inst._keyEvent = true;
6967		if ($.datepicker._datepickerShowing)
6968			switch (event.keyCode) {
6969				case 9: $.datepicker._hideDatepicker();
6970						handled = false;
6971						break; // hide on tab out
6972				case 13: var sel = $('td.' + $.datepicker._dayOverClass + ':not(.' +
6973									$.datepicker._currentClass + ')', inst.dpDiv);
6974						if (sel[0])
6975							$.datepicker._selectDay(event.target, inst.selectedMonth, inst.selectedYear, sel[0]);
6976							var onSelect = $.datepicker._get(inst, 'onSelect');
6977							if (onSelect) {
6978								var dateStr = $.datepicker._formatDate(inst);
6979
6980								// trigger custom callback
6981								onSelect.apply((inst.input ? inst.input[0] : null), [dateStr, inst]);
6982							}
6983						else
6984							$.datepicker._hideDatepicker();
6985						return false; // don't submit the form
6986						break; // select the value on enter
6987				case 27: $.datepicker._hideDatepicker();
6988						break; // hide on escape
6989				case 33: $.datepicker._adjustDate(event.target, (event.ctrlKey ?
6990							-$.datepicker._get(inst, 'stepBigMonths') :
6991							-$.datepicker._get(inst, 'stepMonths')), 'M');
6992						break; // previous month/year on page up/+ ctrl
6993				case 34: $.datepicker._adjustDate(event.target, (event.ctrlKey ?
6994							+$.datepicker._get(inst, 'stepBigMonths') :
6995							+$.datepicker._get(inst, 'stepMonths')), 'M');
6996						break; // next month/year on page down/+ ctrl
6997				case 35: if (event.ctrlKey || event.metaKey) $.datepicker._clearDate(event.target);
6998						handled = event.ctrlKey || event.metaKey;
6999						break; // clear on ctrl or command +end
7000				case 36: if (event.ctrlKey || event.metaKey) $.datepicker._gotoToday(event.target);
7001						handled = event.ctrlKey || event.metaKey;
7002						break; // current on ctrl or command +home
7003				case 37: if (event.ctrlKey || event.metaKey) $.datepicker._adjustDate(event.target, (isRTL ? +1 : -1), 'D');
7004						handled = event.ctrlKey || event.metaKey;
7005						// -1 day on ctrl or command +left
7006						if (event.originalEvent.altKey) $.datepicker._adjustDate(event.target, (event.ctrlKey ?
7007									-$.datepicker._get(inst, 'stepBigMonths') :
7008									-$.datepicker._get(inst, 'stepMonths')), 'M');
7009						// next month/year on alt +left on Mac
7010						break;
7011				case 38: if (event.ctrlKey || event.metaKey) $.datepicker._adjustDate(event.target, -7, 'D');
7012						handled = event.ctrlKey || event.metaKey;
7013						break; // -1 week on ctrl or command +up
7014				case 39: if (event.ctrlKey || event.metaKey) $.datepicker._adjustDate(event.target, (isRTL ? -1 : +1), 'D');
7015						handled = event.ctrlKey || event.metaKey;
7016						// +1 day on ctrl or command +right
7017						if (event.originalEvent.altKey) $.datepicker._adjustDate(event.target, (event.ctrlKey ?
7018									+$.datepicker._get(inst, 'stepBigMonths') :
7019									+$.datepicker._get(inst, 'stepMonths')), 'M');
7020						// next month/year on alt +right
7021						break;
7022				case 40: if (event.ctrlKey || event.metaKey) $.datepicker._adjustDate(event.target, +7, 'D');
7023						handled = event.ctrlKey || event.metaKey;
7024						break; // +1 week on ctrl or command +down
7025				default: handled = false;
7026			}
7027		else if (event.keyCode == 36 && event.ctrlKey) // display the date picker on ctrl+home
7028			$.datepicker._showDatepicker(this);
7029		else {
7030			handled = false;
7031		}
7032		if (handled) {
7033			event.preventDefault();
7034			event.stopPropagation();
7035		}
7036	},
7037
7038	/* Filter entered characters - based on date format. */
7039	_doKeyPress: function(event) {
7040		var inst = $.datepicker._getInst(event.target);
7041		if ($.datepicker._get(inst, 'constrainInput')) {
7042			var chars = $.datepicker._possibleChars($.datepicker._get(inst, 'dateFormat'));
7043			var chr = String.fromCharCode(event.charCode == undefined ? event.keyCode : event.charCode);
7044			return event.ctrlKey || event.metaKey || (chr < ' ' || !chars || chars.indexOf(chr) > -1);
7045		}
7046	},
7047
7048	/* Synchronise manual entry and field/alternate field. */
7049	_doKeyUp: function(event) {
7050		var inst = $.datepicker._getInst(event.target);
vendor: 8,608 bytes, lines 7051-7252
7051		if (inst.input.val() != inst.lastVal) {
7052			try {
7053				var date = $.datepicker.parseDate($.datepicker._get(inst, 'dateFormat'),
7054					(inst.input ? inst.input.val() : null),
7055					$.datepicker._getFormatConfig(inst));
7056				if (date) { // only if valid
7057					$.datepicker._setDateFromField(inst);
7058					$.datepicker._updateAlternate(inst);
7059					$.datepicker._updateDatepicker(inst);
7060				}
7061			}
7062			catch (err) {
7063				$.datepicker.log(err);
7064			}
7065		}
7066		return true;
7067	},
7068
7069	/* Pop-up the date picker for a given input field.
7070	   If false returned from beforeShow event handler do not show.
7071	   @param  input  element - the input field attached to the date picker or
7072	                  event - if triggered by focus */
7073	_showDatepicker: function(input) {
7074		input = input.target || input;
7075		if (input.nodeName.toLowerCase() != 'input') // find from button/image trigger
7076			input = $('input', input.parentNode)[0];
7077		if ($.datepicker._isDisabledDatepicker(input) || $.datepicker._lastInput == input) // already here
7078			return;
7079		var inst = $.datepicker._getInst(input);
7080		if ($.datepicker._curInst && $.datepicker._curInst != inst) {
7081			$.datepicker._curInst.dpDiv.stop(true, true);
7082			if ( inst && $.datepicker._datepickerShowing ) {
7083				$.datepicker._hideDatepicker( $.datepicker._curInst.input[0] );
7084			}
7085		}
7086		var beforeShow = $.datepicker._get(inst, 'beforeShow');
7087		var beforeShowSettings = beforeShow ? beforeShow.apply(input, [input, inst]) : {};
7088		if(beforeShowSettings === false){
7089			//false
7090			return;
7091		}
7092		extendRemove(inst.settings, beforeShowSettings);
7093		inst.lastVal = null;
7094		$.datepicker._lastInput = input;
7095		$.datepicker._setDateFromField(inst);
7096		if ($.datepicker._inDialog) // hide cursor
7097			input.value = '';
7098		if (!$.datepicker._pos) { // position below input
7099			$.datepicker._pos = $.datepicker._findPos(input);
7100			$.datepicker._pos[1] += input.offsetHeight; // add the height
7101		}
7102		var isFixed = false;
7103		$(input).parents().each(function() {
7104			isFixed |= $(this).css('position') == 'fixed';
7105			return !isFixed;
7106		});
7107		var offset = {left: $.datepicker._pos[0], top: $.datepicker._pos[1]};
7108		$.datepicker._pos = null;
7109		//to avoid flashes on Firefox
7110		inst.dpDiv.empty();
7111		// determine sizing offscreen
7112		inst.dpDiv.css({position: 'absolute', display: 'block', top: '-1000px'});
7113		$.datepicker._updateDatepicker(inst);
7114		// fix width for dynamic number of date pickers
7115		// and adjust position before showing
7116		offset = $.datepicker._checkOffset(inst, offset, isFixed);
7117		inst.dpDiv.css({position: ($.datepicker._inDialog && $.blockUI ?
7118			'static' : (isFixed ? 'fixed' : 'absolute')), display: 'none',
7119			left: offset.left + 'px', top: offset.top + 'px'});
7120		if (!inst.inline) {
7121			var showAnim = $.datepicker._get(inst, 'showAnim');
7122			var duration = $.datepicker._get(inst, 'duration');
7123			var postProcess = function() {
7124				var cover = inst.dpDiv.find('iframe.ui-datepicker-cover'); // IE6- only
7125				if( !! cover.length ){
7126					var borders = $.datepicker._getBorders(inst.dpDiv);
7127					cover.css({left: -borders[0], top: -borders[1],
7128						width: inst.dpDiv.outerWidth(), height: inst.dpDiv.outerHeight()});
7129				}
7130			};
7131			inst.dpDiv.zIndex($(input).zIndex()+1);
7132			$.datepicker._datepickerShowing = true;
7133
7134			// DEPRECATED: after BC for 1.8.x $.effects[ showAnim ] is not needed
7135			if ( $.effects && ( $.effects.effect[ showAnim ] || $.effects[ showAnim ] ) )
7136				inst.dpDiv.show(showAnim, $.datepicker._get(inst, 'showOptions'), duration, postProcess);
7137			else
7138				inst.dpDiv[showAnim || 'show']((showAnim ? duration : null), postProcess);
7139			if (!showAnim || !duration)
7140				postProcess();
7141			if (inst.input.is(':visible') && !inst.input.is(':disabled'))
7142				inst.input.focus();
7143			$.datepicker._curInst = inst;
7144		}
7145	},
7146
7147	/* Generate the date picker content. */
7148	_updateDatepicker: function(inst) {
7149		this.maxRows = 4; //Reset the max number of rows being displayed (see #7043)
7150		var borders = $.datepicker._getBorders(inst.dpDiv);
7151		instActive = inst; // for delegate hover events
7152		inst.dpDiv.empty().append(this._generateHTML(inst));
7153		this._attachHandlers(inst);
7154		var cover = inst.dpDiv.find('iframe.ui-datepicker-cover'); // IE6- only
7155		if( !!cover.length ){ //avoid call to outerXXXX() when not in IE6
7156			cover.css({left: -borders[0], top: -borders[1], width: inst.dpDiv.outerWidth(), height: inst.dpDiv.outerHeight()})
7157		}
7158		inst.dpDiv.find('.' + this._dayOverClass + ' a').mouseover();
7159		var numMonths = this._getNumberOfMonths(inst);
7160		var cols = numMonths[1];
7161		var width = 17;
7162		inst.dpDiv.removeClass('ui-datepicker-multi-2 ui-datepicker-multi-3 ui-datepicker-multi-4').width('');
7163		if (cols > 1)
7164			inst.dpDiv.addClass('ui-datepicker-multi-' + cols).css('width', (width * cols) + 'em');
7165		inst.dpDiv[(numMonths[0] != 1 || numMonths[1] != 1 ? 'add' : 'remove') +
7166			'Class']('ui-datepicker-multi');
7167		inst.dpDiv[(this._get(inst, 'isRTL') ? 'add' : 'remove') +
7168			'Class']('ui-datepicker-rtl');
7169		if (inst == $.datepicker._curInst && $.datepicker._datepickerShowing && inst.input &&
7170				// #6694 - don't focus the input if it's already focused
7171				// this breaks the change event in IE
7172				inst.input.is(':visible') && !inst.input.is(':disabled') && inst.input[0] != document.activeElement)
7173			inst.input.focus();
7174		// deffered render of the years select (to avoid flashes on Firefox)
7175		if( inst.yearshtml ){
7176			var origyearshtml = inst.yearshtml;
7177			setTimeout(function(){
7178				//assure that inst.yearshtml didn't change.
7179				if( origyearshtml === inst.yearshtml && inst.yearshtml ){
7180					inst.dpDiv.find('select.ui-datepicker-year:first').replaceWith(inst.yearshtml);
7181				}
7182				origyearshtml = inst.yearshtml = null;
7183			}, 0);
7184		}
7185	},
7186
7187	/* Retrieve the size of left and top borders for an element.
7188	   @param  elem  (jQuery object) the element of interest
7189	   @return  (number[2]) the left and top borders */
7190	_getBorders: function(elem) {
7191		var convert = function(value) {
7192			return {thin: 1, medium: 2, thick: 3}[value] || value;
7193		};
7194		return [parseFloat(convert(elem.css('border-left-width'))),
7195			parseFloat(convert(elem.css('border-top-width')))];
7196	},
7197
7198	/* Check positioning to remain on screen. */
7199	_checkOffset: function(inst, offset, isFixed) {
7200		var dpWidth = inst.dpDiv.outerWidth();
7201		var dpHeight = inst.dpDiv.outerHeight();
7202		var inputWidth = inst.input ? inst.input.outerWidth() : 0;
7203		var inputHeight = inst.input ? inst.input.outerHeight() : 0;
7204		var viewWidth = document.documentElement.clientWidth + (isFixed ? 0 : $(document).scrollLeft());
7205		var viewHeight = document.documentElement.clientHeight + (isFixed ? 0 : $(document).scrollTop());
7206
7207		offset.left -= (this._get(inst, 'isRTL') ? (dpWidth - inputWidth) : 0);
7208		offset.left -= (isFixed && offset.left == inst.input.offset().left) ? $(document).scrollLeft() : 0;
7209		offset.top -= (isFixed && offset.top == (inst.input.offset().top + inputHeight)) ? $(document).scrollTop() : 0;
7210
7211		// now check if datepicker is showing outside window viewport - move to a better place if so.
7212		offset.left -= Math.min(offset.left, (offset.left + dpWidth > viewWidth && viewWidth > dpWidth) ?
7213			Math.abs(offset.left + dpWidth - viewWidth) : 0);
7214		offset.top -= Math.min(offset.top, (offset.top + dpHeight > viewHeight && viewHeight > dpHeight) ?
7215			Math.abs(dpHeight + inputHeight) : 0);
7216
7217		return offset;
7218	},
7219
7220	/* Find an object's position on the screen. */
7221	_findPos: function(obj) {
7222		var inst = this._getInst(obj);
7223		var isRTL = this._get(inst, 'isRTL');
7224		while (obj && (obj.type == 'hidden' || obj.nodeType != 1 || $.expr.filters.hidden(obj))) {
7225			obj = obj[isRTL ? 'previousSibling' : 'nextSibling'];
7226		}
7227		var position = $(obj).offset();
7228		return [position.left, position.top];
7229	},
7230
7231	/* Hide the date picker from view.
7232	   @param  input  element - the input field attached to the date picker */
7233	_hideDatepicker: function(input) {
7234		var inst = this._curInst;
7235		if (!inst || (input && inst != $.data(input, PROP_NAME)))
7236			return;
7237		if (this._datepickerShowing) {
7238			var showAnim = this._get(inst, 'showAnim');
7239			var duration = this._get(inst, 'duration');
7240			var postProcess = function() {
7241				$.datepicker._tidyDialog(inst);
7242			};
7243
7244			// DEPRECATED: after BC for 1.8.x $.effects[ showAnim ] is not needed
7245			if ( $.effects && ( $.effects.effect[ showAnim ] || $.effects[ showAnim ] ) )
7246				inst.dpDiv.hide(showAnim, $.datepicker._get(inst, 'showOptions'), duration, postProcess);
7247			else
7248				inst.dpDiv[(showAnim == 'slideDown' ? 'slideUp' :
7249					(showAnim == 'fadeIn' ? 'fadeOut' : 'hide'))]((showAnim ? duration : null), postProcess);
7250			if (!showAnim)
7251				postProcess();
7252			this._datepickerShowing = false;
7253			var onClose = this._get(inst, 'onClose');
7254			if (onClose)
7255				onClose.apply((inst.input ? inst.input[0] : null),
7256					[(inst.input ? inst.input.val() : ''), inst]);
7257			this._lastInput = null;
7258			if (this._inDialog) {
7259				this._dialogInput.css({ position: 'absolute', left: '0', top: '-100px' });
7260				if ($.blockUI) {
7261					$.unblockUI();
7262					$('body').append(this.dpDiv);
7263				}
7264			}
7265			this._inDialog = false;
7266		}
7267	},
7268
7269	/* Tidy up after a dialog display. */
7270	_tidyDialog: function(inst) {
7271		inst.dpDiv.removeClass(this._dialogClass).unbind('.ui-datepicker-calendar');
7272	},
7273
7274	/* Close date picker if clicked elsewhere. */
7275	_checkExternalClick: function(event) {
7276		if (!$.datepicker._curInst)
7277			return;
7278
7279		var $target = $(event.target),
7280			inst = $.datepicker._getInst($target[0]);
7281
7282		if ( ( ( $target[0].id != $.datepicker._mainDivId &&
7283				$target.parents('#' + $.datepicker._mainDivId).length == 0 &&
7284				!$target.hasClass($.datepicker.markerClassName) &&
7285				!$target.closest("." + $.datepicker._triggerClass).length &&
7286				$.datepicker._datepickerShowing && !($.datepicker._inDialog && $.blockUI) ) ) ||
7287			( $target.hasClass($.datepicker.markerClassName) && $.datepicker._curInst != inst ) )
7288			$.datepicker._hideDatepicker();
7289	},
7290
7291	/* Adjust one of the date sub-fields. */
7292	_adjustDate: function(id, offset, period) {
7293		var target = $(id);
7294		var inst = this._getInst(target[0]);
7295		if (this._isDisabledDatepicker(target[0])) {
7296			return;
7297		}
7298		this._adjustInstDate(inst, offset +
7299			(period == 'M' ? this._get(inst, 'showCurrentAtPos') : 0), // undo positioning
7300			period);
7301		this._updateDatepicker(inst);
7302	},
7303
7304	/* Action for current link. */
7305	_gotoToday: function(id) {
7306		var target = $(id);
7307		var inst = this._getInst(target[0]);
7308		if (this._get(inst, 'gotoCurrent') && inst.currentDay) {
7309			inst.selectedDay = inst.currentDay;
7310			inst.drawMonth = inst.selectedMonth = inst.currentMonth;
7311			inst.drawYear = inst.selectedYear = inst.currentYear;
7312		}
7313		else {
7314			var date = new Date();
7315			inst.selectedDay = date.getDate();
7316			inst.drawMonth = inst.selectedMonth = date.getMonth();
7317			inst.drawYear = inst.selectedYear = date.getFullYear();
7318		}
7319		this._notifyChange(inst);
7320		this._adjustDate(target);
7321	},
7322
7323	/* Action for selecting a new month/year. */
7324	_selectMonthYear: function(id, select, period) {
7325		var target = $(id);
7326		var inst = this._getInst(target[0]);
7327		inst['selected' + (period == 'M' ? 'Month' : 'Year')] =
7328		inst['draw' + (period == 'M' ? 'Month' : 'Year')] =
7329			parseInt(select.options[select.selectedIndex].value,10);
7330		this._notifyChange(inst);
7331		this._adjustDate(target);
7332	},
7333
7334	/* Action for selecting a day. */
7335	_selectDay: function(id, month, year, td) {
7336		var target = $(id);
7337		if ($(td).hasClass(this._unselectableClass) || this._isDisabledDatepicker(target[0])) {
7338			return;
7339		}
7340		var inst = this._getInst(target[0]);
7341		inst.selectedDay = inst.currentDay = $('a', td).html();
7342		inst.selectedMonth = inst.currentMonth = month;
7343		inst.selectedYear = inst.currentYear = year;
7344		this._selectDate(id, this._formatDate(inst,
7345			inst.currentDay, inst.currentMonth, inst.currentYear));
7346	},
7347
7348	/* Erase the input field and hide the date picker. */
7349	_clearDate: function(id) {
7350		var target = $(id);
7351		var inst = this._getInst(target[0]);
7352		this._selectDate(target, '');
7353	},
7354
7355	/* Update the input field with the selected date. */
7356	_selectDate: function(id, dateStr) {
7357		var target = $(id);
7358		var inst = this._getInst(target[0]);
7359		dateStr = (dateStr != null ? dateStr : this._formatDate(inst));
7360		if (inst.input)
7361			inst.input.val(dateStr);
7362		this._updateAlternate(inst);
7363		var onSelect = this._get(inst, 'onSelect');
7364		if (onSelect)
7365			onSelect.apply((inst.input ? inst.input[0] : null), [dateStr, inst]);  // trigger custom callback
7366		else if (inst.input)
7367			inst.input.trigger('change'); // fire the change event
7368		if (inst.inline)
7369			this._updateDatepicker(inst);
7370		else {
7371			this._hideDatepicker();
7372			this._lastInput = inst.input[0];
7373			if (typeof(inst.input[0]) != 'object')
7374				inst.input.focus(); // restore focus
7375			this._lastInput = null;
7376		}
7377	},
7378
7379	/* Update any alternate field to synchronise with the main field. */
7380	_updateAlternate: function(inst) {
7381		var altField = this._get(inst, 'altField');
7382		if (altField) { // update alternate field too
7383			var altFormat = this._get(inst, 'altFormat') || this._get(inst, 'dateFormat');
7384			var date = this._getDate(inst);
7385			var dateStr = this.formatDate(altFormat, date, this._getFormatConfig(inst));
7386			$(altField).each(function() { $(this).val(dateStr); });
7387		}
7388	},
7389
7390	/* Set as beforeShowDay function to prevent selection of weekends.
7391	   @param  date  Date - the date to customise
7392	   @return [boolean, string] - is this date selectable?, what is its CSS class? */
7393	noWeekends: function(date) {
7394		var day = date.getDay();
7395		return [(day > 0 && day < 6), ''];
7396	},
7397
7398	/* Set as calculateWeek to determine the week of the year based on the ISO 8601 definition.
7399	   @param  date  Date - the date to get the week for
7400	   @return  number - the number of the week within the year that contains this date */
7401	iso8601Week: function(date) {
7402		var checkDate = new Date(date.getTime());
7403		// Find Thursday of this week starting on Monday
7404		checkDate.setDate(checkDate.getDate() + 4 - (checkDate.getDay() || 7));
7405		var time = checkDate.getTime();
7406		checkDate.setMonth(0); // Compare with Jan 1
7407		checkDate.setDate(1);
7408		return Math.floor(Math.round((time - checkDate) / 86400000) / 7) + 1;
7409	},
7410
7411	/* Parse a string value into a date object.
7412	   See formatDate below for the possible formats.
7413
vendor: 4,158 bytes, lines 7414-7522
7414	   @param  format    string - the expected format of the date
7415	   @param  value     string - the date in the above format
7416	   @param  settings  Object - attributes include:
7417	                     shortYearCutoff  number - the cutoff year for determining the century (optional)
7418	                     dayNamesShort    string[7] - abbreviated names of the days from Sunday (optional)
7419	                     dayNames         string[7] - names of the days from Sunday (optional)
7420	                     monthNamesShort  string[12] - abbreviated names of the months (optional)
7421	                     monthNames       string[12] - names of the months (optional)
7422	   @return  Date - the extracted date value or null if value is blank */
7423	parseDate: function (format, value, settings) {
7424		if (format == null || value == null)
7425			throw 'Invalid arguments';
7426		value = (typeof value == 'object' ? value.toString() : value + '');
7427		if (value == '')
7428			return null;
7429		var shortYearCutoff = (settings ? settings.shortYearCutoff : null) || this._defaults.shortYearCutoff;
7430		shortYearCutoff = (typeof shortYearCutoff != 'string' ? shortYearCutoff :
7431				new Date().getFullYear() % 100 + parseInt(shortYearCutoff, 10));
7432		var dayNamesShort = (settings ? settings.dayNamesShort : null) || this._defaults.dayNamesShort;
7433		var dayNames = (settings ? settings.dayNames : null) || this._defaults.dayNames;
7434		var monthNamesShort = (settings ? settings.monthNamesShort : null) || this._defaults.monthNamesShort;
7435		var monthNames = (settings ? settings.monthNames : null) || this._defaults.monthNames;
7436		var year = -1;
7437		var month = -1;
7438		var day = -1;
7439		var doy = -1;
7440		var literal = false;
7441		// Check whether a format character is doubled
7442		var lookAhead = function(match) {
7443			var matches = (iFormat + 1 < format.length && format.charAt(iFormat + 1) == match);
7444			if (matches)
7445				iFormat++;
7446			return matches;
7447		};
7448		// Extract a number from the string value
7449		var getNumber = function(match) {
7450			var isDoubled = lookAhead(match);
7451			var size = (match == '@' ? 14 : (match == '!' ? 20 :
7452				(match == 'y' && isDoubled ? 4 : (match == 'o' ? 3 : 2))));
7453			var digits = new RegExp('^\\d{1,' + size + '}');
7454			var num = value.substring(iValue).match(digits);
7455			if (!num)
7456				throw 'Missing number at position ' + iValue;
7457			iValue += num[0].length;
7458			return parseInt(num[0], 10);
7459		};
7460		// Extract a name from the string value and convert to an index
7461		var getName = function(match, shortNames, longNames) {
7462			var names = $.map(lookAhead(match) ? longNames : shortNames, function (v, k) {
7463				return [ [k, v] ];
7464			}).sort(function (a, b) {
7465				return -(a[1].length - b[1].length);
7466			});
7467			var index = -1;
7468			$.each(names, function (i, pair) {
7469				var name = pair[1];
7470				if (value.substr(iValue, name.length).toLowerCase() == name.toLowerCase()) {
7471					index = pair[0];
7472					iValue += name.length;
7473					return false;
7474				}
7475			});
7476			if (index != -1)
7477				return index + 1;
7478			else
7479				throw 'Unknown name at position ' + iValue;
7480		};
7481		// Confirm that a literal character matches the string value
7482		var checkLiteral = function() {
7483			if (value.charAt(iValue) != format.charAt(iFormat))
7484				throw 'Unexpected literal at position ' + iValue;
7485			iValue++;
7486		};
7487		var iValue = 0;
7488		for (var iFormat = 0; iFormat < format.length; iFormat++) {
7489			if (literal)
7490				if (format.charAt(iFormat) == "'" && !lookAhead("'"))
7491					literal = false;
7492				else
7493					checkLiteral();
7494			else
7495				switch (format.charAt(iFormat)) {
7496					case 'd':
7497						day = getNumber('d');
7498						break;
7499					case 'D':
7500						getName('D', dayNamesShort, dayNames);
7501						break;
7502					case 'o':
7503						doy = getNumber('o');
7504						break;
7505					case 'm':
7506						month = getNumber('m');
7507						break;
7508					case 'M':
7509						month = getName('M', monthNamesShort, monthNames);
7510						break;
7511					case 'y':
7512						year = getNumber('y');
7513						break;
7514					case '@':
7515						var date = new Date(getNumber('@'));
7516						year = date.getFullYear();
7517						month = date.getMonth() + 1;
7518						day = date.getDate();
7519						break;
7520					case '!':
7521						var date = new Date((getNumber('!') - this._ticksTo1970) / 10000);
7522						year = date.getFullYear();
7523						month = date.getMonth() + 1;
7524						day = date.getDate();
7525						break;
7526					case "'":
7527						if (lookAhead("'"))
7528							checkLiteral();
7529						else
7530							literal = true;
7531						break;
7532					default:
7533						checkLiteral();
7534				}
7535		}
7536		if (iValue < value.length){
7537			var extra = value.substr(iValue);
7538			if (!/^\s+/.test(extra)) {
7539				throw "Extra/unparsed characters found in date: " + extra;
7540			}
7541		}
7542		if (year == -1)
7543			year = new Date().getFullYear();
7544		else if (year < 100)
7545			year += new Date().getFullYear() - new Date().getFullYear() % 100 +
7546				(year <= shortYearCutoff ? 0 : -100);
7547		if (doy > -1) {
7548			month = 1;
7549			day = doy;
7550			do {
7551				var dim = this._getDaysInMonth(year, month - 1);
7552				if (day <= dim)
7553					break;
7554				month++;
7555				day -= dim;
7556			} while (true);
7557		}
7558		var date = this._daylightSavingAdjust(new Date(year, month - 1, day));
7559		if (date.getFullYear() != year || date.getMonth() + 1 != month || date.getDate() != day)
7560			throw 'Invalid date'; // E.g. 31/02/00
7561		return date;
7562	},
7563
7564	/* Standard date formats. */
7565	ATOM: 'yy-mm-dd', // RFC 3339 (ISO 8601)
7566	COOKIE: 'D, dd M yy',
7567	ISO_8601: 'yy-mm-dd',
7568	RFC_822: 'D, d M y',
7569	RFC_850: 'DD, dd-M-y',
7570	RFC_1036: 'D, d M y',
7571	RFC_1123: 'D, d M yy',
7572	RFC_2822: 'D, d M yy',
7573	RSS: 'D, d M y', // RFC 822
7574	TICKS: '!',
7575	TIMESTAMP: '@',
7576	W3C: 'yy-mm-dd', // ISO 8601
7577
7578	_ticksTo1970: (((1970 - 1) * 365 + Math.floor(1970 / 4) - Math.floor(1970 / 100) +
7579		Math.floor(1970 / 400)) * 24 * 60 * 60 * 10000000),
7580
7581	/* Format a date object into a string value.
7582	   The format can be combinations of the following:
7583	   d  - day of month (no leading zero)
7584	   dd - day of month (two digit)
7585	   o  - day of year (no leading zeros)
7586	   oo - day of year (three digit)
7587	   D  - day name short
7588	   DD - day name long
7589	   m  - month of year (no leading zero)
7590	   mm - month of year (two digit)
7591	   M  - month name short
7592	   MM - month name long
7593	   y  - year (two digit)
7594	   yy - year (four digit)
7595	   @ - Unix timestamp (ms since 01/01/1970)
7596	   ! - Windows ticks (100ns since 01/01/0001)
7597	   '...' - literal text
7598	   '' - single quote
7599
7600	   @param  format    string - the desired format of the date
7601	   @param  date      Date - the date value to format
7602	   @param  settings  Object - attributes include:
7603	                     dayNamesShort    string[7] - abbreviated names of the days from Sunday (optional)
7604	                     dayNames         string[7] - names of the days from Sunday (optional)
7605	                     monthNamesShort  string[12] - abbreviated names of the months (optional)
7606	                     monthNames       string[12] - names of the months (optional)
7607	   @return  string - the date in the above format */
7608	formatDate: function (format, date, settings) {
7609		if (!date)
7610			return '';
7611		var dayNamesShort = (settings ? settings.dayNamesShort : null) || this._defaults.dayNamesShort;
7612		var dayNames = (settings ? settings.dayNames : null) || this._defaults.dayNames;
7613		var monthNamesShort = (settings ? settings.monthNamesShort : null) || this._defaults.monthNamesShort;
7614		var monthNames = (settings ? settings.monthNames : null) || this._defaults.monthNames;
7615		// Check whether a format character is doubled
7616		var lookAhead = function(match) {
7617			var matches = (iFormat + 1 < format.length && format.charAt(iFormat + 1) == match);
7618			if (matches)
7619				iFormat++;
7620			return matches;
7621		};
7622		// Format a number, with leading zero if necessary
7623		var formatNumber = function(match, value, len) {
7624			var num = '' + value;
7625			if (lookAhead(match))
7626				while (num.length < len)
7627					num = '0' + num;
7628			return num;
7629		};
7630		// Format a name, short or long as requested
7631		var formatName = function(match, value, shortNames, longNames) {
7632			return (lookAhead(match) ? longNames[value] : shortNames[value]);
7633		};
7634		var output = '';
7635		var literal = false;
7636		if (date)
7637			for (var iFormat = 0; iFormat < format.length; iFormat++) {
7638				if (literal)
7639					if (format.charAt(iFormat) == "'" && !lookAhead("'"))
7640						literal = false;
7641					else
7642						output += format.charAt(iFormat);
7643				else
7644					switch (format.charAt(iFormat)) {
7645						case 'd':
7646							output += formatNumber('d', date.getDate(), 2);
7647							break;
7648						case 'D':
7649							output += formatName('D', date.getDay(), dayNamesShort, dayNames);
7650							break;
7651						case 'o':
7652							output += formatNumber('o',
7653								Math.round((new Date(date.getFullYear(), date.getMonth(), date.getDate()).getTime() - new Date(date.getFullYear(), 0, 0).getTime()) / 86400000), 3);
7654							break;
7655						case 'm':
7656							output += formatNumber('m', date.getMonth() + 1, 2);
7657							break;
7658						case 'M':
7659							output += formatName('M', date.getMonth(), monthNamesShort, monthNames);
7660							break;
7661						case 'y':
7662							output += (lookAhead('y') ? date.getFullYear() :
7663								(date.getYear() % 100 < 10 ? '0' : '') + date.getYear() % 100);
7664							break;
7665						case '@':
7666							output += date.getTime();
7667							break;
7668						case '!':
7669							output += date.getTime() * 10000 + this._ticksTo1970;
7670							break;
vendor: 5,981 bytes, lines 7671-7852
7671						case "'":
7672							if (lookAhead("'"))
7673								output += "'";
7674							else
7675								literal = true;
7676							break;
7677						default:
7678							output += format.charAt(iFormat);
7679					}
7680			}
7681		return output;
7682	},
7683
7684	/* Extract all possible characters from the date format. */
7685	_possibleChars: function (format) {
7686		var chars = '';
7687		var literal = false;
7688		// Check whether a format character is doubled
7689		var lookAhead = function(match) {
7690			var matches = (iFormat + 1 < format.length && format.charAt(iFormat + 1) == match);
7691			if (matches)
7692				iFormat++;
7693			return matches;
7694		};
7695		for (var iFormat = 0; iFormat < format.length; iFormat++)
7696			if (literal)
7697				if (format.charAt(iFormat) == "'" && !lookAhead("'"))
7698					literal = false;
7699				else
7700					chars += format.charAt(iFormat);
7701			else
7702				switch (format.charAt(iFormat)) {
7703					case 'd': case 'm': case 'y': case '@':
7704						chars += '0123456789';
7705						break;
7706					case 'D': case 'M':
7707						return null; // Accept anything
7708					case "'":
7709						if (lookAhead("'"))
7710							chars += "'";
7711						else
7712							literal = true;
7713						break;
7714					default:
7715						chars += format.charAt(iFormat);
7716				}
7717		return chars;
7718	},
7719
7720	/* Get a setting value, defaulting if necessary. */
7721	_get: function(inst, name) {
7722		return inst.settings[name] !== undefined ?
7723			inst.settings[name] : this._defaults[name];
7724	},
7725
7726	/* Parse existing date and initialise date picker. */
7727	_setDateFromField: function(inst, noDefault) {
7728		if (inst.input.val() == inst.lastVal) {
7729			return;
7730		}
7731		var dateFormat = this._get(inst, 'dateFormat');
7732		var dates = inst.lastVal = inst.input ? inst.input.val() : null;
7733		var date, defaultDate;
7734		date = defaultDate = this._getDefaultDate(inst);
7735		var settings = this._getFormatConfig(inst);
7736		try {
7737			date = this.parseDate(dateFormat, dates, settings) || defaultDate;
7738		} catch (event) {
7739			this.log(event);
7740			dates = (noDefault ? '' : dates);
7741		}
7742		inst.selectedDay = date.getDate();
7743		inst.drawMonth = inst.selectedMonth = date.getMonth();
7744		inst.drawYear = inst.selectedYear = date.getFullYear();
7745		inst.currentDay = (dates ? date.getDate() : 0);
7746		inst.currentMonth = (dates ? date.getMonth() : 0);
7747		inst.currentYear = (dates ? date.getFullYear() : 0);
7748		this._adjustInstDate(inst);
7749	},
7750
7751	/* Retrieve the default date shown on opening. */
7752	_getDefaultDate: function(inst) {
7753		return this._restrictMinMax(inst,
7754			this._determineDate(inst, this._get(inst, 'defaultDate'), new Date()));
7755	},
7756
7757	/* A date may be specified as an exact value or a relative one. */
7758	_determineDate: function(inst, date, defaultDate) {
7759		var offsetNumeric = function(offset) {
7760			var date = new Date();
7761			date.setDate(date.getDate() + offset);
7762			return date;
7763		};
7764		var offsetString = function(offset) {
7765			try {
7766				return $.datepicker.parseDate($.datepicker._get(inst, 'dateFormat'),
7767					offset, $.datepicker._getFormatConfig(inst));
7768			}
7769			catch (e) {
7770				// Ignore
7771			}
7772			var date = (offset.toLowerCase().match(/^c/) ?
7773				$.datepicker._getDate(inst) : null) || new Date();
7774			var year = date.getFullYear();
7775			var month = date.getMonth();
7776			var day = date.getDate();
7777			var pattern = /([+-]?[0-9]+)\s*(d|D|w|W|m|M|y|Y)?/g;
7778			var matches = pattern.exec(offset);
7779			while (matches) {
7780				switch (matches[2] || 'd') {
7781					case 'd' : case 'D' :
7782						day += parseInt(matches[1],10); break;
7783					case 'w' : case 'W' :
7784						day += parseInt(matches[1],10) * 7; break;
7785					case 'm' : case 'M' :
7786						month += parseInt(matches[1],10);
7787						day = Math.min(day, $.datepicker._getDaysInMonth(year, month));
7788						break;
7789					case 'y': case 'Y' :
7790						year += parseInt(matches[1],10);
7791						day = Math.min(day, $.datepicker._getDaysInMonth(year, month));
7792						break;
7793				}
7794				matches = pattern.exec(offset);
7795			}
7796			return new Date(year, month, day);
7797		};
7798		var newDate = (date == null || date === '' ? defaultDate : (typeof date == 'string' ? offsetString(date) :
7799			(typeof date == 'number' ? (isNaN(date) ? defaultDate : offsetNumeric(date)) : new Date(date.getTime()))));
7800		newDate = (newDate && newDate.toString() == 'Invalid Date' ? defaultDate : newDate);
7801		if (newDate) {
7802			newDate.setHours(0);
7803			newDate.setMinutes(0);
7804			newDate.setSeconds(0);
7805			newDate.setMilliseconds(0);
7806		}
7807		return this._daylightSavingAdjust(newDate);
7808	},
7809
7810	/* Handle switch to/from daylight saving.
7811	   Hours may be non-zero on daylight saving cut-over:
7812	   > 12 when midnight changeover, but then cannot generate
7813	   midnight datetime, so jump to 1AM, otherwise reset.
7814	   @param  date  (Date) the date to check
7815	   @return  (Date) the corrected date */
7816	_daylightSavingAdjust: function(date) {
7817		if (!date) return null;
7818		date.setHours(date.getHours() > 12 ? date.getHours() + 2 : 0);
7819		return date;
7820	},
7821
7822	/* Set the date(s) directly. */
7823	_setDate: function(inst, date, noChange) {
7824		var clear = !date;
7825		var origMonth = inst.selectedMonth;
7826		var origYear = inst.selectedYear;
7827		var newDate = this._restrictMinMax(inst, this._determineDate(inst, date, new Date()));
7828		inst.selectedDay = inst.currentDay = newDate.getDate();
7829		inst.drawMonth = inst.selectedMonth = inst.currentMonth = newDate.getMonth();
7830		inst.drawYear = inst.selectedYear = inst.currentYear = newDate.getFullYear();
7831		if ((origMonth != inst.selectedMonth || origYear != inst.selectedYear) && !noChange)
7832			this._notifyChange(inst);
7833		this._adjustInstDate(inst);
7834		if (inst.input) {
7835			inst.input.val(clear ? '' : this._formatDate(inst));
7836		}
7837	},
7838
7839	/* Retrieve the date(s) directly. */
7840	_getDate: function(inst) {
7841		var startDate = (!inst.currentYear || (inst.input && inst.input.val() == '') ? null :
7842			this._daylightSavingAdjust(new Date(
7843			inst.currentYear, inst.currentMonth, inst.currentDay)));
7844			return startDate;
7845	},
7846
7847	/* Attach the onxxx handlers.  These are declared statically so
7848	 * they work with static code transformers like Caja.
7849	 */
7850	_attachHandlers: function(inst) {
7851		var stepMonths = this._get(inst, 'stepMonths');
7852		var id = '#' + inst.id.replace( /\\\\/g, "\\" );
7853		inst.dpDiv.find('[data-handler]').map(function () {
7854			var handler = {
7855				prev: function () {
7856					window['DP_jQuery_' + dpuuid].datepicker._adjustDate(id, -stepMonths, 'M');
7857				},
7858				next: function () {
7859					window['DP_jQuery_' + dpuuid].datepicker._adjustDate(id, +stepMonths, 'M');
7860				},
7861				hide: function () {
7862					window['DP_jQuery_' + dpuuid].datepicker._hideDatepicker();
7863				},
7864				today: function () {
7865					window['DP_jQuery_' + dpuuid].datepicker._gotoToday(id);
7866				},
7867				selectDay: function () {
7868					window['DP_jQuery_' + dpuuid].datepicker._selectDay(id, +this.getAttribute('data-month'), +this.getAttribute('data-year'), this);
7869					return false;
7870				},
7871				selectMonth: function () {
7872					window['DP_jQuery_' + dpuuid].datepicker._selectMonthYear(id, this, 'M');
7873					return false;
7874				},
7875				selectYear: function () {
7876					window['DP_jQuery_' + dpuuid].datepicker._selectMonthYear(id, this, 'Y');
7877					return false;
7878				}
7879			};
7880			$(this).bind(this.getAttribute('data-event'), handler[this.getAttribute('data-handler')]);
7881		});
7882	},
7883
7884	/* Generate the HTML for the current state of the date picker. */
7885	_generateHTML: function(inst) {
7886		var today = new Date();
7887		today = this._daylightSavingAdjust(
7888			new Date(today.getFullYear(), today.getMonth(), today.getDate())); // clear time
7889		var isRTL = this._get(inst, 'isRTL');
7890		var showButtonPanel = this._get(inst, 'showButtonPanel');
7891		var hideIfNoPrevNext = this._get(inst, 'hideIfNoPrevNext');
7892		var navigationAsDateFormat = this._get(inst, 'navigationAsDateFormat');
7893		var numMonths = this._getNumberOfMonths(inst);
7894		var showCurrentAtPos = this._get(inst, 'showCurrentAtPos');
7895		var stepMonths = this._get(inst, 'stepMonths');
7896		var isMultiMonth = (numMonths[0] != 1 || numMonths[1] != 1);
7897		var currentDate = this._daylightSavingAdjust((!inst.currentDay ? new Date(9999, 9, 9) :
7898			new Date(inst.currentYear, inst.currentMonth, inst.currentDay)));
7899		var minDate = this._getMinMaxDate(inst, 'min');
7900		var maxDate = this._getMinMaxDate(inst, 'max');
7901		var drawMonth = inst.drawMonth - showCurrentAtPos;
7902		var drawYear = inst.drawYear;
7903		if (drawMonth < 0) {
7904			drawMonth += 12;
7905			drawYear--;
7906		}
7907		if (maxDate) {
7908			var maxDraw = this._daylightSavingAdjust(new Date(maxDate.getFullYear(),
7909				maxDate.getMonth() - (numMonths[0] * numMonths[1]) + 1, maxDate.getDate()));
7910			maxDraw = (minDate && maxDraw < minDate ? minDate : maxDraw);
7911			while (this._daylightSavingAdjust(new Date(drawYear, drawMonth, 1)) > maxDraw) {
7912				drawMonth--;
7913				if (drawMonth < 0) {
7914					drawMonth = 11;
7915					drawYear--;
7916				}
7917			}
7918		}
7919		inst.drawMonth = drawMonth;
7920		inst.drawYear = drawYear;
7921		var prevText = this._get(inst, 'prevText');
7922		prevText = (!navigationAsDateFormat ? prevText : this.formatDate(prevText,
7923			this._daylightSavingAdjust(new Date(drawYear, drawMonth - stepMonths, 1)),
7924			this._getFormatConfig(inst)));
7925		var prev = (this._canAdjustMonth(inst, -1, drawYear, drawMonth) ?
7926			'<a class="ui-datepicker-prev ui-corner-all" data-handler="prev" data-event="click"' +
7927			' title="' + prevText + '"><span class="ui-icon ui-icon-circle-triangle-' + ( isRTL ? 'e' : 'w') + '">' + prevText + '</span></a>' :
7928			(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>'));
7929		var nextText = this._get(inst, 'nextText');
7930		nextText = (!navigationAsDateFormat ? nextText : this.formatDate(nextText,
7931			this._daylightSavingAdjust(new Date(drawYear, drawMonth + stepMonths, 1)),
7932			this._getFormatConfig(inst)));
7933		var next = (this._canAdjustMonth(inst, +1, drawYear, drawMonth) ?
7934			'<a class="ui-datepicker-next ui-corner-all" data-handler="next" data-event="click"' +
7935			' title="' + nextText + '"><span class="ui-icon ui-icon-circle-triangle-' + ( isRTL ? 'w' : 'e') + '">' + nextText + '</span></a>' :
7936			(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>'));
7937		var currentText = this._get(inst, 'currentText');
7938		var gotoDate = (this._get(inst, 'gotoCurrent') && inst.currentDay ? currentDate : today);
7939		currentText = (!navigationAsDateFormat ? currentText :
7940			this.formatDate(currentText, gotoDate, this._getFormatConfig(inst)));
7941		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">' +
7942			this._get(inst, 'closeText') + '</button>' : '');
7943		var buttonPanel = (showButtonPanel) ? '<div class="ui-datepicker-buttonpane ui-widget-content">' + (isRTL ? controls : '') +
7944			(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"' +
7945			'>' + currentText + '</button>' : '') + (isRTL ? '' : controls) + '</div>' : '';
7946		var firstDay = parseInt(this._get(inst, 'firstDay'),10);
7947		firstDay = (isNaN(firstDay) ? 0 : firstDay);
7948		var showWeek = this._get(inst, 'showWeek');
7949		var dayNames = this._get(inst, 'dayNames');
7950		var dayNamesShort = this._get(inst, 'dayNamesShort');
7951		var dayNamesMin = this._get(inst, 'dayNamesMin');
7952		var monthNames = this._get(inst, 'monthNames');
7953		var monthNamesShort = this._get(inst, 'monthNamesShort');
7954		var beforeShowDay = this._get(inst, 'beforeShowDay');
7955		var showOtherMonths = this._get(inst, 'showOtherMonths');
7956		var selectOtherMonths = this._get(inst, 'selectOtherMonths');
7957		var calculateWeek = this._get(inst, 'calculateWeek') || this.iso8601Week;
7958		var defaultDate = this._getDefaultDate(inst);
7959		var html = '';
7960		for (var row = 0; row < numMonths[0]; row++) {
7961			var group = '';
7962			this.maxRows = 4;
7963			for (var col = 0; col < numMonths[1]; col++) {
7964				var selectedDate = this._daylightSavingAdjust(new Date(drawYear, drawMonth, inst.selectedDay));
7965				var cornerClass = ' ui-corner-all';
7966				var calender = '';
7967				if (isMultiMonth) {
7968					calender += '<div class="ui-datepicker-group';
7969					if (numMonths[1] > 1)
7970						switch (col) {
7971							case 0: calender += ' ui-datepicker-group-first';
7972								cornerClass = ' ui-corner-' + (isRTL ? 'right' : 'left'); break;
7973							case numMonths[1]-1: calender += ' ui-datepicker-group-last';
7974								cornerClass = ' ui-corner-' + (isRTL ? 'left' : 'right'); break;
7975							default: calender += ' ui-datepicker-group-middle'; cornerClass = ''; break;
7976						}
7977					calender += '">';
7978				}
7979				calender += '<div class="ui-datepicker-header ui-widget-header ui-helper-clearfix' + cornerClass + '">' +
7980					(/all|left/.test(cornerClass) && row == 0 ? (isRTL ? next : prev) : '') +
7981					(/all|right/.test(cornerClass) && row == 0 ? (isRTL ? prev : next) : '') +
7982					this._generateMonthYearHeader(inst, drawMonth, drawYear, minDate, maxDate,
7983					row > 0 || col > 0, monthNames, monthNamesShort) + // draw month headers
7984					'</div><table class="ui-datepicker-calendar"><thead>' +
7985					'<tr>';
7986				var thead = (showWeek ? '<th class="ui-datepicker-week-col">' + this._get(inst, 'weekHeader') + '</th>' : '');
7987				for (var dow = 0; dow < 7; dow++) { // days of the week
7988					var day = (dow + firstDay) % 7;
7989					thead += '<th' + ((dow + firstDay + 6) % 7 >= 5 ? ' class="ui-datepicker-week-end"' : '') + '>
7989' +
7990						'<span title="' + dayNames[day] + '">' + dayNamesMin[day] + '</span></th>';
7991				}
7992				calender += thead + '</tr></thead><tbody>';
7993				var daysInMonth = this._getDaysInMonth(drawYear, drawMonth);
7994				if (drawYear == inst.selectedYear && drawMonth == inst.selectedMonth)
7995					inst.selectedDay = Math.min(inst.selectedDay, daysInMonth);
7996				var leadDays = (this._getFirstDayOfMonth(drawYear, drawMonth) - firstDay + 7) % 7;
7997				var curRows = Math.ceil((leadDays + daysInMonth) / 7); // calculate the number of rows to generate
7998				var numRows = (isMultiMonth ? this.maxRows > curRows ? this.maxRows : curRows : curRows); //If multiple months, use the higher number of rows (see #7043)
7999				this.maxRows = numRows;
8000				var printDate = this._daylightSavingAdjust(new Date(drawYear, drawMonth, 1 - leadDays));
8001				for (var dRow = 0; dRow < numRows; dRow++) { // create date picker rows
8002					calender += '<tr>';
8003					var tbody = (!showWeek ? '' : '<td class="ui-datepicker-week-col">' +
8004						this._get(inst, 'calculateWeek')(printDate) + '</td>');
8005					for (var dow = 0; dow < 7; dow++) { // create date picker days
8006						var daySettings = (beforeShowDay ?
8007							beforeShowDay.apply((inst.input ? inst.input[0] : null), [printDate]) : [true, '']);
8008						var otherMonth = (printDate.getMonth() != drawMonth);
8009						var unselectable = (otherMonth && !selectOtherMonths) || !daySettings[0] ||
8010							(minDate && printDate < minDate) || (maxDate && printDate > maxDate);
8011						tbody += '<td class="' +
8012							((dow + firstDay + 6) % 7 >= 5 ? ' ui-datepicker-week-end' : '') + // highlight weekends
8013							(otherMonth ? ' ui-datepicker-other-month' : '') + // highlight days from other months
8014							((printDate.getTime() == selectedDate.getTime() && drawMonth == inst.selectedMonth && inst._keyEvent) || // user pressed key
8015							(defaultDate.getTime() == printDate.getTime() && defaultDate.getTime() == selectedDate.getTime()) ?
8016							// or defaultDate is current printedDate and defaultDate is selectedDate
8017							' ' + this._dayOverClass : '') + // highlight selected day
8018							(unselectable ? ' ' + this._unselectableClass + ' ui-state-disabled': '') +  // highlight unselectable days
8019							(otherMonth && !showOtherMonths ? '' : ' ' + daySettings[1] + // highlight custom dates
8020							(printDate.getTime() == currentDate.getTime() ? ' ' + this._currentClass : '') + // highlight selected day
8021							(printDate.getTime() == today.getTime() ? ' ui-datepicker-today' : '')) + '"' + // highlight today (if different)
8022							((!otherMonth || showOtherMonths) && daySettings[2] ? ' title="' + daySettings[2] + '"' : '') + // cell title
8023							(unselectable ? '' : ' data-handler="selectDay" data-event="click" data-month="' + printDate.getMonth() + '" data-year="' + printDate.getFullYear() + '"') + '>' + // actions
8024							(otherMonth && !showOtherMonths ? '&#xa0;' : // display for other months
8025							(unselectable ? '<span class="ui-state-default">' + printDate.getDate() + '</span>' : '<a class="ui-state-default' +
8026							(printDate.getTime() == today.getTime() ? ' ui-state-highlight' : '') +
8027							(printDate.getTime() == currentDate.getTime() ? ' ui-state-active' : '') + // highlight selected day
8028							(otherMonth ? ' ui-priority-secondary' : '') + // distinguish dates from other months
8029							'" href="#">' + printDate.getDate() + '</a>')) + '</td>'; // display selectable date
8030						printDate.setDate(printDate.getDate() + 1);
8031						printDate = this._daylightSavingAdjust(printDate);
8032					}
8033					calender += tbody + '</tr>';
8034				}
8035				drawMonth++;
8036				if (drawMonth > 11) {
8037					drawMonth = 0;
8038					drawYear++;
8039				}
8040				calender += '</tbody></table>' + (isMultiMonth ? '</div>' +
8041							((numMonths[0] > 0 && col == numMonths[1]-1) ? '<div class="ui-datepicker-row-break"></div>' : '') : '');
8042				group += calender;
8043			}
8044			html += group;
8045		}
8046		html += buttonPanel + ($.ui.ie6 && !inst.inline ?
8047			'<iframe src="javascript:false;" class="ui-datepicker-cover" frameborder="0"></iframe>' : '');
8048		inst._keyEvent = false;
8049		return html;
8050	},
8051
8052	/* Generate the month and year header. */
8053	_generateMonthYearHeader: function(inst, drawMonth, drawYear, minDate, maxDate,
8054			secondary, monthNames, monthNamesShort) {
8055		var changeMonth = this._get(inst, 'changeMonth');
8056		var changeYear = this._get(inst, 'changeYear');
8057		var showMonthAfterYear = this._get(inst, 'showMonthAfterYear');
8058		var html = '<div class="ui-datepicker-title">';
8059		var monthHtml = '';
8060		
8061		// year selection
8062		if ( !inst.yearshtml ) {
8063			inst.yearshtml = '';
8064			if (secondary || !changeYear)
8065				html += '<span class="ui-datepicker-year">' + drawYear + '년 </span>';
8066			else {
8067				// determine range of years to display
8068				var years = this._get(inst, 'yearRange').split(':');
8069				var thisYear = new Date().getFullYear();
8070				var determineYear = function(value) {
8071					var year = (value.match(/c[+-].*/) ? drawYear + parseInt(value.substring(1), 10) :
8072						(value.match(/[+-].*/) ? thisYear + parseInt(value, 10) :
8073						parseInt(value, 10)));
8074					return (isNaN(year) ? thisYear : year);
8075				};
8076				var year = determineYear(years[0]);
8077				var endYear = Math.max(year, determineYear(years[1] || ''));
8078				year = (minDate ? Math.max(year, minDate.getFullYear()) : year);
8079				endYear = (maxDate ? Math.min(endYear, maxDate.getFullYear()) : endYear);
8080				inst.yearshtml += '<select class="ui-datepicker-year" data-handler="selectYear" data-event="change">';
8081				for (; year <= endYear; year++) {
8082					inst.yearshtml += '<option value="' + year + '"' +
8083						(year == drawYear ? ' selected="selected"' : '') +
8084						'>' + year + '</option>';
8085				}
8086				inst.yearshtml += '</select>';
8087
8088				html += inst.yearshtml;
8089				inst.yearshtml = null;
8090			}
8091		}
8092		html += this._get(inst, 'yearSuffix');
8093		if (showMonthAfterYear)
8094			html += (secondary || !(changeMonth && changeYear) ? '&#xa0;' : '') + monthHtml;
8095		// month selection
8096		if (secondary || !changeMonth)
8097			monthHtml += '<span class="ui-datepicker-month">' + monthNames[drawMonth] + '</span>';
8098		else {
8099			var inMinYear = (minDate && minDate.getFullYear() == drawYear);
8100			var inMaxYear = (maxDate && maxDate.getFullYear() == drawYear);
8101			monthHtml += '<select class="ui-datepicker-month" data-handler="selectMonth" data-event="change">';
8102			for (var month = 0; month < 12; month++) {
8103				if ((!inMinYear || month >= minDate.getMonth()) &&
8104						(!inMaxYear || month <= maxDate.getMonth()))
8105					monthHtml += '<option value="' + month + '"' +
8106						(month == drawMonth ? ' selected="selected"' : '') +
8107						'>' + monthNamesShort[month] + '</option>';
8108			}
8109			monthHtml += '</select>';
8110		}
8111		if (!showMonthAfterYear)
8112			html += monthHtml + (secondary || !(changeMonth && changeYear) ? '&#xa0;' : '');
8113		html += '</div>'; // Close datepicker_header
8114		return html;
8115	},
8116
8117	/* Adjust one of the date sub-fields. */
8118	_adjustInstDate: function(inst, offset, period) {
8119		var year = inst.drawYear + (period == 'Y' ? offset : 0);
8120		var month = inst.drawMonth + (period == 'M' ? offset : 0);
8121		var day = Math.min(inst.selectedDay, this._getDaysInMonth(year, month)) +
8122			(period == 'D' ? offset : 0);
8123		var date = this._restrictMinMax(inst,
8124			this._daylightSavingAdjust(new Date(year, month, day)));
8125		inst.selectedDay = date.getDate();
8126		inst.drawMonth = inst.selectedMonth = date.getMonth();
8127		inst.drawYear = inst.selectedYear = date.getFullYear();
8128		if (period == 'M' || period == 'Y')
8129			this._notifyChange(inst);
8130	},
8131
8132	/* Ensure a date is within any min/max bounds. */
8133	_restrictMinMax: function(inst, date) {
8134		var minDate = this._getMinMaxDate(inst, 'min');
8135		var maxDate = this._getMinMaxDate(inst, 'max');
8136		var newDate = (minDate && date < minDate ? minDate : date);
8137		newDate = (maxDate && newDate > maxDate ? maxDate : newDate);
8138		return newDate;
8139	},
8140
8141	/* Notify change of month/year. */
8142	_notifyChange: function(inst) {
8143		var onChange = this._get(inst, 'onChangeMonthYear');
8144		if (onChange)
8145			onChange.apply((inst.input ? inst.input[0] : null),
8146				[inst.selectedYear, inst.selectedMonth + 1, inst]);
8147	},
8148
8149	/* Determine the number of months to show. */
8150	_getNumberOfMonths: function(inst) {
8151		var numMonths = this._get(inst, 'numberOfMonths');
8152		return (numMonths == null ? [1, 1] : (typeof numMonths == 'number' ? [1, numMonths] : numMonths));
8153	},
8154
8155	/* Determine the current maximum date - ensure no time components are set. */
8156	_getMinMaxDate: function(inst, minMax) {
8157		return this._determineDate(inst, this._get(inst, minMax + 'Date'), null);
8158	},
8159
8160	/* Find the number of days in a given month. */
8161	_getDaysInMonth: function(year, month) {
8162		return 32 - this._daylightSavingAdjust(new Date(year, month, 32)).getDate();
8163	},
8164
8165	/* Find the day of the week of the first of a month. */
8166	_getFirstDayOfMonth: function(year, month) {
8167		return new Date(year, month, 1).getDay();
8168	},
8169
8170	/* Determines if we should allow a "next/prev" month display change. */
8171	_canAdjustMonth: function(inst, offset, curYear, curMonth) {
8172		var numMonths = this._getNumberOfMonths(inst);
8173		var date = this._daylightSavingAdjust(new Date(curYear,
8174			curMonth + (offset < 0 ? offset : numMonths[0] * numMonths[1]), 1));
8175		if (offset < 0)
8176			date.setDate(this._getDaysInMonth(date.getFullYear(), date.getMonth()));
8177		return this._isInRange(inst, date);
8178	},
8179
8180	/* Is the given date in the accepted range? */
8181	_isInRange: function(inst, date) {
8182		var minDate = this._getMinMaxDate(inst, 'min');
8183		var maxDate = this._getMinMaxDate(inst, 'max');
8184		return ((!minDate || date.getTime() >= minDate.getTime()) &&
8185			(!maxDate || date.getTime() <= maxDate.getTime()));
8186	},
8187
8188	/* Provide the configuration settings for formatting/parsing. */
8189	_getFormatConfig: function(inst) {
8190		var shortYearCutoff = this._get(inst, 'shortYearCutoff');
8191		shortYearCutoff = (typeof shortYearCutoff != 'string' ? shortYearCutoff :
8192			new Date().getFullYear() % 100 + parseInt(shortYearCutoff, 10));
8193		return {shortYearCutoff: shortYearCutoff,
8194			dayNamesShort: this._get(inst, 'dayNamesShort'), dayNames: this._get(inst, 'dayNames'),
8195			monthNamesShort: this._get(inst, 'monthNamesShort'), monthNames: this._get(inst, 'monthNames')};
8196	},
8197
8198	/* Format the given date for display. */
8199	_formatDate: function(inst, day, month, year) {
8200		if (!day) {
8201			inst.currentDay = inst.selectedDay;
8202			inst.currentMonth = inst.selectedMonth;
8203			inst.currentYear = inst.selectedYear;
8204		}
8205		var date = (day ? (typeof day == 'object' ? day :
8206			this._daylightSavingAdjust(new Date(year, month, day))) :
8207			this._daylightSavingAdjust(new Date(inst.currentYear, inst.currentMonth, inst.currentDay)));
8208		return this.formatDate(this._get(inst, 'dateFormat'), date, this._getFormatConfig(inst));
8209	}
8210});
8211
8212/*
8213 * Bind hover events for datepicker elements.
8214 * Done via delegate so the binding only occurs once in the lifetime of the parent div.
8215 * Global instActive, set by _updateDatepicker allows the handlers to find their way back to the active picker.
8216 */
8217function bindHover(dpDiv) {
8218	var selector = 'button, .ui-datepicker-prev, .ui-datepicker-next, .ui-datepicker-calendar td a';
8219	return dpDiv.delegate(selector, 'mouseout', function() {
8220			$(this).removeClass('ui-state-hover');
8221			if (this.className.indexOf('ui-datepicker-prev') != -1) $(this).removeClass('ui-datepicker-prev-hover');
8222			if (this.className.indexOf('ui-datepicker-next') != -1) $(this).removeClass('ui-datepicker-next-hover');
8223		})
8224		.delegate(selector, 'mouseover', function(){
8225			if (!$.datepicker._isDisabledDatepicker( instActive.inline ? dpDiv.parent()[0] : instActive.input[0])) {
8226				$(this).parents('.ui-datepicker-calendar').find('a').removeClass('ui-state-hover');
8227				$(this).addClass('ui-state-hover');
8228				if (this.className.indexOf('ui-datepicker-prev') != -1) $(this).addClass('ui-datepicker-prev-hover');
8229				if (this.className.indexOf('ui-datepicker-next') != -1) $(this).addClass('ui-datepicker-next-hover');
8230			}
8231		});
8232}
8233
8234/* jQuery extend now ignores nulls! */
8235function extendRemove(target, props) {
8236	$.extend(target, props);
8237	for (var name in props)
8238		if (props[name] == null || props[name] == undefined)
8239			target[name] = props[name];
8240	return target;
8241};
8242
8243/* Invoke the datepicker functionality.
8244   @param  options  string - a command, optionally followed by additional parameters or
8245	                Object - settings for attaching new datepicker functionality
8246   @return  jQuery object */
8247$.fn.datepicker = function(options){
8248
8249	/* Verify an empty collection wasn't passed - Fixes #6976 */
8250	if ( !this.length ) {
8251		return this;
8252	}
8253
8254	/* Initialise the date picker. */
8255	if (!$.datepicker.initialized) {
8256		$(document).mousedown($.datepicker._checkExternalClick).
8257			find(document.body).append($.datepicker.dpDiv);
8258		$.datepicker.initialized = true;
8259	}
8260
8261	var otherArgs = Array.prototype.slice.call(arguments, 1);
8262	if (typeof options == 'string' && (options == 'isDisabled' || options == 'getDate' || options == 'widget'))
8263		return $.datepicker['_' + options + 'Datepicker'].
8264			apply($.datepicker, [this[0]].concat(otherArgs));
8265	if (options == 'option' && arguments.length == 2 && typeof arguments[1] == 'string')
8266		return $.datepicker['_' + options + 'Datepicker'].
8267			apply($.datepicker, [this[0]].concat(otherArgs));
8268	return this.each(function() {
8269		typeof options == 'string' ?
8270			$.datepicker['_' + options + 'Datepicker'].
8271				apply($.datepicker, [this].concat(otherArgs)) :
8272			$.datepicker._attachDatepicker(this, options);
8273	});
8274};
8275
8276$.datepicker = new Datepicker(); // singleton instance
8277$.datepicker.initialized = false;
8278$.datepicker.uuid = new Date().getTime();
8279$.datepicker.version = "1.9.2";
8280
8281// Workaround for #4055
8282// Add another global to avoid noConflict issues with inline event handlers
8283window['DP_jQuery_' + dpuuid] = $;
8284
8285})(jQuery);
8286(function( $, undefined ) {
8287
8288var uiDialogClasses = "ui-dialog ui-widget ui-widget-content ui-corner-all ",
8289	sizeRelatedOptions = {
8290		buttons: true,
8291		height: true,
8292		maxHeight: true,
8293		maxWidth: true,
8294		minHeight: true,
8295		minWidth: true,
8296		width: true
8297	},
8298	resizableRelatedOptions = {
8299		maxHeight: true,
8300		maxWidth: true,
8301		minHeight: true,
8302		minWidth: true
8303	};
8304
8305$.widget("ui.dialog", {
8306	version: "1.9.2",
8307	options: {
8308		autoOpen: true,
8309		buttons: {},
8310		closeOnEscape: true,
8311		closeText: "close",
8312		dialogClass: "",
8313		draggable: true,
8314		hide: null,
8315		height: "auto",
8316		maxHeight: false,
8317		maxWidth: false,
8318		minHeight: 150,
8319		minWidth: 150,
8320		modal: false,
8321		position: {
8322			my: "center",
8323			at: "center",
8324			of: window,
8325			collision: "fit",
8326			// ensure that the titlebar is never outside the document
8327			using: function( pos ) {
8328				var topOffset = $( this ).css( pos ).offset().top;
8329				if ( topOffset < 0 ) {
8330					$( this ).css( "top", pos.top - topOffset );
8331				}
8332			}
8333		},
8334		resizable: true,
8335		show: null,
8336		stack: true,
8337		title: "",
8338		width: 300,
8339		zIndex: 1000
8340	},
8341
8342	_create: function() {
8343		this.originalTitle = this.element.attr( "title" );
8344		// #5742 - .attr() might return a DOMElement
8345		if ( typeof this.originalTitle !== "string" ) {
8346			this.originalTitle = "";
8347		}
8348		this.oldPosition = {
8349			parent: this.element.parent(),
8350			index: this.element.parent().children().index( this.element )
8351		};
8352		this.options.title = this.options.title || this.originalTitle;
8353		var that = this,
8354			options = this.options,
8355
8356			title = options.title || "&#160;",
8357			uiDialog,
8358			uiDialogTitlebar,
8359			uiDialogTitlebarClose,
8360			uiDialogTitle,
8361			uiDialogButtonPane;
8362
8363			uiDialog = ( this.uiDialog = $( "<div>" ) )
8364				.addClass( uiDialogClasses + options.dialogClass )
8365				.css({
8366					display: "none",
8367					outline: 0, // TODO: move to stylesheet
8368					zIndex: options.zIndex
8369				})
8370				// setting tabIndex makes the div focusable
8371				.attr( "tabIndex", -1)
8372				.keydown(function( event ) {
8373					if ( options.closeOnEscape && !event.isDefaultPrevented() && event.keyCode &&
8374							event.keyCode === $.ui.keyCode.ESCAPE ) {
8375						that.close( event );
8376						event.preventDefault();
8377					}
8378				})
8379				.mousedown(function( event ) {
8380					that.moveToTop( false, event );
8381				})
8382				.appendTo( "body" );
8383
8384			this.element
8385				.show()
8386				.removeAttr( "title" )
8387				.addClass( "ui-dialog-content ui-widget-content" )
8388				.appendTo( uiDialog );
8389
8390			uiDialogTitlebar = ( this.uiDialogTitlebar = $( "<div>" ) )
8391				.addClass( "ui-dialog-titlebar  ui-widget-header  " +
8392					"ui-corner-all  ui-helper-clearfix" )
8393				.bind( "mousedown", function() {
8394					// Dialog isn't getting focus when dragging (#8063)
8395					uiDialog.focus();
8396				})
8397				.prependTo( uiDialog );
8398
8399			uiDialogTitlebarClose = $( "<a href='#'></a>" )
8400				.addClass( "ui-dialog-titlebar-close  ui-corner-all" )
8401				.attr( "role", "button" )
8402				.click(function( event ) {
8403					event.preventDefault();
8404					that.close( event );
8405				})
8406				.appendTo( uiDialogTitlebar );
8407
8408			( this.uiDialogTitlebarCloseText = $( "<span>" ) )
8409				.addClass( "ui-icon ui-icon-closethick" )
8410				.text( options.closeText )
8411				.appendTo( uiDialogTitlebarClose );
8412
8413			uiDialogTitle = $( "<span>" )
8414				.uniqueId()
8415				.addClass( "ui-dialog-title" )
8416				.html( title )
8417				.prependTo( uiDialogTitlebar );
8418
8419			uiDialogButtonPane = ( this.uiDialogButtonPane = $( "<div>" ) )
8420				.addClass( "ui-dialog-buttonpane ui-widget-content ui-helper-clearfix" );
8421
8422			( this.uiButtonSet = $( "<div>" ) )
8423				.addClass( "ui-dialog-buttonset" )
8424				.appendTo( uiDialogButtonPane );
8425
8426		uiDialog.attr({
8427			role: "dialog",
8428			"aria-labelledby": uiDialogTitle.attr( "id" )
8429		});
8430
8431		uiDialogTitlebar.find( "*" ).add( uiDialogTitlebar ).disableSelection();
8432		this._hoverable( uiDialogTitlebarClose );
8433		this._focusable( uiDialogTitlebarClose );
8434
8435		if ( options.draggable && $.fn.draggable ) {
8436			this._makeDraggable();
8437		}
8438		if ( options.resizable && $.fn.resizable ) {
8439			this._makeResizable();
8440		}
8441
8442		this._createButtons( options.buttons );
8443		this._isOpen = false;
8444
8445		if ( $.fn.bgiframe ) {
8446			uiDialog.bgiframe();
8447		}
8448
8449		// prevent tabbing out of modal dialogs
8450		this._on( uiDialog, { keydown: function( event ) {
8451			if ( !options.modal || event.keyCode !== $.ui.keyCode.TAB ) {
8452				return;
8453			}
8454
8455			var tabbables = $( ":tabbable", uiDialog ),
8456				first = tabbables.filter( ":first" ),
8457				last  = tabbables.filter( ":last" );
8458
8459			if ( event.target === last[0] && !event.shiftKey ) {
8460				first.focus( 1 );
8461				return false;
8462			} else if ( event.target === first[0] && event.shiftKey ) {
8463				last.focus( 1 );
8464				return false;
8465			}
8466		}});
8467	},
8468
8469	_init: function() {
8470		if ( this.options.autoOpen ) {
8471			this.open();
8472		}
8473	},
8474
8475	_destroy: function() {
8476		var next,
8477			oldPosition = this.oldPosition;
8478
8479		if ( this.overlay ) {
8480			this.overlay.destroy();
8481		}
8482		this.uiDialog.hide();
8483		this.element
8484			.removeClass( "ui-dialog-content ui-widget-content" )
8485			.hide()
8486			.appendTo( "body" );
8487		this.uiDialog.remove();
8488
8489		if ( this.originalTitle ) {
8490			this.element.attr( "title", this.originalTitle );
8491		}
8492
8493		next = oldPosition.parent.children().eq( oldPosition.index );
8494		// Don't try to place the dialog next to itself (#8613)
8495		if ( next.length && next[ 0 ] !== this.element[ 0 ] ) {
8496			next.before( this.element );
8497		} else {
8498			oldPosition.parent.append( this.element );
8499		}
8500	},
8501
8502	widget: function() {
8503		return this.uiDialog;
8504	},
8505
8506	close: function( event ) {
8507		var that = this,
8508			maxZ, thisZ;
8509
8510		if ( !this._isOpen ) {
8511			return;
8512		}
8513
8514		if ( false === this._trigger( "beforeClose", event ) ) {
8515			return;
8516		}
8517
8518		this._isOpen = false;
8519
8520		if ( this.overlay ) {
8521			this.overlay.destroy();
8522		}
8523
8524		if ( this.options.hide ) {
8525			this._hide( this.uiDialog, this.options.hide, function() {
8526				that._trigger( "close", event );
8527			});
8528		} else {
8529			this.uiDialog.hide();
8530			this._trigger( "close", event );
8531		}
8532
8533		$.ui.dialog.overlay.resize();
8534
8535		// adjust the maxZ to allow other modal dialogs to continue to work (see #4309)
8536		if ( this.options.modal ) {
8537			maxZ = 0;
8538			$( ".ui-dialog" ).each(function() {
8539				if ( this !== that.uiDialog[0] ) {
8540					thisZ = $( this ).css( "z-index" );
8541					if ( !isNaN( thisZ ) ) {
8542						maxZ = Math.max( maxZ, thisZ );
8543					}
8544				}
8545			});
8546			$.ui.dialog.maxZ = maxZ;
8547		}
8548
8549		return this;
8550	},
8551
8552	isOpen: function() {
8553		return this._isOpen;
8554	},
8555
8556	// the force parameter allows us to move modal dialogs to their correct
8557	// position on open
8558	moveToTop: function( force, event ) {
8559		var options = this.options,
8560			saveScroll;
8561
8562		if ( ( options.modal && !force ) ||
8563				( !options.stack && !options.modal ) ) {
8564			return this._trigger( "focus", event );
8565		}
8566
8567		if ( options.zIndex > $.ui.dialog.maxZ ) {
8568			$.ui.dialog.maxZ = options.zIndex;
8569		}
8570		if ( this.overlay ) {
8571			$.ui.dialog.maxZ += 1;
8572			$.ui.dialog.overlay.maxZ = $.ui.dialog.maxZ;
8573			this.overlay.$el.css( "z-index", $.ui.dialog.overlay.maxZ );
8574		}
8575
8576		// Save and then restore scroll
8577		// Opera 9.5+ resets when parent z-index is changed.
8578		// http://bugs.jqueryui.com/ticket/3193
8579		saveScroll = {
8580			scrollTop: this.element.scrollTop(),
8581			scrollLeft: this.element.scrollLeft()
8582		};
8583		$.ui.dialog.maxZ += 1;
8584		this.uiDialog.css( "z-index", $.ui.dialog.maxZ );
8585		this.element.attr( saveScroll );
8586		this._trigger( "focus", event );
8587
8588		return this;
8589	},
8590
8591	open: function() {
8592		if ( this._isOpen ) {
8593			return;
8594		}
8595
8596		var hasFocus,
8597			options = this.options,
8598			uiDialog = this.uiDialog;
8599
8600		this._size();
8601		this._position( options.position );
8602		uiDialog.show( options.show );
8603		this.overlay = options.modal ? new $.ui.dialog.overlay( this ) : null;
8604		this.moveToTop( true );
8605
8606		// set focus to the first tabbable element in the content area or the first button
8607		// if there are no tabbable elements, set focus on the dialog itself
8608		hasFocus = this.element.find( ":tabbable" );
8609		if ( !hasFocus.length ) {
8610			hasFocus = this.uiDialogButtonPane.find( ":tabbable" );
8611			if ( !hasFocus.length ) {
8612				hasFocus = uiDialog;
8613			}
8614		}
8615		hasFocus.eq( 0 ).focus();
8616
8617		this._isOpen = true;
8618		this._trigger( "open" );
8619
8620		return this;
8621	},
8622
8623	_createButtons: function( buttons ) {
8624		var that = this,
8625			hasButtons = false;
8626
8627		// if we already have a button pane, remove it
8628		this.uiDialogButtonPane.remove();
8629		this.uiButtonSet.empty();
8630
8631		if ( typeof buttons === "object" && buttons !== null ) {
8632			$.each( buttons, function() {
8633				return !(hasButtons = true);
8634			});
8635		}
8636		if ( hasButtons ) {
8637			$.each( buttons, function( name, props ) {
8638				var button, click;
8639				props = $.isFunction( props ) ?
8640					{ click: props, text: name } :
8641					props;
8642				// Default to a non-submitting button
8643				props = $.extend( { type: "button" }, props );
8644				// Change the context for the click callback to be the main element
8645				click = props.click;
8646				props.click = function() {
8647					click.apply( that.element[0], arguments );
8648				};
8649				button = $( "<button></button>", props )
8650					.appendTo( that.uiButtonSet );
8651				if ( $.fn.button ) {
8652					button.button();
8653				}
8654			});
8655			this.uiDialog.addClass( "ui-dialog-buttons" );
8656			this.uiDialogButtonPane.appendTo( this.uiDialog );
8657		} else {
8658			this.uiDialog.removeClass( "ui-dialog-buttons" );
8659		}
8660	},
8661
8662	_makeDraggable: function() {
8663		var that = this,
8664			options = this.options;
8665
8666		function filteredUi( ui ) {
8667			return {
8668				position: ui.position,
8669				offset: ui.offset
8670			};
8671		}
8672
8673		this.uiDialog.draggable({
8674			cancel: ".ui-dialog-content, .ui-dialog-titlebar-close",
8675			handle: ".ui-dialog-titlebar",
8676			containment: "document",
8677			start: function( event, ui ) {
8678				$( this )
8679					.addClass( "ui-dialog-dragging" );
8680				that._trigger( "dragStart", event, filteredUi( ui ) );
8681			},
8682			drag: function( event, ui ) {
8683				that._trigger( "drag", event, filteredUi( ui ) );
8684			},
8685			stop: function( event, ui ) {
8686				options.position = [
8687					ui.position.left - that.document.scrollLeft(),
8688					ui.position.top - that.document.scrollTop()
8689				];
8690				$( this )
8691					.removeClass( "ui-dialog-dragging" );
8692				that._trigger( "dragStop", event, filteredUi( ui ) );
8693				$.ui.dialog.overlay.resize();
8694			}
8695		});
8696	},
8697
8698	_makeResizable: function( handles ) {
8699		handles = (handles === undefined ? this.options.resizable : handles);
8700		var that = this,
8701			options = this.options,
8702			// .ui-resizable has position: relative defined in the stylesheet
8703			// but dialogs have to use absolute or fixed positioning
8704			position = this.uiDialog.css( "position" ),
8705			resizeHandles = typeof handles === 'string' ?
8706				handles	:
8707				"n,e,s,w,se,sw,ne,nw";
8708
8709		function filteredUi( ui ) {
8710			return {
8711				originalPosition: ui.originalPosition,
8712				originalSize: ui.originalSize,
8713				position: ui.position,
8714				size: ui.size
8715			};
8716		}
8717
8718		this.uiDialog.resizable({
8719			cancel: ".ui-dialog-content",
8720			containment: "document",
8721			alsoResize: this.element,
8722			maxWidth: options.maxWidth,
8723			maxHeight: options.maxHeight,
8724			minWidth: options.minWidth,
8725			minHeight: this._minHeight(),
8726			handles: resizeHandles,
8727			start: function( event, ui ) {
8728				$( this ).addClass( "ui-dialog-resizing" );
8729				that._trigger( "resizeStart", event, filteredUi( ui ) );
8730			},
8731			resize: function( event, ui ) {
8732				that._trigger( "resize", event, filteredUi( ui ) );
8733			},
8734			stop: function( event, ui ) {
8735				$( this ).removeClass( "ui-dialog-resizing" );
8736				options.height = $( this ).height();
8737				options.width = $( this ).width();
8738				that._trigger( "resizeStop", event, filteredUi( ui ) );
8739				$.ui.dialog.overlay.resize();
8740			}
8741		})
8742		.css( "position", position )
8743		.find( ".ui-resizable-se" )
8744			.addClass( "ui-icon ui-icon-grip-diagonal-se" );
8745	},
8746
8747	_minHeight: function() {
8748		var options = this.options;
8749
8750		if ( options.height === "auto" ) {
8751			return options.minHeight;
8752		} else {
8753			return Math.min( options.minHeight, options.height );
8754		}
8755	},
8756
8757	_position: function( position ) {
8758		var myAt = [],
8759			offset = [ 0, 0 ],
8760			isVisible;
8761
8762		if ( position ) {
8763			// deep extending converts arrays to objects in jQuery <= 1.3.2 :-(
8764	//		if (typeof position == 'string' || $.isArray(position)) {
8765	//			myAt = $.isArray(position) ? position : position.split(' ');
8766
8767			if ( typeof position === "string" || (typeof position === "object" && "0" in position ) ) {
8768				myAt = position.split ? position.split( " " ) : [ position[ 0 ], position[ 1 ] ];
8769				if ( myAt.length === 1 ) {
8770					myAt[ 1 ] = myAt[ 0 ];
8771				}
8772
8773				$.each( [ "left", "top" ], function( i, offsetPosition ) {
8774					if ( +myAt[ i ] === myAt[ i ] ) {
8775						offset[ i ] = myAt[ i ];
8776						myAt[ i ] = offsetPosition;
8777					}
8778				});
8779
8780				position = {
8781					my: myAt[0] + (offset[0] < 0 ? offset[0] : "+" + offset[0]) + " " +
8782						myAt[1] + (offset[1] < 0 ? offset[1] : "+" + offset[1]),
8783					at: myAt.join( " " )
8784				};
8785			}
8786
8787			position = $.extend( {}, $.ui.dialog.prototype.options.position, position );
8788		} else {
8789			position = $.ui.dialog.prototype.options.position;
8790		}
8791
8792		// need to show the dialog to get the actual offset in the position plugin
8793		isVisible = this.uiDialog.is( ":visible" );
8794		if ( !isVisible ) {
8795			this.uiDialog.show();
8796		}
8797		this.uiDialog.position( position );
8798		if ( !isVisible ) {
8799			this.uiDialog.hide();
8800		}
8801	},
8802
8803	_setOptions: function( options ) {
8804		var that = this,
8805			resizableOptions = {},
8806			resize = false;
8807
8808		$.each( options, function( key, value ) {
8809			that._setOption( key, value );
8810
8811			if ( key in sizeRelatedOptions ) {
8812				resize = true;
8813			}
8814			if ( key in resizableRelatedOptions ) {
8815				resizableOptions[ key ] = value;
8816			}
8817		});
8818
8819		if ( resize ) {
8820			this._size();
8821		}
8822		if ( this.uiDialog.is( ":data(resizable)" ) ) {
8823			this.uiDialog.resizable( "option", resizableOptions );
8824		}
8825	},
8826
8827	_setOption: function( key, value ) {
8828		var isDraggable, isResizable,
8829			uiDialog = this.uiDialog;
8830
8831		switch ( key ) {
8832			case "buttons":
8833				this._createButtons( value );
8834				break;
8835			case "closeText":
8836				// ensure that we always pass a string
8837				this.uiDialogTitlebarCloseText.text( "" + value );
8838				break;
8839			case "dialogClass":
8840				uiDialog
8841					.removeClass( this.options.dialogClass )
8842					.addClass( uiDialogClasses + value );
8843				break;
8844			case "disabled":
8845				if ( value ) {
8846					uiDialog.addClass( "ui-dialog-disabled" );
8847				} else {
8848					uiDialog.removeClass( "ui-dialog-disabled" );
8849				}
8850				break;
8851			case "draggable":
8852				isDraggable = uiDialog.is( ":data(draggable)" );
8853				if ( isDraggable && !value ) {
8854					uiDialog.draggable( "destroy" );
8855				}
8856
8857				if ( !isDraggable && value ) {
8858					this._makeDraggable();
8859				}
8860				break;
8861			case "position":
8862				this._position( value );
8863				break;
8864			case "resizable":
8865				// currently resizable, becoming non-resizable
8866				isResizable = uiDialog.is( ":data(resizable)" );
8867				if ( isResizable && !value ) {
8868					uiDialog.resizable( "destroy" );
8869				}
8870
8871				// currently resizable, changing handles
8872				if ( isResizable && typeof value === "string" ) {
8873					uiDialog.resizable( "option", "handles", value );
8874				}
8875
8876				// currently non-resizable, becoming resizable
8877				if ( !isResizable && value !== false ) {
8878					this._makeResizable( value );
8879				}
8880				break;
8881			case "title":
8882				// convert whatever was passed in o a string, for html() to not throw up
8883				$( ".ui-dialog-title", this.uiDialogTitlebar )
8884					.html( "" + ( value || "&#160;" ) );
8885				break;
8886		}
8887
8888		this._super( key, value );
8889	},
8890
8891	_size: function() {
8892		/* If the user has resized the dialog, the .ui-dialog and .ui-dialog-content
8893		 * divs will both have width and height set, so we need to reset them
8894		 */
8895		var nonContentHeight, minContentHeight, autoHeight,
8896			options = this.options,
8897			isVisible = this.uiDialog.is( ":visible" );
8898
8899		// reset content sizing
8900		this.element.show().css({
8901			width: "auto",
8902			minHeight: 0,
8903			height: 0
8904		});
8905
8906		if ( options.minWidth > options.width ) {
8907			options.width = options.minWidth;
8908		}
8909
8910		// reset wrapper sizing
8911		// determine the height of all the non-content elements
8912		nonContentHeight = this.uiDialog.css({
8913				height: "auto",
8914				width: options.width
8915			})
8916			.outerHeight();
8917		minContentHeight = Math.max( 0, options.minHeight - nonContentHeight );
8918
8919		if ( options.height === "auto" ) {
8920			// only needed for IE6 support
8921			if ( $.support.minHeight ) {
8922				this.element.css({
8923					minHeight: minContentHeight,
8924					height: "auto"
8925				});
8926			} else {
8927				this.uiDialog.show();
8928				autoHeight = this.element.css( "height", "auto" ).height();
8929				if ( !isVisible ) {
8930					this.uiDialog.hide();
8931				}
8932				this.element.height( Math.max( autoHeight, minContentHeight ) );
8933			}
8934		} else {
8935			this.element.height( Math.max( options.height - nonContentHeight, 0 ) );
8936		}
8937
8938		if (this.uiDialog.is( ":data(resizable)" ) ) {
8939			this.uiDialog.resizable( "option", "minHeight", this._minHeight() );
8940		}
8941	}
8942});
8943
8944$.extend($.ui.dialog, {
8945	uuid: 0,
8946	maxZ: 0,
8947
8948	getTitleId: function($el) {
8949		var id = $el.attr( "id" );
8950		if ( !id ) {
8951			this.uuid += 1;
8952			id = this.uuid;
8953		}
8954		return "ui-dialog-title-" + id;
8955	},
8956
8957	overlay: function( dialog ) {
8958		this.$el = $.ui.dialog.overlay.create( dialog );
8959	}
8960});
8961
8962$.extend( $.ui.dialog.overlay, {
8963	instances: [],
8964	// reuse old instances due to IE memory leak with alpha transparency (see #5185)
8965	oldInstances: [],
8966	maxZ: 0,
8967	events: $.map(
8968		"focus,mousedown,mouseup,keydown,keypress,click".split( "," ),
8969		function( event ) {
8970			return event + ".dialog-overlay";
8971		}
8972	).join( " " ),
8973	create: function( dialog ) {
8974		if ( this.instances.length === 0 ) {
8975			// prevent use of anchors and inputs
8976			// we use a setTimeout in case the overlay is created from an
8977			// event that we're going to be cancelling (see #2804)
8978			setTimeout(function() {
8979				// handle $(el).dialog().dialog('close') (see #4065)
8980				if ( $.ui.dialog.overlay.instances.length ) {
8981					$( document ).bind( $.ui.dialog.overlay.events, function( event ) {
8982						// stop events if the z-index of the target is < the z-index of the overlay
8983						// we cannot return true when we don't want to cancel the event (#3523)
8984						if ( $( event.target ).zIndex() < $.ui.dialog.overlay.maxZ ) {
8985							return false;
8986						}
8987					});
8988				}
8989			}, 1 );
8990
8991			// handle window resize
8992			$( window ).bind( "resize.dialog-overlay", $.ui.dialog.overlay.resize );
8993		}
8994
8995		var $el = ( this.oldInstances.pop() || $( "<div>" ).addClass( "ui-widget-overlay" ) );
8996
8997		// allow closing by pressing the escape key
8998		$( document ).bind( "keydown.dialog-overlay", function( event ) {
8999			var instances = $.ui.dialog.overlay.instances;
9000			// only react to the event if we're the top overlay
9001			if ( instances.length !== 0 && instances[ instances.length - 1 ] === $el &&
9002				dialog.options.closeOnEscape && !event.isDefaultPrevented() && event.keyCode &&
9003				event.keyCode === $.ui.keyCode.ESCAPE ) {
9004
9005				dialog.close( event );
9006				event.preventDefault();
9007			}
9008		});
9009
9010		$el.appendTo( document.body ).css({
9011			width: this.width(),
9012			height: this.height()
9013		});
9014
9015		if ( $.fn.bgiframe ) {
9016			$el.bgiframe();
9017		}
9018
9019		this.instances.push( $el );
9020		return $el;
9021	},
9022
9023	destroy: function( $el ) {
9024		var indexOf = $.inArray( $el, this.instances ),
9025			maxZ = 0;
9026
9027		if ( indexOf !== -1 ) {
9028			this.oldInstances.push( this.instances.splice( indexOf, 1 )[ 0 ] );
9029		}
9030
9031		if ( this.instances.length === 0 ) {
9032			$( [ document, window ] ).unbind( ".dialog-overlay" );
9033		}
9034
9035		$el.height( 0 ).width( 0 ).remove();
9036
9037		// adjust the maxZ to allow other modal dialogs to continue to work (see #4309)
9038		$.each( this.instances, function() {
9039			maxZ = Math.max( maxZ, this.css( "z-index" ) );
9040		});
9041		this.maxZ = maxZ;
9042	},
9043
9044	height: function() {
9045		var scrollHeight,
9046			offsetHeight;
9047		// handle IE
9048		if ( $.ui.ie ) {
9049			scrollHeight = Math.max(
9050				document.documentElement.scrollHeight,
9051				document.body.scrollHeight
9052			);
9053			offsetHeight = Math.max(
9054				document.documentElement.offsetHeight,
9055				document.body.offsetHeight
9056			);
9057
9058			if ( scrollHeight < offsetHeight ) {
9059				return $( window ).height() + "px";
9060			} else {
9061				return scrollHeight + "px";
9062			}
9063		// handle "good" browsers
9064		} else {
9065			return $( document ).height() + "px";
9066		}
9067	},
9068
9069	width: function() {
9070		var scrollWidth,
9071			offsetWidth;
9072		// handle IE
9073		if ( $.ui.ie ) {
9074			scrollWidth = Math.max(
9075				document.documentElement.scrollWidth,
9076				document.body.scrollWidth
9077			);
9078			offsetWidth = Math.max(
9079				document.documentElement.offsetWidth,
9080				document.body.offsetWidth
9081			);
9082
9083			if ( scrollWidth < offsetWidth ) {
9084				return $( window ).width() + "px";
9085			} else {
9086				return scrollWidth + "px";
9087			}
9088		// handle "good" browsers
9089		} else {
9090			return $( document ).width() + "px";
9091		}
9092	},
9093
9094	resize: function() {
9095		/* If the dialog is draggable and the user drags it past the
9096		 * right edge of the window, the document becomes wider so we
9097		 * need to stretch the overlay. If the user then drags the
9098		 * dialog back to the left, the document will become narrower,
9099		 * so we need to shrink the overlay to the appropriate size.
9100		 * This is handled by shrinking the overlay before setting it
9101		 * to the full document size.
9102		 */
9103		var $overlays = $( [] );
9104		$.each( $.ui.dialog.overlay.instances, function() {
9105			$overlays = $overlays.add( this );
9106		});
9107
9108		$overlays.css({
9109			width: 0,
9110			height: 0
9111		}).css({
9112			width: $.ui.dialog.overlay.width(),
9113			height: $.ui.dialog.overlay.height()
9114		});
9115	}
9116});
9117
9118$.extend( $.ui.dialog.overlay.prototype, {
9119	destroy: function() {
9120		$.ui.dialog.overlay.destroy( this.$el );
9121	}
9122});
9123
9124}( jQuery ) );
9125(function( $, undefined ) {
9126
9127var mouseHandled = false;
9128
9129$.widget( "ui.menu", {
9130	version: "1.9.2",
9131	defaultElement: "<ul>",
9132	delay: 300,
9133	options: {
9134		icons: {
9135			submenu: "ui-icon-carat-1-e"
9136		},
9137		menus: "ul",
9138		position: {
9139			my: "left top",
9140			at: "right top"
9141		},
9142		role: "menu",
9143
9144		// callbacks
9145		blur: null,
9146		focus: null,
9147		select: null
9148	},
9149
9150	_create: function() {
9151		this.activeMenu = this.element;
9152		this.element
9153			.uniqueId()
9154			.addClass( "ui-menu ui-widget ui-widget-content ui-corner-all" )
9155			.toggleClass( "ui-menu-icons", !!this.element.find( ".ui-icon" ).length )
9156			.attr({
9157				role: this.options.role,
9158				tabIndex: 0
9159			})
9160			// need to catch all clicks on disabled menu
9161			// not possible through _on
9162			.bind( "click" + this.eventNamespace, $.proxy(function( event ) {
9163				if ( this.options.disabled ) {
9164					event.preventDefault();
9165				}
9166			}, this ));
9167
9168		if ( this.options.disabled ) {
9169			this.element
9170				.addClass( "ui-state-disabled" )
9171				.attr( "aria-disabled", "true" );
9172		}
9173
9174		this._on({
9175			// Prevent focus from sticking to links inside menu after clicking
9176			// them (focus should always stay on UL during navigation).
9177			"mousedown .ui-menu-item > a": function( event ) {
9178				event.preventDefault();
9179			},
9180			"click .ui-state-disabled > a": function( event ) {
9181				event.preventDefault();
9182			},
9183			"click .ui-menu-item:has(a)": function( event ) {
9184				var target = $( event.target ).closest( ".ui-menu-item" );
9185				if ( !mouseHandled && target.not( ".ui-state-disabled" ).length ) {
9186					mouseHandled = true;
9187
9188					this.select( event );
9189					// Open submenu on click
9190					if ( target.has( ".ui-menu" ).length ) {
9191						this.expand( event );
9192					} else if ( !this.element.is( ":focus" ) ) {
9193						// Redirect focus to the menu
9194						this.element.trigger( "focus", [ true ] );
9195
9196						// If the active item is on the top level, let it stay active.
9197						// Otherwise, blur the active item since it is no longer visible.
9198						if ( this.active && this.active.parents( ".ui-menu" ).length === 1 ) {
9199							clearTimeout( this.timer );
9200						}
9201					}
9202				}
9203			},
9204			"mouseenter .ui-menu-item": function( event ) {
9205				var target = $( event.currentTarget );
9206				// Remove ui-state-active class from siblings of the newly focused menu item
9207				// to avoid a jump caused by adjacent elements both having a class with a border
9208				target.siblings().children( ".ui-state-active" ).removeClass( "ui-state-active" );
9209				this.focus( event, target );
9210			},
9211			mouseleave: "collapseAll",
9212			"mouseleave .ui-menu": "collapseAll",
9213			focus: function( event, keepActiveItem ) {
9214				// If there's already an active item, keep it active
9215				// If not, activate the first item
9216				var item = this.active || this.element.children( ".ui-menu-item" ).eq( 0 );
9217
9218				if ( !keepActiveItem ) {
9219					this.focus( event, item );
9220				}
9221			},
9222			blur: function( event ) {
9223				this._delay(function() {
9224					if ( !$.contains( this.element[0], this.document[0].activeElement ) ) {
9225						this.collapseAll( event );
9226					}
9227				});
9228			},
9229			keydown: "_keydown"
9230		});
9231
9232		this.refresh();
9233
vendor: 40,717 bytes, lines 9234-10778
9234		// Clicks outside of a menu collapse any open menus
9235		this._on( this.document, {
9236			click: function( event ) {
9237				if ( !$( event.target ).closest( ".ui-menu" ).length ) {
9238					this.collapseAll( event );
9239				}
9240
9241				// Reset the mouseHandled flag
9242				mouseHandled = false;
9243			}
9244		});
9245	},
9246
9247	_destroy: function() {
9248		// Destroy (sub)menus
9249		this.element
9250			.removeAttr( "aria-activedescendant" )
9251			.find( ".ui-menu" ).andSelf()
9252				.removeClass( "ui-menu ui-widget ui-widget-content ui-corner-all ui-menu-icons" )
9253				.removeAttr( "role" )
9254				.removeAttr( "tabIndex" )
9255				.removeAttr( "aria-labelledby" )
9256				.removeAttr( "aria-expanded" )
9257				.removeAttr( "aria-hidden" )
9258				.removeAttr( "aria-disabled" )
9259				.removeUniqueId()
9260				.show();
9261
9262		// Destroy menu items
9263		this.element.find( ".ui-menu-item" )
9264			.removeClass( "ui-menu-item" )
9265			.removeAttr( "role" )
9266			.removeAttr( "aria-disabled" )
9267			.children( "a" )
9268				.removeUniqueId()
9269				.removeClass( "ui-corner-all ui-state-hover" )
9270				.removeAttr( "tabIndex" )
9271				.removeAttr( "role" )
9272				.removeAttr( "aria-haspopup" )
9273				.children().each( function() {
9274					var elem = $( this );
9275					if ( elem.data( "ui-menu-submenu-carat" ) ) {
9276						elem.remove();
9277					}
9278				});
9279
9280		// Destroy menu dividers
9281		this.element.find( ".ui-menu-divider" ).removeClass( "ui-menu-divider ui-widget-content" );
9282	},
9283
9284	_keydown: function( event ) {
9285		var match, prev, character, skip, regex,
9286			preventDefault = true;
9287
9288		function escape( value ) {
9289			return value.replace( /[\-\[\]{}()*+?.,\\\^$|#\s]/g, "\\$&" );
9290		}
9291
9292		switch ( event.keyCode ) {
9293		case $.ui.keyCode.PAGE_UP:
9294			this.previousPage( event );
9295			break;
9296		case $.ui.keyCode.PAGE_DOWN:
9297			this.nextPage( event );
9298			break;
9299		case $.ui.keyCode.HOME:
9300			this._move( "first", "first", event );
9301			break;
9302		case $.ui.keyCode.END:
9303			this._move( "last", "last", event );
9304			break;
9305		case $.ui.keyCode.UP:
9306			this.previous( event );
9307			break;
9308		case $.ui.keyCode.DOWN:
9309			this.next( event );
9310			break;
9311		case $.ui.keyCode.LEFT:
9312			this.collapse( event );
9313			break;
9314		case $.ui.keyCode.RIGHT:
9315			if ( this.active && !this.active.is( ".ui-state-disabled" ) ) {
9316				this.expand( event );
9317			}
9318			break;
9319		case $.ui.keyCode.ENTER:
9320		case $.ui.keyCode.SPACE:
9321			this._activate( event );
9322			break;
9323		case $.ui.keyCode.ESCAPE:
9324			this.collapse( event );
9325			break;
9326		default:
9327			preventDefault = false;
9328			prev = this.previousFilter || "";
9329			character = String.fromCharCode( event.keyCode );
9330			skip = false;
9331
9332			clearTimeout( this.filterTimer );
9333
9334			if ( character === prev ) {
9335				skip = true;
9336			} else {
9337				character = prev + character;
9338			}
9339
9340			regex = new RegExp( "^" + escape( character ), "i" );
9341			match = this.activeMenu.children( ".ui-menu-item" ).filter(function() {
9342				return regex.test( $( this ).children( "a" ).text() );
9343			});
9344			match = skip && match.index( this.active.next() ) !== -1 ?
9345				this.active.nextAll( ".ui-menu-item" ) :
9346				match;
9347
9348			// If no matches on the current filter, reset to the last character pressed
9349			// to move down the menu to the first item that starts with that character
9350			if ( !match.length ) {
9351				character = String.fromCharCode( event.keyCode );
9352				regex = new RegExp( "^" + escape( character ), "i" );
9353				match = this.activeMenu.children( ".ui-menu-item" ).filter(function() {
9354					return regex.test( $( this ).children( "a" ).text() );
9355				});
9356			}
9357
9358			if ( match.length ) {
9359				this.focus( event, match );
9360				if ( match.length > 1 ) {
9361					this.previousFilter = character;
9362					this.filterTimer = this._delay(function() {
9363						delete this.previousFilter;
9364					}, 1000 );
9365				} else {
9366					delete this.previousFilter;
9367				}
9368			} else {
9369				delete this.previousFilter;
9370			}
9371		}
9372
9373		if ( preventDefault ) {
9374			event.preventDefault();
9375		}
9376	},
9377
9378	_activate: function( event ) {
9379		if ( !this.active.is( ".ui-state-disabled" ) ) {
9380			if ( this.active.children( "a[aria-haspopup='true']" ).length ) {
9381				this.expand( event );
9382			} else {
9383				this.select( event );
9384			}
9385		}
9386	},
9387
9388	refresh: function() {
9389		var menus,
9390			icon = this.options.icons.submenu,
9391			submenus = this.element.find( this.options.menus );
9392
9393		// Initialize nested menus
9394		submenus.filter( ":not(.ui-menu)" )
9395			.addClass( "ui-menu ui-widget ui-widget-content ui-corner-all" )
9396			.hide()
9397			.attr({
9398				role: this.options.role,
9399				"aria-hidden": "true",
9400				"aria-expanded": "false"
9401			})
9402			.each(function() {
9403				var menu = $( this ),
9404					item = menu.prev( "a" ),
9405					submenuCarat = $( "<span>" )
9406						.addClass( "ui-menu-icon ui-icon " + icon )
9407						.data( "ui-menu-submenu-carat", true );
9408
9409				item
9410					.attr( "aria-haspopup", "true" )
9411					.prepend( submenuCarat );
9412				menu.attr( "aria-labelledby", item.attr( "id" ) );
9413			});
9414
9415		menus = submenus.add( this.element );
9416
9417		// Don't refresh list items that are already adapted
9418		menus.children( ":not(.ui-menu-item):has(a)" )
9419			.addClass( "ui-menu-item" )
9420			.attr( "role", "presentation" )
9421			.children( "a" )
9422				.uniqueId()
9423				.addClass( "ui-corner-all" )
9424				.attr({
9425					tabIndex: -1,
9426					role: this._itemRole()
9427				});
9428
9429		// Initialize unlinked menu-items containing spaces and/or dashes only as dividers
9430		menus.children( ":not(.ui-menu-item)" ).each(function() {
9431			var item = $( this );
9432			// hyphen, em dash, en dash
9433			if ( !/[^\-—–\s]/.test( item.text() ) ) {
9434				item.addClass( "ui-widget-content ui-menu-divider" );
9435			}
9436		});
9437
9438		// Add aria-disabled attribute to any disabled menu item
9439		menus.children( ".ui-state-disabled" ).attr( "aria-disabled", "true" );
9440
9441		// If the active item has been removed, blur the menu
9442		if ( this.active && !$.contains( this.element[ 0 ], this.active[ 0 ] ) ) {
9443			this.blur();
9444		}
9445	},
9446
9447	_itemRole: function() {
9448		return {
9449			menu: "menuitem",
9450			listbox: "option"
9451		}[ this.options.role ];
9452	},
9453
9454	focus: function( event, item ) {
9455		var nested, focused;
9456		this.blur( event, event && event.type === "focus" );
9457
9458		this._scrollIntoView( item );
9459
9460		this.active = item.first();
9461		focused = this.active.children( "a" ).addClass( "ui-state-focus" );
9462		// Only update aria-activedescendant if there's a role
9463		// otherwise we assume focus is managed elsewhere
9464		if ( this.options.role ) {
9465			this.element.attr( "aria-activedescendant", focused.attr( "id" ) );
9466		}
9467
9468		// Highlight active parent menu item, if any
9469		this.active
9470			.parent()
9471			.closest( ".ui-menu-item" )
9472			.children( "a:first" )
9473			.addClass( "ui-state-active" );
9474
9475		if ( event && event.type === "keydown" ) {
9476			this._close();
9477		} else {
9478			this.timer = this._delay(function() {
9479				this._close();
9480			}, this.delay );
9481		}
9482
9483		nested = item.children( ".ui-menu" );
9484		if ( nested.length && ( /^mouse/.test( event.type ) ) ) {
9485			this._startOpening(nested);
9486		}
9487		this.activeMenu = item.parent();
9488
9489		this._trigger( "focus", event, { item: item } );
9490	},
9491
9492	_scrollIntoView: function( item ) {
9493		var borderTop, paddingTop, offset, scroll, elementHeight, itemHeight;
9494		if ( this._hasScroll() ) {
9495			borderTop = parseFloat( $.css( this.activeMenu[0], "borderTopWidth" ) ) || 0;
9496			paddingTop = parseFloat( $.css( this.activeMenu[0], "paddingTop" ) ) || 0;
9497			offset = item.offset().top - this.activeMenu.offset().top - borderTop - paddingTop;
9498			scroll = this.activeMenu.scrollTop();
9499			elementHeight = this.activeMenu.height();
9500			itemHeight = item.height();
9501
9502			if ( offset < 0 ) {
9503				this.activeMenu.scrollTop( scroll + offset );
9504			} else if ( offset + itemHeight > elementHeight ) {
9505				this.activeMenu.scrollTop( scroll + offset - elementHeight + itemHeight );
9506			}
9507		}
9508	},
9509
9510	blur: function( event, fromFocus ) {
9511		if ( !fromFocus ) {
9512			clearTimeout( this.timer );
9513		}
9514
9515		if ( !this.active ) {
9516			return;
9517		}
9518
9519		this.active.children( "a" ).removeClass( "ui-state-focus" );
9520		this.active = null;
9521
9522		this._trigger( "blur", event, { item: this.active } );
9523	},
9524
9525	_startOpening: function( submenu ) {
9526		clearTimeout( this.timer );
9527
9528		// Don't open if already open fixes a Firefox bug that caused a .5 pixel
9529		// shift in the submenu position when mousing over the carat icon
9530		if ( submenu.attr( "aria-hidden" ) !== "true" ) {
9531			return;
9532		}
9533
9534		this.timer = this._delay(function() {
9535			this._close();
9536			this._open( submenu );
9537		}, this.delay );
9538	},
9539
9540	_open: function( submenu ) {
9541		var position = $.extend({
9542			of: this.active
9543		}, this.options.position );
9544
9545		clearTimeout( this.timer );
9546		this.element.find( ".ui-menu" ).not( submenu.parents( ".ui-menu" ) )
9547			.hide()
9548			.attr( "aria-hidden", "true" );
9549
9550		submenu
9551			.show()
9552			.removeAttr( "aria-hidden" )
9553			.attr( "aria-expanded", "true" )
9554			.position( position );
9555	},
9556
9557	collapseAll: function( event, all ) {
9558		clearTimeout( this.timer );
9559		this.timer = this._delay(function() {
9560			// If we were passed an event, look for the submenu that contains the event
9561			var currentMenu = all ? this.element :
9562				$( event && event.target ).closest( this.element.find( ".ui-menu" ) );
9563
9564			// If we found no valid submenu ancestor, use the main menu to close all sub menus anyway
9565			if ( !currentMenu.length ) {
9566				currentMenu = this.element;
9567			}
9568
9569			this._close( currentMenu );
9570
9571			this.blur( event );
9572			this.activeMenu = currentMenu;
9573		}, this.delay );
9574	},
9575
9576	// With no arguments, closes the currently active menu - if nothing is active
9577	// it closes all menus.  If passed an argument, it will search for menus BELOW
9578	_close: function( startMenu ) {
9579		if ( !startMenu ) {
9580			startMenu = this.active ? this.active.parent() : this.element;
9581		}
9582
9583		startMenu
9584			.find( ".ui-menu" )
9585				.hide()
9586				.attr( "aria-hidden", "true" )
9587				.attr( "aria-expanded", "false" )
9588			.end()
9589			.find( "a.ui-state-active" )
9590				.removeClass( "ui-state-active" );
9591	},
9592
9593	collapse: function( event ) {
9594		var newItem = this.active &&
9595			this.active.parent().closest( ".ui-menu-item", this.element );
9596		if ( newItem && newItem.length ) {
9597			this._close();
9598			this.focus( event, newItem );
9599		}
9600	},
9601
9602	expand: function( event ) {
9603		var newItem = this.active &&
9604			this.active
9605				.children( ".ui-menu " )
9606				.children( ".ui-menu-item" )
9607				.first();
9608
9609		if ( newItem && newItem.length ) {
9610			this._open( newItem.parent() );
9611
9612			// Delay so Firefox will not hide activedescendant change in expanding submenu from AT
9613			this._delay(function() {
9614				this.focus( event, newItem );
9615			});
9616		}
9617	},
9618
9619	next: function( event ) {
9620		this._move( "next", "first", event );
9621	},
9622
9623	previous: function( event ) {
9624		this._move( "prev", "last", event );
9625	},
9626
9627	isFirstItem: function() {
9628		return this.active && !this.active.prevAll( ".ui-menu-item" ).length;
9629	},
9630
9631	isLastItem: function() {
9632		return this.active && !this.active.nextAll( ".ui-menu-item" ).length;
9633	},
9634
9635	_move: function( direction, filter, event ) {
9636		var next;
9637		if ( this.active ) {
9638			if ( direction === "first" || direction === "last" ) {
9639				next = this.active
9640					[ direction === "first" ? "prevAll" : "nextAll" ]( ".ui-menu-item" )
9641					.eq( -1 );
9642			} else {
9643				next = this.active
9644					[ direction + "All" ]( ".ui-menu-item" )
9645					.eq( 0 );
9646			}
9647		}
9648		if ( !next || !next.length || !this.active ) {
9649			next = this.activeMenu.children( ".ui-menu-item" )[ filter ]();
9650		}
9651
9652		this.focus( event, next );
9653	},
9654
9655	nextPage: function( event ) {
9656		var item, base, height;
9657
9658		if ( !this.active ) {
9659			this.next( event );
9660			return;
9661		}
9662		if ( this.isLastItem() ) {
9663			return;
9664		}
9665		if ( this._hasScroll() ) {
9666			base = this.active.offset().top;
9667			height = this.element.height();
9668			this.active.nextAll( ".ui-menu-item" ).each(function() {
9669				item = $( this );
9670				return item.offset().top - base - height < 0;
9671			});
9672
9673			this.focus( event, item );
9674		} else {
9675			this.focus( event, this.activeMenu.children( ".ui-menu-item" )
9676				[ !this.active ? "first" : "last" ]() );
9677		}
9678	},
9679
9680	previousPage: function( event ) {
9681		var item, base, height;
9682		if ( !this.active ) {
9683			this.next( event );
9684			return;
9685		}
9686		if ( this.isFirstItem() ) {
9687			return;
9688		}
9689		if ( this._hasScroll() ) {
9690			base = this.active.offset().top;
9691			height = this.element.height();
9692			this.active.prevAll( ".ui-menu-item" ).each(function() {
9693				item = $( this );
9694				return item.offset().top - base + height > 0;
9695			});
9696
9697			this.focus( event, item );
9698		} else {
9699			this.focus( event, this.activeMenu.children( ".ui-menu-item" ).first() );
9700		}
9701	},
9702
9703	_hasScroll: function() {
9704		return this.element.outerHeight() < this.element.prop( "scrollHeight" );
9705	},
9706
9707	select: function( event ) {
9708		// TODO: It should never be possible to not have an active item at this
9709		// point, but the tests don't trigger mouseenter before click.
9710		this.active = this.active || $( event.target ).closest( ".ui-menu-item" );
9711		var ui = { item: this.active };
9712		if ( !this.active.has( ".ui-menu" ).length ) {
9713			this.collapseAll( event, true );
9714		}
9715		this._trigger( "select", event, ui );
9716	}
9717});
9718
9719}( jQuery ));
9720(function( $, undefined ) {
9721
9722$.widget( "ui.progressbar", {
9723	version: "1.9.2",
9724	options: {
9725		value: 0,
9726		max: 100
9727	},
9728
9729	min: 0,
9730
9731	_create: function() {
9732		this.element
9733			.addClass( "ui-progressbar ui-widget ui-widget-content ui-corner-all" )
9734			.attr({
9735				role: "progressbar",
9736				"aria-valuemin": this.min,
9737				"aria-valuemax": this.options.max,
9738				"aria-valuenow": this._value()
9739			});
9740
9741		this.valueDiv = $( "<div class='ui-progressbar-value ui-widget-header ui-corner-left'></div>" )
9742			.appendTo( this.element );
9743
9744		this.oldValue = this._value();
9745		this._refreshValue();
9746	},
9747
9748	_destroy: function() {
9749		this.element
9750			.removeClass( "ui-progressbar ui-widget ui-widget-content ui-corner-all" )
9751			.removeAttr( "role" )
9752			.removeAttr( "aria-valuemin" )
9753			.removeAttr( "aria-valuemax" )
9754			.removeAttr( "aria-valuenow" );
9755
9756		this.valueDiv.remove();
9757	},
9758
9759	value: function( newValue ) {
9760		if ( newValue === undefined ) {
9761			return this._value();
9762		}
9763
9764		this._setOption( "value", newValue );
9765		return this;
9766	},
9767
9768	_setOption: function( key, value ) {
9769		if ( key === "value" ) {
9770			this.options.value = value;
9771			this._refreshValue();
9772			if ( this._value() === this.options.max ) {
9773				this._trigger( "complete" );
9774			}
9775		}
9776
9777		this._super( key, value );
9778	},
9779
9780	_value: function() {
9781		var val = this.options.value;
9782		// normalize invalid value
9783		if ( typeof val !== "number" ) {
9784			val = 0;
9785		}
9786		return Math.min( this.options.max, Math.max( this.min, val ) );
9787	},
9788
9789	_percentage: function() {
9790		return 100 * this._value() / this.options.max;
9791	},
9792
9793	_refreshValue: function() {
9794		var value = this.value(),
9795			percentage = this._percentage();
9796
9797		if ( this.oldValue !== value ) {
9798			this.oldValue = value;
9799			this._trigger( "change" );
9800		}
9801
9802		this.valueDiv
9803			.toggle( value > this.min )
9804			.toggleClass( "ui-corner-right", value === this.options.max )
9805			.width( percentage.toFixed(0) + "%" );
9806		this.element.attr( "aria-valuenow", value );
9807	}
9808});
9809
9810})( jQuery );
9811(function( $, undefined ) {
9812
9813// number of pages in a slider
9814// (how many times can you page up/down to go through the whole range)
9815var numPages = 5;
9816
9817$.widget( "ui.slider", $.ui.mouse, {
9818	version: "1.9.2",
9819	widgetEventPrefix: "slide",
9820
9821	options: {
9822		animate: false,
9823		distance: 0,
9824		max: 100,
9825		min: 0,
9826		orientation: "horizontal",
9827		range: false,
9828		step: 1,
9829		value: 0,
9830		values: null
9831	},
9832
9833	_create: function() {
9834		var i, handleCount,
9835			o = this.options,
9836			existingHandles = this.element.find( ".ui-slider-handle" ).addClass( "ui-state-default ui-corner-all" ),
9837			handle = "<a class='ui-slider-handle ui-state-default ui-corner-all' href='#'></a>",
9838			handles = [];
9839
9840		this._keySliding = false;
9841		this._mouseSliding = false;
9842		this._animateOff = true;
9843		this._handleIndex = null;
9844		this._detectOrientation();
9845		this._mouseInit();
9846
9847		this.element
9848			.addClass( "ui-slider" +
9849				" ui-slider-" + this.orientation +
9850				" ui-widget" +
9851				" ui-widget-content" +
9852				" ui-corner-all" +
9853				( o.disabled ? " ui-slider-disabled ui-disabled" : "" ) );
9854
9855		this.range = $([]);
9856
9857		if ( o.range ) {
9858			if ( o.range === true ) {
9859				if ( !o.values ) {
9860					o.values = [ this._valueMin(), this._valueMin() ];
9861				}
9862				if ( o.values.length && o.values.length !== 2 ) {
9863					o.values = [ o.values[0], o.values[0] ];
9864				}
9865			}
9866
9867			this.range = $( "<div></div>" )
9868				.appendTo( this.element )
9869				.addClass( "ui-slider-range" +
9870				// note: this isn't the most fittingly semantic framework class for this element,
9871				// but worked best visually with a variety of themes
9872				" ui-widget-header" +
9873				( ( o.range === "min" || o.range === "max" ) ? " ui-slider-range-" + o.range : "" ) );
9874		}
9875
9876		handleCount = ( o.values && o.values.length ) || 1;
9877
9878		for ( i = existingHandles.length; i < handleCount; i++ ) {
9879			handles.push( handle );
9880		}
9881
9882		this.handles = existingHandles.add( $( handles.join( "" ) ).appendTo( this.element ) );
9883
9884		this.handle = this.handles.eq( 0 );
9885
9886		this.handles.add( this.range ).filter( "a" )
9887			.click(function( event ) {
9888				event.preventDefault();
9889			})
9890			.mouseenter(function() {
9891				if ( !o.disabled ) {
9892					$( this ).addClass( "ui-state-hover" );
9893				}
9894			})
9895			.mouseleave(function() {
9896				$( this ).removeClass( "ui-state-hover" );
9897			})
9898			.focus(function() {
9899				if ( !o.disabled ) {
9900					$( ".ui-slider .ui-state-focus" ).removeClass( "ui-state-focus" );
9901					$( this ).addClass( "ui-state-focus" );
9902				} else {
9903					$( this ).blur();
9904				}
9905			})
9906			.blur(function() {
9907				$( this ).removeClass( "ui-state-focus" );
9908			});
9909
9910		this.handles.each(function( i ) {
9911			$( this ).data( "ui-slider-handle-index", i );
9912		});
9913
9914		this._on( this.handles, {
9915			keydown: function( event ) {
9916				var allowed, curVal, newVal, step,
9917					index = $( event.target ).data( "ui-slider-handle-index" );
9918
9919				switch ( event.keyCode ) {
9920					case $.ui.keyCode.HOME:
9921					case $.ui.keyCode.END:
9922					case $.ui.keyCode.PAGE_UP:
9923					case $.ui.keyCode.PAGE_DOWN:
9924					case $.ui.keyCode.UP:
9925					case $.ui.keyCode.RIGHT:
9926					case $.ui.keyCode.DOWN:
9927					case $.ui.keyCode.LEFT:
9928						event.preventDefault();
9929						if ( !this._keySliding ) {
9930							this._keySliding = true;
9931							$( event.target ).addClass( "ui-state-active" );
9932							allowed = this._start( event, index );
9933							if ( allowed === false ) {
9934								return;
9935							}
9936						}
9937						break;
9938				}
9939
9940				step = this.options.step;
9941				if ( this.options.values && this.options.values.length ) {
9942					curVal = newVal = this.values( index );
9943				} else {
9944					curVal = newVal = this.value();
9945				}
9946
9947				switch ( event.keyCode ) {
9948					case $.ui.keyCode.HOME:
9949						newVal = this._valueMin();
9950						break;
9951					case $.ui.keyCode.END:
9952						newVal = this._valueMax();
9953						break;
9954					case $.ui.keyCode.PAGE_UP:
9955						newVal = this._trimAlignValue( curVal + ( (this._valueMax() - this._valueMin()) / numPages ) );
9956						break;
9957					case $.ui.keyCode.PAGE_DOWN:
9958						newVal = this._trimAlignValue( curVal - ( (this._valueMax() - this._valueMin()) / numPages ) );
9959						break;
9960					case $.ui.keyCode.UP:
9961					case $.ui.keyCode.RIGHT:
9962						if ( curVal === this._valueMax() ) {
9963							return;
9964						}
9965						newVal = this._trimAlignValue( curVal + step );
9966						break;
9967					case $.ui.keyCode.DOWN:
9968					case $.ui.keyCode.LEFT:
9969						if ( curVal === this._valueMin() ) {
9970							return;
9971						}
9972						newVal = this._trimAlignValue( curVal - step );
9973						break;
9974				}
9975
9976				this._slide( event, index, newVal );
9977			},
9978			keyup: function( event ) {
9979				var index = $( event.target ).data( "ui-slider-handle-index" );
9980
9981				if ( this._keySliding ) {
9982					this._keySliding = false;
9983					this._stop( event, index );
9984					this._change( event, index );
9985					$( event.target ).removeClass( "ui-state-active" );
9986				}
9987			}
9988		});
9989
9990		this._refreshValue();
9991
9992		this._animateOff = false;
9993	},
9994
9995	_destroy: function() {
9996		this.handles.remove();
9997		this.range.remove();
9998
9999		this.element
10000			.removeClass( "ui-slider" +
10001				" ui-slider-horizontal" +
10002				" ui-slider-vertical" +
10003				" ui-slider-disabled" +
10004				" ui-widget" +
10005				" ui-widget-content" +
10006				" ui-corner-all" );
10007
10008		this._mouseDestroy();
10009	},
10010
10011	_mouseCapture: function( event ) {
10012		var position, normValue, distance, closestHandle, index, allowed, offset, mouseOverHandle,
10013			that = this,
10014			o = this.options;
10015
10016		if ( o.disabled ) {
10017			return false;
10018		}
10019
10020		this.elementSize = {
10021			width: this.element.outerWidth(),
10022			height: this.element.outerHeight()
10023		};
10024		this.elementOffset = this.element.offset();
10025
10026		position = { x: event.pageX, y: event.pageY };
10027		normValue = this._normValueFromMouse( position );
10028		distance = this._valueMax() - this._valueMin() + 1;
10029		this.handles.each(function( i ) {
10030			var thisDistance = Math.abs( normValue - that.values(i) );
10031			if ( distance > thisDistance ) {
10032				distance = thisDistance;
10033				closestHandle = $( this );
10034				index = i;
10035			}
10036		});
10037
10038		// workaround for bug #3736 (if both handles of a range are at 0,
10039		// the first is always used as the one with least distance,
10040		// and moving it is obviously prevented by preventing negative ranges)
10041		if( o.range === true && this.values(1) === o.min ) {
10042			index += 1;
10043			closestHandle = $( this.handles[index] );
10044		}
10045
10046		allowed = this._start( event, index );
10047		if ( allowed === false ) {
10048			return false;
10049		}
10050		this._mouseSliding = true;
10051
10052		this._handleIndex = index;
10053
10054		closestHandle
10055			.addClass( "ui-state-active" )
10056			.focus();
10057
10058		offset = closestHandle.offset();
10059		mouseOverHandle = !$( event.target ).parents().andSelf().is( ".ui-slider-handle" );
10060		this._clickOffset = mouseOverHandle ? { left: 0, top: 0 } : {
10061			left: event.pageX - offset.left - ( closestHandle.width() / 2 ),
10062			top: event.pageY - offset.top -
10063				( closestHandle.height() / 2 ) -
10064				( parseInt( closestHandle.css("borderTopWidth"), 10 ) || 0 ) -
10065				( parseInt( closestHandle.css("borderBottomWidth"), 10 ) || 0) +
10066				( parseInt( closestHandle.css("marginTop"), 10 ) || 0)
10067		};
10068
10069		if ( !this.handles.hasClass( "ui-state-hover" ) ) {
10070			this._slide( event, index, normValue );
10071		}
10072		this._animateOff = true;
10073		return true;
10074	},
10075
10076	_mouseStart: function() {
10077		return true;
10078	},
10079
10080	_mouseDrag: function( event ) {
10081		var position = { x: event.pageX, y: event.pageY },
10082			normValue = this._normValueFromMouse( position );
10083
10084		this._slide( event, this._handleIndex, normValue );
10085
10086		return false;
10087	},
10088
10089	_mouseStop: function( event ) {
10090		this.handles.removeClass( "ui-state-active" );
10091		this._mouseSliding = false;
10092
10093		this._stop( event, this._handleIndex );
10094		this._change( event, this._handleIndex );
10095
10096		this._handleIndex = null;
10097		this._clickOffset = null;
10098		this._animateOff = false;
10099
10100		return false;
10101	},
10102
10103	_detectOrientation: function() {
10104		this.orientation = ( this.options.orientation === "vertical" ) ? "vertical" : "horizontal";
10105	},
10106
10107	_normValueFromMouse: function( position ) {
10108		var pixelTotal,
10109			pixelMouse,
10110			percentMouse,
10111			valueTotal,
10112			valueMouse;
10113
10114		if ( this.orientation === "horizontal" ) {
10115			pixelTotal = this.elementSize.width;
10116			pixelMouse = position.x - this.elementOffset.left - ( this._clickOffset ? this._clickOffset.left : 0 );
10117		} else {
10118			pixelTotal = this.elementSize.height;
10119			pixelMouse = position.y - this.elementOffset.top - ( this._clickOffset ? this._clickOffset.top : 0 );
10120		}
10121
10122		percentMouse = ( pixelMouse / pixelTotal );
10123		if ( percentMouse > 1 ) {
10124			percentMouse = 1;
10125		}
10126		if ( percentMouse < 0 ) {
10127			percentMouse = 0;
10128		}
10129		if ( this.orientation === "vertical" ) {
10130			percentMouse = 1 - percentMouse;
10131		}
10132
10133		valueTotal = this._valueMax() - this._valueMin();
10134		valueMouse = this._valueMin() + percentMouse * valueTotal;
10135
10136		return this._trimAlignValue( valueMouse );
10137	},
10138
10139	_start: function( event, index ) {
10140		var uiHash = {
10141			handle: this.handles[ index ],
10142			value: this.value()
10143		};
10144		if ( this.options.values && this.options.values.length ) {
10145			uiHash.value = this.values( index );
10146			uiHash.values = this.values();
10147		}
10148		return this._trigger( "start", event, uiHash );
10149	},
10150
10151	_slide: function( event, index, newVal ) {
10152		var otherVal,
10153			newValues,
10154			allowed;
10155
10156		if ( this.options.values && this.options.values.length ) {
10157			otherVal = this.values( index ? 0 : 1 );
10158
10159			if ( ( this.options.values.length === 2 && this.options.range === true ) &&
10160					( ( index === 0 && newVal > otherVal) || ( index === 1 && newVal < otherVal ) )
10161				) {
10162				newVal = otherVal;
10163			}
10164
10165			if ( newVal !== this.values( index ) ) {
10166				newValues = this.values();
10167				newValues[ index ] = newVal;
10168				// A slide can be canceled by returning false from the slide callback
10169				allowed = this._trigger( "slide", event, {
10170					handle: this.handles[ index ],
10171					value: newVal,
10172					values: newValues
10173				} );
10174				otherVal = this.values( index ? 0 : 1 );
10175				if ( allowed !== false ) {
10176					this.values( index, newVal, true );
10177				}
10178			}
10179		} else {
10180			if ( newVal !== this.value() ) {
10181				// A slide can be canceled by returning false from the slide callback
10182				allowed = this._trigger( "slide", event, {
10183					handle: this.handles[ index ],
10184					value: newVal
10185				} );
10186				if ( allowed !== false ) {
10187					this.value( newVal );
10188				}
10189			}
10190		}
10191	},
10192
10193	_stop: function( event, index ) {
10194		var uiHash = {
10195			handle: this.handles[ index ],
10196			value: this.value()
10197		};
10198		if ( this.options.values && this.options.values.length ) {
10199			uiHash.value = this.values( index );
10200			uiHash.values = this.values();
10201		}
10202
10203		this._trigger( "stop", event, uiHash );
10204	},
10205
10206	_change: function( event, index ) {
10207		if ( !this._keySliding && !this._mouseSliding ) {
10208			var uiHash = {
10209				handle: this.handles[ index ],
10210				value: this.value()
10211			};
10212			if ( this.options.values && this.options.values.length ) {
10213				uiHash.value = this.values( index );
10214				uiHash.values = this.values();
10215			}
10216
10217			this._trigger( "change", event, uiHash );
10218		}
10219	},
10220
10221	value: function( newValue ) {
10222		if ( arguments.length ) {
10223			this.options.value = this._trimAlignValue( newValue );
10224			this._refreshValue();
10225			this._change( null, 0 );
10226			return;
10227		}
10228
10229		return this._value();
10230	},
10231
10232	values: function( index, newValue ) {
10233		var vals,
10234			newValues,
10235			i;
10236
10237		if ( arguments.length > 1 ) {
10238			this.options.values[ index ] = this._trimAlignValue( newValue );
10239			this._refreshValue();
10240			this._change( null, index );
10241			return;
10242		}
10243
10244		if ( arguments.length ) {
10245			if ( $.isArray( arguments[ 0 ] ) ) {
10246				vals = this.options.values;
10247				newValues = arguments[ 0 ];
10248				for ( i = 0; i < vals.length; i += 1 ) {
10249					vals[ i ] = this._trimAlignValue( newValues[ i ] );
10250					this._change( null, i );
10251				}
10252				this._refreshValue();
10253			} else {
10254				if ( this.options.values && this.options.values.length ) {
10255					return this._values( index );
10256				} else {
10257					return this.value();
10258				}
10259			}
10260		} else {
10261			return this._values();
10262		}
10263	},
10264
10265	_setOption: function( key, value ) {
10266		var i,
10267			valsLength = 0;
10268
10269		if ( $.isArray( this.options.values ) ) {
10270			valsLength = this.options.values.length;
10271		}
10272
10273		$.Widget.prototype._setOption.apply( this, arguments );
10274
10275		switch ( key ) {
10276			case "disabled":
10277				if ( value ) {
10278					this.handles.filter( ".ui-state-focus" ).blur();
10279					this.handles.removeClass( "ui-state-hover" );
10280					this.handles.prop( "disabled", true );
10281					this.element.addClass( "ui-disabled" );
10282				} else {
10283					this.handles.prop( "disabled", false );
10284					this.element.removeClass( "ui-disabled" );
10285				}
10286				break;
10287			case "orientation":
10288				this._detectOrientation();
10289				this.element
10290					.removeClass( "ui-slider-horizontal ui-slider-vertical" )
10291					.addClass( "ui-slider-" + this.orientation );
10292				this._refreshValue();
10293				break;
10294			case "value":
10295				this._animateOff = true;
10296				this._refreshValue();
10297				this._change( null, 0 );
10298				this._animateOff = false;
10299				break;
10300			case "values":
10301				this._animateOff = true;
10302				this._refreshValue();
10303				for ( i = 0; i < valsLength; i += 1 ) {
10304					this._change( null, i );
10305				}
10306				this._animateOff = false;
10307				break;
10308			case "min":
10309			case "max":
10310				this._animateOff = true;
10311				this._refreshValue();
10312				this._animateOff = false;
10313				break;
10314		}
10315	},
10316
10317	//internal value getter
10318	// _value() returns value trimmed by min and max, aligned by step
10319	_value: function() {
10320		var val = this.options.value;
10321		val = this._trimAlignValue( val );
10322
10323		return val;
10324	},
10325
10326	//internal values getter
10327	// _values() returns array of values trimmed by min and max, aligned by step
10328	// _values( index ) returns single value trimmed by min and max, aligned by step
10329	_values: function( index ) {
10330		var val,
10331			vals,
10332			i;
10333
10334		if ( arguments.length ) {
10335			val = this.options.values[ index ];
10336			val = this._trimAlignValue( val );
10337
10338			return val;
10339		} else {
10340			// .slice() creates a copy of the array
10341			// this copy gets trimmed by min and max and then returned
10342			vals = this.options.values.slice();
10343			for ( i = 0; i < vals.length; i+= 1) {
10344				vals[ i ] = this._trimAlignValue( vals[ i ] );
10345			}
10346
10347			return vals;
10348		}
10349	},
10350
10351	// returns the step-aligned value that val is closest to, between (inclusive) min and max
10352	_trimAlignValue: function( val ) {
10353		if ( val <= this._valueMin() ) {
10354			return this._valueMin();
10355		}
10356		if ( val >= this._valueMax() ) {
10357			return this._valueMax();
10358		}
10359		var step = ( this.options.step > 0 ) ? this.options.step : 1,
10360			valModStep = (val - this._valueMin()) % step,
10361			alignValue = val - valModStep;
10362
10363		if ( Math.abs(valModStep) * 2 >= step ) {
10364			alignValue += ( valModStep > 0 ) ? step : ( -step );
10365		}
10366
10367		// Since JavaScript has problems with large floats, round
10368		// the final value to 5 digits after the decimal point (see #4124)
10369		return parseFloat( alignValue.toFixed(5) );
10370	},
10371
10372	_valueMin: function() {
10373		return this.options.min;
10374	},
10375
10376	_valueMax: function() {
10377		return this.options.max;
10378	},
10379
10380	_refreshValue: function() {
10381		var lastValPercent, valPercent, value, valueMin, valueMax,
10382			oRange = this.options.range,
10383			o = this.options,
10384			that = this,
10385			animate = ( !this._animateOff ) ? o.animate : false,
10386			_set = {};
10387
10388		if ( this.options.values && this.options.values.length ) {
10389			this.handles.each(function( i ) {
10390				valPercent = ( that.values(i) - that._valueMin() ) / ( that._valueMax() - that._valueMin() ) * 100;
10391				_set[ that.orientation === "horizontal" ? "left" : "bottom" ] = valPercent + "%";
10392				$( this ).stop( 1, 1 )[ animate ? "animate" : "css" ]( _set, o.animate );
10393				if ( that.options.range === true ) {
10394					if ( that.orientation === "horizontal" ) {
10395						if ( i === 0 ) {
10396							that.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { left: valPercent + "%" }, o.animate );
10397						}
10398						if ( i === 1 ) {
10399							that.range[ animate ? "animate" : "css" ]( { width: ( valPercent - lastValPercent ) + "%" }, { queue: false, duration: o.animate } );
10400						}
10401					} else {
10402						if ( i === 0 ) {
10403							that.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { bottom: ( valPercent ) + "%" }, o.animate );
10404						}
10405						if ( i === 1 ) {
10406							that.range[ animate ? "animate" : "css" ]( { height: ( valPercent - lastValPercent ) + "%" }, { queue: false, duration: o.animate } );
10407						}
10408					}
10409				}
10410				lastValPercent = valPercent;
10411			});
10412		} else {
10413			value = this.value();
10414			valueMin = this._valueMin();
10415			valueMax = this._valueMax();
10416			valPercent = ( valueMax !== valueMin ) ?
10417					( value - valueMin ) / ( valueMax - valueMin ) * 100 :
10418					0;
10419			_set[ this.orientation === "horizontal" ? "left" : "bottom" ] = valPercent + "%";
10420			this.handle.stop( 1, 1 )[ animate ? "animate" : "css" ]( _set, o.animate );
10421
10422			if ( oRange === "min" && this.orientation === "horizontal" ) {
10423				this.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { width: valPercent + "%" }, o.animate );
10424			}
10425			if ( oRange === "max" && this.orientation === "horizontal" ) {
10426				this.range[ animate ? "animate" : "css" ]( { width: ( 100 - valPercent ) + "%" }, { queue: false, duration: o.animate } );
10427			}
10428			if ( oRange === "min" && this.orientation === "vertical" ) {
10429				this.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { height: valPercent + "%" }, o.animate );
10430			}
10431			if ( oRange === "max" && this.orientation === "vertical" ) {
10432				this.range[ animate ? "animate" : "css" ]( { height: ( 100 - valPercent ) + "%" }, { queue: false, duration: o.animate } );
10433			}
10434		}
10435	}
10436
10437});
10438
10439}(jQuery));
10440(function( $ ) {
10441
10442function modifier( fn ) {
10443	return function() {
10444		var previous = this.element.val();
10445		fn.apply( this, arguments );
10446		this._refresh();
10447		if ( previous !== this.element.val() ) {
10448			this._trigger( "change" );
10449		}
10450	};
10451}
10452
10453$.widget( "ui.spinner", {
10454	version: "1.9.2",
10455	defaultElement: "<input>",
10456	widgetEventPrefix: "spin",
10457	options: {
10458		culture: null,
10459		icons: {
10460			down: "ui-icon-triangle-1-s",
10461			up: "ui-icon-triangle-1-n"
10462		},
10463		incremental: true,
10464		max: null,
10465		min: null,
10466		numberFormat: null,
10467		page: 10,
10468		step: 1,
10469
10470		change: null,
10471		spin: null,
10472		start: null,
10473		stop: null
10474	},
10475
10476	_create: function() {
10477		// handle string values that need to be parsed
10478		this._setOption( "max", this.options.max );
10479		this._setOption( "min", this.options.min );
10480		this._setOption( "step", this.options.step );
10481
10482		// format the value, but don't constrain
10483		this._value( this.element.val(), true );
10484
10485		this._draw();
10486		this._on( this._events );
10487		this._refresh();
10488
10489		// turning off autocomplete prevents the browser from remembering the
10490		// value when navigating through history, so we re-enable autocomplete
10491		// if the page is unloaded before the widget is destroyed. #7790
10492		this._on( this.window, {
10493			beforeunload: function() {
10494				this.element.removeAttr( "autocomplete" );
10495			}
10496		});
10497	},
10498
10499	_getCreateOptions: function() {
10500		var options = {},
10501			element = this.element;
10502
10503		$.each( [ "min", "max", "step" ], function( i, option ) {
10504			var value = element.attr( option );
10505			if ( value !== undefined && value.length ) {
10506				options[ option ] = value;
10507			}
10508		});
10509
10510		return options;
10511	},
10512
10513	_events: {
10514		keydown: function( event ) {
10515			if ( this._start( event ) && this._keydown( event ) ) {
10516				event.preventDefault();
10517			}
10518		},
10519		keyup: "_stop",
10520		focus: function() {
10521			this.previous = this.element.val();
10522		},
10523		blur: function( event ) {
10524			if ( this.cancelBlur ) {
10525				delete this.cancelBlur;
10526				return;
10527			}
10528
10529			this._refresh();
10530			if ( this.previous !== this.element.val() ) {
10531				this._trigger( "change", event );
10532			}
10533		},
10534		mousewheel: function( event, delta ) {
10535			if ( !delta ) {
10536				return;
10537			}
10538			if ( !this.spinning && !this._start( event ) ) {
10539				return false;
10540			}
10541
10542			this._spin( (delta > 0 ? 1 : -1) * this.options.step, event );
10543			clearTimeout( this.mousewheelTimer );
10544			this.mousewheelTimer = this._delay(function() {
10545				if ( this.spinning ) {
10546					this._stop( event );
10547				}
10548			}, 100 );
10549			event.preventDefault();
10550		},
10551		"mousedown .ui-spinner-button": function( event ) {
10552			var previous;
10553
10554			// We never want the buttons to have focus; whenever the user is
10555			// interacting with the spinner, the focus should be on the input.
10556			// If the input is focused then this.previous is properly set from
10557			// when the input first received focus. If the input is not focused
10558			// then we need to set this.previous based on the value before spinning.
10559			previous = this.element[0] === this.document[0].activeElement ?
10560				this.previous : this.element.val();
10561			function checkFocus() {
10562				var isActive = this.element[0] === this.document[0].activeElement;
10563				if ( !isActive ) {
10564					this.element.focus();
10565					this.previous = previous;
10566					// support: IE
10567					// IE sets focus asynchronously, so we need to check if focus
10568					// moved off of the input because the user clicked on the button.
10569					this._delay(function() {
10570						this.previous = previous;
10571					});
10572				}
10573			}
10574
10575			// ensure focus is on (or stays on) the text field
10576			event.preventDefault();
10577			checkFocus.call( this );
10578
10579			// support: IE
10580			// IE doesn't prevent moving focus even with event.preventDefault()
10581			// so we set a flag to know when we should ignore the blur event
10582			// and check (again) if focus moved off of the input.
10583			this.cancelBlur = true;
10584			this._delay(function() {
10585				delete this.cancelBlur;
10586				checkFocus.call( this );
10587			});
10588
10589			if ( this._start( event ) === false ) {
10590				return;
10591			}
10592
10593			this._repeat( null, $( event.currentTarget ).hasClass( "ui-spinner-up" ) ? 1 : -1, event );
10594		},
10595		"mouseup .ui-spinner-button": "_stop",
10596		"mouseenter .ui-spinner-button": function( event ) {
10597			// button will add ui-state-active if mouse was down while mouseleave and kept down
10598			if ( !$( event.currentTarget ).hasClass( "ui-state-active" ) ) {
10599				return;
10600			}
10601
10602			if ( this._start( event ) === false ) {
10603				return false;
10604			}
10605			this._repeat( null, $( event.currentTarget ).hasClass( "ui-spinner-up" ) ? 1 : -1, event );
10606		},
10607		// TODO: do we really want to consider this a stop?
10608		// shouldn't we just stop the repeater and wait until mouseup before
10609		// we trigger the stop event?
10610		"mouseleave .ui-spinner-button": "_stop"
10611	},
10612
10613	_draw: function() {
10614		var uiSpinner = this.uiSpinner = this.element
10615			.addClass( "ui-spinner-input" )
10616			.attr( "autocomplete", "off" )
10617			.wrap( this._uiSpinnerHtml() )
10618			.parent()
10619				// add buttons
10620				.append( this._buttonHtml() );
10621
10622		this.element.attr( "role", "spinbutton" );
10623
10624		// button bindings
10625		this.buttons = uiSpinner.find( ".ui-spinner-button" )
10626			.attr( "tabIndex", -1 )
10627			.button()
10628			.removeClass( "ui-corner-all" );
10629
10630		// IE 6 doesn't understand height: 50% for the buttons
10631		// unless the wrapper has an explicit height
10632		if ( this.buttons.height() > Math.ceil( uiSpinner.height() * 0.5 ) &&
10633				uiSpinner.height() > 0 ) {
10634			uiSpinner.height( uiSpinner.height() );
10635		}
10636
10637		// disable spinner if element was already disabled
10638		if ( this.options.disabled ) {
10639			this.disable();
10640		}
10641	},
10642
10643	_keydown: function( event ) {
10644		var options = this.options,
10645			keyCode = $.ui.keyCode;
10646
10647		switch ( event.keyCode ) {
10648		case keyCode.UP:
10649			this._repeat( null, 1, event );
10650			return true;
10651		case keyCode.DOWN:
10652			this._repeat( null, -1, event );
10653			return true;
10654		case keyCode.PAGE_UP:
10655			this._repeat( null, options.page, event );
10656			return true;
10657		case keyCode.PAGE_DOWN:
10658			this._repeat( null, -options.page, event );
10659			return true;
10660		}
10661
10662		return false;
10663	},
10664
10665	_uiSpinnerHtml: function() {
10666		return "<span class='ui-spinner ui-widget ui-widget-content ui-corner-all'></span>";
10667	},
10668
10669	_buttonHtml: function() {
10670		return "" +
10671			"<a class='ui-spinner-button ui-spinner-up ui-corner-tr'>" +
10672				"<span class='ui-icon " + this.options.icons.up + "'>&#9650;</span>" +
10673			"</a>" +
10674			"<a class='ui-spinner-button ui-spinner-down ui-corner-br'>" +
10675				"<span class='ui-icon " + this.options.icons.down + "'>&#9660;</span>" +
10676			"</a>";
10677	},
10678
10679	_start: function( event ) {
10680		if ( !this.spinning && this._trigger( "start", event ) === false ) {
10681			return false;
10682		}
10683
10684		if ( !this.counter ) {
10685			this.counter = 1;
10686		}
10687		this.spinning = true;
10688		return true;
10689	},
10690
10691	_repeat: function( i, steps, event ) {
10692		i = i || 500;
10693
10694		clearTimeout( this.timer );
10695		this.timer = this._delay(function() {
10696			this._repeat( 40, steps, event );
10697		}, i );
10698
10699		this._spin( steps * this.options.step, event );
10700	},
10701
10702	_spin: function( step, event ) {
10703		var value = this.value() || 0;
10704
10705		if ( !this.counter ) {
10706			this.counter = 1;
10707		}
10708
10709		value = this._adjustValue( value + step * this._increment( this.counter ) );
10710
10711		if ( !this.spinning || this._trigger( "spin", event, { value: value } ) !== false) {
10712			this._value( value );
10713			this.counter++;
10714		}
10715	},
10716
10717	_increment: function( i ) {
10718		var incremental = this.options.incremental;
10719
10720		if ( incremental ) {
10721			return $.isFunction( incremental ) ?
10722				incremental( i ) :
10723				Math.floor( i*i*i/50000 - i*i/500 + 17*i/200 + 1 );
10724		}
10725
10726		return 1;
10727	},
10728
10729	_precision: function() {
10730		var precision = this._precisionOf( this.options.step );
10731		if ( this.options.min !== null ) {
10732			precision = Math.max( precision, this._precisionOf( this.options.min ) );
10733		}
10734		return precision;
10735	},
10736
10737	_precisionOf: function( num ) {
10738		var str = num.toString(),
10739			decimal = str.indexOf( "." );
10740		return decimal === -1 ? 0 : str.length - decimal - 1;
10741	},
10742
10743	_adjustValue: function( value ) {
10744		var base, aboveMin,
10745			options = this.options;
10746
10747		// make sure we're at a valid step
10748		// - find out where we are relative to the base (min or 0)
10749		base = options.min !== null ? options.min : 0;
10750		aboveMin = value - base;
10751		// - round to the nearest step
10752		aboveMin = Math.round(aboveMin / options.step) * options.step;
10753		// - rounding is based on 0, so adjust back to our base
10754		value = base + aboveMin;
10755
10756		// fix precision from bad JS floating point math
10757		value = parseFloat( value.toFixed( this._precision() ) );
10758
10759		// clamp the value
10760		if ( options.max !== null && value > options.max) {
10761			return options.max;
10762		}
10763		if ( options.min !== null && value < options.min ) {
10764			return options.min;
10765		}
10766
10767		return value;
10768	},
10769
10770	_stop: function( event ) {
10771		if ( !this.spinning ) {
10772			return;
10773		}
10774
10775		clearTimeout( this.timer );
10776		clearTimeout( this.mousewheelTimer );
10777		this.counter = 0;
10778		this.spinning = false;
10779		this._trigger( "stop", event );
10780	},
10781
10782	_setOption: function( key, value ) {
10783		if ( key === "culture" || key === "numberFormat" ) {
10784			var prevValue = this._parse( this.element.val() );
10785			this.options[ key ] = value;
10786			this.element.val( this._format( prevValue ) );
10787			return;
10788		}
10789
10790		if ( key === "max" || key === "min" || key === "step" ) {
10791			if ( typeof value === "string" ) {
10792				value = this._parse( value );
10793			}
10794		}
10795
10796		this._super( key, value );
10797
10798		if ( key === "disabled" ) {
10799			if ( value ) {
10800				this.element.prop( "disabled", true );
10801				this.buttons.button( "disable" );
10802			} else {
10803				this.element.prop( "disabled", false );
10804				this.buttons.button( "enable" );
10805			}
10806		}
10807	},
10808
10809	_setOptions: modifier(function( options ) {
10810		this._super( options );
10811		this._value( this.element.val() );
10812	}),
10813
10814	_parse: function( val ) {
10815		if ( typeof val === "string" && val !== "" ) {
10816			val = window.Globalize && this.options.numberFormat ?
10817				Globalize.parseFloat( val, 10, this.options.culture ) : +val;
10818		}
10819		return val === "" || isNaN( val ) ? null : val;
10820	},
10821
10822	_format: function( value ) {
10823		if ( value === "" ) {
10824			return "";
10825		}
10826		return window.Globalize && this.options.numberFormat ?
10827			Globalize.format( value, this.options.numberFormat, this.options.culture ) :
10828			value;
10829	},
10830
10831	_refresh: function() {
10832		this.element.attr({
10833			"aria-valuemin": this.options.min,
10834			"aria-valuemax": this.options.max,
10835			// TODO: what should we do with values that can't be parsed?
10836			"aria-valuenow": this._parse( this.element.val() )
10837		});
10838	},
10839
10840	// update the value without triggering change
10841	_value: function( value, allowAny ) {
10842		var parsed;
10843		if ( value !== "" ) {
10844			parsed = this._parse( value );
10845			if ( parsed !== null ) {
10846				if ( !allowAny ) {
10847					parsed = this._adjustValue( parsed );
10848				}
10849				value = this._format( parsed );
10850			}
10851		}
10852		this.element.val( value );
10853		this._refresh();
10854	},
10855
10856	_destroy: function() {
10857		this.element
10858			.removeClass( "ui-spinner-input" )
10859			.prop( "disabled", false )
10860			.removeAttr( "autocomplete" )
10861			.removeAttr( "role" )
10862			.removeAttr( "aria-valuemin" )
10863			.removeAttr( "aria-valuemax" )
10864			.removeAttr( "aria-valuenow" );
10865		this.uiSpinner.replaceWith( this.element );
10866	},
10867
10868	stepUp: modifier(function( steps ) {
10869		this._stepUp( steps );
10870	}),
10871	_stepUp: function( steps ) {
10872		this._spin( (steps || 1) * this.options.step );
10873	},
10874
10875	stepDown: modifier(function( steps ) {
10876		this._stepDown( steps );
10877	}),
10878	_stepDown: function( steps ) {
10879		this._spin( (steps || 1) * -this.options.step );
10880	},
10881
10882	pageUp: modifier(function( pages ) {
10883		this._stepUp( (pages || 1) * this.options.page );
10884	}),
10885
10886	pageDown: modifier(function( pages ) {
10887		this._stepDown( (pages || 1) * this.options.page );
10888	}),
10889
10890	value: function( newVal ) {
10891		if ( !arguments.length ) {
10892			return this._parse( this.element.val() );
10893		}
10894		modifier( this._value ).call( this, newVal );
10895	},
10896
10897	widget: function() {
10898		return this.uiSpinner;
10899	}
10900});
10901
10902}( jQuery ) );
10903(function( $, undefined ) {
10904
10905var tabId = 0,
10906	rhash = /#.*$/;
10907
10908function getNextTabId() {
10909	return ++tabId;
10910}
10911
10912function isLocal( anchor ) {
10913	return anchor.hash.length > 1 &&
10914		anchor.href.replace( rhash, "" ) ===
10915			location.href.replace( rhash, "" )
10916				// support: Safari 5.1
10917				// Safari 5.1 doesn't encode spaces in window.location
10918				// but it does encode spaces from anchors (#8777)
10919				.replace( /\s/g, "%20" );
10920}
10921
10922$.widget( "ui.tabs", {
10923	version: "1.9.2",
10924	delay: 300,
10925	options: {
10926		active: null,
10927		collapsible: false,
10928		event: "click",
10929		heightStyle: "content",
10930		hide: null,
10931		show: null,
10932
10933		// callbacks
10934		activate: null,
10935		beforeActivate: null,
10936		beforeLoad: null,
10937		load: null
10938	},
10939
10940	_create: function() {
10941		var that = this,
10942			options = this.options,
10943			active = options.active,
10944			locationHash = location.hash.substring( 1 );
10945
10946		this.running = false;
10947
10948		this.element
10949			.addClass( "ui-tabs ui-widget ui-widget-content ui-corner-all" )
10950			.toggleClass( "ui-tabs-collapsible", options.collapsible )
10951			// Prevent users from focusing disabled tabs via click
10952			.delegate( ".ui-tabs-nav > li", "mousedown" + this.eventNamespace, function( event ) {
10953				if ( $( this ).is( ".ui-state-disabled" ) ) {
10954					event.preventDefault();
10955				}
10956			})
10957			// support: IE <9
10958			// Preventing the default action in mousedown doesn't prevent IE
vendor: 18,149 bytes, lines 10959-11632
10959			// from focusing the element, so if the anchor gets focused, blur.
10960			// We don't have to worry about focusing the previously focused
10961			// element since clicking on a non-focusable element should focus
10962			// the body anyway.
10963			.delegate( ".ui-tabs-anchor", "focus" + this.eventNamespace, function() {
10964				if ( $( this ).closest( "li" ).is( ".ui-state-disabled" ) ) {
10965					this.blur();
10966				}
10967			});
10968
10969		this._processTabs();
10970
10971		if ( active === null ) {
10972			// check the fragment identifier in the URL
10973			if ( locationHash ) {
10974				this.tabs.each(function( i, tab ) {
10975					if ( $( tab ).attr( "aria-controls" ) === locationHash ) {
10976						active = i;
10977						return false;
10978					}
10979				});
10980			}
10981
10982			// check for a tab marked active via a class
10983			if ( active === null ) {
10984				active = this.tabs.index( this.tabs.filter( ".ui-tabs-active" ) );
10985			}
10986
10987			// no active tab, set to false
10988			if ( active === null || active === -1 ) {
10989				active = this.tabs.length ? 0 : false;
10990			}
10991		}
10992
10993		// handle numbers: negative, out of range
10994		if ( active !== false ) {
10995			active = this.tabs.index( this.tabs.eq( active ) );
10996			if ( active === -1 ) {
10997				active = options.collapsible ? false : 0;
10998			}
10999		}
11000		options.active = active;
11001
11002		// don't allow collapsible: false and active: false
11003		if ( !options.collapsible && options.active === false && this.anchors.length ) {
11004			options.active = 0;
11005		}
11006
11007		// Take disabling tabs via class attribute from HTML
11008		// into account and update option properly.
11009		if ( $.isArray( options.disabled ) ) {
11010			options.disabled = $.unique( options.disabled.concat(
11011				$.map( this.tabs.filter( ".ui-state-disabled" ), function( li ) {
11012					return that.tabs.index( li );
11013				})
11014			) ).sort();
11015		}
11016
11017		// check for length avoids error when initializing empty list
11018		if ( this.options.active !== false && this.anchors.length ) {
11019			this.active = this._findActive( this.options.active );
11020		} else {
11021			this.active = $();
11022		}
11023
11024		this._refresh();
11025
11026		if ( this.active.length ) {
11027			this.load( options.active );
11028		}
11029	},
11030
11031	_getCreateEventData: function() {
11032		return {
11033			tab: this.active,
11034			panel: !this.active.length ? $() : this._getPanelForTab( this.active )
11035		};
11036	},
11037
11038	_tabKeydown: function( event ) {
11039		var focusedTab = $( this.document[0].activeElement ).closest( "li" ),
11040			selectedIndex = this.tabs.index( focusedTab ),
11041			goingForward = true;
11042
11043		if ( this._handlePageNav( event ) ) {
11044			return;
11045		}
11046
11047		switch ( event.keyCode ) {
11048			case $.ui.keyCode.RIGHT:
11049			case $.ui.keyCode.DOWN:
11050				selectedIndex++;
11051				break;
11052			case $.ui.keyCode.UP:
11053			case $.ui.keyCode.LEFT:
11054				goingForward = false;
11055				selectedIndex--;
11056				break;
11057			case $.ui.keyCode.END:
11058				selectedIndex = this.anchors.length - 1;
11059				break;
11060			case $.ui.keyCode.HOME:
11061				selectedIndex = 0;
11062				break;
11063			case $.ui.keyCode.SPACE:
11064				// Activate only, no collapsing
11065				event.preventDefault();
11066				clearTimeout( this.activating );
11067				this._activate( selectedIndex );
11068				return;
11069			case $.ui.keyCode.ENTER:
11070				// Toggle (cancel delayed activation, allow collapsing)
11071				event.preventDefault();
11072				clearTimeout( this.activating );
11073				// Determine if we should collapse or activate
11074				this._activate( selectedIndex === this.options.active ? false : selectedIndex );
11075				return;
11076			default:
11077				return;
11078		}
11079
11080		// Focus the appropriate tab, based on which key was pressed
11081		event.preventDefault();
11082		clearTimeout( this.activating );
11083		selectedIndex = this._focusNextTab( selectedIndex, goingForward );
11084
11085		// Navigating with control key will prevent automatic activation
11086		if ( !event.ctrlKey ) {
11087			// Update aria-selected immediately so that AT think the tab is already selected.
11088			// Otherwise AT may confuse the user by stating that they need to activate the tab,
11089			// but the tab will already be activated by the time the announcement finishes.
11090			focusedTab.attr( "aria-selected", "false" );
11091			this.tabs.eq( selectedIndex ).attr( "aria-selected", "true" );
11092
11093			this.activating = this._delay(function() {
11094				this.option( "active", selectedIndex );
11095			}, this.delay );
11096		}
11097	},
11098
11099	_panelKeydown: function( event ) {
11100		if ( this._handlePageNav( event ) ) {
11101			return;
11102		}
11103
11104		// Ctrl+up moves focus to the current tab
11105		if ( event.ctrlKey && event.keyCode === $.ui.keyCode.UP ) {
11106			event.preventDefault();
11107			this.active.focus();
11108		}
11109	},
11110
11111	// Alt+page up/down moves focus to the previous/next tab (and activates)
11112	_handlePageNav: function( event ) {
11113		if ( event.altKey && event.keyCode === $.ui.keyCode.PAGE_UP ) {
11114			this._activate( this._focusNextTab( this.options.active - 1, false ) );
11115			return true;
11116		}
11117		if ( event.altKey && event.keyCode === $.ui.keyCode.PAGE_DOWN ) {
11118			this._activate( this._focusNextTab( this.options.active + 1, true ) );
11119			return true;
11120		}
11121	},
11122
11123	_findNextTab: function( index, goingForward ) {
11124		var lastTabIndex = this.tabs.length - 1;
11125
11126		function constrain() {
11127			if ( index > lastTabIndex ) {
11128				index = 0;
11129			}
11130			if ( index < 0 ) {
11131				index = lastTabIndex;
11132			}
11133			return index;
11134		}
11135
11136		while ( $.inArray( constrain(), this.options.disabled ) !== -1 ) {
11137			index = goingForward ? index + 1 : index - 1;
11138		}
11139
11140		return index;
11141	},
11142
11143	_focusNextTab: function( index, goingForward ) {
11144		index = this._findNextTab( index, goingForward );
11145		this.tabs.eq( index ).focus();
11146		return index;
11147	},
11148
11149	_setOption: function( key, value ) {
11150		if ( key === "active" ) {
11151			// _activate() will handle invalid values and update this.options
11152			this._activate( value );
11153			return;
11154		}
11155
11156		if ( key === "disabled" ) {
11157			// don't use the widget factory's disabled handling
11158			this._setupDisabled( value );
11159			return;
11160		}
11161
11162		this._super( key, value);
11163
11164		if ( key === "collapsible" ) {
11165			this.element.toggleClass( "ui-tabs-collapsible", value );
11166			// Setting collapsible: false while collapsed; open first panel
11167			if ( !value && this.options.active === false ) {
11168				this._activate( 0 );
11169			}
11170		}
11171
11172		if ( key === "event" ) {
11173			this._setupEvents( value );
11174		}
11175
11176		if ( key === "heightStyle" ) {
11177			this._setupHeightStyle( value );
11178		}
11179	},
11180
11181	_tabId: function( tab ) {
11182		return tab.attr( "aria-controls" ) || "ui-tabs-" + getNextTabId();
11183	},
11184
11185	_sanitizeSelector: function( hash ) {
11186		return hash ? hash.replace( /[!"$%&'()*+,.\/:;<=>?@\[\]\^`{|}~]/g, "\\$&" ) : "";
11187	},
11188
11189	refresh: function() {
11190		var options = this.options,
11191			lis = this.tablist.children( ":has(a[href])" );
11192
11193		// get disabled tabs from class attribute from HTML
11194		// this will get converted to a boolean if needed in _refresh()
11195		options.disabled = $.map( lis.filter( ".ui-state-disabled" ), function( tab ) {
11196			return lis.index( tab );
11197		});
11198
11199		this._processTabs();
11200
11201		// was collapsed or no tabs
11202		if ( options.active === false || !this.anchors.length ) {
11203			options.active = false;
11204			this.active = $();
11205		// was active, but active tab is gone
11206		} else if ( this.active.length && !$.contains( this.tablist[ 0 ], this.active[ 0 ] ) ) {
11207			// all remaining tabs are disabled
11208			if ( this.tabs.length === options.disabled.length ) {
11209				options.active = false;
11210				this.active = $();
11211			// activate previous tab
11212			} else {
11213				this._activate( this._findNextTab( Math.max( 0, options.active - 1 ), false ) );
11214			}
11215		// was active, active tab still exists
11216		} else {
11217			// make sure active index is correct
11218			options.active = this.tabs.index( this.active );
11219		}
11220
11221		this._refresh();
11222	},
11223
11224	_refresh: function() {
11225		this._setupDisabled( this.options.disabled );
11226		this._setupEvents( this.options.event );
11227		this._setupHeightStyle( this.options.heightStyle );
11228
11229		this.tabs.not( this.active ).attr({
11230			"aria-selected": "false",
11231			tabIndex: -1
11232		});
11233		this.panels.not( this._getPanelForTab( this.active ) )
11234			.hide()
11235			.attr({
11236				"aria-expanded": "false",
11237				"aria-hidden": "true"
11238			});
11239
11240		// Make sure one tab is in the tab order
11241		if ( !this.active.length ) {
11242			this.tabs.eq( 0 ).attr( "tabIndex", 0 );
11243		} else {
11244			this.active
11245				.addClass( "ui-tabs-active ui-state-active" )
11246				.attr({
11247					"aria-selected": "true",
11248					tabIndex: 0
11249				});
11250			this._getPanelForTab( this.active )
11251				.show()
11252				.attr({
11253					"aria-expanded": "true",
11254					"aria-hidden": "false"
11255				});
11256		}
11257	},
11258
11259	_processTabs: function() {
11260		var that = this;
11261
11262		this.tablist = this._getList()
11263			.addClass( "ui-tabs-nav ui-helper-reset ui-helper-clearfix ui-widget-header ui-corner-all" )
11264			.attr( "role", "tablist" );
11265
11266		this.tabs = this.tablist.find( "> li:has(a[href])" )
11267			.addClass( "ui-state-default ui-corner-top" )
11268			.attr({
11269				role: "tab",
11270				tabIndex: -1
11271			});
11272
11273		this.anchors = this.tabs.map(function() {
11274				return $( "a", this )[ 0 ];
11275			})
11276			.addClass( "ui-tabs-anchor" )
11277			.attr({
11278				role: "presentation",
11279				tabIndex: -1
11280			});
11281
11282		this.panels = $();
11283
11284		this.anchors.each(function( i, anchor ) {
11285			var selector, panel, panelId,
11286				anchorId = $( anchor ).uniqueId().attr( "id" ),
11287				tab = $( anchor ).closest( "li" ),
11288				originalAriaControls = tab.attr( "aria-controls" );
11289
11290			// inline tab
11291			if ( isLocal( anchor ) ) {
11292				selector = anchor.hash;
11293				panel = that.element.find( that._sanitizeSelector( selector ) );
11294			// remote tab
11295			} else {
11296				panelId = that._tabId( tab );
11297				selector = "#" + panelId;
11298				panel = that.element.find( selector );
11299				if ( !panel.length ) {
11300					panel = that._createPanel( panelId );
11301					panel.insertAfter( that.panels[ i - 1 ] || that.tablist );
11302				}
11303				panel.attr( "aria-live", "polite" );
11304			}
11305
11306			if ( panel.length) {
11307				that.panels = that.panels.add( panel );
11308			}
11309			if ( originalAriaControls ) {
11310				tab.data( "ui-tabs-aria-controls", originalAriaControls );
11311			}
11312			tab.attr({
11313				"aria-controls": selector.substring( 1 ),
11314				"aria-labelledby": anchorId
11315			});
11316			panel.attr( "aria-labelledby", anchorId );
11317		});
11318
11319		this.panels
11320			.addClass( "ui-tabs-panel ui-widget-content ui-corner-bottom" )
11321			.attr( "role", "tabpanel" );
11322	},
11323
11324	// allow overriding how to find the list for rare usage scenarios (#7715)
11325	_getList: function() {
11326		return this.element.find( "ol,ul" ).eq( 0 );
11327	},
11328
11329	_createPanel: function( id ) {
11330		return $( "<div>" )
11331			.attr( "id", id )
11332			.addClass( "ui-tabs-panel ui-widget-content ui-corner-bottom" )
11333			.data( "ui-tabs-destroy", true );
11334	},
11335
11336	_setupDisabled: function( disabled ) {
11337		if ( $.isArray( disabled ) ) {
11338			if ( !disabled.length ) {
11339				disabled = false;
11340			} else if ( disabled.length === this.anchors.length ) {
11341				disabled = true;
11342			}
11343		}
11344
11345		// disable tabs
11346		for ( var i = 0, li; ( li = this.tabs[ i ] ); i++ ) {
11347			if ( disabled === true || $.inArray( i, disabled ) !== -1 ) {
11348				$( li )
11349					.addClass( "ui-state-disabled" )
11350					.attr( "aria-disabled", "true" );
11351			} else {
11352				$( li )
11353					.removeClass( "ui-state-disabled" )
11354					.removeAttr( "aria-disabled" );
11355			}
11356		}
11357
11358		this.options.disabled = disabled;
11359	},
11360
11361	_setupEvents: function( event ) {
11362		var events = {
11363			click: function( event ) {
11364				event.preventDefault();
11365			}
11366		};
11367		if ( event ) {
11368			$.each( event.split(" "), function( index, eventName ) {
11369				events[ eventName ] = "_eventHandler";
11370			});
11371		}
11372
11373		this._off( this.anchors.add( this.tabs ).add( this.panels ) );
11374		this._on( this.anchors, events );
11375		this._on( this.tabs, { keydown: "_tabKeydown" } );
11376		this._on( this.panels, { keydown: "_panelKeydown" } );
11377
11378		this._focusable( this.tabs );
11379		this._hoverable( this.tabs );
11380	},
11381
11382	_setupHeightStyle: function( heightStyle ) {
11383		var maxHeight, overflow,
11384			parent = this.element.parent();
11385
11386		if ( heightStyle === "fill" ) {
11387			// IE 6 treats height like minHeight, so we need to turn off overflow
11388			// in order to get a reliable height
11389			// we use the minHeight support test because we assume that only
11390			// browsers that don't support minHeight will treat height as minHeight
11391			if ( !$.support.minHeight ) {
11392				overflow = parent.css( "overflow" );
11393				parent.css( "overflow", "hidden");
11394			}
11395			maxHeight = parent.height();
11396			this.element.siblings( ":visible" ).each(function() {
11397				var elem = $( this ),
11398					position = elem.css( "position" );
11399
11400				if ( position === "absolute" || position === "fixed" ) {
11401					return;
11402				}
11403				maxHeight -= elem.outerHeight( true );
11404			});
11405			if ( overflow ) {
11406				parent.css( "overflow", overflow );
11407			}
11408
11409			this.element.children().not( this.panels ).each(function() {
11410				maxHeight -= $( this ).outerHeight( true );
11411			});
11412
11413			this.panels.each(function() {
11414				$( this ).height( Math.max( 0, maxHeight -
11415					$( this ).innerHeight() + $( this ).height() ) );
11416			})
11417			.css( "overflow", "auto" );
11418		} else if ( heightStyle === "auto" ) {
11419			maxHeight = 0;
11420			this.panels.each(function() {
11421				maxHeight = Math.max( maxHeight, $( this ).height( "" ).height() );
11422			}).height( maxHeight );
11423		}
11424	},
11425
11426	_eventHandler: function( event ) {
11427		var options = this.options,
11428			active = this.active,
11429			anchor = $( event.currentTarget ),
11430			tab = anchor.closest( "li" ),
11431			clickedIsActive = tab[ 0 ] === active[ 0 ],
11432			collapsing = clickedIsActive && options.collapsible,
11433			toShow = collapsing ? $() : this._getPanelForTab( tab ),
11434			toHide = !active.length ? $() : this._getPanelForTab( active ),
11435			eventData = {
11436				oldTab: active,
11437				oldPanel: toHide,
11438				newTab: collapsing ? $() : tab,
11439				newPanel: toShow
11440			};
11441
11442		event.preventDefault();
11443
11444		if ( tab.hasClass( "ui-state-disabled" ) ||
11445				// tab is already loading
11446				tab.hasClass( "ui-tabs-loading" ) ||
11447				// can't switch durning an animation
11448				this.running ||
11449				// click on active header, but not collapsible
11450				( clickedIsActive && !options.collapsible ) ||
11451				// allow canceling activation
11452				( this._trigger( "beforeActivate", event, eventData ) === false ) ) {
11453			return;
11454		}
11455
11456		options.active = collapsing ? false : this.tabs.index( tab );
11457
11458		this.active = clickedIsActive ? $() : tab;
11459		if ( this.xhr ) {
11460			this.xhr.abort();
11461		}
11462
11463		if ( !toHide.length && !toShow.length ) {
11464			$.error( "jQuery UI Tabs: Mismatching fragment identifier." );
11465		}
11466
11467		if ( toShow.length ) {
11468			this.load( this.tabs.index( tab ), event );
11469		}
11470		this._toggle( event, eventData );
11471	},
11472
11473	// handles show/hide for selecting tabs
11474	_toggle: function( event, eventData ) {
11475		var that = this,
11476			toShow = eventData.newPanel,
11477			toHide = eventData.oldPanel;
11478
11479		this.running = true;
11480
11481		function complete() {
11482			that.running = false;
11483			that._trigger( "activate", event, eventData );
11484		}
11485
11486		function show() {
11487			eventData.newTab.closest( "li" ).addClass( "ui-tabs-active ui-state-active" );
11488
11489			if ( toShow.length && that.options.show ) {
11490				that._show( toShow, that.options.show, complete );
11491			} else {
11492				toShow.show();
11493				complete();
11494			}
11495		}
11496
11497		// start out by hiding, then showing, then completing
11498		if ( toHide.length && this.options.hide ) {
11499			this._hide( toHide, this.options.hide, function() {
11500				eventData.oldTab.closest( "li" ).removeClass( "ui-tabs-active ui-state-active" );
11501				show();
11502			});
11503		} else {
11504			eventData.oldTab.closest( "li" ).removeClass( "ui-tabs-active ui-state-active" );
11505			toHide.hide();
11506			show();
11507		}
11508
11509		toHide.attr({
11510			"aria-expanded": "false",
11511			"aria-hidden": "true"
11512		});
11513		eventData.oldTab.attr( "aria-selected", "false" );
11514		// If we're switching tabs, remove the old tab from the tab order.
11515		// If we're opening from collapsed state, remove the previous tab from the tab order.
11516		// If we're collapsing, then keep the collapsing tab in the tab order.
11517		if ( toShow.length && toHide.length ) {
11518			eventData.oldTab.attr( "tabIndex", -1 );
11519		} else if ( toShow.length ) {
11520			this.tabs.filter(function() {
11521				return $( this ).attr( "tabIndex" ) === 0;
11522			})
11523			.attr( "tabIndex", -1 );
11524		}
11525
11526		toShow.attr({
11527			"aria-expanded": "true",
11528			"aria-hidden": "false"
11529		});
11530		eventData.newTab.attr({
11531			"aria-selected": "true",
11532			tabIndex: 0
11533		});
11534	},
11535
11536	_activate: function( index ) {
11537		var anchor,
11538			active = this._findActive( index );
11539
11540		// trying to activate the already active panel
11541		if ( active[ 0 ] === this.active[ 0 ] ) {
11542			return;
11543		}
11544
11545		// trying to collapse, simulate a click on the current active header
11546		if ( !active.length ) {
11547			active = this.active;
11548		}
11549
11550		anchor = active.find( ".ui-tabs-anchor" )[ 0 ];
11551		this._eventHandler({
11552			target: anchor,
11553			currentTarget: anchor,
11554			preventDefault: $.noop
11555		});
11556	},
11557
11558	_findActive: function( index ) {
11559		return index === false ? $() : this.tabs.eq( index );
11560	},
11561
11562	_getIndex: function( index ) {
11563		// meta-function to give users option to provide a href string instead of a numerical index.
11564		if ( typeof index === "string" ) {
11565			index = this.anchors.index( this.anchors.filter( "[href$='" + index + "']" ) );
11566		}
11567
11568		return index;
11569	},
11570
11571	_destroy: function() {
11572		if ( this.xhr ) {
11573			this.xhr.abort();
11574		}
11575
11576		this.element.removeClass( "ui-tabs ui-widget ui-widget-content ui-corner-all ui-tabs-collapsible" );
11577
11578		this.tablist
11579			.removeClass( "ui-tabs-nav ui-helper-reset ui-helper-clearfix ui-widget-header ui-corner-all" )
11580			.removeAttr( "role" );
11581
11582		this.anchors
11583			.removeClass( "ui-tabs-anchor" )
11584			.removeAttr( "role" )
11585			.removeAttr( "tabIndex" )
11586			.removeData( "href.tabs" )
11587			.removeData( "load.tabs" )
11588			.removeUniqueId();
11589
11590		this.tabs.add( this.panels ).each(function() {
11591			if ( $.data( this, "ui-tabs-destroy" ) ) {
11592				$( this ).remove();
11593			} else {
11594				$( this )
11595					.removeClass( "ui-state-default ui-state-active ui-state-disabled " +
11596						"ui-corner-top ui-corner-bottom ui-widget-content ui-tabs-active ui-tabs-panel" )
11597					.removeAttr( "tabIndex" )
11598					.removeAttr( "aria-live" )
11599					.removeAttr( "aria-busy" )
11600					.removeAttr( "aria-selected" )
11601					.removeAttr( "aria-labelledby" )
11602					.removeAttr( "aria-hidden" )
11603					.removeAttr( "aria-expanded" )
11604					.removeAttr( "role" );
11605			}
11606		});
11607
11608		this.tabs.each(function() {
11609			var li = $( this ),
11610				prev = li.data( "ui-tabs-aria-controls" );
11611			if ( prev ) {
11612				li.attr( "aria-controls", prev );
11613			} else {
11614				li.removeAttr( "aria-controls" );
11615			}
11616		});
11617
11618		this.panels.show();
11619
11620		if ( this.options.heightStyle !== "content" ) {
11621			this.panels.css( "height", "" );
11622		}
11623	},
11624
11625	enable: function( index ) {
11626		var disabled = this.options.disabled;
11627		if ( disabled === false ) {
11628			return;
11629		}
11630
11631		if ( index === undefined ) {
11632			disabled = false;
11633		} else {
11634			index = this._getIndex( index );
11635			if ( $.isArray( disabled ) ) {
11636				disabled = $.map( disabled, function( num ) {
11637					return num !== index ? num : null;
11638				});
11639			} else {
11640				disabled = $.map( this.tabs, function( li, num ) {
11641					return num !== index ? num : null;
11642				});
11643			}
11644		}
11645		this._setupDisabled( disabled );
11646	},
11647
11648	disable: function( index ) {
11649		var disabled = this.options.disabled;
11650		if ( disabled === true ) {
11651			return;
11652		}
11653
11654		if ( index === undefined ) {
11655			disabled = true;
11656		} else {
11657			index = this._getIndex( index );
11658			if ( $.inArray( index, disabled ) !== -1 ) {
11659				return;
11660			}
11661			if ( $.isArray( disabled ) ) {
11662				disabled = $.merge( [ index ], disabled ).sort();
11663			} else {
11664				disabled = [ index ];
11665			}
11666		}
11667		this._setupDisabled( disabled );
11668	},
11669
11670	load: function( index, event ) {
11671		index = this._getIndex( index );
11672		var that = this,
11673			tab = this.tabs.eq( index ),
11674			anchor = tab.find( ".ui-tabs-anchor" ),
11675			panel = this._getPanelForTab( tab ),
11676			eventData = {
11677				tab: tab,
11678				panel: panel
11679			};
11680
11681		// not remote
11682		if ( isLocal( anchor[ 0 ] ) ) {
11683			return;
11684		}
11685
11686		this.xhr = $.ajax( this._ajaxSettings( anchor, event, eventData ) );
11687
11688		// support: jQuery <1.8
11689		// jQuery <1.8 returns false if the request is canceled in beforeSend,
11690		// but as of 1.8, $.ajax() always returns a jqXHR object.
11691		if ( this.xhr && this.xhr.statusText !== "canceled" ) {
11692			tab.addClass( "ui-tabs-loading" );
11693			panel.attr( "aria-busy", "true" );
11694
11695			this.xhr
11696				.success(function( response ) {
11697					// support: jQuery <1.8
11698					// http://bugs.jquery.com/ticket/11778
11699					setTimeout(function() {
11700						panel.html( response );
11701						that._trigger( "load", event, eventData );
11702					}, 1 );
11703				})
11704				.complete(function( jqXHR, status ) {
11705					// support: jQuery <1.8
11706					// http://bugs.jquery.com/ticket/11778
11707					setTimeout(function() {
11708						if ( status === "abort" ) {
11709							that.panels.stop( false, true );
11710						}
11711
11712						tab.removeClass( "ui-tabs-loading" );
11713						panel.removeAttr( "aria-busy" );
11714
11715						if ( jqXHR === that.xhr ) {
11716							delete that.xhr;
11717						}
11718					}, 1 );
11719				});
11720		}
11721	},
11722
11723	// TODO: Remove this function in 1.10 when ajaxOptions is removed
11724	_ajaxSettings: function( anchor, event, eventData ) {
11725		var that = this;
11726		return {
11727			url: anchor.attr( "href" ),
11728			beforeSend: function( jqXHR, settings ) {
11729				return that._trigger( "beforeLoad", event,
11730					$.extend( { jqXHR : jqXHR, ajaxSettings: settings }, eventData ) );
11731			}
11732		};
11733	},
11734
11735	_getPanelForTab: function( tab ) {
11736		var id = $( tab ).attr( "aria-controls" );
11737		return this.element.find( this._sanitizeSelector( "#" + id ) );
11738	}
11739});
11740
11741// DEPRECATED
11742if ( $.uiBackCompat !== false ) {
11743
11744	// helper method for a lot of the back compat extensions
11745	$.ui.tabs.prototype._ui = function( tab, panel ) {
11746		return {
11747			tab: tab,
11748			panel: panel,
11749			index: this.anchors.index( tab )
11750		};
11751	};
11752
11753	// url method
11754	$.widget( "ui.tabs", $.ui.tabs, {
11755		url: function( index, url ) {
11756			this.anchors.eq( index ).attr( "href", url );
11757		}
11758	});
11759
11760	// TODO: Remove _ajaxSettings() method when removing this extension
11761	// ajaxOptions and cache options
11762	$.widget( "ui.tabs", $.ui.tabs, {
11763		options: {
11764			ajaxOptions: null,
11765			cache: false
11766		},
11767
11768		_create: function() {
11769			this._super();
11770
11771			var that = this;
11772
11773			this._on({ tabsbeforeload: function( event, ui ) {
11774				// tab is already cached
11775				if ( $.data( ui.tab[ 0 ], "cache.tabs" ) ) {
11776					event.preventDefault();
11777					return;
11778				}
11779
11780				ui.jqXHR.success(function() {
11781					if ( that.options.cache ) {
11782						$.data( ui.tab[ 0 ], "cache.tabs", true );
11783					}
11784				});
11785			}});
11786		},
11787
11788		_ajaxSettings: function( anchor, event, ui ) {
11789			var ajaxOptions = this.options.ajaxOptions;
11790			return $.extend( {}, ajaxOptions, {
11791				error: function( xhr, status ) {
11792					try {
11793						// Passing index avoid a race condition when this method is
11794						// called after the user has selected another tab.
11795						// Pass the anchor that initiated this request allows
11796						// loadError to manipulate the tab content panel via $(a.hash)
11797						ajaxOptions.error(
11798							xhr, status, ui.tab.closest( "li" ).index(), ui.tab[ 0 ] );
11799					}
11800					catch ( error ) {}
11801				}
11802			}, this._superApply( arguments ) );
11803		},
11804
11805		_setOption: function( key, value ) {
11806			// reset cache if switching from cached to not cached
11807			if ( key === "cache" && value === false ) {
11808				this.anchors.removeData( "cache.tabs" );
11809			}
11810			this._super( key, value );
11811		},
11812
11813		_destroy: function() {
11814			this.anchors.removeData( "cache.tabs" );
11815			this._super();
11816		},
11817
11818		url: function( index ){
11819			this.anchors.eq( index ).removeData( "cache.tabs" );
11820			this._superApply( arguments );
11821		}
11822	});
11823
11824	// abort method
11825	$.widget( "ui.tabs", $.ui.tabs, {
11826		abort: function() {
11827			if ( this.xhr ) {
11828				this.xhr.abort();
11829			}
11830		}
11831	});
11832
11833	// spinner
11834	$.widget( "ui.tabs", $.ui.tabs, {
11835		options: {
11836			spinner: "<em>Loading&#8230;</em>"
11837		},
11838		_create: function() {
11839			this._super();
11840			this._on({
11841				tabsbeforeload: function( event, ui ) {
11842					// Don't react to nested tabs or tabs that don't use a spinner
11843					if ( event.target !== this.element[ 0 ] ||
11844							!this.options.spinner ) {
11845						return;
11846					}
11847
11848					var span = ui.tab.find( "span" ),
11849						html = span.html();
11850					span.html( this.options.spinner );
11851					ui.jqXHR.complete(function() {
11852						span.html( html );
11853					});
11854				}
11855			});
11856		}
11857	});
11858
11859	// enable/disable events
11860	$.widget( "ui.tabs", $.ui.tabs, {
11861		options: {
11862			enable: null,
11863			disable: null
11864		},
11865
11866		enable: function( index ) {
11867			var options = this.options,
11868				trigger;
11869
11870			if ( index && options.disabled === true ||
11871					( $.isArray( options.disabled ) && $.inArray( index, options.disabled ) !== -1 ) ) {
11872				trigger = true;
11873			}
11874
11875			this._superApply( arguments );
11876
11877			if ( trigger ) {
11878				this._trigger( "enable", null, this._ui( this.anchors[ index ], this.panels[ index ] ) );
11879			}
11880		},
11881
11882		disable: function( index ) {
11883			var options = this.options,
11884				trigger;
11885
11886			if ( index && options.disabled === false ||
11887					( $.isArray( options.disabled ) && $.inArray( index, options.disabled ) === -1 ) ) {
11888				trigger = true;
11889			}
11890
11891			this._superApply( arguments );
11892
11893			if ( trigger ) {
11894				this._trigger( "disable", null, this._ui( this.anchors[ index ], this.panels[ index ] ) );
11895			}
11896		}
11897	});
11898
11899	// add/remove methods and events
11900	$.widget( "ui.tabs", $.ui.tabs, {
11901		options: {
11902			add: null,
11903			remove: null,
11904			tabTemplate: "<li><a href='#{href}'><span>#{label}</span></a></li>"
11905		},
11906
11907		add: function( url, label, index ) {
11908			if ( index === undefined ) {
11909				index = this.anchors.length;
11910			}
11911
11912			var doInsertAfter, panel,
11913				options = this.options,
11914				li = $( options.tabTemplate
11915					.replace( /#\{href\}/g, url )
11916					.replace( /#\{label\}/g, label ) ),
11917				id = !url.indexOf( "#" ) ?
11918					url.replace( "#", "" ) :
11919					this._tabId( li );
11920
11921			li.addClass( "ui-state-default ui-corner-top" ).data( "ui-tabs-destroy", true );
11922			li.attr( "aria-controls", id );
11923
11924			doInsertAfter = index >= this.tabs.length;
11925
11926			// try to find an existing element before creating a new one
11927			panel = this.element.find( "#" + id );
11928			if ( !panel.length ) {
11929				panel = this._createPanel( id );
11930				if ( doInsertAfter ) {
11931					if ( index > 0 ) {
11932						panel.insertAfter( this.panels.eq( -1 ) );
11933					} else {
11934						panel.appendTo( this.element );
11935					}
11936				} else {
11937					panel.insertBefore( this.panels[ index ] );
11938				}
11939			}
11940			panel.addClass( "ui-tabs-panel ui-widget-content ui-corner-bottom" ).hide();
11941
11942			if ( doInsertAfter ) {
11943				li.appendTo( this.tablist );
11944			} else {
11945				li.insertBefore( this.tabs[ index ] );
11946			}
11947
11948			options.disabled = $.map( options.disabled, function( n ) {
11949				return n >= index ? ++n : n;
11950			});
11951
11952			this.refresh();
11953			if ( this.tabs.length === 1 && options.active === false ) {
11954				this.option( "active", 0 );
11955			}
11956
11957			this._trigger( "add", null, this._ui( this.anchors[ index ], this.panels[ index ] ) );
11958			return this;
11959		},
11960
11961		remove: function( index ) {
11962			index = this._getIndex( index );
11963			var options = this.options,
11964				tab = this.tabs.eq( index ).remove(),
11965				panel = this._getPanelForTab( tab ).remove();
11966
11967			// If selected tab was removed focus tab to the right or
11968			// in case the last tab was removed the tab to the left.
11969			// We check for more than 2 tabs, because if there are only 2,
11970			// then when we remove this tab, there will only be one tab left
11971			// so we don't need to detect which tab to activate.
11972			if ( tab.hasClass( "ui-tabs-active" ) && this.anchors.length > 2 ) {
11973				this._activate( index + ( index + 1 < this.anchors.length ? 1 : -1 ) );
11974			}
11975
11976			options.disabled = $.map(
11977				$.grep( options.disabled, function( n ) {
11978					return n !== index;
11979				}),
11980				function( n ) {
11981					return n >= index ? --n : n;
11982				});
11983
11984			this.refresh();
11985
11986			this._trigger( "remove", null, this._ui( tab.find( "a" )[ 0 ], panel[ 0 ] ) );
11987			return this;
11988		}
11989	});
11990
11991	// length method
11992	$.widget( "ui.tabs", $.ui.tabs, {
11993		length: function() {
11994			return this.anchors.length;
11995		}
11996	});
11997
11998	// panel ids (idPrefix option + title attribute)
11999	$.widget( "ui.tabs", $.ui.tabs, {
12000		options: {
12001			idPrefix: "ui-tabs-"
12002		},
12003
12004		_tabId: function( tab ) {
12005			var a = tab.is( "li" ) ? tab.find( "a[href]" ) : tab;
12006			a = a[0];
12007			return $( a ).closest( "li" ).attr( "aria-controls" ) ||
12008				a.title && a.title.replace( /\s/g, "_" ).replace( /[^\w\u00c0-\uFFFF\-]/g, "" ) ||
12009				this.options.idPrefix + getNextTabId();
12010		}
12011	});
12012
12013	// _createPanel method
12014	$.widget( "ui.tabs", $.ui.tabs, {
12015		options: {
12016			panelTemplate: "<div></div>"
12017		},
12018
12019		_createPanel: function( id ) {
12020			return $( this.options.panelTemplate )
12021				.attr( "id", id )
12022				.addClass( "ui-tabs-panel ui-widget-content ui-corner-bottom" )
12023				.data( "ui-tabs-destroy", true );
12024		}
12025	});
12026
12027	// selected option
12028	$.widget( "ui.tabs", $.ui.tabs, {
12029		_create: function() {
12030			var options = this.options;
12031			if ( options.active === null && options.selected !== undefined ) {
12032				options.active = options.selected === -1 ? false : options.selected;
12033			}
12034			this._super();
12035			options.selected = options.active;
12036			if ( options.selected === false ) {
12037				options.selected = -1;
12038			}
12039		},
12040
12041		_setOption: function( key, value ) {
12042			if ( key !== "selected" ) {
12043				return this._super( key, value );
12044			}
12045
12046			var options = this.options;
12047			this._super( "active", value === -1 ? false : value );
12048			options.selected = options.active;
12049			if ( options.selected === false ) {
12050				options.selected = -1;
12051			}
12052		},
12053
12054		_eventHandler: function() {
12055			this._superApply( arguments );
12056			this.options.selected = this.options.active;
12057			if ( this.options.selected === false ) {
12058				this.options.selected = -1;
12059			}
12060		}
12061	});
12062
12063	// show and select event
12064	$.widget( "ui.tabs", $.ui.tabs, {
12065		options: {
12066			show: null,
12067			select: null
12068		},
12069		_create: function() {
12070			this._super();
12071			if ( this.options.active !== false ) {
12072				this._trigger( "show", null, this._ui(
12073					this.active.find( ".ui-tabs-anchor" )[ 0 ],
12074					this._getPanelForTab( this.active )[ 0 ] ) );
12075			}
12076		},
12077		_trigger: function( type, event, data ) {
12078			var tab, panel,
12079				ret = this._superApply( arguments );
12080
12081			if ( !ret ) {
12082				return false;
12083			}
12084
12085			if ( type === "beforeActivate" ) {
12086				tab = data.newTab.length ? data.newTab : data.oldTab;
12087				panel = data.newPanel.length ? data.newPanel : data.oldPanel;
12088				ret = this._super( "select", event, {
12089					tab: tab.find( ".ui-tabs-anchor" )[ 0],
12090					panel: panel[ 0 ],
12091					index: tab.closest( "li" ).index()
12092				});
12093			} else if ( type === "activate" && data.newTab.length ) {
12094				ret = this._super( "show", event, {
12095					tab: data.newTab.find( ".ui-tabs-anchor" )[ 0 ],
12096					panel: data.newPanel[ 0 ],
12097					index: data.newTab.closest( "li" ).index()
12098				});
12099			}
12100			return ret;
12101		}
12102	});
12103
12104	// select method
12105	$.widget( "ui.tabs", $.ui.tabs, {
12106		select: function( index ) {
12107			index = this._getIndex( index );
12108			if ( index === -1 ) {
12109				if ( this.options.collapsible && this.options.selected !== -1 ) {
12110					index = this.options.selected;
12111				} else {
12112					return;
12113				}
12114			}
12115			this.anchors.eq( index ).trigger( this.options.event + this.eventNamespace );
12116		}
12117	});
12118
12119	// cookie option
12120	(function() {
12121
12122	var listId = 0;
12123
12124	$.widget( "ui.tabs", $.ui.tabs, {
12125		options: {
12126			cookie: null // e.g. { expires: 7, path: '/', domain: 'jquery.com', secure: true }
12127		},
12128		_create: function() {
12129			var options = this.options,
12130				active;
12131			if ( options.active == null && options.cookie ) {
12132				active = parseInt( this._cookie(), 10 );
12133				if ( active === -1 ) {
12134					active = false;
12135				}
12136				options.active = active;
12137			}
12138			this._super();
12139		},
12140		_cookie: function( active ) {
12141			var cookie = [ this.cookie ||
12142				( this.cookie = this.options.cookie.name || "ui-tabs-" + (++listId) ) ];
12143			if ( arguments.length ) {
12144				cookie.push( active === false ? -1 : active );
12145				cookie.push( this.options.cookie );
12146			}
12147			return $.cookie.apply( null, cookie );
12148		},
12149		_refresh: function() {
12150			this._super();
12151			if ( this.options.cookie ) {
12152				this._cookie( this.options.active, this.options.cookie );
12153			}
12154		},
12155		_eventHandler: function() {
12156			this._superApply( arguments );
12157			if ( this.options.cookie ) {
12158				this._cookie( this.options.active, this.options.cookie );
12159			}
12160		},
12161		_destroy: function() {
12162			this._super();
12163			if ( this.options.cookie ) {
12164				this._cookie( null, this.options.cookie );
12165			}
12166		}
12167	});
12168
12169	})();
12170
12171	// load event
12172	$.widget( "ui.tabs", $.ui.tabs, {
12173		_trigger: function( type, event, data ) {
12174			var _data = $.extend( {}, data );
12175			if ( type === "load" ) {
12176				_data.panel = _data.panel[ 0 ];
12177				_data.tab = _data.tab.find( ".ui-tabs-anchor" )[ 0 ];
12178			}
12179			return this._super( type, event, _data );
12180		}
12181	});
12182
12183	// fx option
12184	// The new animation options (show, hide) conflict with the old show callback.
12185	// The old fx option wins over show/hide anyway (always favor back-compat).
12186	// If a user wants to use the new animation API, they must give up the old API.
12187	$.widget( "ui.tabs", $.ui.tabs, {
12188		options: {
12189			fx: null // e.g. { height: "toggle", opacity: "toggle", duration: 200 }
12190		},
12191
12192		_getFx: function() {
12193			var hide, show,
12194				fx = this.options.fx;
12195
12196			if ( fx ) {
12197				if ( $.isArray( fx ) ) {
12198					hide = fx[ 0 ];
12199					show = fx[ 1 ];
12200				} else {
12201					hide = show = fx;
12202				}
12203			}
12204
12205			return fx ? { show: show, hide: hide } : null;
12206		},
12207
12208		_toggle: function( event, eventData ) {
12209			var that = this,
12210				toShow = eventData.newPanel,
12211				toHide = eventData.oldPanel,
12212				fx = this._getFx();
12213
12214			if ( !fx ) {
12215				return this._super( event, eventData );
12216			}
12217
12218			that.running = true;
12219
12220			function complete() {
12221				that.running = false;
12222				that._trigger( "activate", event, eventData );
12223			}
12224
12225			function show() {
12226				eventData.newTab.closest( "li" ).addClass( "ui-tabs-active ui-state-active" );
12227
12228				if ( toShow.length && fx.show ) {
12229					toShow
12230						.animate( fx.show, fx.show.duration, function() {
12231							complete();
12232						});
12233				} else {
12234					toShow.show();
12235					complete();
12236				}
12237			}
12238
12239			// start out by hiding, then showing, then completing
12240			if ( toHide.length && fx.hide ) {
12241				toHide.animate( fx.hide, fx.hide.duration, function() {
12242					eventData.oldTab.closest( "li" ).removeClass( "ui-tabs-active ui-state-active" );
12243					show();
12244				});
12245			} else {
12246				eventData.oldTab.closest( "li" ).removeClass( "ui-tabs-active ui-state-active" );
12247				toHide.hide();
12248				show();
12249			}
12250		}
12251	});
12252}
12253
12254})( jQuery );
12255(function( $ ) {
12256
12257var increments = 0;
12258
12259function addDescribedBy( elem, id ) {
12260	var describedby = (elem.attr( "aria-describedby" ) || "").split( /\s+/ );
12261	describedby.push( id );
12262	elem
12263		.data( "ui-tooltip-id", id )
12264		.attr( "aria-describedby", $.trim( describedby.join( " " ) ) );
12265}
12266
12267function removeDescribedBy( elem ) {
12268	var id = elem.data( "ui-tooltip-id" ),
vendor: 65,202 bytes, lines 12269-14880
12269		describedby = (elem.attr( "aria-describedby" ) || "").split( /\s+/ ),
12270		index = $.inArray( id, describedby );
12271	if ( index !== -1 ) {
12272		describedby.splice( index, 1 );
12273	}
12274
12275	elem.removeData( "ui-tooltip-id" );
12276	describedby = $.trim( describedby.join( " " ) );
12277	if ( describedby ) {
12278		elem.attr( "aria-describedby", describedby );
12279	} else {
12280		elem.removeAttr( "aria-describedby" );
12281	}
12282}
12283
12284$.widget( "ui.tooltip", {
12285	version: "1.9.2",
12286	options: {
12287		content: function() {
12288			return $( this ).attr( "title" );
12289		},
12290		hide: true,
12291		// Disabled elements have inconsistent behavior across browsers (#8661)
12292		items: "[title]:not([disabled])",
12293		position: {
12294			my: "left top+15",
12295			at: "left bottom",
12296			collision: "flipfit flip"
12297		},
12298		show: true,
12299		tooltipClass: null,
12300		track: false,
12301
12302		// callbacks
12303		close: null,
12304		open: null
12305	},
12306
12307	_create: function() {
12308		this._on({
12309			mouseover: "open",
12310			focusin: "open"
12311		});
12312
12313		// IDs of generated tooltips, needed for destroy
12314		this.tooltips = {};
12315		// IDs of parent tooltips where we removed the title attribute
12316		this.parents = {};
12317
12318		if ( this.options.disabled ) {
12319			this._disable();
12320		}
12321	},
12322
12323	_setOption: function( key, value ) {
12324		var that = this;
12325
12326		if ( key === "disabled" ) {
12327			this[ value ? "_disable" : "_enable" ]();
12328			this.options[ key ] = value;
12329			// disable element style changes
12330			return;
12331		}
12332
12333		this._super( key, value );
12334
12335		if ( key === "content" ) {
12336			$.each( this.tooltips, function( id, element ) {
12337				that._updateContent( element );
12338			});
12339		}
12340	},
12341
12342	_disable: function() {
12343		var that = this;
12344
12345		// close open tooltips
12346		$.each( this.tooltips, function( id, element ) {
12347			var event = $.Event( "blur" );
12348			event.target = event.currentTarget = element[0];
12349			that.close( event, true );
12350		});
12351
12352		// remove title attributes to prevent native tooltips
12353		this.element.find( this.options.items ).andSelf().each(function() {
12354			var element = $( this );
12355			if ( element.is( "[title]" ) ) {
12356				element
12357					.data( "ui-tooltip-title", element.attr( "title" ) )
12358					.attr( "title", "" );
12359			}
12360		});
12361	},
12362
12363	_enable: function() {
12364		// restore title attributes
12365		this.element.find( this.options.items ).andSelf().each(function() {
12366			var element = $( this );
12367			if ( element.data( "ui-tooltip-title" ) ) {
12368				element.attr( "title", element.data( "ui-tooltip-title" ) );
12369			}
12370		});
12371	},
12372
12373	open: function( event ) {
12374		var that = this,
12375			target = $( event ? event.target : this.element )
12376				// we need closest here due to mouseover bubbling,
12377				// but always pointing at the same event target
12378				.closest( this.options.items );
12379
12380		// No element to show a tooltip for or the tooltip is already open
12381		if ( !target.length || target.data( "ui-tooltip-id" ) ) {
12382			return;
12383		}
12384
12385		if ( target.attr( "title" ) ) {
12386			target.data( "ui-tooltip-title", target.attr( "title" ) );
12387		}
12388
12389		target.data( "ui-tooltip-open", true );
12390
12391		// kill parent tooltips, custom or native, for hover
12392		if ( event && event.type === "mouseover" ) {
12393			target.parents().each(function() {
12394				var parent = $( this ),
12395					blurEvent;
12396				if ( parent.data( "ui-tooltip-open" ) ) {
12397					blurEvent = $.Event( "blur" );
12398					blurEvent.target = blurEvent.currentTarget = this;
12399					that.close( blurEvent, true );
12400				}
12401				if ( parent.attr( "title" ) ) {
12402					parent.uniqueId();
12403					that.parents[ this.id ] = {
12404						element: this,
12405						title: parent.attr( "title" )
12406					};
12407					parent.attr( "title", "" );
12408				}
12409			});
12410		}
12411
12412		this._updateContent( target, event );
12413	},
12414
12415	_updateContent: function( target, event ) {
12416		var content,
12417			contentOption = this.options.content,
12418			that = this,
12419			eventType = event ? event.type : null;
12420
12421		if ( typeof contentOption === "string" ) {
12422			return this._open( event, target, contentOption );
12423		}
12424
12425		content = contentOption.call( target[0], function( response ) {
12426			// ignore async response if tooltip was closed already
12427			if ( !target.data( "ui-tooltip-open" ) ) {
12428				return;
12429			}
12430			// IE may instantly serve a cached response for ajax requests
12431			// delay this call to _open so the other call to _open runs first
12432			that._delay(function() {
12433				// jQuery creates a special event for focusin when it doesn't
12434				// exist natively. To improve performance, the native event
12435				// object is reused and the type is changed. Therefore, we can't
12436				// rely on the type being correct after the event finished
12437				// bubbling, so we set it back to the previous value. (#8740)
12438				if ( event ) {
12439					event.type = eventType;
12440				}
12441				this._open( event, target, response );
12442			});
12443		});
12444		if ( content ) {
12445			this._open( event, target, content );
12446		}
12447	},
12448
12449	_open: function( event, target, content ) {
12450		var tooltip, events, delayedShow,
12451			positionOption = $.extend( {}, this.options.position );
12452
12453		if ( !content ) {
12454			return;
12455		}
12456
12457		// Content can be updated multiple times. If the tooltip already
12458		// exists, then just update the content and bail.
12459		tooltip = this._find( target );
12460		if ( tooltip.length ) {
12461			tooltip.find( ".ui-tooltip-content" ).html( content );
12462			return;
12463		}
12464
12465		// if we have a title, clear it to prevent the native tooltip
12466		// we have to check first to avoid defining a title if none exists
12467		// (we don't want to cause an element to start matching [title])
12468		//
12469		// We use removeAttr only for key events, to allow IE to export the correct
12470		// accessible attributes. For mouse events, set to empty string to avoid
12471		// native tooltip showing up (happens only when removing inside mouseover).
12472		if ( target.is( "[title]" ) ) {
12473			if ( event && event.type === "mouseover" ) {
12474				target.attr( "title", "" );
12475			} else {
12476				target.removeAttr( "title" );
12477			}
12478		}
12479
12480		tooltip = this._tooltip( target );
12481		addDescribedBy( target, tooltip.attr( "id" ) );
12482		tooltip.find( ".ui-tooltip-content" ).html( content );
12483
12484		function position( event ) {
12485			positionOption.of = event;
12486			if ( tooltip.is( ":hidden" ) ) {
12487				return;
12488			}
12489			tooltip.position( positionOption );
12490		}
12491		if ( this.options.track && event && /^mouse/.test( event.type ) ) {
12492			this._on( this.document, {
12493				mousemove: position
12494			});
12495			// trigger once to override element-relative positioning
12496			position( event );
12497		} else {
12498			tooltip.position( $.extend({
12499				of: target
12500			}, this.options.position ) );
12501		}
12502
12503		tooltip.hide();
12504
12505		this._show( tooltip, this.options.show );
12506		// Handle tracking tooltips that are shown with a delay (#8644). As soon
12507		// as the tooltip is visible, position the tooltip using the most recent
12508		// event.
12509		if ( this.options.show && this.options.show.delay ) {
12510			delayedShow = setInterval(function() {
12511				if ( tooltip.is( ":visible" ) ) {
12512					position( positionOption.of );
12513					clearInterval( delayedShow );
12514				}
12515			}, $.fx.interval );
12516		}
12517
12518		this._trigger( "open", event, { tooltip: tooltip } );
12519
12520		events = {
12521			keyup: function( event ) {
12522				if ( event.keyCode === $.ui.keyCode.ESCAPE ) {
12523					var fakeEvent = $.Event(event);
12524					fakeEvent.currentTarget = target[0];
12525					this.close( fakeEvent, true );
12526				}
12527			},
12528			remove: function() {
12529				this._removeTooltip( tooltip );
12530			}
12531		};
12532		if ( !event || event.type === "mouseover" ) {
12533			events.mouseleave = "close";
12534		}
12535		if ( !event || event.type === "focusin" ) {
12536			events.focusout = "close";
12537		}
12538		this._on( true, target, events );
12539	},
12540
12541	close: function( event ) {
12542		var that = this,
12543			target = $( event ? event.currentTarget : this.element ),
12544			tooltip = this._find( target );
12545
12546		// disabling closes the tooltip, so we need to track when we're closing
12547		// to avoid an infinite loop in case the tooltip becomes disabled on close
12548		if ( this.closing ) {
12549			return;
12550		}
12551
12552		// only set title if we had one before (see comment in _open())
12553		if ( target.data( "ui-tooltip-title" ) ) {
12554			target.attr( "title", target.data( "ui-tooltip-title" ) );
12555		}
12556
12557		removeDescribedBy( target );
12558
12559		tooltip.stop( true );
12560		this._hide( tooltip, this.options.hide, function() {
12561			that._removeTooltip( $( this ) );
12562		});
12563
12564		target.removeData( "ui-tooltip-open" );
12565		this._off( target, "mouseleave focusout keyup" );
12566		// Remove 'remove' binding only on delegated targets
12567		if ( target[0] !== this.element[0] ) {
12568			this._off( target, "remove" );
12569		}
12570		this._off( this.document, "mousemove" );
12571
12572		if ( event && event.type === "mouseleave" ) {
12573			$.each( this.parents, function( id, parent ) {
12574				$( parent.element ).attr( "title", parent.title );
12575				delete that.parents[ id ];
12576			});
12577		}
12578
12579		this.closing = true;
12580		this._trigger( "close", event, { tooltip: tooltip } );
12581		this.closing = false;
12582	},
12583
12584	_tooltip: function( element ) {
12585		var id = "ui-tooltip-" + increments++,
12586			tooltip = $( "<div>" )
12587				.attr({
12588					id: id,
12589					role: "tooltip"
12590				})
12591				.addClass( "ui-tooltip ui-widget ui-corner-all ui-widget-content " +
12592					( this.options.tooltipClass || "" ) );
12593		$( "<div>" )
12594			.addClass( "ui-tooltip-content" )
12595			.appendTo( tooltip );
12596		tooltip.appendTo( this.document[0].body );
12597		if ( $.fn.bgiframe ) {
12598			tooltip.bgiframe();
12599		}
12600		this.tooltips[ id ] = element;
12601		return tooltip;
12602	},
12603
12604	_find: function( target ) {
12605		var id = target.data( "ui-tooltip-id" );
12606		return id ? $( "#" + id ) : $();
12607	},
12608
12609	_removeTooltip: function( tooltip ) {
12610		tooltip.remove();
12611		delete this.tooltips[ tooltip.attr( "id" ) ];
12612	},
12613
12614	_destroy: function() {
12615		var that = this;
12616
12617		// close open tooltips
12618		$.each( this.tooltips, function( id, element ) {
12619			// Delegate to close method to handle common cleanup
12620			var event = $.Event( "blur" );
12621			event.target = event.currentTarget = element[0];
12622			that.close( event, true );
12623
12624			// Remove immediately; destroying an open tooltip doesn't use the
12625			// hide animation
12626			$( "#" + id ).remove();
12627
12628			// Restore the title
12629			if ( element.data( "ui-tooltip-title" ) ) {
12630				element.attr( "title", element.data( "ui-tooltip-title" ) );
12631				element.removeData( "ui-tooltip-title" );
12632			}
12633		});
12634	}
12635});
12636
12637}( jQuery ) );
12638;(jQuery.effects || (function($, undefined) {
12639
12640var backCompat = $.uiBackCompat !== false,
12641	// prefix used for storing data on .data()
12642	dataSpace = "ui-effects-";
12643
12644$.effects = {
12645	effect: {}
12646};
12647
12648/*!
12649 * jQuery Color Animations v2.0.0
12650 * http://jquery.com/
12651 *
12652 * Copyright 2012 jQuery Foundation and other contributors
12653 * Released under the MIT license.
12654 * http://jquery.org/license
12655 *
12656 * Date: Mon Aug 13 13:41:02 2012 -0500
12657 */
12658(function( jQuery, undefined ) {
12659
12660	var stepHooks = "backgroundColor borderBottomColor borderLeftColor borderRightColor borderTopColor color columnRuleColor outlineColor textDecorationColor textEmphasisColor".split(" "),
12661
12662	// plusequals test for += 100 -= 100
12663	rplusequals = /^([\-+])=\s*(\d+\.?\d*)/,
12664	// a set of RE's that can match strings and generate color tuples.
12665	stringParsers = [{
12666			re: /rgba?\(\s*(\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(\d{1,3})\s*(?:,\s*(\d+(?:\.\d+)?)\s*)?\)/,
12667			parse: function( execResult ) {
12668				return [
12669					execResult[ 1 ],
12670					execResult[ 2 ],
12671					execResult[ 3 ],
12672					execResult[ 4 ]
12673				];
12674			}
12675		}, {
12676			re: /rgba?\(\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*(?:,\s*(\d+(?:\.\d+)?)\s*)?\)/,
12677			parse: function( execResult ) {
12678				return [
12679					execResult[ 1 ] * 2.55,
12680					execResult[ 2 ] * 2.55,
12681					execResult[ 3 ] * 2.55,
12682					execResult[ 4 ]
12683				];
12684			}
12685		}, {
12686			// this regex ignores A-F because it's compared against an already lowercased string
12687			re: /#([a-f0-9]{2})([a-f0-9]{2})([a-f0-9]{2})/,
12688			parse: function( execResult ) {
12689				return [
12690					parseInt( execResult[ 1 ], 16 ),
12691					parseInt( execResult[ 2 ], 16 ),
12692					parseInt( execResult[ 3 ], 16 )
12693				];
12694			}
12695		}, {
12696			// this regex ignores A-F because it's compared against an already lowercased string
12697			re: /#([a-f0-9])([a-f0-9])([a-f0-9])/,
12698			parse: function( execResult ) {
12699				return [
12700					parseInt( execResult[ 1 ] + execResult[ 1 ], 16 ),
12701					parseInt( execResult[ 2 ] + execResult[ 2 ], 16 ),
12702					parseInt( execResult[ 3 ] + execResult[ 3 ], 16 )
12703				];
12704			}
12705		}, {
12706			re: /hsla?\(\s*(\d+(?:\.\d+)?)\s*,\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*(?:,\s*(\d+(?:\.\d+)?)\s*)?\)/,
12707			space: "hsla",
12708			parse: function( execResult ) {
12709				return [
12710					execResult[ 1 ],
12711					execResult[ 2 ] / 100,
12712					execResult[ 3 ] / 100,
12713					execResult[ 4 ]
12714				];
12715			}
12716		}],
12717
12718	// jQuery.Color( )
12719	color = jQuery.Color = function( color, green, blue, alpha ) {
12720		return new jQuery.Color.fn.parse( color, green, blue, alpha );
12721	},
12722	spaces = {
12723		rgba: {
12724			props: {
12725				red: {
12726					idx: 0,
12727					type: "byte"
12728				},
12729				green: {
12730					idx: 1,
12731					type: "byte"
12732				},
12733				blue: {
12734					idx: 2,
12735					type: "byte"
12736				}
12737			}
12738		},
12739
12740		hsla: {
12741			props: {
12742				hue: {
12743					idx: 0,
12744					type: "degrees"
12745				},
12746				saturation: {
12747					idx: 1,
12748					type: "percent"
12749				},
12750				lightness: {
12751					idx: 2,
12752					type: "percent"
12753				}
12754			}
12755		}
12756	},
12757	propTypes = {
12758		"byte": {
12759			floor: true,
12760			max: 255
12761		},
12762		"percent": {
12763			max: 1
12764		},
12765		"degrees": {
12766			mod: 360,
12767			floor: true
12768		}
12769	},
12770	support = color.support = {},
12771
12772	// element for support tests
12773	supportElem = jQuery( "<p>" )[ 0 ],
12774
12775	// colors = jQuery.Color.names
12776	colors,
12777
12778	// local aliases of functions called often
12779	each = jQuery.each;
12780
12781// determine rgba support immediately
12782supportElem.style.cssText = "background-color:rgba(1,1,1,.5)";
12783support.rgba = supportElem.style.backgroundColor.indexOf( "rgba" ) > -1;
12784
12785// define cache name and alpha properties
12786// for rgba and hsla spaces
12787each( spaces, function( spaceName, space ) {
12788	space.cache = "_" + spaceName;
12789	space.props.alpha = {
12790		idx: 3,
12791		type: "percent",
12792		def: 1
12793	};
12794});
12795
12796function clamp( value, prop, allowEmpty ) {
12797	var type = propTypes[ prop.type ] || {};
12798
12799	if ( value == null ) {
12800		return (allowEmpty || !prop.def) ? null : prop.def;
12801	}
12802
12803	// ~~ is an short way of doing floor for positive numbers
12804	value = type.floor ? ~~value : parseFloat( value );
12805
12806	// IE will pass in empty strings as value for alpha,
12807	// which will hit this case
12808	if ( isNaN( value ) ) {
12809		return prop.def;
12810	}
12811
12812	if ( type.mod ) {
12813		// we add mod before modding to make sure that negatives values
12814		// get converted properly: -10 -> 350
12815		return (value + type.mod) % type.mod;
12816	}
12817
12818	// for now all property types without mod have min and max
12819	return 0 > value ? 0 : type.max < value ? type.max : value;
12820}
12821
12822function stringParse( string ) {
12823	var inst = color(),
12824		rgba = inst._rgba = [];
12825
12826	string = string.toLowerCase();
12827
12828	each( stringParsers, function( i, parser ) {
12829		var parsed,
12830			match = parser.re.exec( string ),
12831			values = match && parser.parse( match ),
12832			spaceName = parser.space || "rgba";
12833
12834		if ( values ) {
12835			parsed = inst[ spaceName ]( values );
12836
12837			// if this was an rgba parse the assignment might happen twice
12838			// oh well....
12839			inst[ spaces[ spaceName ].cache ] = parsed[ spaces[ spaceName ].cache ];
12840			rgba = inst._rgba = parsed._rgba;
12841
12842			// exit each( stringParsers ) here because we matched
12843			return false;
12844		}
12845	});
12846
12847	// Found a stringParser that handled it
12848	if ( rgba.length ) {
12849
12850		// if this came from a parsed string, force "transparent" when alpha is 0
12851		// chrome, (and maybe others) return "transparent" as rgba(0,0,0,0)
12852		if ( rgba.join() === "0,0,0,0" ) {
12853			jQuery.extend( rgba, colors.transparent );
12854		}
12855		return inst;
12856	}
12857
12858	// named colors
12859	return colors[ string ];
12860}
12861
12862color.fn = jQuery.extend( color.prototype, {
12863	parse: function( red, green, blue, alpha ) {
12864		if ( red === undefined ) {
12865			this._rgba = [ null, null, null, null ];
12866			return this;
12867		}
12868		if ( red.jquery || red.nodeType ) {
12869			red = jQuery( red ).css( green );
12870			green = undefined;
12871		}
12872
12873		var inst = this,
12874			type = jQuery.type( red ),
12875			rgba = this._rgba = [];
12876
12877		// more than 1 argument specified - assume ( red, green, blue, alpha )
12878		if ( green !== undefined ) {
12879			red = [ red, green, blue, alpha ];
12880			type = "array";
12881		}
12882
12883		if ( type === "string" ) {
12884			return this.parse( stringParse( red ) || colors._default );
12885		}
12886
12887		if ( type === "array" ) {
12888			each( spaces.rgba.props, function( key, prop ) {
12889				rgba[ prop.idx ] = clamp( red[ prop.idx ], prop );
12890			});
12891			return this;
12892		}
12893
12894		if ( type === "object" ) {
12895			if ( red instanceof color ) {
12896				each( spaces, function( spaceName, space ) {
12897					if ( red[ space.cache ] ) {
12898						inst[ space.cache ] = red[ space.cache ].slice();
12899					}
12900				});
12901			} else {
12902				each( spaces, function( spaceName, space ) {
12903					var cache = space.cache;
12904					each( space.props, function( key, prop ) {
12905
12906						// if the cache doesn't exist, and we know how to convert
12907						if ( !inst[ cache ] && space.to ) {
12908
12909							// if the value was null, we don't need to copy it
12910							// if the key was alpha, we don't need to copy it either
12911							if ( key === "alpha" || red[ key ] == null ) {
12912								return;
12913							}
12914							inst[ cache ] = space.to( inst._rgba );
12915						}
12916
12917						// this is the only case where we allow nulls for ALL properties.
12918						// call clamp with alwaysAllowEmpty
12919						inst[ cache ][ prop.idx ] = clamp( red[ key ], prop, true );
12920					});
12921
12922					// everything defined but alpha?
12923					if ( inst[ cache ] && $.inArray( null, inst[ cache ].slice( 0, 3 ) ) < 0 ) {
12924						// use the default of 1
12925						inst[ cache ][ 3 ] = 1;
12926						if ( space.from ) {
12927							inst._rgba = space.from( inst[ cache ] );
12928						}
12929					}
12930				});
12931			}
12932			return this;
12933		}
12934	},
12935	is: function( compare ) {
12936		var is = color( compare ),
12937			same = true,
12938			inst = this;
12939
12940		each( spaces, function( _, space ) {
12941			var localCache,
12942				isCache = is[ space.cache ];
12943			if (isCache) {
12944				localCache = inst[ space.cache ] || space.to && space.to( inst._rgba ) || [];
12945				each( space.props, function( _, prop ) {
12946					if ( isCache[ prop.idx ] != null ) {
12947						same = ( isCache[ prop.idx ] === localCache[ prop.idx ] );
12948						return same;
12949					}
12950				});
12951			}
12952			return same;
12953		});
12954		return same;
12955	},
12956	_space: function() {
12957		var used = [],
12958			inst = this;
12959		each( spaces, function( spaceName, space ) {
12960			if ( inst[ space.cache ] ) {
12961				used.push( spaceName );
12962			}
12963		});
12964		return used.pop();
12965	},
12966	transition: function( other, distance ) {
12967		var end = color( other ),
12968			spaceName = end._space(),
12969			space = spaces[ spaceName ],
12970			startColor = this.alpha() === 0 ? color( "transparent" ) : this,
12971			start = startColor[ space.cache ] || space.to( startColor._rgba ),
12972			result = start.slice();
12973
12974		end = end[ space.cache ];
12975		each( space.props, function( key, prop ) {
12976			var index = prop.idx,
12977				startValue = start[ index ],
12978				endValue = end[ index ],
12979				type = propTypes[ prop.type ] || {};
12980
12981			// if null, don't override start value
12982			if ( endValue === null ) {
12983				return;
12984			}
12985			// if null - use end
12986			if ( startValue === null ) {
12987				result[ index ] = endValue;
12988			} else {
12989				if ( type.mod ) {
12990					if ( endValue - startValue > type.mod / 2 ) {
12991						startValue += type.mod;
12992					} else if ( startValue - endValue > type.mod / 2 ) {
12993						startValue -= type.mod;
12994					}
12995				}
12996				result[ index ] = clamp( ( endValue - startValue ) * distance + startValue, prop );
12997			}
12998		});
12999		return this[ spaceName ]( result );
13000	},
13001	blend: function( opaque ) {
13002		// if we are already opaque - return ourself
13003		if ( this._rgba[ 3 ] === 1 ) {
13004			return this;
13005		}
13006
13007		var rgb = this._rgba.slice(),
13008			a = rgb.pop(),
13009			blend = color( opaque )._rgba;
13010
13011		return color( jQuery.map( rgb, function( v, i ) {
13012			return ( 1 - a ) * blend[ i ] + a * v;
13013		}));
13014	},
13015	toRgbaString: function() {
13016		var prefix = "rgba(",
13017			rgba = jQuery.map( this._rgba, function( v, i ) {
13018				return v == null ? ( i > 2 ? 1 : 0 ) : v;
13019			});
13020
13021		if ( rgba[ 3 ] === 1 ) {
13022			rgba.pop();
13023			prefix = "rgb(";
13024		}
13025
13026		return prefix + rgba.join() + ")";
13027	},
13028	toHslaString: function() {
13029		var prefix = "hsla(",
13030			hsla = jQuery.map( this.hsla(), function( v, i ) {
13031				if ( v == null ) {
13032					v = i > 2 ? 1 : 0;
13033				}
13034
13035				// catch 1 and 2
13036				if ( i && i < 3 ) {
13037					v = Math.round( v * 100 ) + "%";
13038				}
13039				return v;
13040			});
13041
13042		if ( hsla[ 3 ] === 1 ) {
13043			hsla.pop();
13044			prefix = "hsl(";
13045		}
13046		return prefix + hsla.join() + ")";
13047	},
13048	toHexString: function( includeAlpha ) {
13049		var rgba = this._rgba.slice(),
13050			alpha = rgba.pop();
13051
13052		if ( includeAlpha ) {
13053			rgba.push( ~~( alpha * 255 ) );
13054		}
13055
13056		return "#" + jQuery.map( rgba, function( v ) {
13057
13058			// default to 0 when nulls exist
13059			v = ( v || 0 ).toString( 16 );
13060			return v.length === 1 ? "0" + v : v;
13061		}).join("");
13062	},
13063	toString: function() {
13064		return this._rgba[ 3 ] === 0 ? "transparent" : this.toRgbaString();
13065	}
13066});
13067color.fn.parse.prototype = color.fn;
13068
13069// hsla conversions adapted from:
13070// https://code.google.com/p/maashaack/source/browse/packages/graphics/trunk/src/graphics/colors/HUE2RGB.as?r=5021
13071
13072function hue2rgb( p, q, h ) {
13073	h = ( h + 1 ) % 1;
13074	if ( h * 6 < 1 ) {
13075		return p + (q - p) * h * 6;
13076	}
13077	if ( h * 2 < 1) {
13078		return q;
13079	}
13080	if ( h * 3 < 2 ) {
13081		return p + (q - p) * ((2/3) - h) * 6;
13082	}
13083	return p;
13084}
13085
13086spaces.hsla.to = function ( rgba ) {
13087	if ( rgba[ 0 ] == null || rgba[ 1 ] == null || rgba[ 2 ] == null ) {
13088		return [ null, null, null, rgba[ 3 ] ];
13089	}
13090	var r = rgba[ 0 ] / 255,
13091		g = rgba[ 1 ] / 255,
13092		b = rgba[ 2 ] / 255,
13093		a = rgba[ 3 ],
13094		max = Math.max( r, g, b ),
13095		min = Math.min( r, g, b ),
13096		diff = max - min,
13097		add = max + min,
13098		l = add * 0.5,
13099		h, s;
13100
13101	if ( min === max ) {
13102		h = 0;
13103	} else if ( r === max ) {
13104		h = ( 60 * ( g - b ) / diff ) + 360;
13105	} else if ( g === max ) {
13106		h = ( 60 * ( b - r ) / diff ) + 120;
13107	} else {
13108		h = ( 60 * ( r - g ) / diff ) + 240;
13109	}
13110
13111	if ( l === 0 || l === 1 ) {
13112		s = l;
13113	} else if ( l <= 0.5 ) {
13114		s = diff / add;
13115	} else {
13116		s = diff / ( 2 - add );
13117	}
13118	return [ Math.round(h) % 360, s, l, a == null ? 1 : a ];
13119};
13120
13121spaces.hsla.from = function ( hsla ) {
13122	if ( hsla[ 0 ] == null || hsla[ 1 ] == null || hsla[ 2 ] == null ) {
13123		return [ null, null, null, hsla[ 3 ] ];
13124	}
13125	var h = hsla[ 0 ] / 360,
13126		s = hsla[ 1 ],
13127		l = hsla[ 2 ],
13128		a = hsla[ 3 ],
13129		q = l <= 0.5 ? l * ( 1 + s ) : l + s - l * s,
13130		p = 2 * l - q;
13131
13132	return [
13133		Math.round( hue2rgb( p, q, h + ( 1 / 3 ) ) * 255 ),
13134		Math.round( hue2rgb( p, q, h ) * 255 ),
13135		Math.round( hue2rgb( p, q, h - ( 1 / 3 ) ) * 255 ),
13136		a
13137	];
13138};
13139
13140
13141each( spaces, function( spaceName, space ) {
13142	var props = space.props,
13143		cache = space.cache,
13144		to = space.to,
13145		from = space.from;
13146
13147	// makes rgba() and hsla()
13148	color.fn[ spaceName ] = function( value ) {
13149
13150		// generate a cache for this space if it doesn't exist
13151		if ( to && !this[ cache ] ) {
13152			this[ cache ] = to( this._rgba );
13153		}
13154		if ( value === undefined ) {
13155			return this[ cache ].slice();
13156		}
13157
13158		var ret,
13159			type = jQuery.type( value ),
13160			arr = ( type === "array" || type === "object" ) ? value : arguments,
13161			local = this[ cache ].slice();
13162
13163		each( props, function( key, prop ) {
13164			var val = arr[ type === "object" ? key : prop.idx ];
13165			if ( val == null ) {
13166				val = local[ prop.idx ];
13167			}
13168			local[ prop.idx ] = clamp( val, prop );
13169		});
13170
13171		if ( from ) {
13172			ret = color( from( local ) );
13173			ret[ cache ] = local;
13174			return ret;
13175		} else {
13176			return color( local );
13177		}
13178	};
13179
13180	// makes red() green() blue() alpha() hue() saturation() lightness()
13181	each( props, function( key, prop ) {
13182		// alpha is included in more than one space
13183		if ( color.fn[ key ] ) {
13184			return;
13185		}
13186		color.fn[ key ] = function( value ) {
13187			var vtype = jQuery.type( value ),
13188				fn = ( key === "alpha" ? ( this._hsla ? "hsla" : "rgba" ) : spaceName ),
13189				local = this[ fn ](),
13190				cur = local[ prop.idx ],
13191				match;
13192
13193			if ( vtype === "undefined" ) {
13194				return cur;
13195			}
13196
13197			if ( vtype === "function" ) {
13198				value = value.call( this, cur );
13199				vtype = jQuery.type( value );
13200			}
13201			if ( value == null && prop.empty ) {
13202				return this;
13203			}
13204			if ( vtype === "string" ) {
13205				match = rplusequals.exec( value );
13206				if ( match ) {
13207					value = cur + parseFloat( match[ 2 ] ) * ( match[ 1 ] === "+" ? 1 : -1 );
13208				}
13209			}
13210			local[ prop.idx ] = value;
13211			return this[ fn ]( local );
13212		};
13213	});
13214});
13215
13216// add .fx.step functions
13217each( stepHooks, function( i, hook ) {
13218	jQuery.cssHooks[ hook ] = {
13219		set: function( elem, value ) {
13220			var parsed, curElem,
13221				backgroundColor = "";
13222
13223			if ( jQuery.type( value ) !== "string" || ( parsed = stringParse( value ) ) ) {
13224				value = color( parsed || value );
13225				if ( !support.rgba && value._rgba[ 3 ] !== 1 ) {
13226					curElem = hook === "backgroundColor" ? elem.parentNode : elem;
13227					while (
13228						(backgroundColor === "" || backgroundColor === "transparent") &&
13229						curElem && curElem.style
13230					) {
13231						try {
13232							backgroundColor = jQuery.css( curElem, "backgroundColor" );
13233							curElem = curElem.parentNode;
13234						} catch ( e ) {
13235						}
13236					}
13237
13238					value = value.blend( backgroundColor && backgroundColor !== "transparent" ?
13239						backgroundColor :
13240						"_default" );
13241				}
13242
13243				value = value.toRgbaString();
13244			}
13245			try {
13246				elem.style[ hook ] = value;
13247			} catch( error ) {
13248				// wrapped to prevent IE from throwing errors on "invalid" values like 'auto' or 'inherit'
13249			}
13250		}
13251	};
13252	jQuery.fx.step[ hook ] = function( fx ) {
13253		if ( !fx.colorInit ) {
13254			fx.start = color( fx.elem, hook );
13255			fx.end = color( fx.end );
13256			fx.colorInit = true;
13257		}
13258		jQuery.cssHooks[ hook ].set( fx.elem, fx.start.transition( fx.end, fx.pos ) );
13259	};
13260});
13261
13262jQuery.cssHooks.borderColor = {
13263	expand: function( value ) {
13264		var expanded = {};
13265
13266		each( [ "Top", "Right", "Bottom", "Left" ], function( i, part ) {
13267			expanded[ "border" + part + "Color" ] = value;
13268		});
13269		return expanded;
13270	}
13271};
13272
13273// Basic color names only.
13274// Usage of any of the other color names requires adding yourself or including
13275// jquery.color.svg-names.js.
13276colors = jQuery.Color.names = {
13277	// 4.1. Basic color keywords
13278	aqua: "#00ffff",
13279	black: "#000000",
13280	blue: "#0000ff",
13281	fuchsia: "#ff00ff",
13282	gray: "#808080",
13283	green: "#008000",
13284	lime: "#00ff00",
13285	maroon: "#800000",
13286	navy: "#000080",
13287	olive: "#808000",
13288	purple: "#800080",
13289	red: "#ff0000",
13290	silver: "#c0c0c0",
13291	teal: "#008080",
13292	white: "#ffffff",
13293	yellow: "#ffff00",
13294
13295	// 4.2.3. "transparent" color keyword
13296	transparent: [ null, null, null, 0 ],
13297
13298	_default: "#ffffff"
13299};
13300
13301})( jQuery );
13302
13303
13304
13305/******************************************************************************/
13306/****************************** CLASS ANIMATIONS ******************************/
13307/******************************************************************************/
13308(function() {
13309
13310var classAnimationActions = [ "add", "remove", "toggle" ],
13311	shorthandStyles = {
13312		border: 1,
13313		borderBottom: 1,
13314		borderColor: 1,
13315		borderLeft: 1,
13316		borderRight: 1,
13317		borderTop: 1,
13318		borderWidth: 1,
13319		margin: 1,
13320		padding: 1
13321	};
13322
13323$.each([ "borderLeftStyle", "borderRightStyle", "borderBottomStyle", "borderTopStyle" ], function( _, prop ) {
13324	$.fx.step[ prop ] = function( fx ) {
13325		if ( fx.end !== "none" && !fx.setAttr || fx.pos === 1 && !fx.setAttr ) {
13326			jQuery.style( fx.elem, prop, fx.end );
13327			fx.setAttr = true;
13328		}
13329	};
13330});
13331
13332function getElementStyles() {
13333	var style = this.ownerDocument.defaultView ?
13334			this.ownerDocument.defaultView.getComputedStyle( this, null ) :
13335			this.currentStyle,
13336		newStyle = {},
13337		key,
13338		len;
13339
13340	// webkit enumerates style porperties
13341	if ( style && style.length && style[ 0 ] && style[ style[ 0 ] ] ) {
13342		len = style.length;
13343		while ( len-- ) {
13344			key = style[ len ];
13345			if ( typeof style[ key ] === "string" ) {
13346				newStyle[ $.camelCase( key ) ] = style[ key ];
13347			}
13348		}
13349	} else {
13350		for ( key in style ) {
13351			if ( typeof style[ key ] === "string" ) {
13352				newStyle[ key ] = style[ key ];
13353			}
13354		}
13355	}
13356
13357	return newStyle;
13358}
13359
13360
13361function styleDifference( oldStyle, newStyle ) {
13362	var diff = {},
13363		name, value;
13364
13365	for ( name in newStyle ) {
13366		value = newStyle[ name ];
13367		if ( oldStyle[ name ] !== value ) {
13368			if ( !shorthandStyles[ name ] ) {
13369				if ( $.fx.step[ name ] || !isNaN( parseFloat( value ) ) ) {
13370					diff[ name ] = value;
13371				}
13372			}
13373		}
13374	}
13375
13376	return diff;
13377}
13378
13379$.effects.animateClass = function( value, duration, easing, callback ) {
13380	var o = $.speed( duration, easing, callback );
13381
13382	return this.queue( function() {
13383		var animated = $( this ),
13384			baseClass = animated.attr( "class" ) || "",
13385			applyClassChange,
13386			allAnimations = o.children ? animated.find( "*" ).andSelf() : animated;
13387
13388		// map the animated objects to store the original styles.
13389		allAnimations = allAnimations.map(function() {
13390			var el = $( this );
13391			return {
13392				el: el,
13393				start: getElementStyles.call( this )
13394			};
13395		});
13396
13397		// apply class change
13398		applyClassChange = function() {
13399			$.each( classAnimationActions, function(i, action) {
13400				if ( value[ action ] ) {
13401					animated[ action + "Class" ]( value[ action ] );
13402				}
13403			});
13404		};
13405		applyClassChange();
13406
13407		// map all animated objects again - calculate new styles and diff
13408		allAnimations = allAnimations.map(function() {
13409			this.end = getElementStyles.call( this.el[ 0 ] );
13410			this.diff = styleDifference( this.start, this.end );
13411			return this;
13412		});
13413
13414		// apply original class
13415		animated.attr( "class", baseClass );
13416
13417		// map all animated objects again - this time collecting a promise
13418		allAnimations = allAnimations.map(function() {
13419			var styleInfo = this,
13420				dfd = $.Deferred(),
13421				opts = jQuery.extend({}, o, {
13422					queue: false,
13423					complete: function() {
13424						dfd.resolve( styleInfo );
13425					}
13426				});
13427
13428			this.el.animate( this.diff, opts );
13429			return dfd.promise();
13430		});
13431
13432		// once all animations have completed:
13433		$.when.apply( $, allAnimations.get() ).done(function() {
13434
13435			// set the final class
13436			applyClassChange();
13437
13438			// for each animated element,
13439			// clear all css properties that were animated
13440			$.each( arguments, function() {
13441				var el = this.el;
13442				$.each( this.diff, function(key) {
13443					el.css( key, '' );
13444				});
13445			});
13446
13447			// this is guarnteed to be there if you use jQuery.speed()
13448			// it also handles dequeuing the next anim...
13449			o.complete.call( animated[ 0 ] );
13450		});
13451	});
13452};
13453
13454$.fn.extend({
13455	_addClass: $.fn.addClass,
13456	addClass: function( classNames, speed, easing, callback ) {
13457		return speed ?
13458			$.effects.animateClass.call( this,
13459				{ add: classNames }, speed, easing, callback ) :
13460			this._addClass( classNames );
13461	},
13462
13463	_removeClass: $.fn.removeClass,
13464	removeClass: function( classNames, speed, easing, callback ) {
13465		return speed ?
13466			$.effects.animateClass.call( this,
13467				{ remove: classNames }, speed, easing, callback ) :
13468			this._removeClass( classNames );
13469	},
13470
13471	_toggleClass: $.fn.toggleClass,
13472	toggleClass: function( classNames, force, speed, easing, callback ) {
13473		if ( typeof force === "boolean" || force === undefined ) {
13474			if ( !speed ) {
13475				// without speed parameter
13476				return this._toggleClass( classNames, force );
13477			} else {
13478				return $.effects.animateClass.call( this,
13479					(force ? { add: classNames } : { remove: classNames }),
13480					speed, easing, callback );
13481			}
13482		} else {
13483			// without force parameter
13484			return $.effects.animateClass.call( this,
13485				{ toggle: classNames }, force, speed, easing );
13486		}
13487	},
13488
13489	switchClass: function( remove, add, speed, easing, callback) {
13490		return $.effects.animateClass.call( this, {
13491			add: add,
13492			remove: remove
13493		}, speed, easing, callback );
13494	}
13495});
13496
13497})();
13498
13499/******************************************************************************/
13500/*********************************** EFFECTS **********************************/
13501/******************************************************************************/
13502
13503(function() {
13504
13505$.extend( $.effects, {
13506	version: "1.9.2",
13507
13508	// Saves a set of properties in a data storage
13509	save: function( element, set ) {
13510		for( var i=0; i < set.length; i++ ) {
13511			if ( set[ i ] !== null ) {
13512				element.data( dataSpace + set[ i ], element[ 0 ].style[ set[ i ] ] );
13513			}
13514		}
13515	},
13516
13517	// Restores a set of previously saved properties from a data storage
13518	restore: function( element, set ) {
13519		var val, i;
13520		for( i=0; i < set.length; i++ ) {
13521			if ( set[ i ] !== null ) {
13522				val = element.data( dataSpace + set[ i ] );
13523				// support: jQuery 1.6.2
13524				// http://bugs.jquery.com/ticket/9917
13525				// jQuery 1.6.2 incorrectly returns undefined for any falsy value.
13526				// We can't differentiate between "" and 0 here, so we just assume
13527				// empty string since it's likely to be a more common value...
13528				if ( val === undefined ) {
13529					val = "";
13530				}
13531				element.css( set[ i ], val );
13532			}
13533		}
13534	},
13535
13536	setMode: function( el, mode ) {
13537		if (mode === "toggle") {
13538			mode = el.is( ":hidden" ) ? "show" : "hide";
13539		}
13540		return mode;
13541	},
13542
13543	// Translates a [top,left] array into a baseline value
13544	// this should be a little more flexible in the future to handle a string & hash
13545	getBaseline: function( origin, original ) {
13546		var y, x;
13547		switch ( origin[ 0 ] ) {
13548			case "top": y = 0; break;
13549			case "middle": y = 0.5; break;
13550			case "bottom": y = 1; break;
13551			default: y = origin[ 0 ] / original.height;
13552		}
13553		switch ( origin[ 1 ] ) {
13554			case "left": x = 0; break;
13555			case "center": x = 0.5; break;
13556			case "right": x = 1; break;
13557			default: x = origin[ 1 ] / original.width;
13558		}
13559		return {
13560			x: x,
13561			y: y
13562		};
13563	},
13564
13565	// Wraps the element around a wrapper that copies position properties
13566	createWrapper: function( element ) {
13567
13568		// if the element is already wrapped, return it
13569		if ( element.parent().is( ".ui-effects-wrapper" )) {
13570			return element.parent();
13571		}
13572
13573		// wrap the element
13574		var props = {
13575				width: element.outerWidth(true),
13576				height: element.outerHeight(true),
13577				"float": element.css( "float" )
13578			},
13579			wrapper = $( "<div></div>" )
13580				.addClass( "ui-effects-wrapper" )
13581				.css({
13582					fontSize: "100%",
13583					background: "transparent",
13584					border: "none",
13585					margin: 0,
13586					padding: 0
13587				}),
13588			// Store the size in case width/height are defined in % - Fixes #5245
13589			size = {
13590				width: element.width(),
13591				height: element.height()
13592			},
13593			active = document.activeElement;
13594
13595		// support: Firefox
13596		// Firefox incorrectly exposes anonymous content
13597		// https://bugzilla.mozilla.org/show_bug.cgi?id=561664
13598		try {
13599			active.id;
13600		} catch( e ) {
13601			active = document.body;
13602		}
13603
13604		element.wrap( wrapper );
13605
13606		// Fixes #7595 - Elements lose focus when wrapped.
13607		if ( element[ 0 ] === active || $.contains( element[ 0 ], active ) ) {
13608			$( active ).focus();
13609		}
13610
13611		wrapper = element.parent(); //Hotfix for jQuery 1.4 since some change in wrap() seems to actually lose the reference to the wrapped element
13612
13613		// transfer positioning properties to the wrapper
13614		if ( element.css( "position" ) === "static" ) {
13615			wrapper.css({ position: "relative" });
13616			element.css({ position: "relative" });
13617		} else {
13618			$.extend( props, {
13619				position: element.css( "position" ),
13620				zIndex: element.css( "z-index" )
13621			});
13622			$.each([ "top", "left", "bottom", "right" ], function(i, pos) {
13623				props[ pos ] = element.css( pos );
13624				if ( isNaN( parseInt( props[ pos ], 10 ) ) ) {
13625					props[ pos ] = "auto";
13626				}
13627			});
13628			element.css({
13629				position: "relative",
13630				top: 0,
13631				left: 0,
13632				right: "auto",
13633				bottom: "auto"
13634			});
13635		}
13636		element.css(size);
13637
13638		return wrapper.css( props ).show();
13639	},
13640
13641	removeWrapper: function( element ) {
13642		var active = document.activeElement;
13643
13644		if ( element.parent().is( ".ui-effects-wrapper" ) ) {
13645			element.parent().replaceWith( element );
13646
13647			// Fixes #7595 - Elements lose focus when wrapped.
13648			if ( element[ 0 ] === active || $.contains( element[ 0 ], active ) ) {
13649				$( active ).focus();
13650			}
13651		}
13652
13653
13654		return element;
13655	},
13656
13657	setTransition: function( element, list, factor, value ) {
13658		value = value || {};
13659		$.each( list, function( i, x ) {
13660			var unit = element.cssUnit( x );
13661			if ( unit[ 0 ] > 0 ) {
13662				value[ x ] = unit[ 0 ] * factor + unit[ 1 ];
13663			}
13664		});
13665		return value;
13666	}
13667});
13668
13669// return an effect options object for the given parameters:
13670function _normalizeArguments( effect, options, speed, callback ) {
13671
13672	// allow passing all options as the first parameter
13673	if ( $.isPlainObject( effect ) ) {
13674		options = effect;
13675		effect = effect.effect;
13676	}
13677
13678	// convert to an object
13679	effect = { effect: effect };
13680
13681	// catch (effect, null, ...)
13682	if ( options == null ) {
13683		options = {};
13684	}
13685
13686	// catch (effect, callback)
13687	if ( $.isFunction( options ) ) {
13688		callback = options;
13689		speed = null;
13690		options = {};
13691	}
13692
13693	// catch (effect, speed, ?)
13694	if ( typeof options === "number" || $.fx.speeds[ options ] ) {
13695		callback = speed;
13696		speed = options;
13697		options = {};
13698	}
13699
13700	// catch (effect, options, callback)
13701	if ( $.isFunction( speed ) ) {
13702		callback = speed;
13703		speed = null;
13704	}
13705
13706	// add options to effect
13707	if ( options ) {
13708		$.extend( effect, options );
13709	}
13710
13711	speed = speed || options.duration;
13712	effect.duration = $.fx.off ? 0 :
13713		typeof speed === "number" ? speed :
13714		speed in $.fx.speeds ? $.fx.speeds[ speed ] :
13715		$.fx.speeds._default;
13716
13717	effect.complete = callback || options.complete;
13718
13719	return effect;
13720}
13721
13722function standardSpeed( speed ) {
13723	// valid standard speeds
13724	if ( !speed || typeof speed === "number" || $.fx.speeds[ speed ] ) {
13725		return true;
13726	}
13727
13728	// invalid strings - treat as "normal" speed
13729	if ( typeof speed === "string" && !$.effects.effect[ speed ] ) {
13730		// TODO: remove in 2.0 (#7115)
13731		if ( backCompat && $.effects[ speed ] ) {
13732			return false;
13733		}
13734		return true;
13735	}
13736
13737	return false;
13738}
13739
13740$.fn.extend({
13741	effect: function( /* effect, options, speed, callback */ ) {
13742		var args = _normalizeArguments.apply( this, arguments ),
13743			mode = args.mode,
13744			queue = args.queue,
13745			effectMethod = $.effects.effect[ args.effect ],
13746
13747			// DEPRECATED: remove in 2.0 (#7115)
13748			oldEffectMethod = !effectMethod && backCompat && $.effects[ args.effect ];
13749
13750		if ( $.fx.off || !( effectMethod || oldEffectMethod ) ) {
13751			// delegate to the original method (e.g., .show()) if possible
13752			if ( mode ) {
13753				return this[ mode ]( args.duration, args.complete );
13754			} else {
13755				return this.each( function() {
13756					if ( args.complete ) {
13757						args.complete.call( this );
13758					}
13759				});
13760			}
13761		}
13762
13763		function run( next ) {
13764			var elem = $( this ),
13765				complete = args.complete,
13766				mode = args.mode;
13767
13768			function done() {
13769				if ( $.isFunction( complete ) ) {
13770					complete.call( elem[0] );
13771				}
13772				if ( $.isFunction( next ) ) {
13773					next();
13774				}
13775			}
13776
13777			// if the element is hiddden and mode is hide,
13778			// or element is visible and mode is show
13779			if ( elem.is( ":hidden" ) ? mode === "hide" : mode === "show" ) {
13780				done();
13781			} else {
13782				effectMethod.call( elem[0], args, done );
13783			}
13784		}
13785
13786		// TODO: remove this check in 2.0, effectMethod will always be true
13787		if ( effectMethod ) {
13788			return queue === false ? this.each( run ) : this.queue( queue || "fx", run );
13789		} else {
13790			// DEPRECATED: remove in 2.0 (#7115)
13791			return oldEffectMethod.call(this, {
13792				options: args,
13793				duration: args.duration,
13794				callback: args.complete,
13795				mode: args.mode
13796			});
13797		}
13798	},
13799
13800	_show: $.fn.show,
13801	show: function( speed ) {
13802		if ( standardSpeed( speed ) ) {
13803			return this._show.apply( this, arguments );
13804		} else {
13805			var args = _normalizeArguments.apply( this, arguments );
13806			args.mode = "show";
13807			return this.effect.call( this, args );
13808		}
13809	},
13810
13811	_hide: $.fn.hide,
13812	hide: function( speed ) {
13813		if ( standardSpeed( speed ) ) {
13814			return this._hide.apply( this, arguments );
13815		} else {
13816			var args = _normalizeArguments.apply( this, arguments );
13817			args.mode = "hide";
13818			return this.effect.call( this, args );
13819		}
13820	},
13821
13822	// jQuery core overloads toggle and creates _toggle
13823	__toggle: $.fn.toggle,
13824	toggle: function( speed ) {
13825		if ( standardSpeed( speed ) || typeof speed === "boolean" || $.isFunction( speed ) ) {
13826			return this.__toggle.apply( this, arguments );
13827		} else {
13828			var args = _normalizeArguments.apply( this, arguments );
13829			args.mode = "toggle";
13830			return this.effect.call( this, args );
13831		}
13832	},
13833
13834	// helper functions
13835	cssUnit: function(key) {
13836		var style = this.css( key ),
13837			val = [];
13838
13839		$.each( [ "em", "px", "%", "pt" ], function( i, unit ) {
13840			if ( style.indexOf( unit ) > 0 ) {
13841				val = [ parseFloat( style ), unit ];
13842			}
13843		});
13844		return val;
13845	}
13846});
13847
13848})();
13849
13850/******************************************************************************/
13851/*********************************** EASING ***********************************/
13852/******************************************************************************/
13853
13854(function() {
13855
13856// based on easing equations from Robert Penner (http://www.robertpenner.com/easing)
13857
13858var baseEasings = {};
13859
13860$.each( [ "Quad", "Cubic", "Quart", "Quint", "Expo" ], function( i, name ) {
13861	baseEasings[ name ] = function( p ) {
13862		return Math.pow( p, i + 2 );
13863	};
13864});
13865
13866$.extend( baseEasings, {
13867	Sine: function ( p ) {
13868		return 1 - Math.cos( p * Math.PI / 2 );
13869	},
13870	Circ: function ( p ) {
13871		return 1 - Math.sqrt( 1 - p * p );
13872	},
13873	Elastic: function( p ) {
13874		return p === 0 || p === 1 ? p :
13875			-Math.pow( 2, 8 * (p - 1) ) * Math.sin( ( (p - 1) * 80 - 7.5 ) * Math.PI / 15 );
13876	},
13877	Back: function( p ) {
13878		return p * p * ( 3 * p - 2 );
13879	},
13880	Bounce: function ( p ) {
13881		var pow2,
13882			bounce = 4;
13883
13884		while ( p < ( ( pow2 = Math.pow( 2, --bounce ) ) - 1 ) / 11 ) {}
13885		return 1 / Math.pow( 4, 3 - bounce ) - 7.5625 * Math.pow( ( pow2 * 3 - 2 ) / 22 - p, 2 );
13886	}
13887});
13888
13889$.each( baseEasings, function( name, easeIn ) {
13890	$.easing[ "easeIn" + name ] = easeIn;
13891	$.easing[ "easeOut" + name ] = function( p ) {
13892		return 1 - easeIn( 1 - p );
13893	};
13894	$.easing[ "easeInOut" + name ] = function( p ) {
13895		return p < 0.5 ?
13896			easeIn( p * 2 ) / 2 :
13897			1 - easeIn( p * -2 + 2 ) / 2;
13898	};
13899});
13900
13901})();
13902
13903})(jQuery));
13904(function( $, undefined ) {
13905
13906var rvertical = /up|down|vertical/,
13907	rpositivemotion = /up|left|vertical|horizontal/;
13908
13909$.effects.effect.blind = function( o, done ) {
13910	// Create element
13911	var el = $( this ),
13912		props = [ "position", "top", "bottom", "left", "right", "height", "width" ],
13913		mode = $.effects.setMode( el, o.mode || "hide" ),
13914		direction = o.direction || "up",
13915		vertical = rvertical.test( direction ),
13916		ref = vertical ? "height" : "width",
13917		ref2 = vertical ? "top" : "left",
13918		motion = rpositivemotion.test( direction ),
13919		animation = {},
13920		show = mode === "show",
13921		wrapper, distance, margin;
13922
13923	// if already wrapped, the wrapper's properties are my property. #6245
13924	if ( el.parent().is( ".ui-effects-wrapper" ) ) {
13925		$.effects.save( el.parent(), props );
13926	} else {
13927		$.effects.save( el, props );
13928	}
13929	el.show();
13930	wrapper = $.effects.createWrapper( el ).css({
13931		overflow: "hidden"
13932	});
13933
13934	distance = wrapper[ ref ]();
13935	margin = parseFloat( wrapper.css( ref2 ) ) || 0;
13936
13937	animation[ ref ] = show ? distance : 0;
13938	if ( !motion ) {
13939		el
13940			.css( vertical ? "bottom" : "right", 0 )
13941			.css( vertical ? "top" : "left", "auto" )
13942			.css({ position: "absolute" });
13943
13944		animation[ ref2 ] = show ? margin : distance + margin;
13945	}
13946
13947	// start at 0 if we are showing
13948	if ( show ) {
13949		wrapper.css( ref, 0 );
13950		if ( ! motion ) {
13951			wrapper.css( ref2, margin + distance );
13952		}
13953	}
13954
13955	// Animate
13956	wrapper.animate( animation, {
13957		duration: o.duration,
13958		easing: o.easing,
13959		queue: false,
13960		complete: function() {
13961			if ( mode === "hide" ) {
13962				el.hide();
13963			}
13964			$.effects.restore( el, props );
13965			$.effects.removeWrapper( el );
13966			done();
13967		}
13968	});
13969
13970};
13971
13972})(jQuery);
13973(function( $, undefined ) {
13974
13975$.effects.effect.bounce = function( o, done ) {
13976	var el = $( this ),
13977		props = [ "position", "top", "bottom", "left", "right", "height", "width" ],
13978
13979		// defaults:
13980		mode = $.effects.setMode( el, o.mode || "effect" ),
13981		hide = mode === "hide",
13982		show = mode === "show",
13983		direction = o.direction || "up",
13984		distance = o.distance,
13985		times = o.times || 5,
13986
13987		// number of internal animations
13988		anims = times * 2 + ( show || hide ? 1 : 0 ),
13989		speed = o.duration / anims,
13990		easing = o.easing,
13991
13992		// utility:
13993		ref = ( direction === "up" || direction === "down" ) ? "top" : "left",
13994		motion = ( direction === "up" || direction === "left" ),
13995		i,
13996		upAnim,
13997		downAnim,
13998
13999		// we will need to re-assemble the queue to stack our animations in place
14000		queue = el.queue(),
14001		queuelen = queue.length;
14002
14003	// Avoid touching opacity to prevent clearType and PNG issues in IE
14004	if ( show || hide ) {
14005		props.push( "opacity" );
14006	}
14007
14008	$.effects.save( el, props );
14009	el.show();
14010	$.effects.createWrapper( el ); // Create Wrapper
14011
14012	// default distance for the BIGGEST bounce is the outer Distance / 3
14013	if ( !distance ) {
14014		distance = el[ ref === "top" ? "outerHeight" : "outerWidth" ]() / 3;
14015	}
14016
14017	if ( show ) {
14018		downAnim = { opacity: 1 };
14019		downAnim[ ref ] = 0;
14020
14021		// if we are showing, force opacity 0 and set the initial position
14022		// then do the "first" animation
14023		el.css( "opacity", 0 )
14024			.css( ref, motion ? -distance * 2 : distance * 2 )
14025			.animate( downAnim, speed, easing );
14026	}
14027
14028	// start at the smallest distance if we are hiding
14029	if ( hide ) {
14030		distance = distance / Math.pow( 2, times - 1 );
14031	}
14032
14033	downAnim = {};
14034	downAnim[ ref ] = 0;
14035	// Bounces up/down/left/right then back to 0 -- times * 2 animations happen here
14036	for ( i = 0; i < times; i++ ) {
14037		upAnim = {};
14038		upAnim[ ref ] = ( motion ? "-=" : "+=" ) + distance;
14039
14040		el.animate( upAnim, speed, easing )
14041			.animate( downAnim, speed, easing );
14042
14043		distance = hide ? distance * 2 : distance / 2;
14044	}
14045
14046	// Last Bounce when Hiding
14047	if ( hide ) {
14048		upAnim = { opacity: 0 };
14049		upAnim[ ref ] = ( motion ? "-=" : "+=" ) + distance;
14050
14051		el.animate( upAnim, speed, easing );
14052	}
14053
14054	el.queue(function() {
14055		if ( hide ) {
14056			el.hide();
14057		}
14058		$.effects.restore( el, props );
14059		$.effects.removeWrapper( el );
14060		done();
14061	});
14062
14063	// inject all the animations we just queued to be first in line (after "inprogress")
14064	if ( queuelen > 1) {
14065		queue.splice.apply( queue,
14066			[ 1, 0 ].concat( queue.splice( queuelen, anims + 1 ) ) );
14067	}
14068	el.dequeue();
14069
14070};
14071
14072})(jQuery);
14073(function( $, undefined ) {
14074
14075$.effects.effect.clip = function( o, done ) {
14076	// Create element
14077	var el = $( this ),
14078		props = [ "position", "top", "bottom", "left", "right", "height", "width" ],
14079		mode = $.effects.setMode( el, o.mode || "hide" ),
14080		show = mode === "show",
14081		direction = o.direction || "vertical",
14082		vert = direction === "vertical",
14083		size = vert ? "height" : "width",
14084		position = vert ? "top" : "left",
14085		animation = {},
14086		wrapper, animate, distance;
14087
14088	// Save & Show
14089	$.effects.save( el, props );
14090	el.show();
14091
14092	// Create Wrapper
14093	wrapper = $.effects.createWrapper( el ).css({
14094		overflow: "hidden"
14095	});
14096	animate = ( el[0].tagName === "IMG" ) ? wrapper : el;
14097	distance = animate[ size ]();
14098
14099	// Shift
14100	if ( show ) {
14101		animate.css( size, 0 );
14102		animate.css( position, distance / 2 );
14103	}
14104
14105	// Create Animation Object:
14106	animation[ size ] = show ? distance : 0;
14107	animation[ position ] = show ? 0 : distance / 2;
14108
14109	// Animate
14110	animate.animate( animation, {
14111		queue: false,
14112		duration: o.duration,
14113		easing: o.easing,
14114		complete: function() {
14115			if ( !show ) {
14116				el.hide();
14117			}
14118			$.effects.restore( el, props );
14119			$.effects.removeWrapper( el );
14120			done();
14121		}
14122	});
14123
14124};
14125
14126})(jQuery);
14127(function( $, undefined ) {
14128
14129$.effects.effect.drop = function( o, done ) {
14130
14131	var el = $( this ),
14132		props = [ "position", "top", "bottom", "left", "right", "opacity", "height", "width" ],
14133		mode = $.effects.setMode( el, o.mode || "hide" ),
14134		show = mode === "show",
14135		direction = o.direction || "left",
14136		ref = ( direction === "up" || direction === "down" ) ? "top" : "left",
14137		motion = ( direction === "up" || direction === "left" ) ? "pos" : "neg",
14138		animation = {
14139			opacity: show ? 1 : 0
14140		},
14141		distance;
14142
14143	// Adjust
14144	$.effects.save( el, props );
14145	el.show();
14146	$.effects.createWrapper( el );
14147
14148	distance = o.distance || el[ ref === "top" ? "outerHeight": "outerWidth" ]( true ) / 2;
14149
14150	if ( show ) {
14151		el
14152			.css( "opacity", 0 )
14153			.css( ref, motion === "pos" ? -distance : distance );
14154	}
14155
14156	// Animation
14157	animation[ ref ] = ( show ?
14158		( motion === "pos" ? "+=" : "-=" ) :
14159		( motion === "pos" ? "-=" : "+=" ) ) +
14160		distance;
14161
14162	// Animate
14163	el.animate( animation, {
14164		queue: false,
14165		duration: o.duration,
14166		easing: o.easing,
14167		complete: function() {
14168			if ( mode === "hide" ) {
14169				el.hide();
14170			}
14171			$.effects.restore( el, props );
14172			$.effects.removeWrapper( el );
14173			done();
14174		}
14175	});
14176};
14177
14178})(jQuery);
14179(function( $, undefined ) {
14180
14181$.effects.effect.explode = function( o, done ) {
14182
14183	var rows = o.pieces ? Math.round( Math.sqrt( o.pieces ) ) : 3,
14184		cells = rows,
14185		el = $( this ),
14186		mode = $.effects.setMode( el, o.mode || "hide" ),
14187		show = mode === "show",
14188
14189		// show and then visibility:hidden the element before calculating offset
14190		offset = el.show().css( "visibility", "hidden" ).offset(),
14191
14192		// width and height of a piece
14193		width = Math.ceil( el.outerWidth() / cells ),
14194		height = Math.ceil( el.outerHeight() / rows ),
14195		pieces = [],
14196
14197		// loop
14198		i, j, left, top, mx, my;
14199
14200	// children animate complete:
14201	function childComplete() {
14202		pieces.push( this );
14203		if ( pieces.length === rows * cells ) {
14204			animComplete();
14205		}
14206	}
14207
14208	// clone the element for each row and cell.
14209	for( i = 0; i < rows ; i++ ) { // ===>
14210		top = offset.top + i * height;
14211		my = i - ( rows - 1 ) / 2 ;
14212
14213		for( j = 0; j < cells ; j++ ) { // |||
14214			left = offset.left + j * width;
14215			mx = j - ( cells - 1 ) / 2 ;
14216
14217			// Create a clone of the now hidden main element that will be absolute positioned
14218			// within a wrapper div off the -left and -top equal to size of our pieces
14219			el
14220				.clone()
14221				.appendTo( "body" )
14222				.wrap( "<div></div>" )
14223				.css({
14224					position: "absolute",
14225					visibility: "visible",
14226					left: -j * width,
14227					top: -i * height
14228				})
14229
14230			// select the wrapper - make it overflow: hidden and absolute positioned based on
14231			// where the original was located +left and +top equal to the size of pieces
14232				.parent()
14233				.addClass( "ui-effects-explode" )
14234				.css({
14235					position: "absolute",
14236					overflow: "hidden",
14237					width: width,
14238					height: height,
14239					left: left + ( show ? mx * width : 0 ),
14240					top: top + ( show ? my * height : 0 ),
14241					opacity: show ? 0 : 1
14242				}).animate({
14243					left: left + ( show ? 0 : mx * width ),
14244					top: top + ( show ? 0 : my * height ),
14245					opacity: show ? 1 : 0
14246				}, o.duration || 500, o.easing, childComplete );
14247		}
14248	}
14249
14250	function animComplete() {
14251		el.css({
14252			visibility: "visible"
14253		});
14254		$( pieces ).remove();
14255		if ( !show ) {
14256			el.hide();
14257		}
14258		done();
14259	}
14260};
14261
14262})(jQuery);
14263(function( $, undefined ) {
14264
14265$.effects.effect.fade = function( o, done ) {
14266	var el = $( this ),
14267		mode = $.effects.setMode( el, o.mode || "toggle" );
14268
14269	el.animate({
14270		opacity: mode
14271	}, {
14272		queue: false,
14273		duration: o.duration,
14274		easing: o.easing,
14275		complete: done
14276	});
14277};
14278
14279})( jQuery );
14280(function( $, undefined ) {
14281
14282$.effects.effect.fold = function( o, done ) {
14283
14284	// Create element
14285	var el = $( this ),
14286		props = [ "position", "top", "bottom", "left", "right", "height", "width" ],
14287		mode = $.effects.setMode( el, o.mode || "hide" ),
14288		show = mode === "show",
14289		hide = mode === "hide",
14290		size = o.size || 15,
14291		percent = /([0-9]+)%/.exec( size ),
14292		horizFirst = !!o.horizFirst,
14293		widthFirst = show !== horizFirst,
14294		ref = widthFirst ? [ "width", "height" ] : [ "height", "width" ],
14295		duration = o.duration / 2,
14296		wrapper, distance,
14297		animation1 = {},
14298		animation2 = {};
14299
14300	$.effects.save( el, props );
14301	el.show();
14302
14303	// Create Wrapper
14304	wrapper = $.effects.createWrapper( el ).css({
14305		overflow: "hidden"
14306	});
14307	distance = widthFirst ?
14308		[ wrapper.width(), wrapper.height() ] :
14309		[ wrapper.height(), wrapper.width() ];
14310
14311	if ( percent ) {
14312		size = parseInt( percent[ 1 ], 10 ) / 100 * distance[ hide ? 0 : 1 ];
14313	}
14314	if ( show ) {
14315		wrapper.css( horizFirst ? {
14316			height: 0,
14317			width: size
14318		} : {
14319			height: size,
14320			width: 0
14321		});
14322	}
14323
14324	// Animation
14325	animation1[ ref[ 0 ] ] = show ? distance[ 0 ] : size;
14326	animation2[ ref[ 1 ] ] = show ? distance[ 1 ] : 0;
14327
14328	// Animate
14329	wrapper
14330		.animate( animation1, duration, o.easing )
14331		.animate( animation2, duration, o.easing, function() {
14332			if ( hide ) {
14333				el.hide();
14334			}
14335			$.effects.restore( el, props );
14336			$.effects.removeWrapper( el );
14337			done();
14338		});
14339
14340};
14341
14342})(jQuery);
14343(function( $, undefined ) {
14344
14345$.effects.effect.highlight = function( o, done ) {
14346	var elem = $( this ),
14347		props = [ "backgroundImage", "backgroundColor", "opacity" ],
14348		mode = $.effects.setMode( elem, o.mode || "show" ),
14349		animation = {
14350			backgroundColor: elem.css( "backgroundColor" )
14351		};
14352
14353	if (mode === "hide") {
14354		animation.opacity = 0;
14355	}
14356
14357	$.effects.save( elem, props );
14358
14359	elem
14360		.show()
14361		.css({
14362			backgroundImage: "none",
14363			backgroundColor: o.color || "#ffff99"
14364		})
14365		.animate( animation, {
14366			queue: false,
14367			duration: o.duration,
14368			easing: o.easing,
14369			complete: function() {
14370				if ( mode === "hide" ) {
14371					elem.hide();
14372				}
14373				$.effects.restore( elem, props );
14374				done();
14375			}
14376		});
14377};
14378
14379})(jQuery);
14380(function( $, undefined ) {
14381
14382$.effects.effect.pulsate = function( o, done ) {
14383	var elem = $( this ),
14384		mode = $.effects.setMode( elem, o.mode || "show" ),
14385		show = mode === "show",
14386		hide = mode === "hide",
14387		showhide = ( show || mode === "hide" ),
14388
14389		// showing or hiding leaves of the "last" animation
14390		anims = ( ( o.times || 5 ) * 2 ) + ( showhide ? 1 : 0 ),
14391		duration = o.duration / anims,
14392		animateTo = 0,
14393		queue = elem.queue(),
14394		queuelen = queue.length,
14395		i;
14396
14397	if ( show || !elem.is(":visible")) {
14398		elem.css( "opacity", 0 ).show();
14399		animateTo = 1;
14400	}
14401
14402	// anims - 1 opacity "toggles"
14403	for ( i = 1; i < anims; i++ ) {
14404		elem.animate({
14405			opacity: animateTo
14406		}, duration, o.easing );
14407		animateTo = 1 - animateTo;
14408	}
14409
14410	elem.animate({
14411		opacity: animateTo
14412	}, duration, o.easing);
14413
14414	elem.queue(function() {
14415		if ( hide ) {
14416			elem.hide();
14417		}
14418		done();
14419	});
14420
14421	// We just queued up "anims" animations, we need to put them next in the queue
14422	if ( queuelen > 1 ) {
14423		queue.splice.apply( queue,
14424			[ 1, 0 ].concat( queue.splice( queuelen, anims + 1 ) ) );
14425	}
14426	elem.dequeue();
14427};
14428
14429})(jQuery);
14430(function( $, undefined ) {
14431
14432$.effects.effect.puff = function( o, done ) {
14433	var elem = $( this ),
14434		mode = $.effects.setMode( elem, o.mode || "hide" ),
14435		hide = mode === "hide",
14436		percent = parseInt( o.percent, 10 ) || 150,
14437		factor = percent / 100,
14438		original = {
14439			height: elem.height(),
14440			width: elem.width(),
14441			outerHeight: elem.outerHeight(),
14442			outerWidth: elem.outerWidth()
14443		};
14444
14445	$.extend( o, {
14446		effect: "scale",
14447		queue: false,
14448		fade: true,
14449		mode: mode,
14450		complete: done,
14451		percent: hide ? percent : 100,
14452		from: hide ?
14453			original :
14454			{
14455				height: original.height * factor,
14456				width: original.width * factor,
14457				outerHeight: original.outerHeight * factor,
14458				outerWidth: original.outerWidth * factor
14459			}
14460	});
14461
14462	elem.effect( o );
14463};
14464
14465$.effects.effect.scale = function( o, done ) {
14466
14467	// Create element
14468	var el = $( this ),
14469		options = $.extend( true, {}, o ),
14470		mode = $.effects.setMode( el, o.mode || "effect" ),
14471		percent = parseInt( o.percent, 10 ) ||
14472			( parseInt( o.percent, 10 ) === 0 ? 0 : ( mode === "hide" ? 0 : 100 ) ),
14473		direction = o.direction || "both",
14474		origin = o.origin,
14475		original = {
14476			height: el.height(),
14477			width: el.width(),
14478			outerHeight: el.outerHeight(),
14479			outerWidth: el.outerWidth()
14480		},
14481		factor = {
14482			y: direction !== "horizontal" ? (percent / 100) : 1,
14483			x: direction !== "vertical" ? (percent / 100) : 1
14484		};
14485
14486	// We are going to pass this effect to the size effect:
14487	options.effect = "size";
14488	options.queue = false;
14489	options.complete = done;
14490
14491	// Set default origin and restore for show/hide
14492	if ( mode !== "effect" ) {
14493		options.origin = origin || ["middle","center"];
14494		options.restore = true;
14495	}
14496
14497	options.from = o.from || ( mode === "show" ? {
14498		height: 0,
14499		width: 0,
14500		outerHeight: 0,
14501		outerWidth: 0
14502	} : original );
14503	options.to = {
14504		height: original.height * factor.y,
14505		width: original.width * factor.x,
14506		outerHeight: original.outerHeight * factor.y,
14507		outerWidth: original.outerWidth * factor.x
14508	};
14509
14510	// Fade option to support puff
14511	if ( options.fade ) {
14512		if ( mode === "show" ) {
14513			options.from.opacity = 0;
14514			options.to.opacity = 1;
14515		}
14516		if ( mode === "hide" ) {
14517			options.from.opacity = 1;
14518			options.to.opacity = 0;
14519		}
14520	}
14521
14522	// Animate
14523	el.effect( options );
14524
14525};
14526
14527$.effects.effect.size = function( o, done ) {
14528
14529	// Create element
14530	var original, baseline, factor,
14531		el = $( this ),
14532		props0 = [ "position", "top", "bottom", "left", "right", "width", "height", "overflow", "opacity" ],
14533
14534		// Always restore
14535		props1 = [ "position", "top", "bottom", "left", "right", "overflow", "opacity" ],
14536
14537		// Copy for children
14538		props2 = [ "width", "height", "overflow" ],
14539		cProps = [ "fontSize" ],
14540		vProps = [ "borderTopWidth", "borderBottomWidth", "paddingTop", "paddingBottom" ],
14541		hProps = [ "borderLeftWidth", "borderRightWidth", "paddingLeft", "paddingRight" ],
14542
14543		// Set options
14544		mode = $.effects.setMode( el, o.mode || "effect" ),
14545		restore = o.restore || mode !== "effect",
14546		scale = o.scale || "both",
14547		origin = o.origin || [ "middle", "center" ],
14548		position = el.css( "position" ),
14549		props = restore ? props0 : props1,
14550		zero = {
14551			height: 0,
14552			width: 0,
14553			outerHeight: 0,
14554			outerWidth: 0
14555		};
14556
14557	if ( mode === "show" ) {
14558		el.show();
14559	}
14560	original = {
14561		height: el.height(),
14562		width: el.width(),
14563		outerHeight: el.outerHeight(),
14564		outerWidth: el.outerWidth()
14565	};
14566
14567	if ( o.mode === "toggle" && mode === "show" ) {
14568		el.from = o.to || zero;
14569		el.to = o.from || original;
14570	} else {
14571		el.from = o.from || ( mode === "show" ? zero : original );
14572		el.to = o.to || ( mode === "hide" ? zero : original );
14573	}
14574
14575	// Set scaling factor
14576	factor = {
14577		from: {
14578			y: el.from.height / original.height,
14579			x: el.from.width / original.width
14580		},
14581		to: {
14582			y: el.to.height / original.height,
14583			x: el.to.width / original.width
14584		}
14585	};
14586
14587	// Scale the css box
14588	if ( scale === "box" || scale === "both" ) {
14589
14590		// Vertical props scaling
14591		if ( factor.from.y !== factor.to.y ) {
14592			props = props.concat( vProps );
14593			el.from = $.effects.setTransition( el, vProps, factor.from.y, el.from );
14594			el.to = $.effects.setTransition( el, vProps, factor.to.y, el.to );
14595		}
14596
14597		// Horizontal props scaling
14598		if ( factor.from.x !== factor.to.x ) {
14599			props = props.concat( hProps );
14600			el.from = $.effects.setTransition( el, hProps, factor.from.x, el.from );
14601			el.to = $.effects.setTransition( el, hProps, factor.to.x, el.to );
14602		}
14603	}
14604
14605	// Scale the content
14606	if ( scale === "content" || scale === "both" ) {
14607
14608		// Vertical props scaling
14609		if ( factor.from.y !== factor.to.y ) {
14610			props = props.concat( cProps ).concat( props2 );
14611			el.from = $.effects.setTransition( el, cProps, factor.from.y, el.from );
14612			el.to = $.effects.setTransition( el, cProps, factor.to.y, el.to );
14613		}
14614	}
14615
14616	$.effects.save( el, props );
14617	el.show();
14618	$.effects.createWrapper( el );
14619	el.css( "overflow", "hidden" ).css( el.from );
14620
14621	// Adjust
14622	if (origin) { // Calculate baseline shifts
14623		baseline = $.effects.getBaseline( origin, original );
14624		el.from.top = ( original.outerHeight - el.outerHeight() ) * baseline.y;
14625		el.from.left = ( original.outerWidth - el.outerWidth() ) * baseline.x;
14626		el.to.top = ( original.outerHeight - el.to.outerHeight ) * baseline.y;
14627		el.to.left = ( original.outerWidth - el.to.outerWidth ) * baseline.x;
14628	}
14629	el.css( el.from ); // set top & left
14630
14631	// Animate
14632	if ( scale === "content" || scale === "both" ) { // Scale the children
14633
14634		// Add margins/font-size
14635		vProps = vProps.concat([ "marginTop", "marginBottom" ]).concat(cProps);
14636		hProps = hProps.concat([ "marginLeft", "marginRight" ]);
14637		props2 = props0.concat(vProps).concat(hProps);
14638
14639		el.find( "*[width]" ).each( function(){
14640			var child = $( this ),
14641				c_original = {
14642					height: child.height(),
14643					width: child.width(),
14644					outerHeight: child.outerHeight(),
14645					outerWidth: child.outerWidth()
14646				};
14647			if (restore) {
14648				$.effects.save(child, props2);
14649			}
14650
14651			child.from = {
14652				height: c_original.height * factor.from.y,
14653				width: c_original.width * factor.from.x,
14654				outerHeight: c_original.outerHeight * factor.from.y,
14655				outerWidth: c_original.outerWidth * factor.from.x
14656			};
14657			child.to = {
14658				height: c_original.height * factor.to.y,
14659				width: c_original.width * factor.to.x,
14660				outerHeight: c_original.height * factor.to.y,
14661				outerWidth: c_original.width * factor.to.x
14662			};
14663
14664			// Vertical props scaling
14665			if ( factor.from.y !== factor.to.y ) {
14666				child.from = $.effects.setTransition( child, vProps, factor.from.y, child.from );
14667				child.to = $.effects.setTransition( child, vProps, factor.to.y, child.to );
14668			}
14669
14670			// Horizontal props scaling
14671			if ( factor.from.x !== factor.to.x ) {
14672				child.from = $.effects.setTransition( child, hProps, factor.from.x, child.from );
14673				child.to = $.effects.setTransition( child, hProps, factor.to.x, child.to );
14674			}
14675
14676			// Animate children
14677			child.css( child.from );
14678			child.animate( child.to, o.duration, o.easing, function() {
14679
14680				// Restore children
14681				if ( restore ) {
14682					$.effects.restore( child, props2 );
14683				}
14684			});
14685		});
14686	}
14687
14688	// Animate
14689	el.animate( el.to, {
14690		queue: false,
14691		duration: o.duration,
14692		easing: o.easing,
14693		complete: function() {
14694			if ( el.to.opacity === 0 ) {
14695				el.css( "opacity", el.from.opacity );
14696			}
14697			if( mode === "hide" ) {
14698				el.hide();
14699			}
14700			$.effects.restore( el, props );
14701			if ( !restore ) {
14702
14703				// we need to calculate our new positioning based on the scaling
14704				if ( position === "static" ) {
14705					el.css({
14706						position: "relative",
14707						top: el.to.top,
14708						left: el.to.left
14709					});
14710				} else {
14711					$.each([ "top", "left" ], function( idx, pos ) {
14712						el.css( pos, function( _, str ) {
14713							var val = parseInt( str, 10 ),
14714								toRef = idx ? el.to.left : el.to.top;
14715
14716							// if original was "auto", recalculate the new value from wrapper
14717							if ( str === "auto" ) {
14718								return toRef + "px";
14719							}
14720
14721							return val + toRef + "px";
14722						});
14723					});
14724				}
14725			}
14726
14727			$.effects.removeWrapper( el );
14728			done();
14729		}
14730	});
14731
14732};
14733
14734})(jQuery);
14735(function( $, undefined ) {
14736
14737$.effects.effect.shake = function( o, done ) {
14738
14739	var el = $( this ),
14740		props = [ "position", "top", "bottom", "left", "right", "height", "width" ],
14741		mode = $.effects.setMode( el, o.mode || "effect" ),
14742		direction = o.direction || "left",
14743		distance = o.distance || 20,
14744		times = o.times || 3,
14745		anims = times * 2 + 1,
14746		speed = Math.round(o.duration/anims),
14747		ref = (direction === "up" || direction === "down") ? "top" : "left",
14748		positiveMotion = (direction === "up" || direction === "left"),
14749		animation = {},
14750		animation1 = {},
14751		animation2 = {},
14752		i,
14753
14754		// we will need to re-assemble the queue to stack our animations in place
14755		queue = el.queue(),
14756		queuelen = queue.length;
14757
14758	$.effects.save( el, props );
14759	el.show();
14760	$.effects.createWrapper( el );
14761
14762	// Animation
14763	animation[ ref ] = ( positiveMotion ? "-=" : "+=" ) + distance;
14764	animation1[ ref ] = ( positiveMotion ? "+=" : "-=" ) + distance * 2;
14765	animation2[ ref ] = ( positiveMotion ? "-=" : "+=" ) + distance * 2;
14766
14767	// Animate
14768	el.animate( animation, speed, o.easing );
14769
14770	// Shakes
14771	for ( i = 1; i < times; i++ ) {
14772		el.animate( animation1, speed, o.easing ).animate( animation2, speed, o.easing );
14773	}
14774	el
14775		.animate( animation1, speed, o.easing )
14776		.animate( animation, speed / 2, o.easing )
14777		.queue(function() {
14778			if ( mode === "hide" ) {
14779				el.hide();
14780			}
14781			$.effects.restore( el, props );
14782			$.effects.removeWrapper( el );
14783			done();
14784		});
14785
14786	// inject all the animations we just queued to be first in line (after "inprogress")
14787	if ( queuelen > 1) {
14788		queue.splice.apply( queue,
14789			[ 1, 0 ].concat( queue.splice( queuelen, anims + 1 ) ) );
14790	}
14791	el.dequeue();
14792
14793};
14794
14795})(jQuery);
14796(function( $, undefined ) {
14797
14798$.effects.effect.slide = function( o, done ) {
14799
14800	// Create element
14801	var el = $( this ),
14802		props = [ "position", "top", "bottom", "left", "right", "width", "height" ],
14803		mode = $.effects.setMode( el, o.mode || "show" ),
14804		show = mode === "show",
14805		direction = o.direction || "left",
14806		ref = (direction === "up" || direction === "down") ? "top" : "left",
14807		positiveMotion = (direction === "up" || direction === "left"),
14808		distance,
14809		animation = {};
14810
14811	// Adjust
14812	$.effects.save( el, props );
14813	el.show();
14814	distance = o.distance || el[ ref === "top" ? "outerHeight" : "outerWidth" ]( true );
14815
14816	$.effects.createWrapper( el ).css({
14817		overflow: "hidden"
14818	});
14819
14820	if ( show ) {
14821		el.css( ref, positiveMotion ? (isNaN(distance) ? "-" + distance : -distance) : distance );
14822	}
14823
14824	// Animation
14825	animation[ ref ] = ( show ?
14826		( positiveMotion ? "+=" : "-=") :
14827		( positiveMotion ? "-=" : "+=")) +
14828		distance;
14829
14830	// Animate
14831	el.animate( animation, {
14832		queue: false,
14833		duration: o.duration,
14834		easing: o.easing,
14835		complete: function() {
14836			if ( mode === "hide" ) {
14837				el.hide();
14838			}
14839			$.effects.restore( el, props );
14840			$.effects.removeWrapper( el );
14841			done();
14842		}
14843	});
14844};
14845
14846})(jQuery);
14847(function( $, undefined ) {
14848
14849$.effects.effect.transfer = function( o, done ) {
14850	var elem = $( this ),
14851		target = $( o.to ),
14852		targetFixed = target.css( "position" ) === "fixed",
14853		body = $("body"),
14854		fixTop = targetFixed ? body.scrollTop() : 0,
14855		fixLeft = targetFixed ? body.scrollLeft() : 0,
14856		endPosition = target.offset(),
14857		animation = {
14858			top: endPosition.top - fixTop ,
14859			left: endPosition.left - fixLeft ,
14860			height: target.innerHeight(),
14861			width: target.innerWidth()
14862		},
14863		startPosition = elem.offset(),
14864		transfer = $( '<div class="ui-effects-transfer"></div>' )
14865			.appendTo( document.body )
14866			.addClass( o.className )
14867			.css({
14868				top: startPosition.top - fixTop ,
14869				left: startPosition.left - fixLeft ,
14870				height: elem.innerHeight(),
14871				width: elem.innerWidth(),
14872				position: targetFixed ? "fixed" : "absolute"
14873			})
14874			.animate( animation, o.duration, o.easing, function() {
14875				transfer.remove();
14876				done();
14877			});
14878};
14879
14880})(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.