PageSourceSearch

https://ecpat.org.tw/Scripts/jquery-ui-1.8.19.js

js ecpat.org.tw collected 2026-09-24 07:15:58 UTC 381,664 bytes, 11,459 lines download raw bytes

1/*! jQuery UI - v1.8.19 - 2012-04-16
2* https://github.com/jquery/jquery-ui
3* Includes: jquery.ui.core.js, jquery.ui.widget.js, jquery.ui.mouse.js, jquery.ui.draggable.js, jquery.ui.droppable.js, jquery.ui.resizable.js, jquery.ui.selectable.js, jquery.ui.sortable.js, jquery.effects.core.js, jquery.effects.blind.js, jquery.effects.bounce.js, jquery.effects.clip.js, jquery.effects.drop.js, jquery.effects.explode.js, jquery.effects.fade.js, jquery.effects.fold.js, jquery.effects.highlight.js, jquery.effects.pulsate.js, jquery.effects.scale.js, jquery.effects.shake.js, jquery.effects.slide.js, jquery.effects.transfer.js, jquery.ui.accordion.js, jquery.ui.autocomplete.js, jquery.ui.button.js, jquery.ui.datepicker.js, jquery.ui.dialog.js, jquery.ui.position.js, jquery.ui.progressbar.js, jquery.ui.slider.js, jquery.ui.tabs.js
4* Copyright (c) 2012 AUTHORS.txt; Licensed MIT, GPL */
5
6(function( $, undefined ) {
7
8// prevent duplicate loading
9// this is only a problem because we proxy existing functions
10// and we don't want to double proxy them
11$.ui = $.ui || {};
12if ( $.ui.version ) {
13	return;
14}
15
16$.extend( $.ui, {
17	version: "@VERSION",
18
19	keyCode: {
20		ALT: 18,
21		BACKSPACE: 8,
22		CAPS_LOCK: 20,
23		COMMA: 188,
24		COMMAND: 91,
25		COMMAND_LEFT: 91, // COMMAND
26		COMMAND_RIGHT: 93,
27		CONTROL: 17,
28		DELETE: 46,
29		DOWN: 40,
30		END: 35,
31		ENTER: 13,
32		ESCAPE: 27,
33		HOME: 36,
34		INSERT: 45,
35		LEFT: 37,
36		MENU: 93, // COMMAND_RIGHT
37		NUMPAD_ADD: 107,
38		NUMPAD_DECIMAL: 110,
39		NUMPAD_DIVIDE: 111,
40		NUMPAD_ENTER: 108,
41		NUMPAD_MULTIPLY: 106,
42		NUMPAD_SUBTRACT: 109,
43		PAGE_DOWN: 34,
44		PAGE_UP: 33,
45		PERIOD: 190,
46		RIGHT: 39,
47		SHIFT: 16,
48		SPACE: 32,
49		TAB: 9,
50		UP: 38,
51		WINDOWS: 91 // COMMAND
52	}
53});
54
55// plugins
56$.fn.extend({
57	propAttr: $.fn.prop || $.fn.attr,
58
59	_focus: $.fn.focus,
60	focus: function( delay, fn ) {
61		return typeof delay === "number" ?
62			this.each(function() {
63				var elem = this;
64				setTimeout(function() {
65					$( elem ).focus();
66					if ( fn ) {
67						fn.call( elem );
68					}
69				}, delay );
70			}) :
71			this._focus.apply( this, arguments );
72	},
73
74	scrollParent: function() {
75		var scrollParent;
76		if (($.browser.msie && (/(static|relative)/).test(this.css('position'))) || (/absolute/).test(this.css('position'))) {
77			scrollParent = this.parents().filter(function() {
78				return (/(relative|absolute|fixed)/).test($.curCSS(this,'position',1)) && (/(auto|scroll)/).test($.curCSS(this,'overflow',1)+$.curCSS(this,'overflow-y',1)+$.curCSS(this,'overflow-x',1));
79			}).eq(0);
80		} else {
81			scrollParent = this.parents().filter(function() {
82				return (/(auto|scroll)/).test($.curCSS(this,'overflow',1)+$.curCSS(this,'overflow-y',1)+$.curCSS(this,'overflow-x',1));
83			}).eq(0);
84		}
85
86		return (/fixed/).test(this.css('position')) || !scrollParent.length ? $(document) : scrollParent;
87	},
88
89	zIndex: function( zIndex ) {
90		if ( zIndex !== undefined ) {
91			return this.css( "zIndex", zIndex );
92		}
93
94		if ( this.length ) {
95			var elem = $( this[ 0 ] ), position, value;
96			while ( elem.length && elem[ 0 ] !== document ) {
97				// Ignore z-index if position is set to a value where z-index is ignored by the browser
98				// This makes behavior of this function consistent across browsers
99				// WebKit always returns auto if the element is positioned
100				position = elem.css( "position" );
101				if ( position === "absolute" || position === "relative" || position === "fixed" ) {
102					// IE returns 0 when zIndex is not specified
103					// other browsers return a string
104					// we ignore the case of nested elements with an explicit value of 0
105					// <div style="z-index: -10;"><div style="z-index: 0;"></div></div>
106					value = parseInt( elem.css( "zIndex" ), 10 );
107					if ( !isNaN( value ) && value !== 0 ) {
108						return value;
109					}
110				}
111				elem = elem.parent();
112			}
113		}
114
115		return 0;
116	},
117
118	disableSelection: function() {
119		return this.bind( ( $.support.selectstart ? "selectstart" : "mousedown" ) +
120			".ui-disableSelection", function( event ) {
121				event.preventDefault();
122			});
123	},
124
125	enableSelection: function() {
126		return this.unbind( ".ui-disableSelection" );
127	}
128});
129
130$.each( [ "Width", "Height" ], function( i, name ) {
131	var side = name === "Width" ? [ "Left", "Right" ] : [ "Top", "Bottom" ],
132		type = name.toLowerCase(),
133		orig = {
134			innerWidth: $.fn.innerWidth,
135			innerHeight: $.fn.innerHeight,
136			outerWidth: $.fn.outerWidth,
137			outerHeight: $.fn.outerHeight
138		};
139
140	function reduce( elem, size, border, margin ) {
141		$.each( side, function() {
142			size -= parseFloat( $.curCSS( elem, "padding" + this, true) ) || 0;
143			if ( border ) {
144				size -= parseFloat( $.curCSS( elem, "border" + this + "Width", true) ) || 0;
145			}
146			if ( margin ) {
147				size -= parseFloat( $.curCSS( elem, "margin" + this, true) ) || 0;
148			}
149		});
150		return size;
151	}
152
153	$.fn[ "inner" + name ] = function( size ) {
154		if ( size === undefined ) {
155			return orig[ "inner" + name ].call( this );
156		}
157
158		return this.each(function() {
159			$( this ).css( type, reduce( this, size ) + "px" );
160		});
161	};
162
163	$.fn[ "outer" + name] = function( size, margin ) {
164		if ( typeof size !== "number" ) {
165			return orig[ "outer" + name ].call( this, size );
166		}
167
168		return this.each(function() {
169			$( this).css( type, reduce( this, size, true, margin ) + "px" );
170		});
171	};
172});
173
174// selectors
175function focusable( element, isTabIndexNotNaN ) {
176	var nodeName = element.nodeName.toLowerCase();
177	if ( "area" === nodeName ) {
178		var map = element.parentNode,
179			mapName = map.name,
180			img;
181		if ( !element.href || !mapName || map.nodeName.toLowerCase() !== "map" ) {
182			return false;
183		}
184		img = $( "img[usemap=#" + mapName + "]" )[0];
185		return !!img && visible( img );
186	}
187	return ( /input|select|textarea|button|object/.test( nodeName )
188		? !element.disabled
189		: "a" == nodeName
190			? element.href || isTabIndexNotNaN
191			: isTabIndexNotNaN)
192		// the element and all of its ancestors must be visible
193		&& visible( element );
194}
195
196function visible( element ) {
197	return !$( element ).parents().andSelf().filter(function() {
198		return $.curCSS( this, "visibility" ) === "hidden" ||
199			$.expr.filters.hidden( this );
200	}).length;
201}
202
203$.extend( $.expr[ ":" ], {
204	data: function( elem, i, match ) {
205		return !!$.data( elem, match[ 3 ] );
206	},
207
208	focusable: function( element ) {
209		return focusable( element, !isNaN( $.attr( element, "tabindex" ) ) );
210	},
211
212	tabbable: function( element ) {
213		var tabIndex = $.attr( element, "tabindex" ),
214			isTabIndexNaN = isNaN( tabIndex );
215		return ( isTabIndexNaN || tabIndex >= 0 ) && focusable( element, !isTabIndexNaN );
216	}
217});
218
219// support
220$(function() {
221	var body = document.body,
222		div = body.appendChild( div = document.createElement( "div" ) );
223
224	// access offsetHeight before setting the style to prevent a layout bug
225	// in IE 9 which causes the elemnt to continue to take up space even
226	// after it is removed from the DOM (#8026)
227	div.offsetHeight;
228
229	$.extend( div.style, {
230		minHeight: "100px",
231		height: "auto",
232		padding: 0,
233		borderWidth: 0
234	});
235
236	$.support.minHeight = div.offsetHeight === 100;
237	$.support.selectstart = "onselectstart" in div;
238
239	// set display to none to avoid a layout bug in IE
240	// http://dev.jquery.com/ticket/4014
241	body.removeChild( div ).style.display = "none";
242});
243
244
245
246
247
248// deprecated
249$.extend( $.ui, {
250	// $.ui.plugin is deprecated.  Use the proxy pattern instead.
251	plugin: {
252		add: function( module, option, set ) {
253			var proto = $.ui[ module ].prototype;
254			for ( var i in set ) {
255				proto.plugins[ i ] = proto.plugins[ i ] || [];
256				proto.plugins[ i ].push( [ option, set[ i ] ] );
257			}
258		},
259		call: function( instance, name, args ) {
260			var set = instance.plugins[ name ];
261			if ( !set || !instance.element[ 0 ].parentNode ) {
262				return;
263			}
264	
265			for ( var i = 0; i < set.length; i++ ) {
266				if ( instance.options[ set[ i ][ 0 ] ] ) {
267					set[ i ][ 1 ].apply( instance.element, args );
268				}
269			}
270		}
271	},
272	
273	// will be deprecated when we switch to jQuery 1.4 - use jQuery.contains()
274	contains: function( a, b ) {
275		return document.compareDocumentPosition ?
276			a.compareDocumentPosition( b ) & 16 :
277			a !== b && a.contains( b );
278	},
279	
280	// only used by resizable
281	hasScroll: function( el, a ) {
282	
283		//If overflow is hidden, the element might have extra content, but the user wants to hide it
284		if ( $( el ).css( "overflow" ) === "hidden") {
285			return false;
286		}
287	
288		var scroll = ( a && a === "left" ) ? "scrollLeft" : "scrollTop",
289			has = false;
290	
291		if ( el[ scroll ] > 0 ) {
292			return true;
293		}
294	
295		// TODO: determine which cases actually cause this to happen
296		// if the element doesn't have the scroll set, see if it's possible to
297		// set the scroll
298		el[ scroll ] = 1;
299		has = ( el[ scroll ] > 0 );
300		el[ scroll ] = 0;
301		return has;
302	},
303	
304	// these are odd functions, fix the API or move into individual plugins
305	isOverAxis: function( x, reference, size ) {
306		//Determines when x coordinate is over "b" element axis
307		return ( x > reference ) && ( x < ( reference + size ) );
308	},
309	isOver: function( y, x, top, left, height, width ) {
310		//Determines when x, y coordinates is over "b" element
311		return $.ui.isOverAxis( y, top, height ) && $.ui.isOverAxis( x, left, width );
312	}
313});
314
315})( jQuery );
316
317(function( $, undefined ) {
318
319// jQuery 1.4+
320if ( $.cleanData ) {
321	var _cleanData = $.cleanData;
322	$.cleanData = function( elems ) {
323		for ( var i = 0, elem; (elem = elems[i]) != null; i++ ) {
324			try {
325				$( elem ).triggerHandler( "remove" );
326			// http://bugs.jquery.com/ticket/8235
327			} catch( e ) {}
328		}
329		_cleanData( elems );
330	};
331} else {
332	var _remove = $.fn.remove;
333	$.fn.remove = function( selector, keepData ) {
334		return this.each(function() {
335			if ( !keepData ) {
336				if ( !selector || $.filter( selector, [ this ] ).length ) {
337					$( "*", this ).add( [ this ] ).each(function() {
338						try {
339							$( this ).triggerHandler( "remove" );
340						// http://bugs.jquery.com/ticket/8235
341						} catch( e ) {}
342					});
343				}
344			}
345			return _remove.call( $(this), selector, keepData );
346		});
347	};
348}
349
350$.widget = function( name, base, prototype ) {
351	var namespace = name.split( "." )[ 0 ],
352		fullName;
353	name = name.split( "." )[ 1 ];
354	fullName = namespace + "-" + name;
355
356	if ( !prototype ) {
357		prototype = base;
358		base = $.Widget;
359	}
360
361	// create selector for plugin
362	$.expr[ ":" ][ fullName ] = function( elem ) {
363		return !!$.data( elem, name );
364	};
365
366	$[ namespace ] = $[ namespace ] || {};
367	$[ namespace ][ name ] = function( options, element ) {
368		// allow instantiation without initializing for simple inheritance
369		if ( arguments.length ) {
370			this._createWidget( options, element );
371		}
372	};
373
374	var basePrototype = new base();
375	// we need to make the options hash a property directly on the new instance
376	// otherwise we'll modify the options hash on the prototype that we're
377	// inheriting from
378//	$.each( basePrototype, function( key, val ) {
379//		if ( $.isPlainObject(val) ) {
380//			basePrototype[ key ] = $.extend( {}, val );
381//		}
382//	});
383	basePrototype.options = $.extend( true, {}, basePrototype.options );
384	$[ namespace ][ name ].prototype = $.extend( true, basePrototype, {
385		namespace: namespace,
386		widgetName: name,
387		widgetEventPrefix: $[ namespace ][ name ].prototype.widgetEventPrefix || name,
388		widgetBaseClass: fullName
389	}, prototype );
390
391	$.widget.bridge( name, $[ namespace ][ name ] );
392};
393
394$.widget.bridge = function( name, object ) {
395	$.fn[ name ] = function( options ) {
396		var isMethodCall = typeof options === "string",
397			args = Array.prototype.slice.call( arguments, 1 ),
398			returnValue = this;
399
400		// allow multiple hashes to be passed on init
401		options = !isMethodCall && args.length ?
402			$.extend.apply( null, [ true, options ].concat(args) ) :
403			options;
404
405		// prevent calls to internal methods
406		if ( isMethodCall && options.charAt( 0 ) === "_" ) {
407			return returnValue;
408		}
409
410		if ( isMethodCall ) {
411			this.each(function() {
412				var instance = $.data( this, name ),
413					methodValue = instance && $.isFunction( instance[options] ) ?
414						instance[ options ].apply( instance, args ) :
415						instance;
416				// TODO: add this back in 1.9 and use $.error() (see #5972)
417//				if ( !instance ) {
418//					throw "cannot call methods on " + name + " prior to initialization; " +
419//						"attempted to call method '" + options + "'";
420//				}
421//				if ( !$.isFunction( instance[options] ) ) {
422//					throw "no such method '" + options + "' for " + name + " widget instance";
423//				}
424//				var methodValue = instance[ options ].apply( instance, args );
425				if ( methodValue !== instance && methodValue !== undefined ) {
426					returnValue = methodValue;
427					return false;
428				}
429			});
430		} else {
431			this.each(function() {
432				var instance = $.data( this, name );
433				if ( instance ) {
434					instance.option( options || {} )._init();
435				} else {
436					$.data( this, name, new object( options, this ) );
437				}
438			});
439		}
440
441		return returnValue;
442	};
443};
444
445$.Widget = function( options, element ) {
446	// allow instantiation without initializing for simple inheritance
447	if ( arguments.length ) {
448		this._createWidget( options, element );
449	}
450};
451
452$.Widget.prototype = {
453	widgetName: "widget",
454	widgetEventPrefix: "",
455	options: {
456		disabled: false
457	},
458	_createWidget: function( options, element ) {
459		// $.widget.bridge stores the plugin instance, but we do it anyway
460		// so that it's stored even before the _create function runs
461		$.data( element, this.widgetName, this );
462		this.element = $( element );
463		this.options = $.extend( true, {},
464			this.options,
465			this._getCreateOptions(),
466			options );
467
468		var self = this;
469		this.element.bind( "remove." + this.widgetName, function() {
470			self.destroy();
471		});
472
473		this._create();
474		this._trigger( "create" );
475		this._init();
476	},
477	_getCreateOptions: function() {
478		return $.metadata && $.metadata.get( this.element[0] )[ this.widgetName ];
479	},
480	_create: function() {},
481	_init: function() {},
482
483	destroy: function() {
484		this.element
485			.unbind( "." + this.widgetName )
486			.removeData( this.widgetName );
487		this.widget()
488			.unbind( "." + this.widgetName )
489			.removeAttr( "aria-disabled" )
490			.removeClass(
491				this.widgetBaseClass + "-disabled " +
492				"ui-state-disabled" );
493	},
494
495	widget: function() {
496		return this.element;
497	},
498
499	option: function( key, value ) {
500		var options = key;
501
502		if ( arguments.length === 0 ) {
503			// don't return a reference to the internal hash
504			return $.extend( {}, this.options );
505		}
506
507		if  (typeof key === "string" ) {
508			if ( value === undefined ) {
509				return this.options[ key ];
510			}
511			options = {};
512			options[ key ] = value;
513		}
514
515		this._setOptions( options );
516
517		return this;
518	},
519	_setOptions: function( options ) {
520		var self = this;
521		$.each( options, function( key, value ) {
522			self._setOption( key, value );
523		});
524
525		return this;
526	},
527	_setOption: function( key, value ) {
528		this.options[ key ] = value;
529
530		if ( key === "disabled" ) {
531			this.widget()
532				[ value ? "addClass" : "removeClass"](
533					this.widgetBaseClass + "-disabled" + " " +
534					"ui-state-disabled" )
535				.attr( "aria-disabled", value );
536		}
537
538		return this;
539	},
540
541	enable: function() {
542		return this._setOption( "disabled", false );
543	},
544	disable: function() {
545		return this._setOption( "disabled", true );
546	},
547
548	_trigger: function( type, event, data ) {
549		var prop, orig,
550			callback = this.options[ type ];
551
552		data = data || {};
553		event = $.Event( event );
554		event.type = ( type === this.widgetEventPrefix ?
555			type :
556			this.widgetEventPrefix + type ).toLowerCase();
557		// the original event may come from any element
558		// so we need to reset the target on the new event
559		event.target = this.element[ 0 ];
560
561		// copy original event properties over to the new event
562		orig = event.originalEvent;
563		if ( orig ) {
564			for ( prop in orig ) {
565				if ( !( prop in event ) ) {
566					event[ prop ] = orig[ prop ];
567				}
568			}
569		}
570
571		this.element.trigger( event, data );
572
573		return !( $.isFunction(callback) &&
574			callback.call( this.element[0], event, data ) === false ||
575			event.isDefaultPrevented() );
576	}
577};
578
579})( jQuery );
580
581(function( $, undefined ) {
582
583var mouseHandled = false;
584$( document ).mouseup( function( e ) {
585	mouseHandled = false;
586});
587
588$.widget("ui.mouse", {
589	options: {
590		cancel: ':input,option',
591		distance: 1,
592		delay: 0
593	},
vendor: 2,188 bytes, lines 594-660
594	_mouseInit: function() {
595		var self = this;
596
597		this.element
598			.bind('mousedown.'+this.widgetName, function(event) {
599				return self._mouseDown(event);
600			})
601			.bind('click.'+this.widgetName, function(event) {
602				if (true === $.data(event.target, self.widgetName + '.preventClickEvent')) {
603				    $.removeData(event.target, self.widgetName + '.preventClickEvent');
604					event.stopImmediatePropagation();
605					return false;
606				}
607			});
608
609		this.started = false;
610	},
611
612	// TODO: make sure destroying one instance of mouse doesn't mess with
613	// other instances of mouse
614	_mouseDestroy: function() {
615		this.element.unbind('.'+this.widgetName);
616		$(document)
617			.unbind('mousemove.'+this.widgetName, this._mouseMoveDelegate)
618			.unbind('mouseup.'+this.widgetName, this._mouseUpDelegate);
619	},
620
621	_mouseDown: function(event) {
622		// don't let more than one widget handle mouseStart
623		if( mouseHandled ) { return };
624
625		// we may have missed mouseup (out of window)
626		(this._mouseStarted && this._mouseUp(event));
627
628		this._mouseDownEvent = event;
629
630		var self = this,
631			btnIsLeft = (event.which == 1),
632			// event.target.nodeName works around a bug in IE 8 with
633			// disabled inputs (#7620)
634			elIsCancel = (typeof this.options.cancel == "string" && event.target.nodeName ? $(event.target).closest(this.options.cancel).length : false);
635		if (!btnIsLeft || elIsCancel || !this._mouseCapture(event)) {
636			return true;
637		}
638
639		this.mouseDelayMet = !this.options.delay;
640		if (!this.mouseDelayMet) {
641			this._mouseDelayTimer = setTimeout(function() {
642				self.mouseDelayMet = true;
643			}, this.options.delay);
644		}
645
646		if (this._mouseDistanceMet(event) && this._mouseDelayMet(event)) {
647			this._mouseStarted = (this._mouseStart(event) !== false);
648			if (!this._mouseStarted) {
649				event.preventDefault();
650				return true;
651			}
652		}
653
654		// Click event may never have fired (Gecko & Opera)
655		if (true === $.data(event.target, this.widgetName + '.preventClickEvent')) {
656			$.removeData(event.target, this.widgetName + '.preventClickEvent');
657		}
658
659		// these delegates are required to keep context
660		this._mouseMoveDelegate = function(event) {
661			return self._mouseMove(event);
662		};
663		this._mouseUpDelegate = function(event) {
664			return self._mouseUp(event);
665		};
666		$(document)
667			.bind('mousemove.'+this.widgetName, this._mouseMoveDelegate)
668			.bind('mouseup.'+this.widgetName, this._mouseUpDelegate);
669
670		event.preventDefault();
671		
672		mouseHandled = true;
673		return true;
674	},
675
676	_mouseMove: function(event) {
677		// IE mouseup check - mouseup happened when mouse was out of window
678		if ($.browser.msie && !(document.documentMode >= 9) && !event.button) {
679			return this._mouseUp(event);
680		}
681
682		if (this._mouseStarted) {
683			this._mouseDrag(event);
684			return event.preventDefault();
685		}
686
687		if (this._mouseDistanceMet(event) && this._mouseDelayMet(event)) {
688			this._mouseStarted =
689				(this._mouseStart(this._mouseDownEvent, event) !== false);
690			(this._mouseStarted ? this._mouseDrag(event) : this._mouseUp(event));
691		}
692
693		return !this._mouseStarted;
694	},
695
696	_mouseUp: function(event) {
697		$(document)
698			.unbind('mousemove.'+this.widgetName, this._mouseMoveDelegate)
699			.unbind('mouseup.'+this.widgetName, this._mouseUpDelegate);
700
701		if (this._mouseStarted) {
702			this._mouseStarted = false;
703
704			if (event.target == this._mouseDownEvent.target) {
705			    $.data(event.target, this.widgetName + '.preventClickEvent', true);
706			}
707
708			this._mouseStop(event);
709		}
710
711		return false;
712	},
713
714	_mouseDistanceMet: function(event) {
715		return (Math.max(
716				Math.abs(this._mouseDownEvent.pageX - event.pageX),
717				Math.abs(this._mouseDownEvent.pageY - event.pageY)
718			) >= this.options.distance
719		);
720	},
721
722	_mouseDelayMet: function(event) {
723		return this.mouseDelayMet;
724	},
725
726	// These are placeholder methods, to be overriden by extending plugin
727	_mouseStart: function(event) {},
728	_mouseDrag: function(event) {},
729	_mouseStop: function(event) {},
730	_mouseCapture: function(event) { return true; }
731});
732
733})(jQuery);
734
735(function( $, undefined ) {
736
737$.widget("ui.draggable", $.ui.mouse, {
738	widgetEventPrefix: "drag",
739	options: {
740		addClasses: true,
741		appendTo: "parent",
742		axis: false,
743		connectToSortable: false,
744		containment: false,
745		cursor: "auto",
746		cursorAt: false,
747		grid: false,
748		handle: false,
749		helper: "original",
750		iframeFix: false,
751		opacity: false,
752		refreshPositions: false,
753		revert: false,
754		revertDuration: 500,
755		scope: "default",
756		scroll: true,
757		scrollSensitivity: 20,
758		scrollSpeed: 20,
759		snap: false,
760		snapMode: "both",
761		snapTolerance: 20,
762		stack: false,
763		zIndex: false
764	},
765	_create: function() {
766
767		if (this.options.helper == 'original' && !(/^(?:r|a|f)/).test(this.element.css("position")))
768			this.element[0].style.position = 'relative';
769
770		(this.options.addClasses && this.element.addClass("ui-draggable"));
771		(this.options.disabled && this.element.addClass("ui-draggable-disabled"));
772
773		this._mouseInit();
774
775	},
776
777	destroy: function() {
778		if(!this.element.data('draggable')) return;
779		this.element
780			.removeData("draggable")
781			.unbind(".draggable")
782			.removeClass("ui-draggable"
783				+ " ui-draggable-dragging"
784				+ " ui-draggable-disabled");
785		this._mouseDestroy();
786
787		return this;
788	},
789
790	_mouseCapture: function(event) {
791
792		var o = this.options;
793
794		// among others, prevent a drag on a resizable-handle
795		if (this.helper || o.disabled || $(event.target).is('.ui-resizable-handle'))
796			return false;
797
798		//Quit if we're not on a valid handle
799		this.handle = this._getHandle(event);
800		if (!this.handle)
801			return false;
802		
803		if ( o.iframeFix ) {
804			$(o.iframeFix === true ? "iframe" : o.iframeFix).each(function() {
805				$('<div class="ui-draggable-iframeFix" style="background: #fff;"></div>')
806				.css({
807					width: this.offsetWidth+"px", height: this.offsetHeight+"px",
808					position: "absolute", opacity: "0.001", zIndex: 1000
809				})
810				.css($(this).offset())
811				.appendTo("body");
812			});
813		}
814
815		return true;
816
817	},
818
819	_mouseStart: function(event) {
820
821		var o = this.options;
822
823		//Create and append the visible helper
824		this.helper = this._createHelper(event);
825
826		//Cache the helper size
827		this._cacheHelperProportions();
828
829		//If ddmanager is used for droppables, set the global draggable
830		if($.ui.ddmanager)
831			$.ui.ddmanager.current = this;
832
833		/*
834		 * - Position generation -
835		 * This block generates everything position related - it's the core of draggables.
836		 */
837
838		//Cache the margins of the original element
839		this._cacheMargins();
840
841		//Store the helper's css position
842		this.cssPosition = this.helper.css("position");
843		this.scrollParent = this.helper.scrollParent();
844
845		//The element's absolute position on the page minus margins
846		this.offset = this.positionAbs = this.element.offset();
847		this.offset = {
848			top: this.offset.top - this.margins.top,
849			left: this.offset.left - this.margins.left
850		};
851
852		$.extend(this.offset, {
853			click: { //Where the click happened, relative to the element
854				left: event.pageX - this.offset.left,
855				top: event.pageY - this.offset.top
856			},
857			parent: this._getParentOffset(),
858			relative: this._getRelativeOffset() //This is a relative to absolute position minus the actual position calculation - only used for relative positioned helper
859		});
860
861		//Generate the original position
862		this.originalPosition = this.position = this._generatePosition(event);
863		this.originalPageX = event.pageX;
864		this.originalPageY = event.pageY;
865
866		//Adjust the mouse offset relative to the helper if 'cursorAt' is supplied
867		(o.cursorAt && this._adjustOffsetFromHelper(o.cursorAt));
868
869		//Set a containment if given in the options
870		if(o.containment)
871			this._setContainment();
872
873		//Trigger event + callbacks
874		if(this._trigger("start", event) === false) {
875			this._clear();
876			return false;
877		}
878
879		//Recache the helper size
880		this._cacheHelperProportions();
881
882		//Prepare the droppable offsets
883		if ($.ui.ddmanager && !o.dropBehaviour)
884			$.ui.ddmanager.prepareOffsets(this, event);
885
886		this.helper.addClass("ui-draggable-dragging");
887		this._mouseDrag(event, true); //Execute the drag once - this causes the helper not to be visible before getting its correct position
888		
889		//If the ddmanager is used for droppables, inform the manager that dragging has started (see #5003)
890		if ( $.ui.ddmanager ) $.ui.ddmanager.dragStart(this, event);
891		
892		return true;
893	},
894
895	_mouseDrag: function(event, noPropagation) {
896
897		//Compute the helpers position
898		this.position = this._generatePosition(event);
899		this.positionAbs = this._convertPositionTo("absolute");
900
901		//Call plugins and callbacks and use the resulting position if something is returned
902		if (!noPropagation) {
903			var ui = this._uiHash();
904			if(this._trigger('drag', event, ui) === false) {
905				this._mouseUp({});
906				return false;
907			}
908			this.position = ui.position;
909		}
910
911		if(!this.options.axis || this.options.axis != "y") this.helper[0].style.left = this.position.left+'px';
912		if(!this.options.axis || this.options.axis != "x") this.helper[0].style.top = this.position.top+'px';
913		if($.ui.ddmanager) $.ui.ddmanager.drag(this, event);
914
915		return false;
916	},
917
918	_mouseStop: function(event) {
919
920		//If we are using droppables, inform the manager about the drop
921		var dropped = false;
922		if ($.ui.ddmanager && !this.options.dropBehaviour)
923			dropped = $.ui.ddmanager.drop(this, event);
924
925		//if a drop comes from outside (a sortable)
926		if(this.dropped) {
927			dropped = this.dropped;
928			this.dropped = false;
929		}
930		
931		//if the original element is removed, don't bother to continue if helper is set to "original"
932		if((!this.element[0] || !this.element[0].parentNode) && this.options.helper == "original")
933			return false;
934
935		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))) {
936			var self = this;
937			$(this.helper).animate(this.originalPosition, parseInt(this.options.revertDuration, 10), function() {
938				if(self._trigger("stop", event) !== false) {
939					self._clear();
940				}
941			});
942		} else {
943			if(this._trigger("stop", event) !== false) {
944				this._clear();
945			}
946		}
947
948		return false;
949	},
950	
951	_mouseUp: function(event) {
952		if (this.options.iframeFix === true) {
953			$("div.ui-draggable-iframeFix").each(function() { 
954				this.parentNode.removeChild(this); 
955			}); //Remove frame helpers
956		}
957		
958		//If the ddmanager is used for droppables, inform the manager that dragging has stopped (see #5003)
959		if( $.ui.ddmanager ) $.ui.ddmanager.dragStop(this, event);
960		
961		return $.ui.mouse.prototype._mouseUp.call(this, event);
962	},
963	
964	cancel: function() {
965		
966		if(this.helper.is(".ui-draggable-dragging")) {
967			this._mouseUp({});
968		} else {
969			this._clear();
970		}
971		
972		return this;
973		
974	},
975
976	_getHandle: function(event) {
977
978		var handle = !this.options.handle || !$(this.options.handle, this.element).length ? true : false;
979		$(this.options.handle, this.element)
980			.find("*")
981			.andSelf()
982			.each(function() {
983				if(this == event.target) handle = true;
984			});
985
986		return handle;
987
988	},
989
990	_createHelper: function(event) {
991
992		var o = this.options;
993		var helper = $.isFunction(o.helper) ? $(o.helper.apply(this.element[0], [event])) : (o.helper == 'clone' ? this.element.clone().removeAttr('id') : this.element);
994
995		if(!helper.parents('body').length)
996			helper.appendTo((o.appendTo == 'parent' ? this.element[0].parentNode : o.appendTo));
997
998		if(helper[0] != this.element[0] && !(/(fixed|absolute)/).test(helper.css("position")))
999			helper.css("position", "absolute");
1000
1001		return helper;
1002
1003	},
1004
1005	_adjustOffsetFromHelper: function(obj) {
1006		if (typeof obj == 'string') {
1007			obj = obj.split(' ');
1008		}
1009		if ($.isArray(obj)) {
1010			obj = {left: +obj[0], top: +obj[1] || 0};
1011		}
1012		if ('left' in obj) {
1013			this.offset.click.left = obj.left + this.margins.left;
1014		}
1015		if ('right' in obj) {
1016			this.offset.click.left = this.helperProportions.width - obj.right + this.margins.left;
1017		}
1018		if ('top' in obj) {
1019			this.offset.click.top = obj.top + this.margins.top;
1020		}
1021		if ('bottom' in obj) {
1022			this.offset.click.top = this.helperProportions.height - obj.bottom + this.margins.top;
1023		}
1024	},
1025
1026	_getParentOffset: function() {
1027
1028		//Get the offsetParent and cache its position
1029		this.offsetParent = this.helper.offsetParent();
1030		var po = this.offsetParent.offset();
1031
1032		// This is a special case where we need to modify a offset calculated on start, since the following happened:
1033		// 1. The position of the helper is absolute, so it's position is calculated based on the next positioned parent
1034		// 2. The actual offset parent is a child of the scroll parent, and the scroll parent isn't the document, which means that
1035		//    the scroll is included in the initial calculation of the offset of the parent, and never recalculated upon drag
1036		if(this.cssPosition == 'absolute' && this.scrollParent[0] != document && $.ui.contains(this.scrollParent[0], this.offsetParent[0])) {
1037			po.left += this.scrollParent.scrollLeft();
1038			po.top += this.scrollParent.scrollTop();
1039		}
1040
1041		if((this.offsetParent[0] == document.body) //This needs to be actually done for all browsers, since pageX/pageY includes this information
1042		|| (this.offsetParent[0].tagName && this.offsetParent[0].tagName.toLowerCase() == 'html' && $.browser.msie)) //Ugly IE fix
1043			po = { top: 0, left: 0 };
1044
1045		return {
1046			top: po.top + (parseInt(this.offsetParent.css("borderTopWidth"),
104610) || 0),
1047			left: po.left + (parseInt(this.offsetParent.css("borderLeftWidth"),10) || 0)
1048		};
1049
1050	},
1051
1052	_getRelativeOffset: function() {
1053
1054		if(this.cssPosition == "relative") {
1055			var p = this.element.position();
1056			return {
1057				top: p.top - (parseInt(this.helper.css("top"),10) || 0) + this.scrollParent.scrollTop(),
1058				left: p.left - (parseInt(this.helper.css("left"),10) || 0) + this.scrollParent.scrollLeft()
1059			};
1060		} else {
1061			return { top: 0, left: 0 };
1062		}
1063
1064	},
1065
1066	_cacheMargins: function() {
1067		this.margins = {
1068			left: (parseInt(this.element.css("marginLeft"),10) || 0),
1069			top: (parseInt(this.element.css("marginTop"),10) || 0),
1070			right: (parseInt(this.element.css("marginRight"),10) || 0),
1071			bottom: (parseInt(this.element.css("marginBottom"),10) || 0)
1072		};
1073	},
1074
1075	_cacheHelperProportions: function() {
1076		this.helperProportions = {
1077			width: this.helper.outerWidth(),
1078			height: this.helper.outerHeight()
1079		};
1080	},
1081
1082	_setContainment: function() {
1083
1084		var o = this.options;
1085		if(o.containment == 'parent') o.containment = this.helper[0].parentNode;
1086		if(o.containment == 'document' || o.containment == 'window') this.containment = [
1087			o.containment == 'document' ? 0 : $(window).scrollLeft() - this.offset.relative.left - this.offset.parent.left,
1088			o.containment == 'document' ? 0 : $(window).scrollTop() - this.offset.relative.top - this.offset.parent.top,
1089			(o.containment == 'document' ? 0 : $(window).scrollLeft()) + $(o.containment == 'document' ? document : window).width() - this.helperProportions.width - this.margins.left,
1090			(o.containment == 'document' ? 0 : $(window).scrollTop()) + ($(o.containment == 'document' ? document : window).height() || document.body.parentNode.scrollHeight) - this.helperProportions.height - this.margins.top
1091		];
1092
1093		if(!(/^(document|window|parent)$/).test(o.containment) && o.containment.constructor != Array) {
1094		        var c = $(o.containment);
1095			var ce = c[0]; if(!ce) return;
1096			var co = c.offset();
1097			var over = ($(ce).css("overflow") != 'hidden');
1098
1099			this.containment = [
1100				(parseInt($(ce).css("borderLeftWidth"),10) || 0) + (parseInt($(ce).css("paddingLeft"),10) || 0),
1101				(parseInt($(ce).css("borderTopWidth"),10) || 0) + (parseInt($(ce).css("paddingTop"),10) || 0),
1102				(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,
1103				(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
1104			];
1105			this.relative_container = c;
1106
1107		} else if(o.containment.constructor == Array) {
1108			this.containment = o.containment;
1109		}
1110
1111	},
1112
1113	_convertPositionTo: function(d, pos) {
1114
1115		if(!pos) pos = this.position;
1116		var mod = d == "absolute" ? 1 : -1;
1117		var o = this.options, scroll = this.cssPosition == 'absolute' && !(this.scrollParent[0] != document && $.ui.contains(this.scrollParent[0], this.offsetParent[0])) ? this.offsetParent : this.scrollParent, scrollIsRootNode = (/(html|body)/i).test(scroll[0].tagName);
1118
1119		return {
1120			top: (
1121				pos.top																	// The absolute mouse position
1122				+ this.offset.relative.top * mod										// Only for relative positioned nodes: Relative offset from element to offset parent
1123				+ this.offset.parent.top * mod											// The offsetParent's offset without borders (offset + border)
1124				- ($.browser.safari && $.browser.version < 526 && this.cssPosition == 'fixed' ? 0 : ( this.cssPosition == 'fixed' ? -this.scrollParent.scrollTop() : ( scrollIsRootNode ? 0 : scroll.scrollTop() ) ) * mod)
1125			),
1126			left: (
1127				pos.left																// The absolute mouse position
1128				+ this.offset.relative.left * mod										// Only for relative positioned nodes: Relative offset from element to offset parent
1129				+ this.offset.parent.left * mod											// The offsetParent's offset without borders (offset + border)
1130				- ($.browser.safari && $.browser.version < 526 && this.cssPosition == 'fixed' ? 0 : ( this.cssPosition == 'fixed' ? -this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 : scroll.scrollLeft() ) * mod)
1131			)
1132		};
1133
1134	},
1135
1136	_generatePosition: function(event) {
1137
1138		var o = this.options, scroll = this.cssPosition == 'absolute' && !(this.scrollParent[0] != document && $.ui.contains(this.scrollParent[0], this.offsetParent[0])) ? this.offsetParent : this.scrollParent, scrollIsRootNode = (/(html|body)/i).test(scroll[0].tagName);
1139		var pageX = event.pageX;
1140		var pageY = event.pageY;
1141
1142		/*
1143		 * - Position constraining -
1144		 * Constrain the position to a mix of grid, containment.
1145		 */
1146
1147		if(this.originalPosition) { //If we are not dragging yet, we won't check for options
1148		         var containment;
1149		         if(this.containment) {
1150				 if (this.relative_container){
1151				     var co = this.relative_container.offset();
1152				     containment = [ this.containment[0] + co.left,
1153						     this.containment[1] + co.top,
1154						     this.containment[2] + co.left,
1155						     this.containment[3] + co.top ];
1156				 }
1157				 else {
1158				     containment = this.containment;
1159				 }
1160
1161				if(event.pageX - this.offset.click.left < containment[0]) pageX = containment[0] + this.offset.click.left;
1162				if(event.pageY - this.offset.click.top < containment[1]) pageY = containment[1] + this.offset.click.top;
1163				if(event.pageX - this.offset.click.left > containment[2]) pageX = containment[2] + this.offset.click.left;
1164				if(event.pageY - this.offset.click.top > containment[3]) pageY = containment[3] + this.offset.click.top;
1165			}
1166
1167			if(o.grid) {
1168				//Check for grid elements set to 0 to prevent divide by 0 error causing invalid argument errors in IE (see ticket #6950)
1169				var top = o.grid[1] ? this.originalPageY + Math.round((pageY - this.originalPageY) / o.grid[1]) * o.grid[1] : this.originalPageY;
1170				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;
1171
1172				var left = o.grid[0] ? this.originalPageX + Math.round((pageX - this.originalPageX) / o.grid[0]) * o.grid[0] : this.originalPageX;
1173				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;
1174			}
1175
1176		}
1177
1178		return {
1179			top: (
1180				pageY																// The absolute mouse position
1181				- this.offset.click.top													// Click offset (relative to the element)
1182				- this.offset.relative.top												// Only for relative positioned nodes: Relative offset from element to offset parent
1183				- this.offset.parent.top												// The offsetParent's offset without borders (offset + border)
1184				+ ($.browser.safari && $.browser.version < 526 && this.cssPosition == 'fixed' ? 0 : ( this.cssPosition == 'fixed' ? -this.scrollParent.scrollTop() : ( scrollIsRootNode ? 0 : scroll.scrollTop() ) ))
1185			),
1186			left: (
1187				pageX																// The absolute mouse position
1188				- this.offset.click.left												// Click offset (relative to the element)
1189				- this.offset.relative.left												// Only for relative positioned nodes: Relative offset from element to offset parent
1190				- this.offset.parent.left												// The offsetParent's offset without borders (offset + border)
1191				+ ($.browser.safari && $.browser.version < 526 && this.cssPosition == 'fixed' ? 0 : ( this.cssPosition == 'fixed' ? -this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 : scroll.scrollLeft() ))
1192			)
1193		};
1194
1195	},
1196
1197	_clear: function() {
1198		this.helper.removeClass("ui-draggable-dragging");
1199		if(this.helper[0] != this.element[0] && !this.cancelHelperRemoval) this.helper.remove();
1200		//if($.ui.ddmanager) $.ui.ddmanager.current = null;
1201		this.helper = null;
1202		this.cancelHelperRemoval = false;
1203	},
1204
1205	// From now on bulk stuff - mainly helpers
1206
1207	_trigger: function(type, event, ui) {
1208		ui = ui || this._uiHash();
1209		$.ui.plugin.call(this, type, [event, ui]);
1210		if(type == "drag") this.positionAbs = this._convertPositionTo("absolute"); //The absolute position has to be recalculated after plugins
1211		return $.Widget.prototype._trigger.call(this, type, event, ui);
1212	},
1213
1214	plugins: {},
1215
1216	_uiHash: function(event) {
1217		return {
1218			helper: this.helper,
1219			position: this.position,
1220			originalPosition: this.originalPosition,
1221			offset: this.positionAbs
1222		};
1223	}
1224
1225});
1226
1227$.extend($.ui.draggable, {
1228	version: "@VERSION"
1229});
1230
1231$.ui.plugin.add("draggable", "connectToSortable", {
1232	start: function(event, ui) {
1233
1234		var inst = $(this).data("draggable"), o = inst.options,
1235			uiSortable = $.extend({}, ui, { item: inst.element });
1236		inst.sortables = [];
1237		$(o.connectToSortable).each(function() {
1238			var sortable = $.data(this, 'sortable');
1239			if (sortable && !sortable.options.disabled) {
1240				inst.sortables.push({
1241					instance: sortable,
1242					shouldRevert: sortable.options.revert
1243				});
1244				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).
1245				sortable._trigger("activate", event, uiSortable);
1246			}
1247		});
1248
1249	},
1250	stop: function(event, ui) {
1251
1252		//If we are still over the sortable, we fake the stop event of the sortable, but also remove helper
1253		var inst = $(this).data("draggable"),
1254			uiSortable = $.extend({}, ui, { item: inst.element });
1255
1256		$.each(inst.sortables, function() {
1257			if(this.instance.isOver) {
1258
1259				this.instance.isOver = 0;
1260
1261				inst.cancelHelperRemoval = true; //Don't remove the helper in the draggable instance
1262				this.instance.cancelHelperRemoval = false; //Remove it in the sortable instance (so sortable plugins like revert still work)
1263
1264				//The sortable revert is supported, and we have to set a temporary dropped variable on the draggable to support revert: 'valid/invalid'
1265				if(this.shouldRevert) this.instance.options.revert = true;
1266
1267				//Trigger the stop of the sortable
1268				this.instance._mouseStop(event);
1269
1270				this.instance.options.helper = this.instance.options._helper;
1271
1272				//If the helper has been the original item, restore properties in the sortable
1273				if(inst.options.helper == 'original')
1274					this.instance.currentItem.css({ top: 'auto', left: 'auto' });
1275
1276			} else {
1277				this.instance.cancelHelperRemoval = false; //Remove the helper in the sortable instance
1278				this.instance._trigger("deactivate", event, uiSortable);
1279			}
1280
1281		});
1282
1283	},
1284	drag: function(event, ui) {
1285
1286		var inst = $(this).data("draggable"), self = this;
1287
1288		var checkPos = function(o) {
1289			var dyClick = this.offset.click.top, dxClick = this.offset.click.left;
1290			var helperTop = this.positionAbs.top, helperLeft = this.positionAbs.left;
1291			var itemHeight = o.height, itemWidth = o.width;
1292			var itemTop = o.top, itemLeft = o.left;
1293
1294			return $.ui.isOver(helperTop + dyClick, helperLeft + dxClick, itemTop, itemLeft, itemHeight, itemWidth);
1295		};
1296
1297		$.each(inst.sortables, function(i) {
1298			
1299			//Copy over some variables to allow calling the sortable's native _intersectsWith
1300			this.instance.positionAbs = inst.positionAbs;
1301			this.instance.helperProportions = inst.helperProportions;
1302			this.instance.offset.click = inst.offset.click;
1303			
1304			if(this.instance._intersectsWith(this.instance.containerCache)) {
1305
1306				//If it intersects, we use a little isOver variable and set it once, so our move-in stuff gets fired only once
1307				if(!this.instance.isOver) {
1308
1309					this.instance.isOver = 1;
1310					//Now we fake the start of dragging for the sortable instance,
1311					//by cloning the list group item, appending it to the sortable and using it as inst.currentItem
1312					//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)
1313					this.instance.currentItem = $(self).clone().removeAttr('id').appendTo(this.instance.element).data("sortable-item", true);
1314					this.instance.options._helper = this.instance.options.helper; //Store helper option to later restore it
1315					this.instance.options.helper = function() { return ui.helper[0]; };
1316
1317					event.target = this.instance.currentItem[0];
1318					this.instance._mouseCapture(event, true);
1319					this.instance._mouseStart(event, true, true);
1320
1321					//Because the browser event is way off the new appended portlet, we modify a couple of variables to reflect the changes
1322					this.instance.offset.click.top = inst.offset.click.top;
1323					this.instance.offset.click.left = inst.offset.click.left;
1324					this.instance.offset.parent.left -= inst.offset.parent.left - this.instance.offset.parent.left;
1325					this.instance.offset.parent.top -= inst.offset.parent.top - this.instance.offset.parent.top;
1326
1327					inst._trigger("toSortable", event);
1328					inst.dropped = this.instance.element; //draggable revert needs that
1329					//hack so receive/update callbacks work (mostly)
1330					inst.currentItem = inst.element;
1331					this.instance.fromOutside = inst;
1332
1333				}
1334
1335				//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
1336				if(this.instance.currentItem) this.instance._mouseDrag(event);
1337
1338			} else {
1339
1340				//If it doesn't intersect with the sortable, and it intersected before,
1341				//we fake the drag stop of the sortable, but make sure it doesn't remove the helper by using cancelHelperRemoval
1342				if(this.instance.isOver) {
1343
1344					this.instance.isOver = 0;
1345					this.instance.cancelHelperRemoval = true;
1346					
1347					//Prevent reverting on this forced stop
1348					this.instance.options.revert = false;
1349					
1350					// The out event needs to be triggered independently
1351					this.instance._trigger('out', event, this.instance._uiHash(this.instance));
1352					
1353					this.instance._mouseStop(event, true);
1354					this.instance.options.helper = this.instance.options._helper;
1355
1356					//Now we remove our currentItem, the list group clone again, and the placeholder, and animate the helper back to it's original size
1357					this.instance.currentItem.remove();
1358					if(this.instance.placeholder) this.instance.placeholder.remove();
1359
1360					inst._trigger("fromSortable", event);
1361					inst.dropped = false; //draggable revert needs that
1362				}
1363
1364			};
1365
1366		});
1367
1368	}
1369});
1370
1371$.ui.plugin.add("draggable", "cursor", {
1372	start: function(event, ui) {
1373		var t = $('body'), o = $(this).data('draggable').options;
1374		if (t.css("cursor")) o._cursor = t.css("cursor");
1375		t.css("cursor", o.cursor);
1376	},
1377	stop: function(event, ui) {
1378		var o = $(this).data('draggable').options;
1379		if (o._cursor) $('body').css("cursor", o._cursor);
1380	}
1381});
1382
1383$.ui.plugin.add("draggable", "opacity", {
1384	start: function(event, ui) {
1385		var t = $(ui.helper), o = $(this).data('draggable').options;
1386		if(t.css("opacity")) o._opacity = t.css("opacity");
1387		t.css('opacity', o.opacity);
1388	},
1389	stop: function(event, ui) {
1390		var o = $(this).data('draggable').options;
1391		if(o._opacity) $(ui.helper).css('opacity', o._opacity);
1392	}
1393});
1394
1395$.ui.plugin.add("draggable", "scroll", {
1396	start: function(event, ui) {
1397		var i = $(this).data("draggable");
1398		if(i.scrollParent[0] != document && i.scrollParent[0].tagName != 'HTML') i.overflowOffset = i.scrollParent.offset();
1399	},
1400	drag: function(event, ui) {
1401
1402		var i = $(this).data("draggable"), o = i.options, scrolled = false;
1403
1404		if(i.scrollParent[0] != document && i.scrollParent[0].tagName != 'HTML') {
1405
1406			if(!o.axis || o.axis != 'x') {
1407				if((i.overflowOffset.top + i.scrollParent[0].offsetHeight) - event.pageY < o.scrollSensitivity)
1408					i.scrollParent[0].scrollTop = scrolled = i.scrollParent[0].scrollTop + o.scrollSpeed;
1409				else if(event.pageY - i.overflowOffset.top < o.scrollSensitivity)
1410					i.scrollParent[0].scrollTop = scrolled = i.scrollParent[0].scrollTop - o.scrollSpeed;
1411			}
1412
1413			if(!o.axis || o.axis != 'y') {
1414				if((i.overflowOffset.left + i.scrollParent[0].offsetWidth) - event.pageX < o.scrollSensitivity)
1415					i.scrollParent[0].scrollLeft = scrolled = i.scrollParent[0].scrollLeft + o.scrollSpeed;
1416				else if(event.pageX - i.overflowOffset.left < o.scrollSensitivity)
1417					i.scrollParent[0].scrollLeft = scrolled = i.scrollParent[0].scrollLeft - o.scrollSpeed;
1418			}
1419
1420		} else {
1421
1422			if(!o.axis || o.axis != 'x') {
1423				if(event.pageY - $(document).scrollTop() < o.scrollSensitivity)
1424					scrolled = $(document).scrollTop($(document).scrollTop() - o.scrollSpeed);
1425				else if($(window).height() - (event.pageY - $(document).scrollTop()) < o.scrollSensitivity)
1426					scrolled = $(document).scrollTop($(document).scrollTop() + o.scrollSpeed);
1427			}
1428
1429			if(!o.axis || o.axis != 'y') {
1430				if(event.pageX - $(document).scrollLeft() < o.scrollSensitivity)
1431					scrolled = $(document).scrollLeft($(document).scrollLeft() - o.scrollSpeed);
1432				else if($(window).width() - (event.pageX - $(document).scrollLeft()) < o.scrollSensitivity)
1433					scrolled = $(document).scrollLeft($(document).scrollLeft() + o.scrollSpeed);
1434			}
1435
1436		}
1437
1438		if(scrolled !== false && $.ui.ddmanager && !o.dropBehaviour)
1439			$.ui.ddmanager.prepareOffsets(i, event);
1440
1441	}
1442});
1443
1444$.ui.plugin.add("draggable", "snap", {
1445	start: function(event, ui) {
1446
1447		var i = $(this).data("draggable"), o = i.options;
1448		i.snapElements = [];
1449
1450		$(o.snap.constructor != String ? ( o.snap.items || ':data(draggable)' ) : o.snap).each(function() {
1451			var $t = $(this); var $o = $t.offset();
1452			if(this != i.element[0]) i.snapElements.push({
1453				item: this,
1454				width: $t.outerWidth(), height: $t.outerHeight(),
1455				top: $o.top, left: $o.left
1456			});
1457		});
1458
1459	},
1460	drag: function(event, ui) {
1461
1462		var inst = $(this).data("draggable"), o = inst.options;
1463		var d = o.snapTolerance;
1464
1465		var x1 = ui.offset.left, x2 = x1 + inst.helperProportions.width,
1466			y1 = ui.offset.top, y2 = y1 + inst.helperProportions.height;
1467
1468		for (var i = inst.snapElements.length - 1; i >= 0; i--){
1469
1470			var l = inst.snapElements[i].left, r = l + inst.snapElements[i].width,
1471				t = inst.snapElements[i].top, b = t + inst.snapElements[i].height;
1472
1473			//Yes, I know, this is insane ;)
1474			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))) {
1475				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 })));
1476				inst.snapElements[i].snapping = false;
1477				continue;
1478			}
1479
1480			if(o.snapMode != 'inner') {
1481				var ts = Math.abs(t - y2) <= d;
1482				var bs = Math.abs(b - y1) <= d;
1483				var ls = Math.abs(l - x2) <= d;
1484				var rs = Math.abs(r - x1) <= d;
1485				if(ts) ui.position.top = inst._convertPositionTo("relative", { top: t - inst.helperProportions.height, left: 0 }).top - inst.margins.top;
1486				if(bs) ui.position.top = inst._convertPositionTo("relative", { top: b, left: 0 }).top - inst.margins.top;
1487				if(ls) ui.position.left = inst._convertPositionTo("relative", { top: 0, left: l - inst.helperProportions.width }).left - inst.margins.left;
1488				if(rs) ui.position.left = inst._convertPositionTo("relative", { top: 0, left: r }).left - inst.margins.left;
1489			}
1490
1491			var first = (ts || bs || ls || rs);
1492
1493			if(o.snapMode != 'outer') {
1494				var ts = Math.abs(t - y1) <= d;
1495				var bs = Math.abs(b - y2) <= d;
1496				var ls = Math.abs(l - x1) <= d;
1497				var rs = Math.abs(r - x2) <= d;
1498				if(ts) ui.position.top = inst._convertPositionTo("relative", { top: t, left: 0 }).top - inst.margins.top;
1499				if(bs) ui.position.top = inst._convertPositionTo("relative", { top: b - inst.helperProportions.height, left: 0 }).top - inst.margins.top;
1500				if(ls) ui.position.left = inst._convertPositionTo("relative", { top: 0, left: l }).left - inst.margins.left;
1501				if(rs) ui.position.left = inst._convertPositionTo("relative", { top: 0, left: r - inst.helperProportions.width }).left - inst.margins.left;
1502			}
1503
1504			if(!inst.snapElements[i].snapping && (ts || bs || ls || rs || first))
1505				(inst.options.snap.snap && inst.options.snap.snap.call(inst.element, event, $.extend(inst._uiHash(), { snapItem: inst.snapElements[i].item })));
1506			inst.snapElements[i].snapping = (ts || bs || ls || rs || first);
1507
1508		};
1509
1510	}
1511});
1512
1513$.ui.plugin.add("draggable", "stack", {
1514	start: function(event, ui) {
1515
1516		var o = $(this).data("draggable").options;
1517
1518		var group = $.makeArray($(o.stack)).sort(function(a,b) {
1519			return (parseInt($(a).css("zIndex"),10) || 0) - (parseInt($(b).css("zIndex"),10) || 0);
1520		});
1521		if (!group.length) { return; }
1522		
1523		var min = parseInt(group[0].style.zIndex) || 0;
1524		$(group).each(function(i) {
1525			this.style.zIndex = min + i;
1526		});
1527
1528		this[0].style.zIndex = min + group.length;
1529
1530	}
1531});
1532
1533$.ui.plugin.add("draggable", "zIndex", {
1534	start: function(event, ui) {
1535		var t = $(ui.helper), o = $(this).data("draggable").options;
1536		if(t.css("zIndex")) o._zIndex = t.css("zIndex");
1537		t.css('zIndex', o.zIndex);
1538	},
1539	stop: function(event, ui) {
1540		var o = $(this).data("draggable").options;
1541		if(o._zIndex) $(ui.helper).css('zIndex', o._zIndex);
1542	}
1543});
1544
1545})(jQuery);
1546
1547(function( $, undefined ) {
1548
1549$.widget("ui.droppable", {
1550	widgetEventPrefix: "drop",
1551	options: {
1552		accept: '*',
1553		activeClass: false,
1554		addClasses: true,
1555		greedy: false,
1556		hoverClass: false,
1557		scope: 'default',
1558		tolerance: 'intersect'
1559	},
1560	_create: function() {
1561
1562		var o = this.options, accept = o.accept;
1563		this.isover = 0; this.isout = 1;
1564
1565		this.accept = $.isFunction(accept) ? accept : function(d) {
1566			return d.is(accept);
1567		};
1568
1569		//Store the droppable's proportions
1570		this.proportions = { width: this.element[0].offsetWidth, height: this.element[0].offsetHeight };
1571
1572		// Add the reference and positions to the manager
1573		$.ui.ddmanager.droppables[o.scope] = $.ui.ddmanager.droppables[o.scope] || [];
1574		$.ui.ddmanager.droppables[o.scope].push(this);
1575
1576		(o.addClasses && this.element.addClass("ui-droppable"));
1577
1578	},
1579
1580	destroy: function() {
1581		var drop = $.ui.ddmanager.droppables[this.options.scope];
1582		for ( var i = 0; i < drop.length; i++ )
1583			if ( drop[i] == this )
1584				drop.splice(i, 1);
1585
1586		this.element
1587			.removeClass("ui-droppable ui-droppable-disabled")
1588			.removeData("droppable")
1589			.unbind(".droppable");
1590
1591		return this;
1592	},
1593
1594	_setOption: function(key, value) {
1595
1596		if(key == 'accept') {
1597			this.accept = $.isFunction(value) ? value : function(d) {
1598				return d.is(value);
1599			};
1600		}
1601		$.Widget.prototype._setOption.apply(this, arguments);
1602	},
1603
1604	_activate: function(event) {
1605		var draggable = $.ui.ddmanager.current;
1606		if(this.options.activeClass) this.element.addClass(this.options.activeClass);
1607		(draggable && this._trigger('activate', event, this.ui(draggable)));
1608	},
1609
1610	_deactivate: function(event) {
1611		var draggable = $.ui.ddmanager.current;
1612		if(this.options.activeClass) this.element.removeClass(this.options.activeClass);
1613		(draggable && this._trigger('deactivate', event, this.ui(draggable)));
1614	},
1615
1616	_over: function(event) {
1617
1618		var draggable = $.ui.ddmanager.current;
1619		if (!draggable || (draggable.currentItem || draggable.element)[0] == this.element[0]) return; // Bail if draggable and droppable are same element
1620
1621		if (this.accept.call(this.element[0],(draggable.currentItem || draggable.element))) {
1622			if(this.options.hoverClass) this.element.addClass(this.options.hoverClass);
1623			this._trigger('over', event, this.ui(draggable));
1624		}
1625
1626	},
1627
1628	_out: function(event) {
1629
1630		var draggable = $.ui.ddmanager.current;
1631		if (!draggable || (draggable.currentItem || draggable.element)[0] == this.element[0]) return; // Bail if draggable and droppable are same element
1632
1633		if (this.accept.call(this.element[0],(draggable.currentItem || draggable.element))) {
1634			if(this.options.hoverClass) this.element.removeClass(this.options.hoverClass);
1635			this._trigger('out', event, this.ui(draggable));
1636		}
1637
1638	},
1639
1640	_drop: function(event,custom) {
1641
1642		var draggable = custom || $.ui.ddmanager.current;
1643		if (!draggable || (draggable.currentItem || draggable.element)[0] == this.element[0]) return false; // Bail if draggable and droppable are same element
1644
1645		var childrenIntersection = false;
1646		this.element.find(":data(droppable)").not(".ui-draggable-dragging").each(function() {
1647			var inst = $.data(this, 'droppable');
1648			if(
1649				inst.options.greedy
1650				&& !inst.options.disabled
1651				&& inst.options.scope == draggable.options.scope
1652				&& inst.accept.call(inst.element[0], (draggable.currentItem || draggable.element))
1653				&& $.ui.intersect(draggable, $.extend(inst, { offset: inst.element.offset() }), inst.options.tolerance)
1654			) { childrenIntersection = true; return false; }
1655		});
1656		if(childrenIntersection) return false;
1657
1658		if(this.accept.call(this.element[0],(draggable.currentItem || draggable.element))) {
1659			if(this.options.activeClass) this.element.removeClass(this.options.activeClass);
1660			if(this.options.hoverClass) this.element.removeClass(this.options.hoverClass);
1661			this._trigger('drop', event, this.ui(draggable));
1662			return this.element;
1663		}
1664
1665		return false;
1666
1667	},
1668
1669	ui: function(c) {
1670		return {
1671			draggable: (c.currentItem || c.element),
1672			helper: c.helper,
1673			position: c.position,
1674			offset: c.positionAbs
1675		};
1676	}
1677
1678});
1679
1680$.extend($.ui.droppable, {
1681	version: "@VERSION"
1682});
1683
1684$.ui.intersect = function(draggable, droppable, toleranceMode) {
1685
1686	if (!droppable.offset) return false;
1687
1688	var x1 = (draggable.positionAbs || draggable.position.absolute).left, x2 = x1 + draggable.helperProportions.width,
1689		y1 = (draggable.positionAbs || draggable.position.absolute).top, y2 = y1 + draggable.helperProportions.height;
1690	var l = droppable.offset.left, r = l + droppable.proportions.width,
1691		t = droppable.offset.top, b = t + droppable.proportions.height;
1692
1693	switch (toleranceMode) {
1694		case 'fit':
1695			return (l <= x1 && x2 <= r
1696				&& t <= y1 && y2 <= b);
1697			break;
1698		case 'intersect':
1699			return (l < x1 + (draggable.helperProportions.width / 2) // Right Half
1700				&& x2 - (draggable.helperProportions.width / 2) < r // Left Half
1701				&& t < y1 + (draggable.helperProportions.height / 2) // Bottom Half
1702				&& y2 - (draggable.helperProportions.height / 2) < b ); // Top Half
1703			break;
1704		case 'pointer':
1705			var draggableLeft = ((draggable.positionAbs || draggable.position.absolute).left + (draggable.clickOffset || draggable.offset.click).left),
1706				draggableTop = ((draggable.positionAbs || draggable.position.absolute).top + (draggable.clickOffset || draggable.offset.click).top),
1707				isOver = $.ui.isOver(draggableTop, draggableLeft, t, l, droppable.proportions.height, droppable.proportions.width);
1708			return isOver;
1709			break;
1710		case 'touch':
1711			return (
1712					(y1 >= t && y1 <= b) ||	// Top edge touching
1713					(y2 >= t && y2 <= b) ||	// Bottom edge touching
1714					(y1 < t && y2 > b)		// Surrounded vertically
1715				) && (
1716					(x1 >= l && x1 <= r) ||	// Left edge touching
1717					(x2 >= l && x2 <= r) ||	// Right edge touching
1718					(x1 < l && x2 > r)		// Surrounded horizontally
1719				);
1720			break;
1721		default:
1722			return false;
1723			break;
1724		}
1725
1726};
1727
1728/*
1729	This manager tracks offsets of draggables and droppables
1730*/
1731$.ui.ddmanager = {
1732	current: null,
1733	droppables: { 'default': [] },
1734	prepareOffsets: function(t, event) {
1735
1736		var m = $.ui.ddmanager.droppables[t.options.scope] || [];
1737		var type = event ? event.type : null; // workaround for #2317
1738		var list = (t.currentItem || t.element).find(":data(droppable)").andSelf();
1739
1740		droppablesLoop: for (var i = 0; i < m.length; i++) {
1741
1742			if(m[i].options.disabled || (t && !m[i].accept.call(m[i].element[0],(t.currentItem || t.element)))) continue;	//No disabled and non-accepted
1743			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
1744			m[i].visible = m[i].element.css("display") != "none"; if(!m[i].visible) continue; 									//If the element is not visible, continue
1745
1746			if(type == "mousedown") m[i]._activate.call(m[i], event); //Activate the droppable if used directly from draggables
1747
1748			m[i].offset = m[i].element.offset();
1749			m[i].proportions = { width: m[i].element[0].offsetWidth, height: m[i].element[0].offsetHeight };
1750
1751		}
1752
1753	},
1754	drop: function(draggable, event) {
1755
1756		var dropped = false;
1757		$.each($.ui.ddmanager.droppables[draggable.options.scope] || [], function() {
1758
1759			if(!this.options) return;
1760			if (!this.options.disabled && this.visible && $.ui.intersect(draggable, this, this.options.tolerance))
1761				dropped = this._drop.call(this, event) || dropped;
1762
1763			if (!this.options.disabled && this.visible && this.accept.call(this.element[0],(draggable.currentItem || draggable.element))) {
1764				this.isout = 1; this.isover = 0;
1765				this._deactivate.call(this, event);
1766			}
1767
1768		});
1769		return dropped;
1770
1771	},
1772	dragStart: function( draggable, event ) {
1773		//Listen for scrolling so that if the dragging causes scrolling the position of the droppables can be recalculated (see #5003)
1774		draggable.element.parents( ":not(body,html)" ).bind( "scroll.droppable", function() {
1775			if( !draggable.options.refreshPositions ) $.ui.ddmanager.prepareOffsets( draggable, event );
1776		});
1777	},
1778	drag: function(draggable, event) {
1779
1780		//If you have a highly dynamic page, you might try this option. It renders positions every time you move the mouse.
1781		if(draggable.options.refreshPositions) $.ui.ddmanager.prepareOffsets(draggable, event);
1782
1783		//Run through all droppables and check their positions based on specific tolerance options
1784		$.each($.ui.ddmanager.droppables[draggable.options.scope] || [], function() {
1785
1786			if(this.options.disabled || this.greedyChild || !this.visible) return;
1787			var intersects = $.ui.intersect(draggable, this, this.options.tolerance);
1788
1789			var c = !intersects && this.isover == 1 ? 'isout' : (intersects && this.isover == 0 ? 'isover' : null);
1790			if(!c) return;
1791
1792			var parentInstance;
1793			if (this.options.greedy) {
1794				var parent = this.element.parents(':data(droppable):eq(0)');
1795				if (parent.length) {
1796					parentInstance = $.data(parent[0], 'droppable');
1797					parentInstance.greedyChild = (c == 'isover' ? 1 : 0);
1798				}
1799			}
1800
1801			// we just moved into a greedy child
1802			if (parentInstance && c == 'isover') {
1803				parentInstance['isover'] = 0;
1804				parentInstance['isout'] = 1;
1805				parentInstance._out.call(parentInstance, event);
1806			}
1807
1808			this[c] = 1; this[c == 'isout' ? 'isover' : 'isout'] = 0;
1809			this[c == "isover" ? "_over" : "_out"].call(this, event);
1810
1811			// we just moved out of a greedy child
1812			if (parentInstance && c == 'isout') {
1813				parentInstance['isout'] = 0;
1814				parentInstance['isover'] = 1;
1815				parentInstance._over.call(parentInstance, event);
1816			}
1817		});
1818
1819	},
1820	dragStop: function( draggable, event ) {
1821		draggable.element.parents( ":not(body,html)" ).unbind( "scroll.droppable" );
1822		//Call prepareOffsets one final time since IE does not fire return scroll events when overflow was caused by drag (see #5003)
1823		if( !draggable.options.refreshPositions ) $.ui.ddmanager.prepareOffsets( draggable, event );
1824	}
1825};
1826
1827})(jQuery);
1828
1829(function( $, undefined ) {
1830
1831$.widget("ui.resizable", $.ui.mouse, {
1832	widgetEventPrefix: "resize",
1833	options: {
1834		alsoResize: false,
1835		animate: false,
1836		animateDuration: "slow",
1837		animateEasing: "swing",
1838		aspectRatio: false,
1839		autoHide: false,
1840		containment: false,
1841		ghost: false,
1842		grid: false,
1843		handles: "e,s,se",
1844		helper: false,
1845		maxHeight: null,
1846		maxWidth: null,
1847		minHeight: 10,
1848		minWidth: 10,
1849		zIndex: 1000
1850	},
1851	_create: function() {
1852
1853		var self = this, o = this.options;
1854		this.element.addClass("ui-resizable");
1855
1856		$.extend(this, {
1857			_aspectRatio: !!(o.aspectRatio),
1858			aspectRatio: o.aspectRatio,
1859			originalElement: this.element,
1860			_proportionallyResizeElements: [],
1861			_helper: o.helper || o.ghost || o.animate ? o.helper || 'ui-resizable-helper' : null
1862		});
1863
1864		//Wrap the element if it cannot hold child nodes
1865		if(this.element[0].nodeName.match(/canvas|textarea|input|select|button|img/i)) {
1866
1867			//Create a wrapper element and set the wrapper to the new current internal element
1868			this.element.wrap(
1869				$('<div class="ui-wrapper" style="overflow: hidden;"></div>').css({
1870					position: this.element.css('position'),
1871					width: this.element.outerWidth(),
1872					height: this.element.outerHeight(),
1873					top: this.element.css('top'),
1874					left: this.element.css('left')
1875				})
1876			);
1877
1878			//Overwrite the original this.element
1879			this.element = this.element.parent().data(
1880				"resizable", this.element.data('resizable')
1881			);
1882
1883			this.elementIsWrapper = true;
1884
1885			//Move margins to the wrapper
1886			this.element.css({ marginLeft: this.originalElement.css("marginLeft"), marginTop: this.originalElement.css("marginTop"), marginRight: this.originalElement.css("marginRight"), marginBottom: this.originalElement.css("marginBottom") });
1887			this.originalElement.css({ marginLeft: 0, marginTop: 0, marginRight: 0, marginBottom: 0});
1888
1889			//Prevent Safari textarea resize
1890			this.originalResizeStyle = this.originalElement.css('resize');
1891			this.originalElement.css('resize', 'none');
1892
1893			//Push the actual element to our proportionallyResize internal array
1894			this._proportionallyResizeElements.push(this.originalElement.css({ position: 'static', zoom: 1, display: 'block' }));
1895
1896			// avoid IE jump (hard set the margin)
1897			this.originalElement.css({ margin: this.originalElement.css('margin') });
1898
1899			// fix handlers offset
1900			this._proportionallyResize();
1901
1902		}
1903
1904		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' });
1905		if(this.handles.constructor == String) {
1906
1907			if(this.handles == 'all') this.handles = 'n,e,s,w,se,sw,ne,nw';
1908			var n = this.handles.split(","); this.handles = {};
1909
1910			for(var i = 0; i < n.length; i++) {
1911
1912				var handle = $.trim(n[i]), hname = 'ui-resizable-'+handle;
1913				var axis = $('<div class="ui-resizable-handle ' + hname + '"></div>');
1914
1915				// increase zIndex of sw, se, ne, nw axis
1916				//TODO : this modifies original option
1917				if(/sw|se|ne|nw/.test(handle)) axis.css({ zIndex: ++o.zIndex });
1918
1919				//TODO : What's going on here?
1920				if ('se' == handle) {
1921					axis.addClass('ui-icon ui-icon-gripsmall-diagonal-se');
1922				};
1923
1924				//Insert into internal handles object and append to element
1925				this.handles[handle] = '.ui-resizable-'+handle;
1926				this.element.append(axis);
1927			}
1928
1929		}
1930
1931		this._renderAxis = function(target) {
1932
1933			target = target || this.element;
1934
1935			for(var i in this.handles) {
1936
1937				if(this.handles[i].constructor == String)
1938					this.handles[i] = $(this.handles[i], this.element).show();
1939
1940				//Apply pad to wrapper element, needed to fix axis position (textarea, inputs, scrolls)
1941				if (this.elementIsWrapper && this.originalElement[0].nodeName.match(/textarea|input|select|button/i)) {
1942
1943					var axis = $(this.handles[i], this.element), padWrapper = 0;
1944
1945					//Checking the correct pad and border
1946					padWrapper = /sw|ne|nw|se|n|s/.test(i) ? axis.outerHeight() : axis.outerWidth();
1947
1948					//The padding type i have to apply...
1949					var padPos = [ 'padding',
1950						/ne|nw|n/.test(i) ? 'Top' :
1951						/se|sw|s/.test(i) ? 'Bottom' :
1952						/^e$/.test(i) ? 'Right' : 'Left' ].join("");
1953
1954					target.css(padPos, padWrapper);
1955
1956					this._proportionallyResize();
1957
1958				}
1959
1960				//TODO: What's that good for? There's not anything to be executed left
1961				if(!$(this.handles[i]).length)
1962					continue;
1963
1964			}
1965		};
1966
1967		//TODO: make renderAxis a prototype function
1968		this._renderAxis(this.element);
1969
1970		this._handles = $('.ui-resizable-handle', this.element)
1971			.disableSelection();
1972
1973		//Matching axis name
1974		this._handles.mouseover(function() {
1975			if (!self.resizing) {
1976				if (this.className)
1977					var axis = this.className.match(/ui-resizable-(se|sw|ne|nw|n|e|s|w)/i);
1978				//Axis, default = se
1979				self.axis = axis && axis[1] ? axis[1] : 'se';
1980			}
1981		});
1982
1983		//If we want to auto hide the elements
1984		if (o.autoHide) {
1985			this._handles.hide();
1986			$(this.element)
1987				.addClass("ui-resizable-autohide")
1988				.hover(function() {
1989					if (o.disabled) return;
1990					$(this).removeClass("ui-resizable-autohide");
1991					self._handles.show();
1992				},
1993				function(){
1994					if (o.disabled) return;
1995					if (!self.resizing) {
1996						$(this).addClass("ui-resizable-autohide");
1997						self._handles.hide();
1998					}
1999				});
2000		}
2001
2002		//Initialize the mouse interaction
2003		this._mouseInit();
2004
2005	},
2006
2007	destroy: function() {
2008
2009		this._mouseDestroy();
2010
2011		var _destroy = function(exp) {
2012			$(exp).removeClass("ui-resizable ui-resizable-disabled ui-resizable-resizing")
2013				.removeData("resizable").unbind(".resizable").find('.ui-resizable-handle').remove();
2014		};
2015
2016		//TODO: Unwrap at same DOM position
2017		if (this.elementIsWrapper) {
2018			_destroy(this.element);
2019			var wrapper = this.element;
2020			wrapper.after(
2021				this.originalElement.css({
2022					position: wrapper.css('position'),
2023					width: wrapper.outerWidth(),
2024					height: wrapper.outerHeight(),
2025					top: wrapper.css('top'),
2026					left: wrapper.css('left')
2027				})
2028			).remove();
2029		}
2030
2031		this.originalElement.css('resize', this.originalResizeStyle);
2032		_destroy(this.originalElement);
2033
2034		return this;
2035	},
2036
2037	_mouseCapture: function(event) {
2038		var handle = false;
2039		for (var i in this.handles) {
2040			if ($(this.handles[i])[0] == event.target) {
2041				handle = true;
2042			}
2043		}
2044
2045		return !this.options.disabled && handle;
2046	},
2047
2048	_mouseStart: function(event) {
2049
2050		var o = this.options, iniPos = this.element.position(), el = this.element;
2051
2052		this.resizing = true;
2053		this.documentScroll = { top: $(document).scrollTop(), left: $(document).scrollLeft() };
2054
2055		// bugfix for http://dev.jquery.com/ticket/1749
2056		if (el.is('.ui-draggable') || (/absolute/).test(el.css('position'))) {
2057			el.css({ position: 'absolute', top: iniPos.top, left: iniPos.left });
2058		}
2059
2060		this._renderProxy();
2061
2062		var curleft = num(this.helper.css('left')), curtop = num(this.helper.css('top'));
2063
2064		if (o.containment) {
2065			curleft += $(o.containment).scrollLeft() || 0;
2066			curtop += $(o.containment).scrollTop() || 0;
2067		}
2068
2069		//Store needed variables
2070		this.offset = this.helper.offset();
2071		this.position = { left: curleft, top: curtop };
2072		this.size = this._helper ? { width: el.outerWidth(), height: el.outerHeight() } : { width: el.width(), height: el.height() };
2073		this.originalSize = this._helper ? { width: el.outerWidth(), height: el.outerHeight() } : { width: el.width(), height: el.height() };
2074		this.originalPosition = { left: curleft, top: curtop };
2075		this.sizeDiff = { width: el.outerWidth() - el.width(), height: el.outerHeight() - el.height() };
2076		this.originalMousePosition = { left: event.pageX, top: event.pageY };
2077
2078		//Aspect Ratio
2079		this.aspectRatio = (typeof o.aspectRatio == 'number') ? o.aspectRatio : ((this.originalSize.width / this.originalSize.height) || 1);
2080
2081	    var cursor = $('.ui-resizable-' + this.axis).css('cursor');
2082	    $('body').css('cursor', cursor == 'auto' ? this.axis + '-resize' : cursor);
2083
2084		el.addClass("ui-resizable-resizing");
2085		this._propagate("start", event);
2086		return true;
2087	},
2088
2089	_mouseDrag: function(event) {
2090
2091		//Increase performance, avoid regex
2092		var el = this.helper, o = this.options, props = {},
2093			self = this, smp = this.originalMousePosition, a = this.axis;
2094
2095		var dx = (event.pageX-smp.left)||0, dy = (event.pageY-smp.top)||0;
2096		var trigger = this._change[a];
2097		if (!trigger) return false;
2098
2099		// Calculate the attrs that will be change
2100		var data = trigger.apply(this, [event, dx, dy]), ie6 = $.browser.msie && $.browser.version < 7, csdif = this.sizeDiff;
2101
2102		// Put this in the mouseDrag handler since the user can start pressing shift while resizing
2103		this._updateVirtualBoundaries(event.shiftKey);
2104		if (this._aspectRatio || event.shiftKey)
2105			data = this._updateRatio(data, event);
2106
2107		data = this._respectSize(data, event);
2108
2109		// plugins callbacks need to be called first
2110		this._propagate("resize", event);
2111
2112		el.css({
2113			top: this.position.top + "px", left: this.position.left + "px",
2114			width: this.size.width + "px", height: this.size.height + "px"
2115		});
2116
2117		if (!this._helper && this._proportionallyResizeElements.length)
2118			this._proportionallyResize();
2119
2120		this._updateCache(data);
2121
2122		// calling the user callback at the end
2123		this._trigger('resize', event, this.ui());
2124
2125		return false;
2126	},
2127
2128	_mouseStop: function(event) {
2129
2130		this.resizing = false;
2131		var o = this.options, self = this;
2132
2133		if(this._helper) {
2134			var pr = this._proportionallyResizeElements, ista = pr.length && (/textarea/i).test(pr[0].nodeName),
2135				soffseth = ista && $.ui.hasScroll(pr[0], 'left') /* TODO - jump height */ ? 0 : self.sizeDiff.height,
2136				soffsetw = ista ? 0 : self.sizeDiff.width;
2137
2138			var s = { width: (self.helper.width()  - soffsetw), height: (self.helper.height() - soffseth) },
2139				left = (parseInt(self.element.css('left'), 10) + (self.position.left - self.originalPosition.left)) || null,
2140				top = (parseInt(self.element.css('top'), 10) + (self.position.top - self.originalPosition.top)) || null;
2141
2142			if (!o.animate)
2143				this.element.css($.extend(s, { top: top, left: left }));
2144
2145			self.helper.height(self.size.height);
2146			self.helper.width(self.size.width);
2147
2148			if (this._helper && !o.animate) this._proportionallyResize();
2149		}
2150
2151		$('body').css('cursor', 'auto');
2152
2153		this.element.removeClass("ui-resizable-resizing");
2154
2155		this._propagate("stop", event);
2156
2157		if (this._helper) this.helper.remove();
2158		return false;
2159
2160	},
2161
2162    _updateVirtualBoundaries: function(forceAspectRatio) {
2163        var o = this.options, pMinWidth, pMaxWidth, pMinHeight, pMaxHeight, b;
2164
2165        b = {
2166            minWidth: isNumber(o.minWidth) ? o.minWidth : 0,
2167            maxWidth: isNumber(o.maxWidth) ? o.maxWidth : Infinity,
2168            minHeight: isNumber(o.minHeight) ? o.minHeight : 0,
2169            maxHeight: isNumber(o.maxHeight) ? o.maxHeight : Infinity
2170        };
2171
2172        if(this._aspectRatio || forceAspectRatio) {
2173            // We want to create an enclosing box whose aspect ration is the requested one
2174            // First, compute the "projected" size for each dimension based on the aspect ratio and other dimension
2175            pMinWidth = b.minHeight * this.aspectRatio;
2176            pMinHeight = b.minWidth / this.aspectRatio;
2177            pMaxWidth = b.maxHeight * this.aspectRatio;
2178            pMaxHeight = b.maxWidth / this.aspectRatio;
2179
2180            if(pMinWidth > b.minWidth) b.minWidth = pMinWidth;
2181            if(pMinHeight > b.minHeight) b.minHeight = pMinHeight;
2182            if(pMaxWidth < b.maxWidth) b.maxWidth = pMaxWidth;
2183            if(pMaxHeight < b.maxHeight) b.maxHeight = pMaxHeight;
2184        }
2185        this._vBoundaries = b;
2186    },
2187
2188	_updateCache: function(data) {
2189		var o = this.options;
2190		this.offset = this.helper.offset();
2191		if (isNumber(data.left)) this.position.left = data.left;
2192		if (isNumber(data.top)) this.position.top = data.top;
2193		if (isNumber(data.height)) this.size.height = data.height;
2194		if (isNumber(data.width)) this.size.width = data.width;
2195	},
2196
2197	_updateRatio: function(data, event) {
2198
2199		var o = this.options, cpos = this.position, csize = this.size, a = this.axis;
2200
2201		if (isNumber(data.height)) data.width = (data.height * this.aspectRatio);
2202		else if (isNumber(data.width)) data.height = (data.width / this.aspectRatio);
2203
2204		if (a == 'sw') {
2205			data.left = cpos.left + (csize.width - data.width);
2206			data.top = null;
2207		}
2208		if (a == 'nw') {
2209			data.top = cpos.top + (csize.height - data.height);
2210			data.left = cpos.left + (csize.width - data.width);
2211		}
2212
2213		return data;
2214	},
2215
2216	_respectSize: function(data, event) {
2217
2218		var el = this.helper, o = this._vBoundaries, pRatio = this._aspectRatio || event.shiftKey, a = this.axis,
2219				ismaxw = isNumber(data.width) && o.maxWidth && (o.maxWidth < data.width), ismaxh = isNumber(data.height) && o.maxHeight && (o.maxHeight < data.height),
2220					isminw = isNumber(data.width) && o.minWidth && (o.minWidth > data.width), isminh = isNumber(data.height) && o.minHeight && (o.minHeight > data.height);
2221
2222		if (isminw) data.width = o.minWidth;
2223		if (isminh) data.height = o.minHeight;
2224		if (ismaxw) data.width = o.maxWidth;
2225		if (ismaxh) data.height = o.maxHeight;
2226
2227		var dw = this.originalPosition.left + this.originalSize.width, dh = this.position.top + this.size.height;
2228		var cw = /sw|nw|w/.test(a), ch = /nw|ne|n/.test(a);
2229
2230		if (isminw && cw) data.left = dw - o.minWidth;
2231		if (ismaxw && cw) data.left = dw - o.maxWidth;
2232		if (isminh && ch)	data.top = dh - o.minHeight;
2233		if (ismaxh && ch)	data.top = dh - o.maxHeight;
2234
2235		// fixing jump error on top/left - bug #2330
2236		var isNotwh = !data.width && !data.height;
2237		if (isNotwh && !data.left && data.top) data.top = null;
2238		else if (isNotwh && !data.top && data.left) data.left = null;
2239
2240		return data;
2241	},
2242
2243	_proportionallyResize: function() {
2244
2245		var o = this.options;
2246		if (!this._proportionallyResizeElements.length) return;
2247		var element = this.helper || this.element;
2248
2249		for (var i=0; i < this._proportionallyResizeElements.length; i++) {
2250
2251			var prel = this._proportionallyResizeElements[i];
2252
2253			if (!this.borderDif) {
2254				var b = [prel.css('borderTopWidth'), prel.css('borderRightWidth'), prel.css('borderBottomWidth'), prel.css('borderLeftWidth')],
2255					p = [prel.css('paddingTop'), prel.css('paddingRight'), prel.css('paddingBottom'), prel.css('paddingLeft')];
2256
2257				this.borderDif = $.map(b, function(v, i) {
2258					var border = parseInt(v,10)||0, padding = parseInt(p[i],10)||0;
2259					return border + padding;
2260				});
2261			}
2262
2263			if ($.browser.msie && !(!($(element).is(':hidden') || $(element).parents(':hidden').length)))
2264				continue;
2265
2266			prel.css({
2267				height: (element.height() - this.borderDif[0] - this.borderDif[2]) || 0,
2268				width: (element.width() - this.borderDif[1] - this.borderDif[3]) || 0
2269			});
2270
2271		};
2272
2273	},
2274
2275	_renderProxy: function() {
2276
2277		var el = this.element, o = this.options;
2278		this.elementOffset = el.offset();
2279
2280		if(this._helper) {
2281
2282			this.helper = this.helper || $('<div style="overflow:hidden;"></div>');
2283
2284			// fix ie6 offset TODO: This seems broken
2285			var ie6 = $.browser.msie && $.browser.version < 7, ie6offset = (ie6 ? 1 : 0),
2286			pxyoffset = ( ie6 ? 2 : -1 );
2287
2288			this.helper.addClass(this._helper).css({
2289				width: this.element.outerWidth() + pxyoffset,
2290				height: this.element.outerHeight() + pxyoffset,
2291				position: 'absolute',
2292				left: this.elementOffset.left - ie6offset +'px',
2293				top: this.elementOffset.top - ie6offset +'px',
2294				zIndex: ++o.zIndex //TODO: Don't modify option
2295			});
2296
2297			this.helper
2298				.appendTo("body")
2299				.disableSelection();
2300
2301		} else {
2302			this.helper = this.element;
2303		}
2304
2305	},
2306
2307	_change: {
2308		e: function(event, dx, dy) {
2309			return { width: this.originalSize.width + dx };
2310		},
2311		w: function(event, dx, dy) {
2312			var o = this.options, cs = this.originalSize, sp = this.originalPosition;
2313			return { left: sp.left + dx, width: cs.width - dx };
2314		},
2315		n: function(event, dx, dy) {
2316			var o = this.options, cs = this.originalSize, sp = this.originalPosition;
2317			return { top: sp.top + dy, height: cs.height - dy };
2318		},
2319		s: function(event, dx, dy) {
2320			return { height: this.originalSize.height + dy };
2321		},
2322		se: function(event, dx, dy) {
2323			return $.extend(this._change.s.apply(this, arguments), this._change.e.apply(this, [event, dx, dy]));
2324		},
2325		sw: function(event, dx, dy) {
2326			return $.extend(this._change.s.apply(this, arguments), this._change.w.apply(this, [event, dx, dy]));
2327		},
2328		ne: function(event, dx, dy) {
2329			return $.extend(this._change.n.apply(this, arguments), this._change.e.apply(this, [event, dx, dy]));
2330		},
2331		nw: function(event, dx, dy) {
2332			return $.extend(this._change.n.apply(this, arguments), this._change.w.apply(this, [event, dx, dy]));
2333		}
2334	},
2335
2336	_propagate: function(n, event) {
2337		$.ui.plugin.call(this, n, [event, this.ui()]);
2338		(n != "resize" && this._trigger(n, event, this.ui()));
2339	},
2340
2341	plugins: {},
2342
2343	ui: function() {
2344		return {
2345			originalElement: this.originalElement,
2346			element: this.element,
2347			helper: this.helper,
2348			position: this.position,
2349			size: this.size,
2350			originalSize: this.originalSize,
2351			originalPosition: this.originalPosition
2352		};
2353	}
2354
2355});
2356
2357$.extend($.ui.resizable, {
2358	version: "@VERSION"
2359});
2360
2361/*
2362 * Resizable Extensions
2363 */
2364
2365$.ui.plugin.add("resizable", "alsoResize", {
2366
2367	start: function (event, ui) {
2368		var self = $(this).data("resizable"), o = self.options;
2369
2370		var _store = function (exp) {
2371			$(exp).each(function() {
2372				var el = $(this);
2373				el.data("resizable-alsoresize", {
2374					width: parseInt(el.width(), 10), height: parseInt(el.height(), 10),
2375					left: parseInt(el.css('left'), 10), top: parseInt(el.css('top'), 10)
2376				});
2377			});
2378		};
2379
2380		if (typeof(o.alsoResize) == 'object' && !o.alsoResize.parentNode) {
2381			if (o.alsoResize.length) { o.alsoResize = o.alsoResize[0]; _store(o.alsoResize); }
2382			else { $.each(o.alsoResize, function (exp) { _store(exp); }); }
2383		}else{
2384			_store(o.alsoResize);
2385		}
2386	},
2387
2388	resize: function (event, ui) {
2389		var self = $(this).data("resizable"), o = self.options, os = self.originalSize, op = self.originalPosition;
2390
2391		var delta = {
2392			height: (self.size.height - os.height) || 0, width: (self.size.width - os.width) || 0,
2393			top: (self.position.top - op.top) || 0, left: (self.position.left - op.left) || 0
2394		},
2395
2396		_alsoResize = function (exp, c) {
2397			$(exp).each(function() {
2398				var el = $(this), start = $(this).data("resizable-alsoresize"), style = {}, 
2399					css = c && c.length ? c : el.parents(ui.originalElement[0]).length ? ['width', 'height'] : ['width', 'height', 'top', 'left'];
2400
2401				$.each(css, function (i, prop) {
2402					var sum = (start[prop]||0) + (delta[prop]||0);
2403					if (sum && sum >= 0)
2404						style[prop] = sum || null;
2405				});
2406
2407				el.css(style);
2408			});
2409		};
2410
2411		if (typeof(o.alsoResize) == 'object' && !o.alsoResize.nodeType) {
2412			$.each(o.alsoResize, function (exp, c) { _alsoResize(exp, c); });
2413		}else{
2414			_alsoResize(o.alsoResize);
2415		}
2416	},
2417
2418	stop: function (event, ui) {
2419		$(this).removeData("resizable-alsoresize");
2420	}
2421});
2422
2423$.ui.plugin.add("resizable", "animate", {
2424
2425	stop: function(event, ui) {
2426		var self = $(this).data("resizable"), o = self.options;
2427
2428		var pr = self._proportionallyResizeElements, ista = pr.length && (/textarea/i).test(pr[0].nodeName),
2429					soffseth = ista && $.ui.hasScroll(pr[0], 'left') /* TODO - jump height */ ? 0 : self.sizeDiff.height,
2430						soffsetw = ista ? 0 : self.sizeDiff.width;
2431
2432		var style = { width: (self.size.width - soffsetw), height: (self.size.height - soffseth) },
2433					left = (parseInt(self.element.css('left'), 10) + (self.position.left - self.originalPosition.left)) || null,
2434						top = (parseInt(self.element.css('top'), 10) + (self.position.top - self.originalPosition.top)) || null;
2435
2436		self.element.animate(
2437			$.extend(style, top && left ? { top: top, left: left } : {}), {
2438				duration: o.animateDuration,
2439				easing: o.animateEasing,
2440				step: function() {
2441
2442					var data = {
2443						width: parseInt(self.element.css('width'), 10),
2444						height: parseInt(self.element.css('height'), 10),
2445						top: parseInt(self.element.css('top'), 10),
2446						left: parseInt(self.element.css('left'), 10)
2447					};
2448
2449					if (pr && pr.length) $(pr[0]).css({ width: data.width, height: data.height });
2450
2451					// propagating resize, and updating values for each animation step
2452					self._updateCache(data);
2453					self._propagate("resize", event);
2454
2455				}
2456			}
2457		);
2458	}
2459
2460});
2461
2462$.ui.plugin.add("resizable", "containment", {
2463
2464	start: function(event, ui) {
2465		var self = $(this).data("resizable"), o = self.options, el = self.element;
2466		var oc = o.containment,	ce = (oc instanceof $) ? oc.get(0) : (/parent/.test(oc)) ? el.parent().get(0) : oc;
2467		if (!ce) return;
2468
2469		self.containerElement = $(ce);
2470
2471		if (/document/.test(oc) || oc == document) {
2472			self.containerOffset = { left: 0, top: 0 };
2473			self.containerPosition = { left: 0, top: 0 };
2474
2475			self.parentData = {
2476				element: $(document), left: 0, top: 0,
2477				width: $(document).width(), height: $(document).height() || document.body.parentNode.scrollHeight
2478			};
2479		}
2480
2481		// i'm a node, so compute top, left, right, bottom
2482		else {
2483			var element = $(ce), p = [];
2484			$([ "Top", "Right", "Left", "Bottom" ]).each(function(i, name) { p[i] = num(element.css("padding" + name)); });
2485
2486			self.containerOffset = element.offset();
2487			self.containerPosition = element.position();
2488			self.containerSize = { height: (element.innerHeight() - p[3]), width: (element.innerWidth() - p[1]) };
2489
2490			var co = self.containerOffset, ch = self.containerSize.height,	cw = self.containerSize.width,
2491						width = ($.ui.hasScroll(ce, "left") ? ce.scrollWidth : cw ), height = ($.ui.hasScroll(ce) ? ce.scrollHeight : ch);
2492
2493			self.parentData = {
2494				element: ce, left: co.left, top: co.top, width: width, height: height
2495			};
2496		}
2497	},
2498
2499	resize: function(event, ui) {
2500		var self = $(this).data("resizable"), o = self.options,
2501				ps = self.containerSize, co = self.containerOffset, cs = self.size, cp = self.position,
2502				pRatio = self._aspectRatio || event.shiftKey, cop = { top:0, left:0 }, ce = self.containerElement;
2503
2504		if (ce[0] != document && (/static/).test(ce.css('position'))) cop = co;
2505
2506		if (cp.left < (self._helper ? co.left : 0)) {
2507			self.size.width = self.size.width + (self._helper ? (self.position.left - co.left) : (self.position.left - cop.left));
2508			if (pRatio) self.size.height = self.size.width / self.aspectRatio;
2509			self.position.left = o.helper ? co.left : 0;
2510		}
2511
2512		if (cp.top < (self._helper ? co.top : 0)) {
2513			self.size.height = self.size.height + (self._helper ? (self.position.top - co.top) : self.position.top);
2514			if (pRatio) self.size.width = self.size.height * self.aspectRatio;
2515			self.position.top = self._helper ? co.top : 0;
2516		}
2517
2518		self.offset.left = self.parentData.left+self.position.left;
2519		self.offset.top = self.parentData.top+self.position.top;
2520
2521		var woset = Math.abs( (self._helper ? self.offset.left - cop.left : (self.offset.left - cop.left)) + self.sizeDiff.width ),
2522					hoset = Math.abs( (self._helper ? self.offset.top - cop.top : (self.offset.top - co.top)) + self.sizeDiff.height );
2523
2524		var isParent = self.containerElement.get(0) == self.element.parent().get(0),
2525		    isOffsetRelative = /relative|absolute/.test(self.containerElement.css('position'));
2526
2527		if(isParent && isOffsetRelative) woset -= self.parentData.left;
2528
2529		if (woset + self.size.width >= self.parentData.width) {
2530			self.size.width = self.parentData.width - woset;
2531			if (pRatio) self.size.height = self.size.width / self.aspectRatio;
2532		}
2533
2534		if (hoset + self.size.height >= self.parentData.height) {
2535			self.size.height = self.parentData.height - hoset;
2536			if (pRatio) self.size.width = self.size.height * self.aspectRatio;
2537		}
2538	},
2539
2540	stop: function(event, ui){
2541		var self = $(this).data("resizable"), o = self.options, cp = self.position,
2542				co = self.containerOffset, cop = self.containerPosition, ce = self.containerElement;
2543
2544		var helper = $(self.helper), ho = helper.offset(), w = helper.outerWidth() - self.sizeDiff.width, h = helper.outerHeight() - self.sizeDiff.height;
2545
2546		if (self._helper && !o.animate && (/relative/).test(ce.css('position')))
2547			$(this).css({ left: ho.left - cop.left - co.left, width: w, height: h });
2548
2549		if (self._helper && !o.animate && (/static/).test(ce.css('position')))
2550			$(this).css({ left: ho.left - cop.left - co.left, width: w, height: h });
2551
2552	}
2553});
2554
2555$.ui.plugin.add("resizable", "ghost", {
2556
2557	start: function(event, ui) {
2558
2559		var self = $(this).data("resizable"), o = self.options, cs = self.size;
2560
2561		self.ghost = self.originalElement.clone();
2562		self.ghost
2563			.css({ opacity: .25, display: 'block', position: 'relative', height: cs.height, width: cs.width, margin: 0, left: 0, top: 0 })
2564			.addClass('ui-resizable-ghost')
2565			.addClass(typeof o.ghost == 'string' ? o.ghost : '');
2566
2567		self.ghost.appendTo(self.helper);
2568
2569	},
2570
2571	resize: function(event, ui){
2572		var self = $(this).data("resizable"), o = self.options;
2573		if (self.ghost) self.ghost.css({ position: 'relative', height: self.size.height, width: self.size.width });
2574	},
2575
2576	stop: function(event, ui){
2577		var self = $(this).data("resizable"), o = self.options;
2578		if (self.ghost && self.helper) self.helper.get(0).removeChild(self.ghost.get(0));
2579	}
2580
2581});
2582
2583$.ui.plugin.add("resizable", "grid", {
2584
2585	resize: function(event, ui) {
2586		var self = $(this).data("resizable"), o = self.options, cs = self.size, os = self.originalSize, op = self.originalPosition, a = self.axis, ratio = o._aspectRatio || event.shiftKey;
2587		o.grid = typeof o.grid == "number" ? [o.grid, o.grid] : o.grid;
2588		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);
2589
2590		if (/^(se|s|e)$/.test(a)) {
2591			self.size.width = os.width + ox;
2592			self.size.height = os.height + oy;
2593		}
2594		else if (/^(ne)$/.test(a)) {
2595			self.size.width = os.width + ox;
2596			self.size.height = os.height + oy;
2597			self.position.top = op.top - oy;
2598		}
2599		else if (/^(sw)$/.test(a)) {
2600			self.size.width = os.width + ox;
2601			self.size.height = os.height + oy;
2602			self.position.left = op.left - ox;
2603		}
2604		else {
2605			self.size.width = os.width + ox;
2606			self.size.height = os.height + oy;
2607			self.position.top = op.top - oy;
2608			self.position.left = op.left - ox;
2609		}
2610	}
2611
2612});
2613
2614var num = function(v) {
2615	return parseInt(v, 10) || 0;
2616};
2617
2618var isNumber = function(value) {
2619	return !isNaN(parseInt(value, 10));
2620};
2621
2622})(jQuery);
2623
2624(function( $, undefined ) {
2625
2626$.widget("ui.selectable", $.ui.mouse, {
2627	options: {
2628		appendTo: 'body',
2629		autoRefresh: true,
2630		distance: 0,
2631		filter: '*',
2632		tolerance: 'touch'
2633	},
2634	_create: function() {
2635		var self = this;
2636
2637		this.element.addClass("ui-selectable");
2638
2639		this.dragged = false;
2640
2641		// cache selectee children based on filter
2642		var selectees;
2643		this.refresh = function() {
2644			selectees = $(self.options.filter, self.element[0]);
2645			selectees.addClass("ui-selectee");
2646			selectees.each(function() {
2647				var $this = $(this);
2648				var pos = $this.offset();
2649				$.data(this, "selectable-item", {
2650					element: this,
2651					$element: $this,
2652					left: pos.left,
2653					top: pos.top,
2654					right: pos.left + $this.outerWidth(),
2655					bottom: pos.top + $this.outerHeight(),
2656					startselected: false,
2657					selected: $this.hasClass('ui-selected'),
2658					selecting: $this.hasClass('ui-selecting'),
2659					unselecting: $this.hasClass('ui-unselecting')
2660				});
2661			});
2662		};
2663		this.refresh();
2664
2665		this.selectees = selectees.addClass("ui-selectee");
2666
2667		this._mouseInit();
2668
2669		this.helper = $("<div class='ui-selectable-helper'></div>");
2670	},
2671
2672	destroy: function() {
2673		this.selectees
2674			.removeClass("ui-selectee")
2675			.removeData("selectable-item");
2676		this.element
2677			.removeClass("ui-selectable ui-selectable-disabled")
2678			.removeData("selectable")
2679			.unbind(".selectable");
2680		this._mouseDestroy();
2681
2682		return this;
2683	},
2684
2685	_mouseStart: function(event) {
2686		var self = this;
2687
2688		this.opos = [event.pageX, event.pageY];
2689
2690		if (this.options.disabled)
2691			return;
2692
2693		var options = this.options;
2694
2695		this.selectees = $(options.filter, this.element[0]);
2696
2697		this._trigger("start", event);
2698
2699		$(options.appendTo).append(this.helper);
2700		// position helper (lasso)
2701		this.helper.css({
2702			"left": event.clientX,
2703			"top": event.clientY,
2704			"width": 0,
2705			"height": 0
2706		});
2707
2708		if (options.autoRefresh) {
2709			this.refresh();
2710		}
2711
2712		this.selectees.filter('.ui-selected').each(function() {
2713			var selectee = $.data(this, "selectable-item");
2714			selectee.startselected = true;
2715			if (!event.metaKey && !event.ctrlKey) {
2716				selectee.$element.removeClass('ui-selected');
2717				selectee.selected = false;
2718				selectee.$element.addClass('ui-unselecting');
2719				selectee.unselecting = true;
2720				// selectable UNSELECTING callback
2721				self._trigger("unselecting", event, {
2722					unselecting: selectee.element
2723				});
2724			}
2725		});
2726
2727		$(event.target).parents().andSelf().each(function() {
2728			var selectee = $.data(this, "selectable-item");
2729			if (selectee) {
2730				var doSelect = (!event.metaKey && !event.ctrlKey) || !selectee.$element.hasClass('ui-selected');
2731				selectee.$element
2732					.removeClass(doSelect ? "ui-unselecting" : "ui-selected")
2733					.addClass(doSelect ? "ui-selecting" : "ui-unselecting");
2734				selectee.unselecting = !doSelect;
2735				selectee.selecting = doSelect;
2736				selectee.selected = doSelect;
2737				// selectable (UN)SELECTING callback
2738				if (doSelect) {
2739					self._trigger("selecting", event, {
2740						selecting: selectee.element
2741					});
2742				} else {
2743					self._trigger("unselecting", event, {
2744						unselecting: selectee.element
2745					});
2746				}
2747				return false;
2748			}
2749		});
2750
2751	},
2752
2753	_mouseDrag: function(event) {
2754		var self = this;
2755		this.dragged = true;
2756
2757		if (this.options.disabled)
2758			return;
2759
2760		var options = this.options;
2761
2762		var x1 = this.opos[0], y1 = this.opos[1], x2 = event.pageX, y2 = event.pageY;
2763		if (x1 > x2) { var tmp = x2; x2 = x1; x1 = tmp; }
2764		if (y1 > y2) { var tmp = y2; y2 = y1; y1 = tmp; }
2765		this.helper.css({left: x1, top: y1, width: x2-x1, height: y2-y1});
2766
2767		this.selectees.each(function() {
2768			var selectee = $.data(this, "selectable-item");
2769			//prevent helper from being selected if appendTo: selectable
2770			if (!selectee || selectee.element == self.element[0])
2771				return;
2772			var hit = false;
2773			if (options.tolerance == 'touch') {
2774				hit = ( !(selectee.left > x2 || selectee.right < x1 || selectee.top > y2 || selectee.bottom < y1) );
2775			} else if (options.tolerance == 'fit') {
2776				hit = (selectee.left > x1 && selectee.right < x2 && selectee.top > y1 && selectee.bottom < y2);
2777			}
2778
2779			if (hit) {
2780				// SELECT
2781				if (selectee.selected) {
2782					selectee.$element.removeClass('ui-selected');
2783					selectee.selected = false;
2784				}
2785				if (selectee.unselecting) {
2786					selectee.$element.removeClass('ui-unselecting');
2787					selectee.unselecting = false;
2788				}
2789				if (!selectee.selecting) {
2790					selectee.$element.addClass('ui-selecting');
2791					selectee.selecting = true;
2792					// selectable SELECTING callback
2793					self._trigger("selecting", event, {
2794						selecting: selectee.element
2795					});
2796				}
2797			} else {
2798				// UNSELECT
2799				if (selectee.selecting) {
2800					if ((event.metaKey || event.ctrlKey) && selectee.startselected) {
2801						selectee.$element.removeClass('ui-selecting');
2802						selectee.selecting = false;
2803						selectee.$element.addClass('ui-selected');
2804						selectee.selected = true;
2805					} else {
2806						selectee.$element.removeClass('ui-selecting');
2807						selectee.selecting = false;
2808						if (selectee.startselected) {
2809							selectee.$element.addClass('ui-unselecting');
2810							selectee.unselecting = true;
2811						}
2812						// selectable UNSELECTING callback
2813						self._trigger("unselecting", event, {
2814							unselecting: selectee.element
2815						});
2816					}
2817				}
2818				if (selectee.selected) {
2819					if (!event.metaKey && !event.ctrlKey && !selectee.startselected) {
2820						selectee.$element.removeClass('ui-selected');
2821						selectee.selected = false;
2822
2823						selectee.$element.addClass('ui-unselecting');
2824						selectee.unselecting = true;
2825						// selectable UNSELECTING callback
2826						self._trigger("unselecting", event, {
2827							unselecting: selectee.element
2828						});
2829					}
2830				}
2831			}
2832		});
2833
2834		return false;
2835	},
2836
2837	_mouseStop: function(event) {
2838		var self = this;
2839
2840		this.dragged = false;
2841
2842		var options = this.options;
2843
2844		$('.ui-unselecting', this.element[0]).each(function() {
2845			var selectee = $.data(this, "selectable-item");
2846			selectee.$element.removeClass('ui-unselecting');
2847			selectee.unselecting = false;
2848			selectee.startselected = false;
2849			self._trigger("unselected", event, {
2850				unselected: selectee.element
2851			});
2852		});
2853		$('.ui-selecting', this.element[0]).each(function() {
2854			var selectee = $.data(this, "selectable-item");
2855			selectee.$element.removeClass('ui-selecting').addClass('ui-selected');
2856			selectee.selecting = false;
2857			selectee.selected = true;
2858			selectee.startselected = true;
2859			self._trigger("selected", event, {
2860				selected: selectee.element
2861			});
2862		});
2863		this._trigger("stop", event);
2864
2865		this.helper.remove();
2866
2867		return false;
2868	}
2869
2870});
2871
2872$.extend($.ui.selectable, {
2873	version: "@VERSION"
2874});
2875
2876})(jQuery);
2877
2878(function( $, undefined ) {
2879
2880$.widget("ui.sortable", $.ui.mouse, {
2881	widgetEventPrefix: "sort",
2882	ready: false,
2883	options: {
2884		appendTo: "parent",
2885		axis: false,
2886		connectWith: false,
2887		containment: false,
2888		cursor: 'auto',
2889		cursorAt: false,
2890		dropOnEmpty: true,
2891		forcePlaceholderSize: false,
2892		forceHelperSize: false,
2893		grid: false,
2894		handle: false,
2895		helper: "original",
2896		items: '> *',
2897		opacity: false,
2898		placeholder: false,
2899		revert: false,
2900		scroll: true,
2901		scrollSensitivity: 20,
2902		scrollSpeed: 20,
2903		scope: "default",
2904		tolerance: "intersect",
2905		zIndex: 1000
2906	},
2907	_create: function() {
2908
2909		var o = this.options;
2910		this.containerCache = {};
2911		this.element.addClass("ui-sortable");
2912
2913		//Get the items
2914		this.refresh();
2915
2916		//Let's determine if the items are being displayed horizontally
2917		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;
2918
2919		//Let's determine the parent's offset
2920		this.offset = this.element.offset();
2921
2922		//Initialize mouse events for interaction
2923		this._mouseInit();
2924		
2925		//We're ready to go
2926		this.ready = true
2927
2928	},
2929
2930	destroy: function() {
2931		$.Widget.prototype.destroy.call( this );
2932		this.element
2933			.removeClass("ui-sortable ui-sortable-disabled");
2934		this._mouseDestroy();
2935
2936		for ( var i = this.items.length - 1; i >= 0; i-- )
2937			this.items[i].item.removeData(this.widgetName + "-item");
2938
2939		return this;
2940	},
2941
2942	_setOption: function(key, value){
2943		if ( key === "disabled" ) {
2944			this.options[ key ] = value;
2945	
2946			this.widget()
2947				[ value ? "addClass" : "removeClass"]( "ui-sortable-disabled" );
2948		} else {
2949			// Don't call widget base _setOption for disable as it adds ui-state-disabled class
2950			$.Widget.prototype._setOption.apply(this, arguments);
2951		}
2952	},
2953
2954	_mouseCapture: function(event, overrideHandle) {
2955		var that = this;
2956
2957		if (this.reverting) {
2958			return false;
2959		}
2960
2961		if(this.options.disabled || this.options.type == 'static') return false;
2962
2963		//We have to refresh the items data once first
2964		this._refreshItems(event);
2965
2966		//Find out if the clicked node (or one of its parents) is a actual item in this.items
2967		var currentItem = null, self = this, nodes = $(event.target).parents().each(function() {
2968			if($.data(this, that.widgetName + '-item') == self) {
2969				currentItem = $(this);
2970				return false;
2971			}
2972		});
2973		if($.data(event.target, that.widgetName + '-item') == self) currentItem = $(event.target);
2974
2975		if(!currentItem) return false;
2976		if(this.options.handle && !overrideHandle) {
2977			var validHandle = false;
2978
2979			$(this.options.handle, currentItem).find("*").andSelf().each(function() { if(this == event.target) validHandle = true; });
2980			if(!validHandle) return false;
2981		}
2982
2983		this.currentItem = currentItem;
2984		this._removeCurrentsFromItems();
2985		return true;
2986
2987	},
2988
2989	_mouseStart: function(event, overrideHandle, noActivation) {
2990
2991		var o = this.options, self = this;
2992		this.currentContainer = this;
2993
2994		//We only need to call refreshPositions, because the refreshItems call has been moved to mouseCapture
2995		this.refreshPositions();
2996
2997		//Create and append the visible helper
2998		this.helper = this._createHelper(event);
2999
3000		//Cache the helper size
3001		this._cacheHelperProportions();
3002
3003		/*
3004		 * - Position generation -
3005		 * This block generates everything position related - it's the core of draggables.
3006		 */
3007
3008		//Cache the margins of the original element
3009		this._cacheMargins();
3010
3011		//Get the next scrolling parent
3012		this.scrollParent = this.helper.scrollParent();
3013
3014		//The element's absolute position on the page minus margins
3015		this.offset = this.currentItem.offset();
3016		this.offset = {
3017			top: this.offset.top - this.margins.top,
3018			left: this.offset.left - this.margins.left
3019		};
3020
3021		// Only after we got the offset, we can change the helper's position to absolute
3022		// TODO: Still need to figure out a way to make relative sorting possible
3023		this.helper.css("position", "absolute");
3024		this.cssPosition = this.helper.css("position");
3025
3026		$.extend(this.offset, {
3027			click: { //Where the click happened, relative to the element
3028				left: event.pageX - this.offset.left,
3029				top: event.pageY - this.offset.top
3030			},
3031			parent: this._getParentOffset(),
3032			relative: this._getRelativeOffset() //This is a relative to absolute position minus the actual position calculation - only used for relative positioned helper
3033		});
3034
3035		//Generate the original position
3036		this.originalPosition = this._generatePosition(event);
3037		this.originalPageX = event.pageX;
3038		this.originalPageY = event.pageY;
3039
3040		//Adjust the mouse offset relative to the helper if 'cursorAt' is supplied
3041		(o.cursorAt && this._adjustOffsetFromHelper(o.cursorAt));
3042
3043		//Cache the former DOM position
3044		this.domPosition = { prev: this.currentItem.prev()[0], parent: this.currentItem.parent()[0] };
3045
3046		//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
3047		if(this.helper[0] != this.currentItem[0]) {
3048			this.currentItem.hide();
3049		}
3050
3051		//Create the placeholder
3052		this._createPlaceholder();
3053
3054		//Set a containment if given in the options
3055		if(o.containment)
3056			this._setContainment();
3057
3058		if(o.cursor) { // cursor option
3059			if ($('body').css("cursor")) this._storedCursor = $('body').css("cursor");
3060			$('body').css("cursor", o.cursor);
3061		}
3062
3063		if(o.opacity) { // opacity option
3064			if (this.helper.css("opacity")) this._storedOpacity = this.helper.css("opacity");
3065			this.helper.css("opacity", o.opacity);
3066		}
3067
3068		if(o.zIndex) { // zIndex option
3069			if (this.helper.css("zIndex")) this._storedZIndex = this.helper.css("zIndex");
3070			this.helper.css("zIndex", o.zIndex);
3071		}
3072
3073		//Prepare scrolling
3074		if(this.scrollParent[0] != document && this.scrollParent[0].tagName != 'HTML')
3075			this.overflowOffset = this.scrollParent.offset();
3076
3077		//Call callbacks
3078		this._trigger("start", event, this._uiHash());
3079
3080		//Recache the helper size
3081		if(!this._preserveHelperProportions)
3082			this._cacheHelperProportions();
3083
3084
3085		//Post 'activate' events to possible containers
3086		if(!noActivation) {
3087			 for (var i = this.containers.length - 1; i >= 0; i--) { this.containers[i]._trigger("activate", event, self._uiHash(this)); }
3088		}
3089
3090		//Prepare possible droppables
3091		if($.ui.ddmanager)
3092			$.ui.ddmanager.current = this;
3093
3094		if ($.ui.ddmanager && !o.dropBehaviour)
3095			$.ui.ddmanager.prepareOffsets(this, event);
3096
3097		this.dragging = true;
3098
3099		this.helper.addClass("ui-sortable-helper");
3100		this._mouseDrag(event); //Execute the drag once - this causes the helper not to be visible before getting its correct position
3101		return true;
3102
3103	},
3104
3105	_mouseDrag: function(event) {
3106
3107		//Compute the helpers position
3108		this.position = this._generatePosition(event);
3109		this.positionAbs = this._convertPositionTo("absolute");
3110
3111		if (!this.lastPositionAbs) {
3112			this.lastPositionAbs = this.positionAbs;
3113		}
3114
3115		//Do scrolling
3116		if(this.options.scroll) {
3117			var o = this.options, scrolled = false;
3118			if(this.scrollParent[0] != document && this.scrollParent[0].tagName != 'HTML') {
3119
3120				if((this.overflowOffset.top + this.scrollParent[0].offsetHeight) - event.pageY < o.scrollSensitivity)
3121					this.scrollParent[0].scrollTop = scrolled = this.scrollParent[0].scrollTop + o.scrollSpeed;
3122				else if(event.pageY - this.overflowOffset.top < o.scrollSensitivity)
3123					this.scrollParent[0].scrollTop = scrolled = this.scrollParent[0].scrollTop - o.scrollSpeed;
3124
3125				if((this.overflowOffset.left + this.scrollParent[0].offsetWidth) - event.pageX < o.scrollSensitivity)
3126					this.scrollParent[0].scrollLeft = scrolled = this.scrollParent[0].scrollLeft + o.scrollSpeed;
3127				else if(event.pageX - this.overflowOffset.left < o.scrollSensitivity)
3128					this.scrollParent[0].scrollLeft = scrolled = this.scrollParent[0].scrollLeft - o.scrollSpeed;
3129
3130			} else {
3131
3132				if(event.pageY - $(document).scrollTop() < o.scrollSensitivity)
3133					scrolled = $(document).scrollTop($(document).scrollTop() - o.scrollSpeed);
3134				else if($(window).height() - (event.pageY - $(document).scrollTop()) < o.scrollSensitivity)
3135					scrolled = $(document).scrollTop($(document).scrollTop() + o.scrollSpeed);
3136
3137				if(event.pageX - $(document).scrollLeft() < o.scrollSensitivity)
3138					scrolled = $(document).scrollLeft($(document).scrollLeft() - o.scrollSpeed);
3139				else if($(window).width() - (event.pageX - $(document).scrollLeft()) < o.scrollSensitivity)
3140					scrolled = $(document).scrollLeft($(document).scrollLeft() + o.scrollSpeed);
3141
3142			}
3143
3144			if(scrolled !== false && $.ui.ddmanager && !o.dropBehaviour)
3145				$.ui.ddmanager.prepareOffsets(this, event);
3146		}
3147
3148		//Regenerate the absolute position used for position checks
3149		this.positionAbs = this._convertPositionTo("absolute");
3150
3151		//Set the helper position
3152		if(!this.options.axis || this.options.axis != "y") this.helper[0].style.left = this.position.left+'px';
3153		if(!this.options.axis || this.options.axis != "x") this.helper[0].style.top = this.position.top+'px';
3154
3155		//Rearrange
3156		for (var i = this.items.length - 1; i >= 0; i--) {
3157
3158			//Cache variables and intersection, continue if no intersection
3159			var item = this.items[i], itemElement = item.item[0], intersection = this._intersectsWithPointer(item);
3160			if (!intersection) continue;
3161
3162			if(itemElement != this.currentItem[0] //cannot intersect with itself
3163				&&	this.placeholder[intersection == 1 ? "next" : "prev"]()[0] != itemElement //no useless actions that have been done before
3164				&&	!$.ui.contains(this.placeholder[0], itemElement) //no action if the item moved is the parent of the item checked
3165				&& (this.options.type == 'semi-dynamic' ? !$.ui.contains(this.element[0], itemElement) : true)
3166				//&& itemElement.parentNode == this.placeholder[0].parentNode // only rearrange items within the same container
3167			) {
3168
3169				this.direction = intersection == 1 ? "down" : "up";
3170
3171				if (this.options.tolerance == "pointer" || this._intersectsWithSides(item)) {
3172					this._rearrange(event, item);
3173				} else {
3174					break;
3175				}
3176
3177				this._trigger("change", event, this._uiHash());
3178				break;
3179			}
3180		}
3181
3182		//Post events to containers
3183		this._contactContainers(event);
3184
3185		//Interconnect with droppables
3186		if($.ui.ddmanager) $.ui.ddmanager.drag(this, event);
3187
3188		//Call callbacks
3189		this._trigger('sort', event, this._uiHash());
3190
3191		this.lastPositionAbs = this.positionAbs;
3192		return false;
3193
3194	},
3195
3196	_mouseStop: function(event, noPropagation) {
3197
3198		if(!event) return;
3199
3200		//If we are using droppables, inform the manager about the drop
3201		if ($.ui.ddmanager && !this.options.dropBehaviour)
3202			$.ui.ddmanager.drop(this, event);
3203
3204		if(this.options.revert) {
3205			var self = this;
3206			var cur = self.placeholder.offset();
3207
3208			self.reverting = true;
3209
3210			$(this.helper).animate({
3211				left: cur.left - this.offset.parent.left - self.margins.left + (this.offsetParent[0] == document.body ? 0 : this.offsetParent[0].scrollLeft),
3212				top: cur.top - this.offset.parent.top - self.margins.top + (this.offsetParent[0] == document.body ? 0 : this.offsetParent[0].scrollTop)
3213			}, parseInt(this.options.revert, 10) || 500, function() {
3214				self._clear(event);
3215			});
3216		} else {
3217			this._clear(event, noPropagation);
3218		}
3219
3220		return false;
3221
3222	},
3223
3224	cancel: function() {
3225
3226		var self = this;
3227
3228		if(this.dragging) {
3229
3230			this._mouseUp({ target: null });
3231
3232			if(this.options.helper == "original")
3233				this.currentItem.css(this._storedCSS).removeClass("ui-sortable-helper");
3234			else
3235				this.currentItem.show();
3236
3237			//Post deactivating events to containers
3238			for (var i = this.containers.length - 1; i >= 0; i--){
3239				this.containers[i]._trigger("deactivate", null, self._uiHash(this));
3240				if(this.containers[i].containerCache.over) {
3241					this.containers[i]._trigger("out", null, self._uiHash(this));
3242					this.containers[i].containerCache.over = 0;
3243				}
3244			}
3245
3246		}
3247
3248		if (this.placeholder) {
3249			//$(this.placeholder[0]).remove(); would have been the jQuery way - unfortunately, it unbinds ALL events from the original node!
3250			if(this.placeholder[0].parentNode) this.placeholder[0].parentNode.removeChild(this.placeholder[0]);
3251			if(this.options.helper != "original" && this.helper && this.helper[0].parentNode) this.helper.remove();
3252
3253			$.extend(this, {
3254				helper: null,
3255				dragging: false,
3256				reverting: false,
3257				_noFinalSort: null
3258			});
3259
3260			if(this.domPosition.prev) {
3261				$(this.domPosition.prev).after(this.currentItem);
3262			} else {
3263				$(this.domPosition.parent).prepend(this.currentItem);
3264			}
3265		}
3266
3267		return this;
3268
3269	},
3270
3271	serialize: function(o) {
3272
3273		var items = this._getItemsAsjQuery(o && o.connected);
3274		var str = []; o = o || {};
3275
3276		$(items).each(function() {
3277			var res = ($(o.item || this).attr(o.attribute || 'id') || '').match(o.expression || (/(.+)[-=_](.+)/));
3278			if(res) str.push((o.key || res[1]+'[]')+'='+(o.key && o.expression ? res[1] : res[2]));
3279		});
3280
3281		if(!str.length && o.key) {
3282			str.push(o.key + '=');
3283		}
3284
3285		return str.join('&');
3286
3287	},
3288
3289	toArray: function(o) {
3290
3291		var items = this._getItemsAsjQuery(o && o.connected);
3292		var ret = []; o = o || {};
3293
3294		items.each(function() { ret.push($(o.item || this).attr(o.attribute || 'id') || ''); });
3295		return ret;
3296
3297	},
3298
3299	/* Be careful with the following core functions */
3300	_intersectsWith: function(item) {
3301
3302		var x1 = this.positionAbs.left,
3303			x2 = x1 + this.helperProportions.width,
3304			y1 = this.positionAbs.top,
3305			y2 = y1 + this.helperProportions.height;
3306
3307		var l = item.left,
3308			r = l + item.width,
3309			t = item.top,
3310			b = t + item.height;
3311
3312		var dyClick = this.offset.click.top,
3313			dxClick = this.offset.click.left;
3314
3315		var isOverElement = (y1 + dyClick) > t && (y1 + dyClick) < b && (x1 + dxClick) > l && (x1 + dxClick) < r;
3316
3317		if(	   this.options.tolerance == "pointer"
3318			|| this.options.forcePointerForContainers
3319			|| (this.options.tolerance != "pointer" && this.helperProportions[this.floating ? 'width' : 'height'] > item[this.floating ? 'width' : 'height'])
3320		) {
3321			return isOverElement;
3322		} else {
3323
3324			return (l < x1 + (this.helperProportions.width / 2) // Right Half
3325				&& x2 - (this.helperProportions.width / 2) < r // Left Half
3326				&& t < y1 + (this.helperProportions.height / 2) // Bottom Half
3327				&& y2 - (this.helperProportions.height / 2) < b ); // Top Half
3328
3329		}
3330	},
3331
3332	_intersectsWithPointer: function(item) {
3333
3334		var isOverElementHeight = $.ui.isOverAxis(this.positionAbs.top + this.offset.click.top, item.top, item.height),
3335			isOverElementWidth = $.ui.isOverAxis(this.positionAbs.left + this.offset.click.left, item.left, item.width),
3336			isOverElement = isOverElementHeight && isOverElementWidth,
3337			verticalDirection = this._getDragVerticalDirection(),
3338			horizontalDirection = this._getDragHorizontalDirection();
3339
3340		if (!isOverElement)
3341			return false;
3342
3343		return this.floating ?
3344			( ((horizontalDirection && horizontalDirection == "right") || verticalDirection == "down") ? 2 : 1 )
3345			: ( verticalDirection && (verticalDirection == "down" ? 2 : 1) );
3346
3347	},
3348
3349	_intersectsWithSides: function(item) {
3350
3351		var isOverBottomHalf = $.ui.isOverAxis(this.positionAbs.top + this.offset.click.top, item.top + (item.height/2), item.height),
3352			isOverRightHalf = $.ui.isOverAxis(this.positionAbs.left + this.offset.click.left, item.left + (item.width/2), item.width),
3353			verticalDirection = this._getDragVerticalDirection(),
3354			horizontalDirection = this._getDragHorizontalDirection();
3355
3356		if (this.floating && horizontalDirection) {
3357			return ((horizontalDirection == "right" && isOverRightHalf) || (horizontalDirection == "left" && !isOverRightHalf));
3358		} else {
3359			return verticalDirection && ((verticalDirection == "down" && isOverBottomHalf) || (verticalDirection == "up" && !isOverBottomHalf));
3360		}
3361
3362	},
3363
3364	_getDragVerticalDirection: function() {
3365		var delta = this.positionAbs.top - this.lastPositionAbs.top;
3366		return delta != 0 && (delta > 0 ? "down" : "up");
3367	},
3368
3369	_getDragHorizontalDirection: function() {
3370		var delta = this.positionAbs.left - this.lastPositionAbs.left;
3371		return delta != 0 && (delta > 0 ? "right" : "left");
3372	},
3373
3374	refresh: function(event) {
3375		this._refreshItems(event);
3376		this.refreshPositions();
3377		return this;
3378	},
3379
3380	_connectWith: function() {
3381		var options = this.options;
3382		return options.connectWith.constructor == String
3383			? [options.connectWith]
3384			: options.connectWith;
3385	},
3386	
3387	_getItemsAsjQuery: function(connected) {
3388
3389		var self = this;
3390		var items = [];
3391		var queries = [];
3392		var connectWith = this._connectWith();
3393
3394		if(connectWith && connected) {
3395			for (var i = connectWith.length - 1; i >= 0; i--){
3396				var cur = $(connectWith[i]);
3397				for (var j = cur.length - 1; j >= 0; j--){
3398					var inst = $.data(cur[j], this.widgetName);
3399					if(inst && inst != this && !inst.options.disabled) {
3400						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]);
3401					}
3402				};
3403			};
3404		}
3405
3406		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]);
3407
3408		for (var i = queries.length - 1; i >= 0; i--){
3409			queries[i][0].each(function() {
3410				items.push(this);
3411			});
3412		};
3413
3414		return $(items);
3415
3416	},
3417
3418	_removeCurrentsFromItems: function() {
3419
3420		var list = this.currentItem.find(":data(" + this.widgetName + "-item)");
3421
3422		for (var i=0; i < this.items.length; i++) {
3423
3424			for (var j=0; j < list.length; j++) {
3425				if(list[j] == this.items[i].item[0])
3426					this.items.splice(i,1);
3427			};
3428
3429		};
3430
3431	},
3432
3433	_refreshItems: function(event) {
3434
3435		this.items = [];
3436		this.containers = [this];
3437		var items = this.items;
3438		var self = this;
3439		var queries = [[$.isFunction(this.options.items) ? this.options.items.call(this.element[0], event, { item: this.currentItem }) : $(this.options.items, this.element), this]];
3440		var connectWith = this._connectWith();
3441
3442		if(connectWith && this.ready) { //Shouldn't be run the first time through due to massive slow-down
3443			for (var i = connectWith.length - 1; i >= 0; i--){
3444				var cur = $(connectWith[i]);
3445				for (var j = cur.length - 1; j >= 0; j--){
3446					var inst = $.data(cur[j], this.widgetName);
3447					if(inst && inst != this && !inst.options.disabled) {
3448						queries.push([$.isFunction(inst.options.items) ? inst.options.items.call(inst.element[0], event, { item: this.currentItem }) : $(inst.options.items, inst.element), inst]);
3449						this.containers.push(inst);
3450					}
3451				};
3452			};
3453		}
3454
3455		for (var i = queries.length - 1; i >= 0; i--) {
3456			var targetData = queries[i][1];
3457			var _queries = queries[i][0];
3458
3459			for (var j=0, queriesLength = _queries.length; j < queriesLength; j++) {
3460				var item = $(_queries[j]);
3461
3462				item.data(this.widgetName + '-item', targetData); // Data for target checking (mouse manager)
3463
3464				items.push({
3465					item: item,
3466					instance: targetData,
3467					width: 0, height: 0,
3468					left: 0, top: 0
3469				});
3470			};
3471		};
3472
3473	},
3474
3475	refreshPositions: function(fast) {
3476
3477		//This has to be redone because due to the item being moved out/into the offsetParent, the offsetParent's position will change
3478		if(this.offsetParent && this.helper) {
3479			this.offset.parent = this._getParentOffset();
3480		}
3481
3482		for (var i = this.items.length - 1; i >= 0; i--){
3483			var item = this.items[i];
3484
3485			//We ignore calculating positions of all connected containers when we're not over them
3486			if(item.instance != this.currentContainer && this.currentContainer && item.item[0] != this.currentItem[0])
3487				continue;
3488
3489			var t = this.options.toleranceElement ? $(this.options.toleranceElement, item.item) : item.item;
3490
3491			if (!fast) {
3492				item.width = t.outerWidth();
3493				item.height = t.outerHeight();
3494			}
3495
3496			var p = t.offset();
3497			item.left = p.left;
3498			item.top = p.top;
3499		};
3500
3501		if(this.options.custom && this.options.custom.refreshContainers
3501) {
3502			this.options.custom.refreshContainers.call(this);
3503		} else {
3504			for (var i = this.containers.length - 1; i >= 0; i--){
3505				var p = this.containers[i].element.offset();
3506				this.containers[i].containerCache.left = p.left;
3507				this.containers[i].containerCache.top = p.top;
3508				this.containers[i].containerCache.width	= this.containers[i].element.outerWidth();
3509				this.containers[i].containerCache.height = this.containers[i].element.outerHeight();
3510			};
3511		}
3512
3513		return this;
3514	},
3515
3516	_createPlaceholder: function(that) {
3517
3518		var self = that || this, o = self.options;
3519
3520		if(!o.placeholder || o.placeholder.constructor == String) {
3521			var className = o.placeholder;
3522			o.placeholder = {
3523				element: function() {
3524
3525					var el = $(document.createElement(self.currentItem[0].nodeName))
3526						.addClass(className || self.currentItem[0].className+" ui-sortable-placeholder")
3527						.removeClass("ui-sortable-helper").html("&nbsp;")[0];
3528
3529					if(!className)
3530						el.style.visibility = "hidden";
3531
3532					return el;
3533				},
3534				update: function(container, p) {
3535
3536					// 1. If a className is set as 'placeholder option, we don't force sizes - the class is responsible for that
3537					// 2. The option 'forcePlaceholderSize can be enabled to force it even if a class name is specified
3538					if(className && !o.forcePlaceholderSize) return;
3539
3540					//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
3541					if(!p.height()) { p.height(self.currentItem.innerHeight() - parseInt(self.currentItem.css('paddingTop')||0, 10) - parseInt(self.currentItem.css('paddingBottom')||0, 10)); };
3542					if(!p.width()) { p.width(self.currentItem.innerWidth() - parseInt(self.currentItem.css('paddingLeft')||0, 10) - parseInt(self.currentItem.css('paddingRight')||0, 10)); };
3543				}
3544			};
3545		}
3546
3547		//Create the placeholder
3548		self.placeholder = $(o.placeholder.element.call(self.element, self.currentItem));
3549
3550		//Append it after the actual current item
3551		self.currentItem.after(self.placeholder);
3552
3553		//Update the size of the placeholder (TODO: Logic to fuzzy, see line 316/317)
3554		o.placeholder.update(self, self.placeholder);
3555
3556	},
3557
3558	_contactContainers: function(event) {
3559		
3560		// get innermost container that intersects with item 
3561		var innermostContainer = null, innermostIndex = null;		
3562		
3563		
3564		for (var i = this.containers.length - 1; i >= 0; i--){
3565
3566			// never consider a container that's located within the item itself 
3567			if($.ui.contains(this.currentItem[0], this.containers[i].element[0]))
3568				continue;
3569
3570			if(this._intersectsWith(this.containers[i].containerCache)) {
3571
3572				// if we've already found a container and it's more "inner" than this, then continue 
3573				if(innermostContainer && $.ui.contains(this.containers[i].element[0], innermostContainer.element[0]))
3574					continue;
3575
3576				innermostContainer = this.containers[i]; 
3577				innermostIndex = i;
3578					
3579			} else {
3580				// container doesn't intersect. trigger "out" event if necessary 
3581				if(this.containers[i].containerCache.over) {
3582					this.containers[i]._trigger("out", event, this._uiHash(this));
3583					this.containers[i].containerCache.over = 0;
3584				}
3585			}
3586
3587		}
3588		
3589		// if no intersecting containers found, return 
3590		if(!innermostContainer) return; 
3591
3592		// move the item into the container if it's not there already
3593		if(this.containers.length === 1) {
3594			this.containers[innermostIndex]._trigger("over", event, this._uiHash(this));
3595			this.containers[innermostIndex].containerCache.over = 1;
3596		} else if(this.currentContainer != this.containers[innermostIndex]) { 
3597
3598			//When entering a new container, we will find the item with the least distance and append our item near it 
3599			var dist = 10000; var itemWithLeastDistance = null; var base = this.positionAbs[this.containers[innermostIndex].floating ? 'left' : 'top']; 
3600			for (var j = this.items.length - 1; j >= 0; j--) { 
3601				if(!$.ui.contains(this.containers[innermostIndex].element[0], this.items[j].item[0])) continue; 
3602				var cur = this.items[j][this.containers[innermostIndex].floating ? 'left' : 'top']; 
3603				if(Math.abs(cur - base) < dist) { 
3604					dist = Math.abs(cur - base); itemWithLeastDistance = this.items[j]; 
3605				} 
3606			} 
3607
3608			if(!itemWithLeastDistance && !this.options.dropOnEmpty) //Check if dropOnEmpty is enabled 
3609				return; 
3610
3611			this.currentContainer = this.containers[innermostIndex]; 
3612			itemWithLeastDistance ? this._rearrange(event, itemWithLeastDistance, null, true) : this._rearrange(event, null, this.containers[innermostIndex].element, true); 
3613			this._trigger("change", event, this._uiHash()); 
3614			this.containers[innermostIndex]._trigger("change", event, this._uiHash(this)); 
3615
3616			//Update the placeholder 
3617			this.options.placeholder.update(this.currentContainer, this.placeholder); 
3618		
3619			this.containers[innermostIndex]._trigger("over", event, this._uiHash(this)); 
3620			this.containers[innermostIndex].containerCache.over = 1;
3621		} 
3622	
3623		
3624	},
3625
3626	_createHelper: function(event) {
3627
3628		var o = this.options;
3629		var helper = $.isFunction(o.helper) ? $(o.helper.apply(this.element[0], [event, this.currentItem])) : (o.helper == 'clone' ? this.currentItem.clone() : this.currentItem);
3630
3631		if(!helper.parents('body').length) //Add the helper to the DOM if that didn't happen already
3632			$(o.appendTo != 'parent' ? o.appendTo : this.currentItem[0].parentNode)[0].appendChild(helper[0]);
3633
3634		if(helper[0] == this.currentItem[0])
3635			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
3635: this.currentItem.css("left") };
3636
3637		if(helper[0].style.width == '' || o.forceHelperSize) helper.width(this.currentItem.width());
3638		if(helper[0].style.height == '' || o.forceHelperSize) helper.height(this.currentItem.height());
3639
3640		return helper;
3641
3642	},
3643
3644	_adjustOffsetFromHelper: function(obj) {
3645		if (typeof obj == 'string') {
3646			obj = obj.split(' ');
3647		}
3648		if ($.isArray(obj)) {
3649			obj = {left: +obj[0], top: +obj[1] || 0};
3650		}
3651		if ('left' in obj) {
3652			this.offset.click.left = obj.left + this.margins.left;
3653		}
3654		if ('right' in obj) {
3655			this.offset.click.left = this.helperProportions.width - obj.right + this.margins.left;
3656		}
3657		if ('top' in obj) {
3658			this.offset.click.top = obj.top + this.margins.top;
3659		}
3660		if ('bottom' in obj) {
3661			this.offset.click.top = this.helperProportions.height - obj.bottom + this.margins.top;
3662		}
3663	},
3664
3665	_getParentOffset: function() {
3666
3667
3668		//Get the offsetParent and cache its position
3669		this.offsetParent = this.helper.offsetParent();
3670		var po = this.offsetParent.offset();
3671
3672		// This is a special case where we need to modify a offset calculated on start, since the following happened:
3673		// 1. The position of the helper is absolute, so it's position is calculated based on the next positioned parent
3674		// 2. The actual offset parent is a child of the scroll parent, and the scroll parent isn't the document, which means that
3675		//    the scroll is included in the initial calculation of the offset of the parent, and never recalculated upon drag
3676		if(this.cssPosition == 'absolute' && this.scrollParent[0] != document && $.ui.contains(this.scrollParent[0], this.offsetParent[0])) {
3677			po.left += this.scrollParent.scrollLeft();
3678			po.top += this.scrollParent.scrollTop();
3679		}
3680
3681		if((this.offsetParent[0] == document.body) //This needs to be actually done for all browsers, since pageX/pageY includes this information
3682		|| (this.offsetParent[0].tagName && this.offsetParent[0].tagName.toLowerCase() == 'html' && $.browser.msie)) //Ugly IE fix
3683			po = { top: 0, left: 0 };
3684
3685		return {
3686			top: po.top + (parseInt(this.offsetParent.css("borderTopWidth"),10) || 0),
3687			left: po.left + (parseInt(this.offsetParent.css("borderLeftWidth"),10) || 0)
3688		};
3689
3690	},
3691
3692	_getRelativeOffset: function() {
3693
3694		if(this.cssPosition == "relative") {
3695			var p = this.currentItem.position();
3696			return {
3697				top: p.top - (parseInt(this.helper.css("top"),10) || 0) + this.scrollParent.scrollTop(),
3698				left: p.left - (parseInt(this.helper.css("left"),10) || 0) + this.scrollParent.scrollLeft()
3699			};
3700		} else {
3701			return { top: 0, left: 0 };
3702		}
3703
3704	},
3705
3706	_cacheMargins: function() {
3707		this.margins = {
3708			left: (parseInt(this.currentItem.css("marginLeft"),10) || 0),
3709			top: (parseInt(this.currentItem.css("marginTop"),10) || 0)
3710		};
3711	},
3712
3713	_cacheHelperProportions: function() {
3714		this.helperProportions = {
3715			width: this.helper.outerWidth(),
3716			height: this.helper.outerHeight()
3717		};
3718	},
3719
3720	_setContainment: function() {
3721
3722		var o = this.options;
3723		if(o.containment == 'parent') o.containment = this.helper[0].parentNode;
3724		if(o.containment == 'document' || o.containment == 'window') this.containment = [
3725			0 - this.offset.relative.left - this.offset.parent.left,
3726			0 - this.offset.relative.top - this.offset.parent.top,
3727			$(o.containment == 'document' ? document : window).width() - this.helperProportions.width - this.margins.left,
3728			($(o.containment == 'document' ? document : window).height() || document.body.parentNode.scrollHeight) - this.helperProportions.height - this.margins.top
3729		];
3730
3731		if(!(/^(document|window|parent)$/).test(o.containment)) {
3732			var ce = $(o.containment)[0];
3733			var co = $(o.containment).offset();
3734			var over = ($(ce).css("overflow") != 'hidden');
3735
3736			this.containment = [
3737				co.left + (parseInt($(ce).css("borderLeftWidth"),10) || 0) + (parseInt($(ce).css("paddingLeft"),10) || 0) - this.margins.left,
3738				co.top + (parseInt($(ce).css("borderTopWidth"),10) || 0) + (parseInt($(ce).css("paddingTop"),10) || 0) - this.margins.top,
3739				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,
3740				co.top+(over ? Math.max(ce.scrollHeight,ce.offsetHeight) : ce.offsetHeight) - (parseInt($(ce).css("borderTopWidth"),
374010) || 0) - (parseInt($(ce).css("paddingBottom"),10) || 0) - this.helperProportions.height - this.margins.top
3741			];
3742		}
3743
3744	},
3745
3746	_convertPositionTo: function(d, pos) {
3747
3748		if(!pos) pos = this.position;
3749		var mod = d == "absolute" ? 1 : -1;
3750		var o = this.options, scroll = this.cssPosition == 'absolute' && !(this.scrollParent[0] != document && $.ui.contains(this.scrollParent[0], this.offsetParent[0])) ? this.offsetParent : this.scrollParent, scrollIsRootNode = (/(html|body)/i).test(scroll[0].tagName);
3751
3752		return {
3753			top: (
3754				pos.top																	// The absolute mouse position
3755				+ this.offset.relative.top * mod										// Only for relative positioned nodes: Relative offset from element to offset parent
3756				+ this.offset.parent.top * mod											// The offsetParent's offset without borders (offset + border)
3757				- ($.browser.safari && this.cssPosition == 'fixed' ? 0 : ( this.cssPosition == 'fixed' ? -this.scrollParent.scrollTop() : ( scrollIsRootNode ? 0 : scroll.scrollTop() ) ) * mod)
3758			),
3759			left: (
3760				pos.left																// The absolute mouse position
3761				+ this.offset.relative.left * mod										// Only for relative positioned nodes: Relative offset from element to offset parent
3762				+ this.offset.parent.left * mod											// The offsetParent's offset without borders (offset + border)
3763				- ($.browser.safari && this.cssPosition == 'fixed' ? 0 : ( this.cssPosition == 'fixed' ? -this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 : scroll.scrollLeft() ) * mod)
3764			)
3765		};
3766
3767	},
3768
3769	_generatePosition: function(event) {
3770
3771		var o = this.options, scroll = this.cssPosition == 'absolute' && !(this.scrollParent[0] != document && $.ui.contains(this.scrollParent[0], this.offsetParent[0])) ? this.offsetParent : this.scrollParent, scrollIsRootNode = (/(html|body)/i).test(scroll[0].tagName);
3772
3773		// This is another very weird special case that only happens for relative elements:
3774		// 1. If the css position is relative
3775		// 2. and the scroll parent is the document or similar to the offset parent
3776		// we have to refresh the relative offset during the scroll so there are no jumps
3777		if(this.cssPosition == 'relative' && !(this.scrollParent[0] != document && this.scrollParent[0] != this.offsetParent[0])) {
3778			this.offset.relative = this._getRelativeOffset();
3779		}
3780
3781		var pageX = event.pageX;
3782		var pageY = event.pageY;
3783
3784		/*
3785		 * - Position constraining -
3786		 * Constrain the position to a mix of grid, containment.
3787		 */
3788
3789		if(this.originalPosition) { //If we are not dragging yet, we won't check for options
3790
3791			if(this.containment) {
3792				if(event.pageX - this.offset.click.left < this.containment[0]) pageX = this.containment[0] + this.offset.click.left;
3793				if(event.pageY - this.offset.click.top < this.containment[1]) pageY = this.containment[1] + this.offset.click.top;
3794				if(event.pageX - this.offset.click.left > this.containment[2]) pageX = this.containment[2] + this.offset.click.left;
3795				if(event.pageY - this.offset.click.top > this.containment[3]) pageY = this.containment[3] + this.offset.click.top;
3796			}
3797
3798			if(o.grid) {
3799				var top = this.originalPageY + Math.round((pageY - this.originalPageY) / o.grid[1]) * o.grid[1];
3800				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;
3801
3802				var left = this.originalPageX + Math.round((pageX - this.originalPageX) / o.grid[0]) * o.grid[0];
3803				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;
3804			}
3805
3806		}
3807
3808		return {
3809			top: (
3810				pageY																// The absolute mouse position
3811				- this.offset.click.top													// Click offset (relative to the element)
3812				- this.offset.relative.top												// Only for relative positioned nodes: Relative offset from element to offset parent
3813				- this.offset.parent.top												// The offsetParent's offset without borders (offset + border)
3814				+ ($.browser.safari && this.cssPosition == 'fixed' ? 0 : ( this.cssPosition == 'fixed' ? -this.scrollParent.scrollTop() : ( scrollIsRootNode ? 0 : scroll.scrollTop() ) ))
3815			),
3816			left: (
3817				pageX																// The absolute mouse position
3818				- this.offset.click.left												// Click offset (relative to the element)
3819				- this.offset.relative.left												// Only for relative positioned nodes: Relative offset from element to offset parent
3820				- this.offset.parent.left												// The offsetParent's offset without borders (offset + border)
3821				+ ($.browser.safari && this.cssPosition == 'fixed' ? 0 : ( this.cssPosition == 'fixed' ? -this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 : scroll.scrollLeft() ))
3822			)
3823		};
3824
3825	},
3826
3827	_rearrange: function(event, i, a, hardRefresh) {
3828
3829		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));
3830
3831		//Various things done here to improve the performance:
3832		// 1. we create a setTimeout, that calls refreshPositions
3833		// 2. on the instance, we have a counter variable, that get's higher after every append
3834		// 3. on the local scope, we copy the counter variable, and check in the timeout, if it's still the same
3835		// 4. this lets only the last addition to the timeout stack through
3836		this.counter = this.counter ? ++this.counter : 1;
3837		var self = this, counter = this.counter;
3838
3839		window.setTimeout(function() {
3840			if(counter == self.counter) self.refreshPositions(!hardRefresh); //Precompute after each DOM insertion, NOT on mousemove
3841		},0);
3842
3843	},
3844
3845	_clear: function(event, noPropagation) {
3846
3847		this.reverting = false;
3848		// We delay all events that have to be triggered to after the point where the placeholder has been removed and
3849		// everything else normalized again
3850		var delayedTriggers = [], self = this;
3851
3852		// We first have to update the dom position of the actual currentItem
3853		// Note: don't do it if the current item is already removed (by a user), or it gets reappended (see #4088)
3854		if(!this._noFinalSort && this.currentItem.parent().length) this.placeholder.before(this.currentItem);
3855		this._noFinalSort = null;
3856
3857		if(this.helper[0] == this.currentItem[0]) {
3858			for(var i in this._storedCSS) {
3859				if(this._storedCSS[i] == 'auto' || this._storedCSS[i] == 'static') this._storedCSS[i] = '';
3860			}
3861			this.currentItem.css(this._storedCSS).removeClass("ui-sortable-helper");
3862		} else {
3863			this.currentItem.show();
3864		}
3865
3866		if(this.fromOutside && !noPropagation) delayedTriggers.push(function(event) { this._trigger("receive", event, this._uiHash(this.fromOutside)); });
3867		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
3868		if(!$.ui.contains(this.element[0], this.currentItem[0])) { //Node was moved out of the current element
3869			if(!noPropagation) delayedTriggers.push(function(event) { this._trigger("remove", event, this._uiHash()); });
3870			for (var i = this.containers.length - 1; i >= 0; i--){
3871				if($.ui.contains(this.containers[i].element[0], this.currentItem[0]) && !noPropagation) {
3872					delayedTriggers.push((function(c) { return function(event) { c._trigger("receive", event, this._uiHash(this)); };  }).call(this, this.containers[i]));
3873					delayedTriggers.push((function(c) { return function(event) { c._trigger("update", event, this._uiHash(this));  }; }).call(this, this.containers[i]));
3874				}
3875			};
3876		};
3877
3878		//Post events to containers
3879		for (var i = this.containers.length - 1; i >= 0; i--){
3880			if(!noPropagation) delayedTriggers.push((function(c) { return function(event) { c._trigger("deactivate", event, this._uiHash(this)); };  }).call(this, this.containers[i]));
3881			if(this.containers[i].containerCache.over) {
3882				delayedTriggers.push((function(c) { return function(event) { c._trigger("out", event, this._uiHash(this)); };  }).call(this, this.containers[i]));
3883				this.containers[i].containerCache.over = 0;
3884			}
3885		}
3886
3887		//Do what was originally in plugins
3888		if(this._storedCursor) $('body').css("cursor", this._storedCursor); //Reset cursor
3889		if(this._storedOpacity) this.helper.css("opacity", this._storedOpacity); //Reset opacity
3890		if(this._storedZIndex) this.helper.css("zIndex", this._storedZIndex == 'auto' ? '' : this._storedZIndex); //Reset z-index
3891
3892		this.dragging = false;
3893		if(this.cancelHelperRemoval) {
3894			if(!noPropagation) {
3895				this._trigger("beforeStop", event, this._uiHash());
3896				for (var i=0; i < delayedTriggers.length; i++) { delayedTriggers[i].call(this, event); }; //Trigger all delayed events
3897				this._trigger("stop", event, this._uiHash());
3898			}
3899			return false;
3900		}
3901
3902		if(!noPropagation) this._trigger("beforeStop", event, this._uiHash());
3903
3904		//$(this.placeholder[0]).remove(); would have been the jQuery way - unfortunately, it unbinds ALL events from the original node!
3905		this.placeholder[0].parentNode.removeChild(this.placeholder[0]);
3906
3907		if(this.helper[0] != this.currentItem[0]) this.helper.remove(); this.helper = null;
3908
3909		if(!noPropagation) {
3910			for (var i=0; i < delayedTriggers.length; i++) { delayedTriggers[i].call(this, event); }; //Trigger all delayed events
3911			this._trigger("stop", event, this._uiHash());
3912		}
3913
3914		this.fromOutside = false;
3915		return true;
3916
3917	},
3918
3919	_trigger: function() {
3920		if ($.Widget.prototype._trigger.apply(this, arguments) === false) {
3921			this.cancel();
3922		}
3923	},
3924
3925	_uiHash: function(inst) {
3926		var self = inst || this;
3927		return {
3928			helper: self.helper,
3929			placeholder: self.placeholder || $([]),
3930			position: self.position,
3931			originalPosition: self.originalPosition,
3932			offset: self.positionAbs,
3933			item: self.currentItem,
3934			sender: inst ? inst.element : null
3935		};
3936	}
3937
3938});
3939
3940$.extend($.ui.sortable, {
3941	version: "@VERSION"
3942});
3943
3944})(jQuery);
3945
3946;jQuery.effects || (function($, undefined) {
3947
3948$.effects = {};
3949
3950
3951
3952/******************************************************************************/
3953/****************************** COLOR ANIMATIONS ******************************/
3954/******************************************************************************/
3955
3956// override the animation for color styles
3957$.each(['backgroundColor', 'borderBottomColor', 'borderLeftColor',
3958	'borderRightColor', 'borderTopColor', 'borderColor', 'color', 'outlineColor'],
3959function(i, attr) {
3960	$.fx.step[attr] = function(fx) {
3961		if (!fx.colorInit) {
3962			fx.start = getColor(fx.elem, attr);
3963			fx.end = getRGB(fx.end);
3964			fx.colorInit = true;
3965		}
3966
3967		fx.elem.style[attr] = 'rgb(' +
3968			Math.max(Math.min(parseInt((fx.pos * (fx.end[0] - fx.start[0])) + fx.start[0], 10), 255), 0
3968) + ',' +
3969			Math.max(Math.min(parseInt((fx.pos * (fx.end[1] - fx.start[1])) + fx.start[1], 10), 255), 0) + ',' +
3970			Math.max(Math.min(parseInt((fx.pos * (fx.end[2] - fx.start[2])) + fx.start[2], 10), 255), 0) + ')';
3971	};
3972});
3973
3974// Color Conversion functions from highlightFade
3975// By Blair Mitchelmore
3976// http://jquery.offput.ca/highlightFade/
3977
3978// Parse strings looking for color tuples [255,255,255]
3979function getRGB(color) {
3980		var result;
3981
3982		// Check if we're already dealing with an array of colors
3983		if ( color && color.constructor == Array && color.length == 3 )
3984				return color;
3985
3986		// Look for rgb(num,num,num)
3987		if (result = /rgb\(\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*\)/.exec(color))
3988				return [parseInt(result[1],10), parseInt(result[2],10), parseInt(result[3],10)];
3989
3990		// Look for rgb(num%,num%,num%)
3991		if (result = /rgb\(\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*\)/.exec(color))
3992				return [parseFloat(result[1])*2.55, parseFloat(result[2])*2.55, parseFloat(result[3])*2.55];
3993
3994		// Look for #a0b1c2
3995		if (result = /#([a-fA-F0-9]{2})([a-fA-F0-9]{2})([a-fA-F0-9]{2})/.exec(color))
3996				return [parseInt(result[1],16), parseInt(result[2],16), parseInt(result[3],16)];
3997
3998		// Look for #fff
3999		if (result = /#([a-fA-F0-9])([a-fA-F0-9])([a-fA-F0-9])/.exec(color))
4000				return [parseInt(result[1]+result[1],16), parseInt(result[2]+result[2],16), parseInt(result[3]+result[3],16)];
4001
4002		// Look for rgba(0, 0, 0, 0) == transparent in Safari 3
4003		if (result = /rgba\(0, 0, 0, 0\)/.exec(color))
4004				return colors['transparent'];
4005
4006		// Otherwise, we're most likely dealing with a named color
4007		return colors[$.trim(color).toLowerCase()];
4008}
4009
4010function getColor(elem, attr) {
4011		var color;
4012
4013		do {
4014				color = $.curCSS(elem, attr);
4015
4016				// Keep going until we find an element that has color, or we hit the body
4017				if ( color != '' && color != 'transparent' || $.nodeName(elem, "body") )
4018						break;
4019
4020				attr = "backgroundColor";
4021		} while ( elem = elem.parentNode );
4022
4023		return getRGB(color);
4024};
4025
4026// Some named colors to work with
4027// From Interface by Stefan Petre
4028// http://interface.eyecon.ro/
4029
4030var colors = {
4031	aqua:[0,255,255],
4032	azure:[240,255,255],
4033	beige:[245,245,220],
4034	black:[0,0,0],
4035	blue:[0,0,255],
4036	brown:[165,42,42],
4037	cyan:[0,255,255],
4038	darkblue:[0,0,139],
4039	darkcyan:[0,139,139],
4040	darkgrey:[169,169,169],
4041	darkgreen:[0,100,0],
4042	darkkhaki:[189,183,107],
4043	darkmagenta:[139,0,139],
4044	darkolivegreen:[85,107,47],
4045	darkorange:[255,140,0],
4046	darkorchid:[153,50,204],
4047	darkred:[139,0,0],
4048	darksalmon:[233,150,122],
4049	darkviolet:[148,0,211],
4050	fuchsia:[255,0,255],
4051	gold:[255,215,0],
4052	green:[0,128,0],
4053	indigo:[75,0,130],
4054	khaki:[240,230,140],
4055	lightblue:[173,216,230],
4056	lightcyan:[224,255,255],
4057	lightgreen:[144,238,144],
4058	lightgrey:[211,211,211],
4059	lightpink:[255,182,193],
4060	lightyellow:[255,255,224],
4061	lime:[0,255,0],
4062	magenta:[255,0,255],
4063	maroon:[128,0,0],
4064	navy:[0,0,128],
4065	olive:[128,128,0],
4066	orange:[255,165,0],
4067	pink:[255,192,203],
4068	purple:[128,0,128],
4069	violet:[128,0,128],
4070	red:[255,0,0],
4071	silver:[192,192,192],
4072	white:[255,255,255],
4073	yellow:[255,255,0],
4074	transparent: [255,255,255]
4075};
4076
4077
4078
4079/******************************************************************************/
4080/****************************** CLASS ANIMATIONS ******************************/
4081/******************************************************************************/
4082
4083var classAnimationActions = ['add', 'remove', 'toggle'],
4084	shorthandStyles = {
4085		border: 1,
4086		borderBottom: 1,
4087		borderColor: 1,
4088		borderLeft: 1,
4089		borderRight: 1,
4090		borderTop: 1,
4091		borderWidth: 1,
4092		margin: 1,
4093		padding: 1
4094	};
4095
4096function getElementStyles() {
4097	var style = document.defaultView
4098			? document.defaultView.getComputedStyle(this, null)
4099			: this.currentStyle,
4100		newStyle = {},
4101		key,
4102		camelCase;
4103
4104	// webkit enumerates style porperties
4105	if (style && style.length && style[0] && style[style[0]]) {
4106		var len = style.length;
4107		while (len--) {
4108			key = style[len];
4109			if (typeof style[key] == 'string') {
4110				camelCase = key.replace(/\-(\w)/g, function(all, letter){
4111					return letter.toUpperCase();
4112				});
4113				newStyle[camelCase] = style[key];
4114			}
4115		}
4116	} else {
4117		for (key in style) {
4118			if (typeof style[key] === 'string') {
4119				newStyle[key] = style[key];
4120			}
4121		}
4122	}
4123	
4124	return newStyle;
4125}
4126
4127function filterStyles(styles) {
4128	var name, value;
4129	for (name in styles) {
4130		value = styles[name];
4131		if (
4132			// ignore null and undefined values
4133			value == null ||
4134			// ignore functions (when does this occur?)
4135			$.isFunction(value) ||
4136			// shorthand styles that need to be expanded
4137			name in shorthandStyles ||
4138			// ignore scrollbars (break in IE)
4139			(/scrollbar/).test(name) ||
4140
4141			// only colors or values that can be converted to numbers
4142			(!(/color/i).test(name) && isNaN(parseFloat(value)))
4143		) {
4144			delete styles[name];
4145		}
4146	}
4147	
4148	return styles;
4149}
4150
4151function styleDifference(oldStyle, newStyle) {
4152	var diff = { _: 0 }, // http://dev.jquery.com/ticket/5459
4153		name;
4154
4155	for (name in newStyle) {
4156		if (oldStyle[name] != newStyle[name]) {
4157			diff[name] = newStyle[name];
4158		}
4159	}
4160
4161	return diff;
4162}
4163
4164$.effects.animateClass = function(value, duration, easing, callback) {
4165	if ($.isFunction(easing)) {
4166		callback = easing;
4167		easing = null;
4168	}
4169
4170	return this.queue(function() {
4171		var that = $(this),
4172			originalStyleAttr = that.attr('style') || ' ',
4173			originalStyle = filterStyles(getElementStyles.call(this)),
4174			newStyle,
4175			className = that.attr('class') || "";
4176
4177		$.each(classAnimationActions, function(i, action) {
4178			if (value[action]) {
4179				that[action + 'Class'](value[action]);
4180			}
4181		});
4182		newStyle = filterStyles(getElementStyles.call(this));
4183		that.attr('class', className);
4184
4185		that.animate(styleDifference(originalStyle, newStyle), {
4186			queue: false,
4187			duration: duration,
4188			easing: easing,
4189			complete: function() {
4190				$.each(classAnimationActions, function(i, action) {
4191					if (value[action]) { that[action + 'Class'](value[action]); }
4192				});
4193				// work around bug in IE by clearing the cssText before setting it
4194				if (typeof that.attr('style') == 'object') {
4195					that.attr('style').cssText = '';
4196					that.attr('style').cssText = originalStyleAttr;
4197				} else {
4198					that.attr('style', originalStyleAttr);
4199				}
4200				if (callback) { callback.apply(this, arguments); }
4201				$.dequeue( this );
4202			}
4203		});
4204	});
4205};
4206
4207$.fn.extend({
4208	_addClass: $.fn.addClass,
4209	addClass: function(classNames, speed, easing, callback) {
4210		return speed ? $.effects.animateClass.apply(this, [{ add: classNames },speed,easing,callback]) : this._addClass(classNames);
4211	},
4212
4213	_removeClass: $.fn.removeClass,
4214	removeClass: function(classNames,speed,easing,callback) {
4215		return speed ? $.effects.animateClass.apply(this, [{ remove: classNames },speed,easing,callback]) : this._removeClass(classNames);
4216	},
4217
4218	_toggleClass: $.fn.toggleClass,
4219	toggleClass: function(classNames, force, speed, easing, callback) {
4220		if ( typeof force == "boolean" || force === undefined ) {
4221			if ( !speed ) {
4222				// without speed parameter;
4223				return this._toggleClass(classNames, force);
4224			} else {
4225				return $.effects.animateClass.apply(this, [(force?{add:classNames}:{remove:classNames}),speed,easing,callback]);
4226			}
4227		} else {
4228			// without switch parameter;
4229			return $.effects.animateClass.apply(this, [{ toggle: classNames },force,speed,easing]);
4230		}
4231	},
4232
4233	switchClass: function(remove,add,speed,easing,callback) {
4234		return $.effects.animateClass.apply(this, [{ add: add, remove: remove },speed,easing,callback]);
4235	}
4236});
4237
4238
4239
4240/******************************************************************************/
4241/*********************************** EFFECTS **********************************/
4242/******************************************************************************/
4243
4244$.extend($.effects, {
4245	version: "@VERSION",
4246
4247	// Saves a set of properties in a data storage
4248	save: function(element, set) {
4249		for(var i=0; i < set.length; i++) {
4250			if(set[i] !== null) element.data("ec.storage."+set[i], element[0].style[set[i]]);
4251		}
4252	},
4253
4254	// Restores a set of previously saved properties from a data storage
4255	restore: function(element, set) {
4256		for(var i=0; i < set.length; i++) {
4257			if(set[i] !== null) element.css(set[i], element.data("ec.storage."+set[i]));
4258		}
4259	},
4260
4261	setMode: function(el, mode) {
4262		if (mode == 'toggle') mode = el.is(':hidden') ? 'show' : 'hide'; // Set for toggle
4263		return mode;
4264	},
4265
4266	getBaseline: function(origin, original) { // Translates a [top,left] array into a baseline value
4267		// this should be a little more flexible in the future to handle a string & hash
4268		var y, x;
4269		switch (origin[0]) {
4270			case 'top': y = 0; break;
4271			case 'middle': y = 0.5; break;
4272			case 'bottom': y = 1; break;
4273			default: y = origin[0] / original.height;
4274		};
4275		switch (origin[1]) {
4276			case 'left': x = 0; break;
4277			case 'center': x = 0.5; break;
4278			case 'right': x = 1; break;
4279			default: x = origin[1] / original.width;
4280		};
4281		return {x: x, y: y};
4282	},
4283
4284	// Wraps the element around a wrapper that copies position properties
4285	createWrapper: function(element) {
4286
4287		// if the element is already wrapped, return it
4288		if (element.parent().is('.ui-effects-wrapper')) {
4289			return element.parent();
4290		}
4291
4292		// wrap the element
4293		var props = {
4294				width: element.outerWidth(true),
4295				height: element.outerHeight(true),
4296				'float': element.css('float')
4297			},
4298			wrapper = $('<div></div>')
4299				.addClass('ui-effects-wrapper')
4300				.css({
4301					fontSize: '100%',
4302					background: 'transparent',
4303					border: 'none',
4304					margin: 0,
4305					padding: 0
4306				}),
4307			active = document.activeElement;
4308
4309		element.wrap(wrapper);
4310
4311		// Fixes #7595 - Elements lose focus when wrapped.
4312		if ( element[ 0 ] === active || $.contains( element[ 0 ], active ) ) {
4313			$( active ).focus();
4314		}
4315		
4316		wrapper = element.parent(); //Hotfix for jQuery 1.4 since some change in wrap() seems to actually loose the reference to the wrapped element
4317
4318		// transfer positioning properties to the wrapper
4319		if (element.css('position') == 'static') {
4320			wrapper.css({ position: 'relative' });
4321			element.css({ position: 'relative' });
4322		} else {
4323			$.extend(props, {
4324				position: element.css('position'),
4325				zIndex: element.css('z-index')
4326			});
4327			$.each(['top', 'left', 'bottom', 'right'], function(i, pos) {
4328				props[pos] = element.css(pos);
4329				if (isNaN(parseInt(props[pos], 10))) {
4330					props[pos] = 'auto';
4331				}
4332			});
4333			element.css({position: 'relative', top: 0, left: 0, right: 'auto', bottom: 'auto' });
4334		}
4335
4336		return wrapper.css(props).show();
4337	},
4338
4339	removeWrapper: function(element) {
4340		var parent,
4341			active = document.activeElement;
4342		
4343		if (element.parent().is('.ui-effects-wrapper')) {
4344			parent = element.parent().replaceWith(element);
4345			// Fixes #7595 - Elements lose focus when wrapped.
4346			if ( element[ 0 ] === active || $.contains( element[ 0 ], active ) ) {
4347				$( active ).focus();
4348			}
4349			return parent;
4350		}
4351			
4352		return element;
4353	},
4354
4355	setTransition: function(element, list, factor, value) {
4356		value = value || {};
4357		$.each(list, function(i, x){
4358			var unit = element.cssUnit(x);
4359			if (unit[0] > 0) value[x] = unit[0] * factor + unit[1];
4360		});
4361		return value;
4362	}
4363});
4364
4365
4366function _normalizeArguments(effect, options, speed, callback) {
4367	// shift params for method overloading
4368	if (typeof effect == 'object') {
4369		callback = options;
4370		speed = null;
4371		options = effect;
4372		effect = options.effect;
4373	}
4374	if ($.isFunction(options)) {
4375		callback = options;
4376		speed = null;
4377		options = {};
4378	}
4379        if (typeof options == 'number' || $.fx.speeds[options]) {
4380		callback = speed;
4381		speed = options;
4382		options = {};
4383	}
4384	if ($.isFunction(speed)) {
4385		callback = speed;
4386		speed = null;
4387	}
4388
4389	options = options || {};
4390
4391	speed = speed || options.duration;
4392	speed = $.fx.off ? 0 : typeof speed == 'number'
4393		? speed : speed in $.fx.speeds ? $.fx.speeds[speed] : $.fx.speeds._default;
4394
4395	callback = callback || options.complete;
4396
4397	return [effect, options, speed, callback];
4398}
4399
4400function standardSpeed( speed ) {
4401	// valid standard speeds
4402	if ( !speed || typeof speed === "number" || $.fx.speeds[ speed ] ) {
4403		return true;
4404	}
4405	
4406	// invalid strings - treat as "normal" speed
4407	if ( typeof speed === "string" && !$.effects[ speed ] ) {
4408		return true;
4409	}
4410	
4411	return false;
4412}
4413
4414$.fn.extend({
4415	effect: function(effect, options, speed, callback) {
4416		var args = _normalizeArguments.apply(this, arguments),
4417			// TODO: make effects take actual parameters instead of a hash
4418			args2 = {
4419				options: args[1],
4420				duration: args[2],
4421				callback: args[3]
4422			},
4423			mode = args2.options.mode,
4424			effectMethod = $.effects[effect];
4425		
4426		if ( $.fx.off || !effectMethod ) {
4427			// delegate to the original method (e.g., .show()) if possible
4428			if ( mode ) {
4429				return this[ mode ]( args2.duration, args2.callback );
4430			} else {
4431				return this.each(function() {
4432					if ( args2.callback ) {
4433						args2.callback.call( this );
4434					}
4435				});
4436			}
4437		}
4438		
4439		return effectMethod.call(this, args2);
4440	},
4441
4442	_show: $.fn.show,
4443	show: function(speed) {
4444		if ( standardSpeed( speed ) ) {
4445			return this._show.apply(this, arguments);
4446		} else {
4447			var args = _normalizeArguments.apply(this, arguments);
4448			args[1].mode = 'show';
4449			return this.effect.apply(this, args);
4450		}
4451	},
4452
4453	_hide: $.fn.hide,
4454	hide: function(speed) {
4455		if ( standardSpeed( speed ) ) {
4456			return this._hide.apply(this, arguments);
4457		} else {
4458			var args = _normalizeArguments.apply(this, arguments);
4459			args[1].mode = 'hide';
4460			return this.effect.apply(this, args);
4461		}
4462	},
4463
4464	// jQuery core overloads toggle and creates _toggle
4465	__toggle: $.fn.toggle,
4466	toggle: function(speed) {
4467		if ( standardSpeed( speed ) || typeof speed === "boolean" || $.isFunction( speed ) ) {
4468			return this.__toggle.apply(this, arguments);
4469		} else {
4470			var args = _normalizeArguments.apply(this, arguments);
4471			args[1].mode = 'toggle';
4472			return this.effect.apply(this, args);
4473		}
4474	},
4475
4476	// helper functions
4477	cssUnit: function(key) {
4478		var style = this.css(key), val = [];
4479		$.each( ['em','px','%','pt'], function(i, unit){
4480			if(style.indexOf(unit) > 0)
4481				val = [parseFloat(style), unit];
4482		});
4483		return val;
4484	}
4485});
4486
4487
4488
4489/******************************************************************************/
4490/*********************************** EASING ***********************************/
4491/******************************************************************************/
4492
4493/*
4494 * jQuery Easing v1.3 - http://gsgd.co.uk/sandbox/jquery/easing/
4495 *
4496 * Uses the built in easing capabilities added In jQuery 1.1
4497 * to offer multiple easing options
4498 *
4499 * TERMS OF USE - jQuery Easing
4500 *
4501 * Open source under the BSD License.
4502 *
4503 * Copyright 2008 George McGinley Smith
4504 * All rights reserved.
4505 *
4506 * Redistribution and use in source and binary forms, with or without modification,
4507 * are permitted provided that the following conditions are met:
4508 *
4509 * Redistributions of source code must retain the above copyright notice, this list of
4510 * conditions and the following disclaimer.
4511 * Redistributions in binary form must reproduce the above copyright notice, this list
4512 * of conditions and the following disclaimer in the documentation and/or other materials
4513 * provided with the distribution.
4514 *
4515 * Neither the name of the author nor the names of contributors may be used to endorse
vendor: 5,639 bytes, lines 4516-4667
4516 * or promote products derived from this software without specific prior written permission.
4517 *
4518 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
4519 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
4520 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
4521 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
4522 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
4523 * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
4524 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
4525 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
4526 * OF THE POSSIBILITY OF SUCH DAMAGE.
4527 *
4528*/
4529
4530// t: current time, b: begInnIng value, c: change In value, d: duration
4531$.easing.jswing = $.easing.swing;
4532
4533$.extend($.easing,
4534{
4535	def: 'easeOutQuad',
4536	swing: function (x, t, b, c, d) {
4537		//alert($.easing.default);
4538		return $.easing[$.easing.def](x, t, b, c, d);
4539	},
4540	easeInQuad: function (x, t, b, c, d) {
4541		return c*(t/=d)*t + b;
4542	},
4543	easeOutQuad: function (x, t, b, c, d) {
4544		return -c *(t/=d)*(t-2) + b;
4545	},
4546	easeInOutQuad: function (x, t, b, c, d) {
4547		if ((t/=d/2) < 1) return c/2*t*t + b;
4548		return -c/2 * ((--t)*(t-2) - 1) + b;
4549	},
4550	easeInCubic: function (x, t, b, c, d) {
4551		return c*(t/=d)*t*t + b;
4552	},
4553	easeOutCubic: function (x, t, b, c, d) {
4554		return c*((t=t/d-1)*t*t + 1) + b;
4555	},
4556	easeInOutCubic: function (x, t, b, c, d) {
4557		if ((t/=d/2) < 1) return c/2*t*t*t + b;
4558		return c/2*((t-=2)*t*t + 2) + b;
4559	},
4560	easeInQuart: function (x, t, b, c, d) {
4561		return c*(t/=d)*t*t*t + b;
4562	},
4563	easeOutQuart: function (x, t, b, c, d) {
4564		return -c * ((t=t/d-1)*t*t*t - 1) + b;
4565	},
4566	easeInOutQuart: function (x, t, b, c, d) {
4567		if ((t/=d/2) < 1) return c/2*t*t*t*t + b;
4568		return -c/2 * ((t-=2)*t*t*t - 2) + b;
4569	},
4570	easeInQuint: function (x, t, b, c, d) {
4571		return c*(t/=d)*t*t*t*t + b;
4572	},
4573	easeOutQuint: function (x, t, b, c, d) {
4574		return c*((t=t/d-1)*t*t*t*t + 1) + b;
4575	},
4576	easeInOutQuint: function (x, t, b, c, d) {
4577		if ((t/=d/2) < 1) return c/2*t*t*t*t*t + b;
4578		return c/2*((t-=2)*t*t*t*t + 2) + b;
4579	},
4580	easeInSine: function (x, t, b, c, d) {
4581		return -c * Math.cos(t/d * (Math.PI/2)) + c + b;
4582	},
4583	easeOutSine: function (x, t, b, c, d) {
4584		return c * Math.sin(t/d * (Math.PI/2)) + b;
4585	},
4586	easeInOutSine: function (x, t, b, c, d) {
4587		return -c/2 * (Math.cos(Math.PI*t/d) - 1) + b;
4588	},
4589	easeInExpo: function (x, t, b, c, d) {
4590		return (t==0) ? b : c * Math.pow(2, 10 * (t/d - 1)) + b;
4591	},
4592	easeOutExpo: function (x, t, b, c, d) {
4593		return (t==d) ? b+c : c * (-Math.pow(2, -10 * t/d) + 1) + b;
4594	},
4595	easeInOutExpo: function (x, t, b, c, d) {
4596		if (t==0) return b;
4597		if (t==d) return b+c;
4598		if ((t/=d/2) < 1) return c/2 * Math.pow(2, 10 * (t - 1)) + b;
4599		return c/2 * (-Math.pow(2, -10 * --t) + 2) + b;
4600	},
4601	easeInCirc: function (x, t, b, c, d) {
4602		return -c * (Math.sqrt(1 - (t/=d)*t) - 1) + b;
4603	},
4604	easeOutCirc: function (x, t, b, c, d) {
4605		return c * Math.sqrt(1 - (t=t/d-1)*t) + b;
4606	},
4607	easeInOutCirc: function (x, t, b, c, d) {
4608		if ((t/=d/2) < 1) return -c/2 * (Math.sqrt(1 - t*t) - 1) + b;
4609		return c/2 * (Math.sqrt(1 - (t-=2)*t) + 1) + b;
4610	},
4611	easeInElastic: function (x, t, b, c, d) {
4612		var s=1.70158;var p=0;var a=c;
4613		if (t==0) return b;  if ((t/=d)==1) return b+c;  if (!p) p=d*.3;
4614		if (a < Math.abs(c)) { a=c; var s=p/4; }
4615		else var s = p/(2*Math.PI) * Math.asin (c/a);
4616		return -(a*Math.pow(2,10*(t-=1)) * Math.sin( (t*d-s)*(2*Math.PI)/p )) + b;
4617	},
4618	easeOutElastic: function (x, t, b, c, d) {
4619		var s=1.70158;var p=0;var a=c;
4620		if (t==0) return b;  if ((t/=d)==1) return b+c;  if (!p) p=d*.3;
4621		if (a < Math.abs(c)) { a=c; var s=p/4; }
4622		else var s = p/(2*Math.PI) * Math.asin (c/a);
4623		return a*Math.pow(2,-10*t) * Math.sin( (t*d-s)*(2*Math.PI)/p ) + c + b;
4624	},
4625	easeInOutElastic: function (x, t, b, c, d) {
4626		var s=1.70158;var p=0;var a=c;
4627		if (t==0) return b;  if ((t/=d/2)==2) return b+c;  if (!p) p=d*(.3*1.5);
4628		if (a < Math.abs(c)) { a=c; var s=p/4; }
4629		else var s = p/(2*Math.PI) * Math.asin (c/a);
4630		if (t < 1) return -.5*(a*Math.pow(2,10*(t-=1)) * Math.sin( (t*d-s)*(2*Math.PI)/p )) + b;
4631		return a*Math.pow(2,-10*(t-=1)) * Math.sin( (t*d-s)*(2*Math.PI)/p )*.5 + c + b;
4632	},
4633	easeInBack: function (x, t, b, c, d, s) {
4634		if (s == undefined) s = 1.70158;
4635		return c*(t/=d)*t*((s+1)*t - s) + b;
4636	},
4637	easeOutBack: function (x, t, b, c, d, s) {
4638		if (s == undefined) s = 1.70158;
4639		return c*((t=t/d-1)*t*((s+1)*t + s) + 1) + b;
4640	},
4641	easeInOutBack: function (x, t, b, c, d, s) {
4642		if (s == undefined) s = 1.70158;
4643		if ((t/=d/2) < 1) return c/2*(t*t*(((s*=(1.525))+1)*t - s)) + b;
4644		return c/2*((t-=2)*t*(((s*=(1.525))+1)*t + s) + 2) + b;
4645	},
4646	easeInBounce: function (x, t, b, c, d) {
4647		return c - $.easing.easeOutBounce (x, d-t, 0, c, d) + b;
4648	},
4649	easeOutBounce: function (x, t, b, c, d) {
4650		if ((t/=d) < (1/2.75)) {
4651			return c*(7.5625*t*t) + b;
4652		} else if (t < (2/2.75)) {
4653			return c*(7.5625*(t-=(1.5/2.75))*t + .75) + b;
4654		} else if (t < (2.5/2.75)) {
4655			return c*(7.5625*(t-=(2.25/2.75))*t + .9375) + b;
4656		} else {
4657			return c*(7.5625*(t-=(2.625/2.75))*t + .984375) + b;
4658		}
4659	},
4660	easeInOutBounce: function (x, t, b, c, d) {
4661		if (t < d/2) return $.easing.easeInBounce (x, t*2, 0, c, d) * .5 + b;
4662		return $.easing.easeOutBounce (x, t*2-d, 0, c, d) * .5 + c*.5 + b;
4663	}
4664});
4665
4666/*
4667 *
4668 * TERMS OF USE - EASING EQUATIONS
4669 *
4670 * Open source under the BSD License.
4671 *
4672 * Copyright 2001 Robert Penner
4673 * All rights reserved.
4674 *
4675 * Redistribution and use in source and binary forms, with or without modification,
4676 * are permitted provided that the following conditions are met:
4677 *
4678 * Redistributions of source code must retain the above copyright notice, this list of
4679 * conditions and the following disclaimer.
4680 * Redistributions in binary form must reproduce the above copyright notice, this list
4681 * of conditions and the following disclaimer in the documentation and/or other materials
4682 * provided with the distribution.
4683 *
4684 * Neither the name of the author nor the names of contributors may be used to endorse
4685 * or promote products derived from this software without specific prior written permission.
4686 *
4687 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
4688 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
4689 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
4690 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
4691 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
4692 * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
4693 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
4694 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
4695 * OF THE POSSIBILITY OF SUCH DAMAGE.
4696 *
4697 */
4698
4699})(jQuery);
4700
4701(function( $, undefined ) {
4702
4703$.effects.blind = function(o) {
4704
4705	return this.queue(function() {
4706
4707		// Create element
4708		var el = $(this), props = ['position','top','bottom','left','right'];
4709
4710		// Set options
4711		var mode = $.effects.setMode(el, o.options.mode || 'hide'); // Set Mode
4712		var direction = o.options.direction || 'vertical'; // Default direction
4713
4714		// Adjust
4715		$.effects.save(el, props); el.show(); // Save & Show
4716		var wrapper = $.effects.createWrapper(el).css({overflow:'hidden'}); // Create Wrapper
4717		var ref = (direction == 'vertical') ? 'height' : 'width';
4718		var distance = (direction == 'vertical') ? wrapper.height() : wrapper.width();
4719		if(mode == 'show') wrapper.css(ref, 0); // Shift
4720
4721		// Animation
4722		var animation = {};
4723		animation[ref] = mode == 'show' ? distance : 0;
4724
4725		// Animate
4726		wrapper.animate(animation, o.duration, o.options.easing, function() {
4727			if(mode == 'hide') el.hide(); // Hide
4728			$.effects.restore(el, props); $.effects.removeWrapper(el); // Restore
4729			if(o.callback) o.callback.apply(el[0], arguments); // Callback
4730			el.dequeue();
4731		});
4732
4733	});
4734
4735};
4736
4737})(jQuery);
4738
4739(function( $, undefined ) {
4740
4741$.effects.bounce = function(o) {
4742
4743	return this.queue(function() {
4744
4745		// Create element
4746		var el = $(this), props = ['position','top','bottom','left','right'];
4747
4748		// Set options
4749		var mode = $.effects.setMode(el, o.options.mode || 'effect'); // Set Mode
4750		var direction = o.options.direction || 'up'; // Default direction
4751		var distance = o.options.distance || 20; // Default distance
4752		var times = o.options.times || 5; // Default # of times
4753		var speed = o.duration || 250; // Default speed per bounce
4754		if (/show|hide/.test(mode)) props.push('opacity'); // Avoid touching opacity to prevent clearType and PNG issues in IE
4755
4756		// Adjust
4757		$.effects.save(el, props); el.show(); // Save & Show
4758		$.effects.createWrapper(el); // Create Wrapper
4759		var ref = (direction == 'up' || direction == 'down') ? 'top' : 'left';
4760		var motion = (direction == 'up' || direction == 'left') ? 'pos' : 'neg';
4761		var distance = o.options.distance || (ref == 'top' ? el.outerHeight({margin:true}) / 3 : el.outerWidth({margin:true}) / 3);
4762		if (mode == 'show') el.css('opacity', 0).css(ref, motion == 'pos' ? -distance : distance); // Shift
4763		if (mode == 'hide') distance = distance / (times * 2);
4764		if (mode != 'hide') times--;
4765
4766		// Animate
4767		if (mode == 'show') { // Show Bounce
4768			var animation = {opacity: 1};
4769			animation[ref] = (motion == 'pos' ? '+=' : '-=') + distance;
4770			el.animate(animation, speed / 2, o.options.easing);
4771			distance = distance / 2;
4772			times--;
4773		};
4774		for (var i = 0; i < times; i++) { // Bounces
4775			var animation1 = {}, animation2 = {};
4776			animation1[ref] = (motion == 'pos' ? '-=' : '+=') + distance;
4777			animation2[ref] = (motion == 'pos' ? '+=' : '-=') + distance;
4778			el.animate(animation1, speed / 2, o.options.easing).animate(animation2, speed / 2, o.options.easing);
4779			distance = (mode == 'hide') ? distance * 2 : distance / 2;
4780		};
4781		if (mode == 'hide') { // Last Bounce
4782			var animation = {opacity: 0};
4783			animation[ref] = (motion == 'pos' ? '-=' : '+=')  + distance;
4784			el.animate(animation, speed / 2, o.options.easing, function(){
4785				el.hide(); // Hide
4786				$.effects.restore(el, props); $.effects.removeWrapper(el); // Restore
4787				if(o.callback) o.callback.apply(this, arguments); // Callback
4788			});
4789		} else {
4790			var animation1 = {}, animation2 = {};
4791			animation1[ref] = (motion == 'pos' ? '-=' : '+=') + distance;
4792			animation2[ref] = (motion == 'pos' ? '+=' : '-=') + distance;
4793			el.animate(animation1, speed / 2, o.options.easing).animate(animation2, speed / 2, o.options.easing, function(){
4794				$.effects.restore(el, props); $.effects.removeWrapper(el); // Restore
4795				if(o.callback) o.callback.apply(this, arguments); // Callback
4796			});
4797		};
4798		el.queue('fx', function() { el.dequeue(); });
4799		el.dequeue();
4800	});
4801
4802};
4803
4804})(jQuery);
4805
4806(function( $, undefined ) {
4807
4808$.effects.clip = function(o) {
4809
4810	return this.queue(function() {
4811
4812		// Create element
4813		var el = $(this), props = ['position','top','bottom','left','right','height','width'];
4814
4815		// Set options
4816		var mode = $.effects.setMode(el, o.options.mode || 'hide'); // Set Mode
4817		var direction = o.options.direction || 'vertical'; // Default direction
4818
4819		// Adjust
4820		$.effects.save(el, props); el.show(); // Save & Show
4821		var wrapper = $.effects.createWrapper(el).css({overflow:'hidden'}); // Create Wrapper
4822		var animate = el[0].tagName == 'IMG' ? wrapper : el;
4823		var ref = {
4824			size: (direction == 'vertical') ? 'height' : 'width',
4825			position: (direction == 'vertical') ? 'top' : 'left'
4826		};
4827		var distance = (direction == 'vertical') ? animate.height() : animate.width();
4828		if(mode == 'show') { animate.css(ref.size, 0); animate.css(ref.position, distance / 2); } // Shift
4829
4830		// Animation
4831		var animation = {};
4832		animation[ref.size] = mode == 'show' ? distance : 0;
4833		animation[ref.position] = mode == 'show' ? 0 : distance / 2;
4834
4835		// Animate
4836		animate.animate(animation, { queue: false, duration: o.duration, easing: o.options.easing, complete: function() {
4837			if(mode == 'hide') el.hide(); // Hide
4838			$.effects.restore(el, props); $.effects.removeWrapper(el); // Restore
4839			if(o.callback) o.callback.apply(el[0], arguments); // Callback
4840			el.dequeue();
4841		}});
4842
4843	});
4844
4845};
4846
4847})(jQuery);
4848
4849(function( $, undefined ) {
4850
4851$.effects.drop = function(o) {
4852
4853	return this.queue(function() {
4854
4855		// Create element
4856		var el = $(this), props = ['position','top','bottom','left','right','opacity'];
4857
4858		// Set options
4859		var mode = $.effects.setMode(el, o.options.mode || 'hide'); // Set Mode
4860		var direction = o.options.direction || 'left'; // Default Direction
4861
4862		// Adjust
4863		$.effects.save(el, props); el.show(); // Save & Show
4864		$.effects.createWrapper(el); // Create Wrapper
4865		var ref = (direction == 'up' || direction == 'down') ? 'top' : 'left';
4866		var motion = (direction == 'up' || direction == 'left') ? 'pos' : 'neg';
4867		var distance = o.options.distance || (ref == 'top' ? el.outerHeight({margin:true}) / 2 : el.outerWidth({margin:true}) / 2);
4868		if (mode == 'show') el.css('opacity', 0).css(ref, motion == 'pos' ? -distance : distance); // Shift
4869
4870		// Animation
4871		var animation = {opacity: mode == 'show' ? 1 : 0};
4872		animation[ref] = (mode == 'show' ? (motion == 'pos' ? '+=' : '-=') : (motion == 'pos' ? '-=' : '+=')) + distance;
4873
4874		// Animate
4875		el.animate(animation, { queue: false, duration: o.duration, easing: o.options.easing, complete: function() {
4876			if(mode == 'hide') el.hide(); // Hide
4877			$.effects.restore(el, props); $.effects.removeWrapper(el); // Restore
4878			if(o.callback) o.callback.apply(this, arguments); // Callback
4879			el.dequeue();
4880		}});
4881
4882	});
4883
4884};
4885
4886})(jQuery);
4887
4888(function( $, undefined ) {
4889
4890$.effects.explode = function(o) {
4891
4892	return this.queue(function() {
4893
4894	var rows = o.options.pieces ? Math.round(Math.sqrt(o.options.pieces)) : 3;
4895	var cells = o.options.pieces ? Math.round(Math.sqrt(o.options.pieces)) : 3;
4896
4897	o.options.mode = o.options.mode == 'toggle' ? ($(this).is(':visible') ? 'hide' : 'show') : o.options.mode;
4898	var el = $(this).show().css('visibility', 'hidden');
4899	var offset = el.offset();
4900
4901	//Substract the margins - not fixing the problem yet.
4902	offset.top -= parseInt(el.css("marginTop"),10) || 0;
4903	offset.left -= parseInt(el.css("marginLeft"),10) || 0;
4904
4905	var width = el.outerWidth(true);
4906	var height = el.outerHeight(true);
4907
4908	for(var i=0;i<rows;i++) { // =
4909		for(var j=0;j<cells;j++) { // ||
4910			el
4911				.clone()
4912				.appendTo('body')
4913				.wrap('<div></div>')
4914				.css({
4915					position: 'absolute',
4916					visibility: 'visible',
4917					left: -j*(width/cells),
4918					top: -i*(height/rows)
4919				})
4920				.parent()
4921				.addClass('ui-effects-explode')
4922				.css({
4923					position: 'absolute',
4924					overflow: 'hidden',
4925					width: width/cells,
4926					height: height/rows,
4927					left: offset.left + j*(width/cells) + (o.options.mode == 'show' ? (j-Math.floor(cells/2))*(width/cells) : 0),
4928					top: offset.top + i*(height/rows) + (o.options.mode == 'show' ? (i-Math.floor(rows/2))*(height/rows) : 0),
4929					opacity: o.options.mode == 'show' ? 0 : 1
4930				}).animate({
4931					left: offset.left + j*(width/cells) + (o.options.mode == 'show' ? 0 : (j-Math.floor(cells/2))*(width/cells)),
4932					top: offset.top + i*(height/rows) + (o.options.mode == 'show' ? 0 : (i-Math.floor(rows/2))*(height/rows)),
4933					opacity: o.options.mode == 'show' ? 1 : 0
4934				}, o.duration || 500);
4935		}
4936	}
4937
4938	// Set a timeout, to call the callback approx. when the other animations have finished
4939	setTimeout(function() {
4940
4941		o.options.mode == 'show' ? el.css({ visibility: 'visible' }) : el.css({ visibility: 'visible' }).hide();
4942				if(o.callback) o.callback.apply(el[0]); // Callback
4943				el.dequeue();
4944
4945				$('div.ui-effects-explode').remove();
4946
4947	}, o.duration || 500);
4948
4949
4950	});
4951
4952};
4953
4954})(jQuery);
4955
4956(function( $, undefined ) {
4957
4958$.effects.fade = function(o) {
4959	return this.queue(function() {
4960		var elem = $(this),
4961			mode = $.effects.setMode(elem, o.options.mode || 'hide');
4962
4963		elem.animate({ opacity: mode }, {
4964			queue: false,
4965			duration: o.duration,
4966			easing: o.options.easing,
4967			complete: function() {
4968				(o.callback && o.callback.apply(this, arguments));
4969				elem.dequeue();
4970			}
4971		});
4972	});
4973};
4974
4975})(jQuery);
4976
4977(function( $, undefined ) {
4978
4979$.effects.fold = function(o) {
4980
4981	return this.queue(function() {
4982
4983		// Create element
4984		var el = $(this), props = ['position','top','bottom','left','right'];
4985
4986		// Set options
4987		var mode = $.effects.setMode(el, o.options.mode || 'hide'); // Set Mode
4988		var size = o.options.size || 15; // Default fold size
4989		var horizFirst = !(!o.options.horizFirst); // Ensure a boolean value
4990		var duration = o.duration ? o.duration / 2 : $.fx.speeds._default / 2;
4991
4992		// Adjust
4993		$.effects.save(el, props); el.show(); // Save & Show
4994		var wrapper = $.effects.createWrapper(el).css({overflow:'hidden'}); // Create Wrapper
4995		var widthFirst = ((mode == 'show') != horizFirst);
4996		var ref = widthFirst ? ['width', 'height'] : ['height', 'width'];
4997		var distance = widthFirst ? [wrapper.width(), wrapper.height()] : [wrapper.height(), wrapper.width()];
4998		var percent = /([0-9]+)%/.exec(size);
4999		if(percent) size = parseInt(percent[1],10) / 100 * distance[mode == 'hide' ? 0 : 1];
5000		if(mode == 'show') wrapper.css(horizFirst ? {height: 0, width: size} : {height: size, width: 0}); // Shift
5001
5002		// Animation
5003		var animation1 = {}, animation2 = {};
5004		animation1[ref[0]] = mode == 'show' ? distance[0] : size;
5005		animation2[ref[1]] = mode == 'show' ? distance[1] : 0;
5006
5007		// Animate
5008		wrapper.animate(animation1, duration, o.options.easing)
5009		.animate(animation2, duration, o.options.easing, function() {
5010			if(mode == 'hide') el.hide(); // Hide
5011			$.effects.restore(el, props); $.effects.removeWrapper(el); // Restore
5012			if(o.callback) o.callback.apply(el[0], arguments); // Callback
5013			el.dequeue();
5014		});
5015
5016	});
5017
5018};
5019
5020})(jQuery);
5021
5022(function( $, undefined ) {
5023
5024$.effects.highlight = function(o) {
5025	return this.queue(function() {
5026		var elem = $(this),
5027			props = ['backgroundImage', 'backgroundColor', 'opacity'],
5028			mode = $.effects.setMode(elem, o.options.mode || 'show'),
5029			animation = {
5030				backgroundColor: elem.css('backgroundColor')
5031			};
5032
5033		if (mode == 'hide') {
5034			animation.opacity = 0;
5035		}
5036
5037		$.effects.save(elem, props);
5038		elem
5039			.show()
5040			.css({
5041				backgroundImage: 'none',
5042				backgroundColor: o.options.color || '#ffff99'
5043			})
5044			.animate(animation, {
5045				queue: false,
5046				duration: o.duration,
5047				easing: o.options.easing,
5048				complete: function() {
5049					(mode == 'hide' && elem.hide());
5050					$.effects.restore(elem, props);
5051					(mode == 'show' && !$.support.opacity && this.style.removeAttribute('filter'));
5052					(o.callback && o.callback.apply(this, arguments));
5053					elem.dequeue();
5054				}
5055			});
5056	});
5057};
5058
5059})(jQuery);
5060
5061(function( $, undefined ) {
5062
5063$.effects.pulsate = function(o) {
5064	return this.queue(function() {
5065		var elem = $(this),
5066			mode = $.effects.setMode(elem, o.options.mode || 'show'),
5067			times = ((o.options.times || 5) * 2) - 1,
5068			duration = o.duration ? o.duration / 2 : $.fx.speeds._default / 2,
5069			isVisible = elem.is(':visible'),
5070			animateTo = 0;
5071
5072		if (!isVisible) {
5073			elem.css('opacity', 0).show();
5074			animateTo = 1;
5075		}
5076
5077		if ((mode == 'hide' && isVisible) || (mode == 'show' && !isVisible)) {
5078			times--;
5079		}
5080
5081		for (var i = 0; i < times; i++) {
5082			elem.animate({ opacity: animateTo }, duration, o.options.easing);
5083			animateTo = (animateTo + 1) % 2;
5084		}
5085
5086		elem.animate({ opacity: animateTo }, duration, o.options.easing, function() {
5087			if (animateTo == 0) {
5088				elem.hide();
5089			}
5090			(o.callback && o.callback.apply(this, arguments));
5091		});
5092
5093		elem
5094			.queue('fx', function() { elem.dequeue(); })
5095			.dequeue();
5096	});
5097};
5098
5099})(jQuery);
5100
5101(function( $, undefined ) {
5102
5103$.effects.puff = function(o) {
5104	return this.queue(function() {
5105		var elem = $(this),
5106			mode = $.effects.setMode(elem, o.options.mode || 'hide'),
5107			percent = parseInt(o.options.percent, 10) || 150,
5108			factor = percent / 100,
5109			original = { height: elem.height(), width: elem.width() };
5110
5111		$.extend(o.options, {
5112			fade: true,
5113			mode: mode,
5114			percent: mode == 'hide' ? percent : 100,
5115			from: mode == 'hide'
5116				? original
5117				: {
5118					height: original.height * factor,
5119					width: original.width * factor
5120				}
5121		});
5122
5123		elem.effect('scale', o.options, o.duration, o.callback);
5124		elem.dequeue();
5125	});
5126};
5127
5128$.effects.scale = function(o) {
5129
5130	return this.queue(function() {
5131
5132		// Create element
5133		var el = $(this);
5134
5135		// Set options
5136		var options = $.extend(true, {}, o.options);
5137		var mode = $.effects.setMode(el, o.options.mode || 'effect'); // Set Mode
5138		var percent = parseInt(o.options.percent,10) || (parseInt(o.options.percent,10) == 0 ? 0 : (mode == 'hide' ? 0 : 100)); // Set default scaling percent
5139		var direction = o.options.direction || 'both'; // Set default axis
5140		var origin = o.options.origin; // The origin of the scaling
5141		if (mode != 'effect') { // Set default origin and restore for show/hide
5142			options.origin = origin || ['middle','center'];
5143			options.restore = true;
5144		}
5145		var original = {height: el.height(), width: el.width()}; // Save original
5146		el.from = o.options.from || (mode == 'show' ? {height: 0, width: 0} : original); // Default from state
5147
5148		// Adjust
5149		var factor = { // Set scaling factor
5150			y: direction != 'horizontal' ? (percent / 100) : 1,
5151			x: direction != 'vertical' ? (percent / 100) : 1
5152		};
5153		el.to = {height: original.height * factor.y, width: original.width * factor.x}; // Set to state
5154
5155		if (o.options.fade) { // Fade option to support puff
5156			if (mode == 'show') {el.from.opacity = 0; el.to.opacity = 1;};
5157			if (mode == 'hide') {el.from.opacity = 1; el.to.opacity = 0;};
5158		};
5159
5160		// Animation
5161		options.from = el.from; options.to = el.to; options.mode = mode;
5162
5163		// Animate
5164		el.effect('size', options, o.duration, o.callback);
5165		el.dequeue();
5166	});
5167
5168};
5169
5170$.effects.size = function(o) {
5171
5172	return this.queue(function() {
5173
5174		// Create element
5175		var el = $(this), props = ['position','top','bottom','left','right','width','height','overflow','opacity'];
5176		var props1 = ['position','top','bottom','left','right','overflow','opacity']; // Always restore
5177		var props2 = ['width','height','overflow']; // Copy for children
5178		var cProps = ['fontSize'];
5179		var vProps = ['borderTopWidth', 'borderBottomWidth', 'paddingTop', 'paddingBottom'];
5180		var hProps = ['borderLeftWidth', 'borderRightWidth', 'paddingLeft', 'paddingRight'];
5181
5182		// Set options
5183		var mode = $.effects.setMode(el, o.options.mode || 'effect'); // Set Mode
5184		var restore = o.options.restore || false; // Default restore
5185		var scale = o.options.scale || 'both'; // Default scale mode
5186		var origin = o.options.origin; // The origin of the sizing
5187		var original = {height: el.height(), width: el.width()}; // Save original
5188		el.from = o.options.from || original; // Default from state
5189		el.to = o.options.to || original; // Default to state
5190		// Adjust
5191		if (origin) { // Calculate baseline shifts
5192			var baseline = $.effects.getBaseline(origin, original);
5193			el.from.top = (original.height - el.from.height) * baseline.y;
5194			el.from.left = (original.width - el.from.width) * baseline.x;
5195			el.to.top = (original.height - el.to.height) * baseline.y;
5196			el.to.left = (original.width - el.to.width) * baseline.x;
5197		};
5198		var factor = { // Set scaling factor
5199			from: {y: el.from.height / original.height, x: el.from.width / original.width},
5200			to: {y: el.to.height / original.height, x: el.to.width / original.width}
5201		};
5202		if (scale == 'box' || scale == 'both') { // Scale the css box
5203			if (factor.from.y != factor.to.y) { // Vertical props scaling
5204				props = props.concat(vProps);
5205				el.from = $.effects.setTransition(el, vProps, factor.from.y, el.from);
5206				el.to = $.effects.setTransition(el, vProps, factor.to.y, el.to);
5207			};
5208			if (factor.from.x != factor.to.x) { // Horizontal props scaling
5209				props = props.concat(hProps);
5210				el.from = $.effects.setTransition(el, hProps, factor.from.x, el.from);
5211				el.to = $.effects.setTransition(el, hProps, factor.to.x, el.to);
5212			};
5213		};
5214		if (scale == 'content' || scale == 'both') { // Scale the content
5215			if (factor.from.y != factor.to.y) { // Vertical props scaling
5216				props = props.concat(cProps);
5217				el.from = $.effects.setTransition(el, cProps, factor.from.y, el.from);
5218				el.to = $.effects.setTransition(el, cProps, factor.to.y, el.to);
5219			};
5220		};
5221		$.effects.save(el, restore ? props : props1); el.show(); // Save & Show
5222		$.effects.createWrapper(el); // Create Wrapper
5223		el.css('overflow','hidden').css(el.from); // Shift
5224
5225		// Animate
5226		if (scale == 'content' || scale == 'both') { // Scale the children
5227			vProps = vProps.concat(['marginTop','marginBottom']).concat(cProps); // Add margins/font-size
5228			hProps = hProps.concat(['marginLeft','marginRight']); // Add margins
5229			props2 = props.concat(vProps).concat(hProps); // Concat
5230			el.find("*[width]").each(function(){
5231				var child = $(this);
5232				if (restore) $.effects.save(child, props2);
5233				var c_original = {height: child.height(), width: child.width()}; // Save original
5234				child.from = {height: c_original.height * factor.from.y, width: c_original.width * factor.from.x};
5235				child.to = {height: c_original.height * factor.to.y, width: c_original.width * factor.to.x};
5236				if (factor.from.y != factor.to.y) { // Vertical props scaling
5237					child.from = $.effects.setTransition(child, vProps, factor.from.y, child.from);
5238					child.to = $.effects.setTransition(child, vProps, factor.to.y, child.to);
5239				};
5240				if (factor.from.x != factor.to.x) { // Horizontal props scaling
5241					child.from = $.effects.setTransition(child, hProps, factor.from.x, child.from);
5242					child.to = $.effects.setTransition(child, hProps, factor.to.x, child.to);
5243				};
5244				child.css(child.from); // Shift children
5245				child.animate(child.to, o.duration, o.options.easing, function(){
5246					if (restore) $.effects.restore(child, props2); // Restore children
5247				}); // Animate children
5248			});
5249		};
5250
5251		// Animate
5252		el.animate(el.to, { queue: false, duration: o.duration, easing: o.options.easing, complete: function() {
5253			if (el.to.opacity === 0) {
5254				el.css('opacity', el.from.opacity);
5255			}
5256			if(mode == 'hide') el.hide(); // Hide
5257			$.effects.restore(el, restore ? props : props1); $.effects.removeWrapper(el); // Restore
5258			if(o.callback) o.callback.apply(this, arguments); // Callback
5259			el.dequeue();
5260		}});
5261
5262	});
5263
5264};
5265
5266})(jQuery);
5267
5268(function( $, undefined ) {
5269
5270$.effects.shake = function(o) {
5271
5272	return this.queue(function() {
5273
5274		// Create element
5275		var el = $(this), props = ['position','top','bottom','left','right'];
5276
5277		// Set options
5278		var mode = $.effects.setMode(el, o.options.mode || 'effect'); // Set Mode
5279		var direction = o.options.direction || 'left'; // Default direction
5280		var distance = o.options.distance || 20; // Default distance
5281		var times = o.options.times || 3; // Default # of times
5282		var speed = o.duration || o.options.duration || 140; // Default speed per shake
5283
5284		// Adjust
5285		$.effects.save(el, props); el.show(); // Save & Show
5286		$.effects.createWrapper(el); // Create Wrapper
5287		var ref = (direction == 'up' || direction == 'down') ? 'top' : 'left';
5288		var motion = (direction == 'up' || direction == 'left') ? 'pos' : 'neg';
5289
5290		// Animation
5291		var animation = {}, animation1 = {}, animation2 = {};
5292		animation[ref] = (motion == 'pos' ? '-=' : '+=')  + distance;
5293		animation1[ref] = (motion == 'pos' ? '+=' : '-=')  + distance * 2;
5294		animation2[ref] = (motion == 'pos' ? '-=' : '+=')  + distance * 2;
5295
5296		// Animate
5297		el.animate(animation, speed, o.options.easing);
5298		for (var i = 1; i < times; i++) { // Shakes
5299			el.animate(animation1, speed, o.options.easing).animate(animation2, speed, o.options.easing);
5300		};
5301		el.animate(animation1, speed, o.options.easing).
5302		animate(animation, speed / 2, o.options.easing, function(){ // Last shake
5303			$.effects.restore(el, props); $.effects.removeWrapper(el); // Restore
5304			if(o.callback) o.callback.apply(this, arguments); // Callback
5305		});
5306		el.queue('fx', function() { el.dequeue(); });
5307		el.dequeue();
5308	});
5309
5310};
5311
5312})(jQuery);
5313
5314(function( $, undefined ) {
5315
5316$.effects.slide = function(o) {
5317
5318	return this.queue(function() {
5319
5320		// Create element
5321		var el = $(this), props = ['position','top','bottom','left','right'];
5322
5323		// Set options
5324		var mode = $.effects.setMode(el, o.options.mode || 'show'); // Set Mode
5325		var direction = o.options.direction || 'left'; // Default Direction
5326
5327		// Adjust
5328		$.effects.save(el, props); el.show(); // Save & Show
5329		$.effects.createWrapper(el).css({overflow:'hidden'}); // Create Wrapper
5330		var ref = (direction == 'up' || direction == 'down') ? 'top' : 'left';
5331		var motion = (direction == 'up' || direction == 'left') ? 'pos' : 'neg';
5332		var distance = o.options.distance || (ref == 'top' ? el.outerHeight({margin:true}) : el.outerWidth({margin:true}));
5333		if (mode == 'show') el.css(ref, motion == 'pos' ? (isNaN(distance) ? "-" + distance : -distance) : distance); // Shift
5334
5335		// Animation
5336		var animation = {};
5337		animation[ref] = (mode == 'show' ? (motion == 'pos' ? '+=' : '-=') : (motion == 'pos' ? '-=' : '+=')) + distance;
5338
5339		// Animate
5340		el.animate(animation, { queue: false, duration: o.duration, easing: o.options.easing, complete: function() {
5341			if(mode == 'hide') el.hide(); // Hide
5342			$.effects.restore(el, props); $.effects.removeWrapper(el); // Restore
5343			if(o.callback) o.callback.apply(this, arguments); // Callback
5344			el.dequeue();
5345		}});
5346
5347	});
5348
5349};
5350
5351})(jQuery);
5352
5353(function( $, undefined ) {
5354
5355$.effects.transfer = function(o) {
5356	return this.queue(function() {
5357		var elem = $(this),
5358			target = $(o.options.to),
5359			endPosition = target.offset(),
5360			animation = {
5361				top: endPosition.top,
5362				left: endPosition.left,
5363				height: target.innerHeight(),
5364				width: target.innerWidth()
5365			},
5366			startPosition = elem.offset(),
5367			transfer = $('<div class="ui-effects-transfer"></div>')
5368				.appendTo(document.body)
5369				.addClass(o.options.className)
5370				.css({
5371					top: startPosition.top,
5372					left: startPosition.left,
5373					height: elem.innerHeight(),
5374					width: elem.innerWidth(),
5375					position: 'absolute'
5376				})
5377				.animate(animation, o.duration, o.options.easing, function() {
5378					transfer.remove();
5379					(o.callback && o.callback.apply(elem[0], arguments));
5380					elem.dequeue();
5381				});
5382	});
5383};
5384
5385})(jQuery);
5386
5387(function( $, undefined ) {
5388
5389$.widget( "ui.accordion", {
5390	options: {
5391		active: 0,
5392		animated: "slide",
5393		autoHeight: true,
5394		clearStyle: false,
5395		collapsible: false,
5396		event: "click",
5397		fillSpace: false,
5398		header: "> li > :first-child,> :not(li):even",
5399		icons: {
5400			header: "ui-icon-triangle-1-e",
5401			headerSelected: "ui-icon-triangle-1-s"
5402		},
5403		navigation: false,
5404		navigationFilter: function() {
5405			return this.href.toLowerCase() === location.href.toLowerCase();
5406		}
5407	},
5408
5409	_create: function() {
5410		var self = this,
5411			options = self.options;
5412
5413		self.running = 0;
5414
5415		self.element
5416			.addClass( "ui-accordion ui-widget ui-helper-reset" )
5417			// in lack of child-selectors in CSS
5418			// we need to mark top-LIs in a UL-accordion for some IE-fix
5419			.children( "li" )
5420				.addClass( "ui-accordion-li-fix" );
5421
5422		self.headers = self.element.find( options.header )
5423			.addClass( "ui-accordion-header ui-helper-reset ui-state-default ui-corner-all" )
5424			.bind( "mouseenter.accordion", function() {
5425				if ( options.disabled ) {
5426					return;
5427				}
5428				$( this ).addClass( "ui-state-hover" );
5429			})
5430			.bind( "mouseleave.accordion", function() {
5431				if ( options.disabled ) {
5432					return;
5433				}
5434				$( this ).removeClass( "ui-state-hover" );
5435			})
5436			.bind( "focus.accordion", function() {
5437				if ( options.disabled ) {
5438					return;
5439				}
5440				$( this ).addClass( "ui-state-focus" );
5441			})
5442			.bind( "blur.accordion", function() {
5443				if ( options.disabled ) {
5444					return;
5445				}
5446				$( this ).removeClass( "ui-state-focus" );
5447			});
5448
5449		self.headers.next()
5450			.addClass( "ui-accordion-content ui-helper-reset ui-widget-content ui-corner-bottom" );
5451
5452		if ( options.navigation ) {
5453			var current = self.element.find( "a" ).filter( options.navigationFilter ).eq( 0 );
5454			if ( current.length ) {
5455				var header = current.closest( ".ui-accordion-header" );
5456				if ( header.length ) {
5457					// anchor within header
5458					self.active = header;
5459				} else {
5460					// anchor within content
5461					self.active = current.closest( ".ui-accordion-content" ).prev();
5462				}
5463			}
5464		}
5465
5466		self.active = self._findActive( self.active || options.active )
5467			.addClass( "ui-state-default ui-state-active" )
5468			.toggleClass( "ui-corner-all" )
5469			.toggleClass( "ui-corner-top" );
5470		self.active.next().addClass( "ui-accordion-content-active" );
5471
5472		self._createIcons();
5473		self.resize();
5474		
5475		// ARIA
5476		self.element.attr( "role", "tablist" );
5477
5478		self.headers
5479			.attr( "role", "tab" )
5480			.bind( "keydown.accordion", function( event ) {
5481				return self._keydown( event );
5482			})
5483			.next()
5484				.attr( "role", "tabpanel" );
5485
5486		self.headers
5487			.not( self.active || "" )
5488			.attr({
5489				"aria-expanded": "false",
5490				"aria-selected": "false",
5491				tabIndex: -1
5492			})
5493			.next()
5494				.hide();
5495
5496		// make sure at least one header is in the tab order
5497		if ( !self.active.length ) {
5498			self.headers.eq( 0 ).attr( "tabIndex", 0 );
5499		} else {
5500			self.active
5501				.attr({
5502					"aria-expanded": "true",
5503					"aria-selected": "true",
5504					tabIndex: 0
5505				});
5506		}
5507
5508		// only need links in tab order for Safari
5509		if ( !$.browser.safari ) {
5510			self.headers.find( "a" ).attr( "tabIndex", -1 );
5511		}
5512
5513		if ( options.event ) {
5514			self.headers.bind( options.event.split(" ").join(".accordion ") + ".accordion", function(event) {
5515				self._clickHandler.call( self, event, this );
5516				event.preventDefault();
5517			});
5518		}
5519	},
5520
5521	_createIcons: function() {
5522		var options = this.options;
5523		if ( options.icons ) {
5524			$( "<span></span>" )
5525				.addClass( "ui-icon " + options.icons.header )
5526				.prependTo( this.headers );
5527			this.active.children( ".ui-icon" )
5528				.toggleClass(options.icons.header)
5529				.toggleClass(options.icons.headerSelected);
5530			this.element.addClass( "ui-accordion-icons" );
5531		}
5532	},
5533
5534	_destroyIcons: function() {
5535		this.headers.children( ".ui-icon" ).remove();
5536		this.element.removeClass( "ui-accordion-icons" );
5537	},
5538
5539	destroy: function() {
5540		var options = this.options;
5541
5542		this.element
5543			.removeClass( "ui-accordion ui-widget ui-helper-reset" )
5544			.removeAttr( "role" );
5545
5546		this.headers
5547			.unbind( ".accordion" )
5548			.removeClass( "ui-accordion-header ui-accordion-disabled ui-helper-reset ui-state-default ui-corner-all ui-state-active ui-state-disabled ui-corner-top" )
5549			.removeAttr( "role" )
5550			.removeAttr( "aria-expanded" )
5551			.removeAttr( "aria-selected" )
5552			.removeAttr( "tabIndex" );
5553
5554		this.headers.find( "a" ).removeAttr( "tabIndex" );
5555		this._destroyIcons();
5556		var contents = this.headers.next()
5557			.css( "display", "" )
5558			.removeAttr( "role" )
5559			.removeClass( "ui-helper-reset ui-widget-content ui-corner-bottom ui-accordion-content ui-accordion-content-active ui-accordion-disabled ui-state-disabled" );
5560		if ( options.autoHeight || options.fillHeight ) {
5561			contents.css( "height", "" );
5562		}
5563
5564		return $.Widget.prototype.destroy.call( this );
5565	},
5566
5567	_setOption: function( key, value ) {
5568		$.Widget.prototype._setOption.apply( this, arguments );
5569			
5570		if ( key == "active" ) {
5571			this.activate( value );
5572		}
5573		if ( key == "icons" ) {
5574			this._destroyIcons();
5575			if ( value ) {
5576				this._createIcons();
5577			}
5578		}
5579		// #5332 - opacity doesn't cascade to positioned elements in IE
5580		// so we need to add the disabled class to the headers and panels
5581		if ( key == "disabled" ) {
5582			this.headers.add(this.headers.next())
5583				[ value ? "addClass" : "removeClass" ](
5584					"ui-accordion-disabled ui-state-disabled" );
5585		}
5586	},
5587
5588	_keydown: function( event ) {
5589		if ( this.options.disabled || event.altKey || event.ctrlKey ) {
5590			return;
5591		}
5592
5593		var keyCode = $.ui.keyCode,
5594			length = this.headers.length,
5595			currentIndex = this.headers.index( event.target ),
5596			toFocus = false;
5597
5598		switch ( event.keyCode ) {
5599			case keyCode.RIGHT:
5600			case keyCode.DOWN:
5601				toFocus = this.headers[ ( currentIndex + 1 ) % length ];
5602				break;
5603			case keyCode.LEFT:
5604			case keyCode.UP:
5605				toFocus = this.headers[ ( currentIndex - 1 + length ) % length ];
5606				break;
5607			case keyCode.SPACE:
5608			case keyCode.ENTER:
5609				this._clickHandler( { target: event.target }, event.target );
5610				event.preventDefault();
5611		}
5612
5613		if ( toFocus ) {
5614			$( event.target ).attr( "tabIndex", -1 );
5615			$( toFocus ).attr( "tabIndex", 0 );
5616			toFocus.focus();
5617			return false;
5618		}
5619
5620		return true;
5621	},
5622
5623	resize: function() {
5624		var options = this.options,
5625			maxHeight;
5626
5627		if ( options.fillSpace ) {
5628			if ( $.browser.msie ) {
5629				var defOverflow = this.element.parent().css( "overflow" );
5630				this.element.parent().css( "overflow", "hidden");
5631			}
5632			maxHeight = this.element.parent().height();
5633			if ($.browser.msie) {
5634				this.element.parent().css( "overflow", defOverflow );
5635			}
5636
5637			this.headers.each(function() {
5638				maxHeight -= $( this ).outerHeight( true );
5639			});
5640
5641			this.headers.next()
5642				.each(function() {
5643					$( this ).height( Math.max( 0, maxHeight -
5644						$( this ).innerHeight() + $( this ).height() ) );
5645				})
5646				.css( "overflow", "auto" );
5647		} else if ( options.autoHeight ) {
5648			maxHeight = 0;
5649			this.headers.next()
5650				.each(function() {
5651					maxHeight = Math.max( maxHeight, $( this ).height( "" ).height() );
5652				})
5653				.height( maxHeight );
5654		}
5655
5656		return this;
5657	},
5658
5659	activate: function( index ) {
5660		// TODO this gets called on init, changing the option without an explicit call for that
5661		this.options.active = index;
5662		// call clickHandler with custom event
5663		var active = this._findActive( index )[ 0 ];
5664		this._clickHandler( { target: active }, active );
5665
5666		return this;
5667	},
5668
5669	_findActive: function( selector ) {
5670		return selector
5671			? typeof selector === "number"
5672				? this.headers.filter( ":eq(" + selector + ")" )
5673				: this.headers.not( this.headers.not( selector ) )
5674			: selector === false
5675				? $( [] )
5676				: this.headers.filter( ":eq(0)" );
5677	},
5678
5679	// TODO isn't event.target enough? why the separate target argument?
5680	_clickHandler: function( event, target ) {
5681		var options = this.options;
5682		if ( options.disabled ) {
5683			return;
5684		}
5685
5686		// called only when using activate(false) to close all parts programmatically
5687		if ( !event.target ) {
5688			if ( !options.collapsible ) {
5689				return;
5690			}
5691			this.active
5692				.removeClass( "ui-state-active ui-corner-top" )
5693				.addClass( "ui-state-default ui-corner-all" )
5694				.children( ".ui-icon" )
5695					.removeClass( options.icons.headerSelected )
5696					.addClass( options.icons.header );
5697			this.active.next().addClass( "ui-accordion-content-active" );
5698			var toHide = this.active.next(),
5699				data = {
5700					options: options,
5701					newHeader: $( [] ),
5702					oldHeader: options.active,
5703					newContent: $( [] ),
5704					oldContent: toHide
5705				},
5706				toShow = ( this.active = $( [] ) );
5707			this._toggle( toShow, toHide, data );
5708			return;
5709		}
5710
5711		// get the click target
5712		var clicked = $( event.currentTarget || target ),
5713			clickedIsActive = clicked[0] === this.active[0];
5714
5715		// TODO the option is changed, is that correct?
5716		// TODO if it is correct, shouldn't that happen after determining that the click is valid?
5717		options.active = options.collapsible && clickedIsActive ?
5718			false :
5719			this.headers.index( clicked );
5720
5721		// if animations are still active, or the active header is the target, ignore click
5722		if ( this.running || ( !options.collapsible && clickedIsActive ) ) {
5723			return;
5724		}
5725
5726		// find elements to show and hide
5727		var active = this.active,
5728			toShow = clicked.next(),
5729			toHide = this.active.next(),
5730			data = {
5731				options: options,
5732				newHeader: clickedIsActive && options.collapsible ? $([]) : clicked,
5733				oldHeader: this.active,
5734				newContent: clickedIsActive && options.collapsible ? $([]) : toShow,
5735				oldContent: toHide
5736			},
5737			down = this.headers.index( this.active[0] ) > this.headers.index( clicked[0] );
5738
5739		// when the call to ._toggle() comes after the class changes
5740		// it causes a very odd bug in IE 8 (see #6720)
5741		this.active = clickedIsActive ? $([]) : clicked;
5742		this._toggle( toShow, toHide, data, clickedIsActive, down );
5743
5744		// switch classes
5745		active
5746			.removeClass( "ui-state-active ui-corner-top" )
5747			.addClass( "ui-state-default ui-corner-all" )
5748			.children( ".ui-icon" )
5749				.removeClass( options.icons.headerSelected )
5750				.addClass( options.icons.header );
5751		if ( !clickedIsActive ) {
5752			clicked
5753				.removeClass( "ui-state-default ui-corner-all" )
5754				.addClass( "ui-state-active ui-corner-top" )
5755				.children( ".ui-icon" )
5756					.removeClass( options.icons.header )
5757					.addClass( options.icons.headerSelected );
5758			clicked
5759				.next()
5760				.addClass( "ui-accordion-content-active" );
5761		}
5762
5763		return;
5764	},
5765
5766	_toggle: function( toShow, toHide, data, clickedIsActive, down ) {
5767		var self = this,
5768			options = self.options;
5769
5770		self.toShow = toShow;
5771		self.toHide = toHide;
5772		self.data = data;
5773
5774		var complete = function() {
5775			if ( !self ) {
5776				return;
5777			}
5778			return self._completed.apply( self, arguments );
5779		};
5780
5781		// trigger changestart event
5782		self._trigger( "changestart", null, self.data );
5783
5784		// count elements to animate
5785		self.running = toHide.size() === 0 ? toShow.size() : toHide.size();
5786
5787		if ( options.animated ) {
5788			var animOptions = {};
5789
5790			if ( options.collapsible && clickedIsActive ) {
5791				animOptions = {
5792					toShow: $( [] ),
5793					toHide: toHide,
5794					complete: complete,
5795					down: down,
5796					autoHeight: options.autoHeight || options.fillSpace
5797				};
5798			} else {
5799				animOptions = {
5800					toShow: toShow,
5801					toHide: toHide,
5802					complete: complete,
5803					down: down,
5804					autoHeight: options.autoHeight || options.fillSpace
5805				};
5806			}
5807
5808			if ( !options.proxied ) {
5809				options.proxied = options.animated;
5810			}
5811
5812			if ( !options.proxiedDuration ) {
5813				options.proxiedDuration = options.duration;
5814			}
5815
5816			options.animated = $.isFunction( options.proxied ) ?
5817				options.proxied( animOptions ) :
5818				options.proxied;
5819
5820			options.duration = $.isFunction( options.proxiedDuration ) ?
5821				options.proxiedDuration( animOptions ) :
5822				options.proxiedDuration;
5823
5824			var animations = $.ui.accordion.animations,
5825				duration = options.duration,
5826				easing = options.animated;
5827
5828			if ( easing && !animations[ easing ] && !$.easing[ easing ] ) {
5829				easing = "slide";
5830			}
5831			if ( !animations[ easing ] ) {
5832				animations[ easing ] = function( options ) {
5833					this.slide( options, {
5834						easing: easing,
5835						duration: duration || 700
5836					});
5837				};
5838			}
5839
5840			animations[ easing ]( animOptions );
5841		} else {
5842			if ( options.collapsible && clickedIsActive ) {
5843				toShow.toggle();
5844			} else {
5845				toHide.hide();
5846				toShow.show();
5847			}
5848
5849			complete( true );
5850		}
5851
5852		// TODO assert that the blur and focus triggers are really necessary, remove otherwise
5853		toHide.prev()
5854			.attr({
5855				"aria-expanded": "false",
5856				"aria-selected": "false",
5857				tabIndex: -1
5858			})
5859			.blur();
5860		toShow.prev()
5861			.attr({
5862				"aria-expanded": "true",
5863				"aria-selected": "true",
5864				tabIndex: 0
5865			})
5866			.focus();
5867	},
5868
5869	_completed: function( cancel ) {
5870		this.running = cancel ? 0 : --this.running;
5871		if ( this.running ) {
5872			return;
5873		}
5874
5875		if ( this.options.clearStyle ) {
5876			this.toShow.add( this.toHide ).css({
5877				height: "",
5878				overflow: ""
5879			});
5880		}
5881
5882		// other classes are removed before the animation; this one needs to stay until completed
5883		this.toHide.removeClass( "ui-accordion-content-active" );
5884		// Work around for rendering bug in IE (#5421)
5885		if ( this.toHide.length ) {
5886			this.toHide.parent()[0].className = this.toHide.parent()[0].className;
5887		}
5888
5889		this._trigger( "change", null, this.data );
5890	}
5891});
5892
5893$.extend( $.ui.accordion, {
5894	version: "@VERSION",
5895	animations: {
5896		slide: function( options, additions ) {
5897			options = $.extend({
5898				easing: "swing",
5899				duration: 300
5900			}, options, additions );
5901			if ( !options.toHide.size() ) {
5902				options.toShow.animate({
5903					height: "show",
5904					paddingTop: "show",
5905					paddingBottom: "show"
5906				}, options );
5907				return;
5908			}
5909			if ( !options.toShow.size() ) {
5910				options.toHide.animate({
5911					height: "hide",
5912					paddingTop: "hide",
5913					paddingBottom: "hide"
5914				}, options );
5915				return;
5916			}
5917			var overflow = options.toShow.css( "overflow" ),
5918				percentDone = 0,
5919				showProps = {},
5920				hideProps = {},
5921				fxAttrs = [ "height", "paddingTop", "paddingBottom" ],
5922				originalWidth;
5923			// fix width before calculating height of hidden element
5924			var s = options.toShow;
5925			originalWidth = s[0].style.width;
5926			s.width( s.parent().width()
5927				- parseFloat( s.css( "paddingLeft" ) )
5928				- parseFloat( s.css( "paddingRight" ) )
5929				- ( parseFloat( s.css( "borderLeftWidth" ) ) || 0 )
5930				- ( parseFloat( s.css( "borderRightWidth" ) ) || 0 ) );
5931
5932			$.each( fxAttrs, function( i, prop ) {
5933				hideProps[ prop ] = "hide";
5934
5935				var parts = ( "" + $.css( options.toShow[0], prop ) ).match( /^([\d+-.]+)(.*)$/ );
5936				showProps[ prop ] = {
5937					value: parts[ 1 ],
5938					unit: parts[ 2 ] || "px"
5939				};
5940			});
5941			options.toShow.css({ height: 0, overflow: "hidden" }).show();
5942			options.toHide
5943				.filter( ":hidden" )
5944					.each( options.complete )
5945				.end()
5946				.filter( ":visible" )
5947				.animate( hideProps, {
5948				step: function( now, settings ) {
5949					// only calculate the percent when animating height
5950					// IE gets very inconsistent results when animating elements
5951					// with small values, which is common for padding
5952					if ( settings.prop == "height" ) {
5953						percentDone = ( settings.end - settings.start === 0 ) ? 0 :
5954							( settings.now - settings.start ) / ( settings.end - settings.start );
5955					}
5956
5957					options.toShow[ 0 ].style[ settings.prop ] =
5958						( percentDone * showProps[ settings.prop ].value )
5959						+ showProps[ settings.prop ].unit;
5960				},
5961				duration: options.duration,
5962				easing: options.easing,
5963				complete: function() {
5964					if ( !options.autoHeight ) {
5965						options.toShow.css( "height", "" );
5966					}
5967					options.toShow.css({
5968						width: originalWidth,
5969						overflow: overflow
5970					});
5971					options.complete();
5972				}
5973			});
5974		},
5975		bounceslide: function( options ) {
5976			this.slide( options, {
5977				easing: options.down ? "easeOutBounce" : "swing",
5978				duration: options.down ? 1000 : 200
5979			});
5980		}
5981	}
5982});
5983
5984})( jQuery );
5985
5986(function( $, undefined ) {
5987
5988// used to prevent race conditions with remote data sources
5989var requestIndex = 0;
5990
5991$.widget( "ui.autocomplete", {
5992	options: {
5993		appendTo: "body",
5994		autoFocus: false,
5995		delay: 300,
5996		minLength: 1,
5997		position: {
5998			my: "left top",
5999			at: "left bottom",
6000			collision: "none"
6001		},
6002		source: null
6003	},
6004
6005	pending: 0,
6006
6007	_create: function() {
6008		var self = this,
6009			doc = this.element[ 0 ].ownerDocument,
6010			suppressKeyPress;
6011		this.isMultiLine = this.element.is( "textarea" );
6012
6013		this.element
6014			.addClass( "ui-autocomplete-input" )
6015			.attr( "autocomplete", "off" )
6016			// TODO verify these actually work as intended
6017			.attr({
6018				role: "textbox",
6019				"aria-autocomplete": "list",
6020				"aria-haspopup": "true"
6021			})
6022			.bind( "keydown.autocomplete", function( event ) {
6023				if ( self.options.disabled || self.element.propAttr( "readOnly" ) ) {
6024					return;
6025				}
6026
6027				suppressKeyPress = false;
6028				var keyCode = $.ui.keyCode;
6029				switch( event.keyCode ) {
6030				case keyCode.PAGE_UP:
6031					self._move( "previousPage", event );
6032					break;
6033				case keyCode.PAGE_DOWN:
6034					self._move( "nextPage", event );
6035					break;
6036				case keyCode.UP:
6037					self._keyEvent( "previous", event );
6038					break;
6039				case keyCode.DOWN:
6040					self._keyEvent( "next", event );
6041					break;
6042				case keyCode.ENTER:
6043				case keyCode.NUMPAD_ENTER:
6044					// when menu is open and has focus
6045					if ( self.menu.active ) {
6046						// #6055 - Opera still allows the keypress to occur
6047						// which causes forms to submit
6048						suppressKeyPress = true;
6049						event.preventDefault();
6050					}
6051					//passthrough - ENTER and TAB both select the current element
6052				case keyCode.TAB:
6053					if ( !self.menu.active ) {
6054						return;
6055					}
6056					self.menu.select( event );
6057					break;
6058				case keyCode.ESCAPE:
6059					self.element.val( self.term );
6060					self.close( event );
6061					break;
6062				default:
6063					// keypress is triggered before the input value is changed
6064					clearTimeout( self.searching );
6065					self.searching = setTimeout(function() {
6066						// only search if the value has changed
6067						if ( self.term != self.element.val() ) {
6068							self.selectedItem = null;
6069							self.search( null, event );
6070						}
6071					}, self.options.delay );
6072					break;
6073				}
6074			})
6075			.bind( "keypress.autocomplete", function( event ) {
6076				if ( suppressKeyPress ) {
6077					suppressKeyPress = false;
6078					event.preventDefault();
6079				}
6080			})
6081			.bind( "focus.autocomplete", function() {
6082				if ( self.options.disabled ) {
6083					return;
6084				}
6085
6086				self.selectedItem = null;
6087				self.previous = self.element.val();
6088			})
6089			.bind( "blur.autocomplete", function( event ) {
6090				if ( self.options.disabled ) {
6091					return;
6092				}
6093
6094				clearTimeout( self.searching );
6095				// clicks on the menu (or a button to trigger a search) will cause a blur event
6096				self.closing = setTimeout(function() {
6097					self.close( event );
6098					self._change( event );
6099				}, 150 );
6100			});
6101		this._initSource();
6102		this.menu = $( "<ul></ul>" )
6103			.addClass( "ui-autocomplete" )
6104			.appendTo( $( this.options.appendTo || "body", doc )[0] )
6105			// prevent the close-on-blur in case of a "slow" click on the menu (long mousedown)
6106			.mousedown(function( event ) {
6107				// clicking on the scrollbar causes focus to shift to the body
6108				// but we can't detect a mouseup or a click immediately afterward
6109				// so we have to track the next mousedown and close the menu if
6110				// the user clicks somewhere outside of the autocomplete
6111				var menuElement = self.menu.element[ 0 ];
6112				if ( !$( event.target ).closest( ".ui-menu-item" ).length ) {
6113					setTimeout(function() {
6114						$( document ).one( 'mousedown', function( event ) {
6115							if ( event.target !== self.element[ 0 ] &&
6116								event.target !== menuElement &&
6117								!$.ui.contains( menuElement, event.target ) ) {
6118								self.close();
6119							}
6120						});
6121					}, 1 );
6122				}
6123
6124				// use another timeout to make sure the blur-event-handler on the input was already triggered
6125				setTimeout(function() {
6126					clearTimeout( self.closing );
6127				}, 13);
6128			})
6129			.menu({
6130				focus: function( event, ui ) {
6131					var item = ui.item.data( "item.autocomplete" );
6132					if ( false !== self._trigger( "focus", event, { item: item } ) ) {
6133						// use value to match what will end up in the input, if it was a key event
6134						if ( /^key/.test(event.originalEvent.type) ) {
6135							self.element.val( item.value );
6136						}
6137					}
6138				},
6139				selected: function( event, ui ) {
6140					var item = ui.item.data( "item.autocomplete" ),
6141						previous = self.previous;
6142
6143					// only trigger when focus was lost (click on menu)
6144					if ( self.element[0] !== doc.activeElement ) {
6145						self.element.focus();
6146						self.previous = previous;
6147						// #6109 - IE triggers two focus events and the second
6148						// is asynchronous, so we need to reset the previous
6149						// term synchronously and asynchronously :-(
6150						setTimeout(function() {
6151							self.previous = previous;
6152							self.selectedItem = item;
6153						}, 1);
6154					}
6155
6156					if ( false !== self._trigger( "select", event, { item: item } ) ) {
6157						self.element.val( item.value );
6158					}
6159					// reset the term after the select event
6160					// this allows custom select handling to work properly
6161					self.term = self.element.val();
6162
6163					self.close( event );
6164					self.selectedItem = item;
6165				},
6166				blur: function( event, ui ) {
6167					// don't set the value of the text field if it's already correct
6168					// this prevents moving the cursor unnecessarily
6169					if ( self.menu.element.is(":visible") &&
6170						( self.element.val() !== self.term ) ) {
6171						self.element.val( self.term );
6172					}
6173				}
6174			})
6175			.css('zindex', this.element.css('zindex') + 1 )
6176			// workaround for jQuery bug #5781 http://dev.jquery.com/ticket/5781
6177			.css({ top: 0, left: 0 })
6178			.hide()
6179			.data( "menu" );
6180		if ( $.fn.bgiframe ) {
6181			 this.menu.element.bgiframe();
6182		}
6183		// turning off autocomplete prevents the browser from remembering the
6184		// value when navigating through history, so we re-enable autocomplete
6185		// if the page is unloaded before the widget is destroyed. #7790
6186		self.beforeunloadHandler = function() {
6187			self.element.removeAttr( "autocomplete" );
6188		};
6189		$( window ).bind( "beforeunload", self.beforeunloadHandler );
6190	},
6191
6192	destroy: function() {
6193		this.element
6194			.removeClass( "ui-autocomplete-input" )
6195			.removeAttr( "autocomplete" )
6196			.removeAttr( "role" )
6197			.removeAttr( "aria-autocomplete" )
6198			.removeAttr( "aria-haspopup" );
6199		this.menu.element.remove();
6200		$( window ).unbind( "beforeunload", this.beforeunloadHandler );
6201		$.Widget.prototype.destroy.call( this );
6202	},
6203
6204	_setOption: function( key, value ) {
6205		$.Widget.prototype._setOption.apply( this, arguments );
6206		if ( key === "source" ) {
6207			this._initSource();
6208		}
6209		if ( key === "appendTo" ) {
6210			this.menu.element.appendTo( $( value || "body", this.element[0].ownerDocument )[0] )
6211		}
6212		if ( key === "disabled" && value && this.xhr ) {
6213			this.xhr.abort();
6214		}
6215	},
6216
6217	_initSource: function() {
6218		var self = this,
6219			array,
6220			url;
6221		if ( $.isArray(this.options.source) ) {
6222			array = this.options.source;
6223			this.source = function( request, response ) {
6224				response( $.ui.autocomplete.filter(array, request.term) );
6225			};
6226		} else if ( typeof this.options.source === "string" ) {
6227			url = this.options.source;
6228			this.source = function( request, response ) {
6229				if ( self.xhr ) {
6230					self.xhr.abort();
6231				}
6232				self.xhr = $.ajax({
6233					url: url,
6234					data: request,
6235					dataType: "json",
6236					success: function( data, status ) {
6237						response( data );
6238					},
6239					error: function() {
6240						response( [] );
6241					}
6242				});
6243			};
6244		} else {
6245			this.source = this.options.source;
6246		}
6247	},
6248
6249	search: function( value, event ) {
6250		value = value != null ? value : this.element.val();
6251
6252		// always save the actual value, not the one passed as an argument
6253		this.term = this.element.val();
6254
6255		if ( value.length < this.options.minLength ) {
6256			return this.close( event );
6257		}
6258
6259		clearTimeout( this.closing );
6260		if ( this._trigger( "search", event ) === false ) {
6261			return;
6262		}
6263
6264		return this._search( value );
6265	},
6266
6267	_search: function( value ) {
6268		this.pending++;
6269		this.element.addClass( "ui-autocomplete-loading" );
6270
6271		this.source( { term: value }, this._response() );
6272	},
6273
6274	_response: function() {
6275		var that = this,
6276			index = ++requestIndex;
6277
6278		return function( content ) {
6279			if ( index === requestIndex ) {
6280				that.__response( content );
6281			}
6282
6283			that.pending--;
6284			if ( !that.pending ) {
6285				that.element.removeClass( "ui-autocomplete-loading" );
6286			}
6287		};
6288	},
6289
6290	__response: function( content ) {
6291		if ( !this.options.disabled && content && content.length ) {
6292			content = this._normalize( content );
6293			this._suggest( content );
6294			this._trigger( "open" );
6295		} else {
6296			this.close();
6297		}
6298	},
6299
6300	close: function( event ) {
6301		clearTimeout( this.closing );
6302		if ( this.menu.element.is(":visible") ) {
6303			this.menu.element.hide();
6304			this.menu.deactivate();
6305			this._trigger( "close", event );
6306		}
6307	},
6308	
6309	_change: function( event ) {
6310		if ( this.previous !== this.element.val() ) {
6311			this._trigger( "change", event, { item: this.selectedItem } );
6312		}
6313	},
6314
6315	_normalize: function( items ) {
6316		// assume all items have the right format when the first item is complete
6317		if ( items.length && items[0].label && items[0].value ) {
6318			return items;
6319		}
6320		return $.map( items, function(item) {
6321			if ( typeof item === "string" ) {
6322				return {
6323					label: item,
6324					value: item
6325				};
6326			}
6327			return $.extend({
6328				label: item.label || item.value,
6329				value: item.value || item.label
6330			}, item );
6331		});
6332	},
6333
6334	_suggest: function( items ) {
6335		var ul = this.menu.element
6336			.empty()
6337			.css('zindex',  this.element.css('zindex') + 1 );
6338		this._renderMenu( ul, items );
6339		// TODO refresh should check if the active item is still in the dom, removing the need for a manual deactivate
6340		this.menu.deactivate();
6341		this.menu.refresh();
6342
6343		// size and position menu
6344		ul.show();
6345		this._resizeMenu();
6346		ul.position( $.extend({
6347			of: this.element
6348		}, this.options.position ));
6349
6350		if ( this.options.autoFocus ) {
6351			this.menu.next( new $.Event("mouseover") );
6352		}
6353	},
6354
6355	_resizeMenu: function() {
6356		var ul = this.menu.element;
6357		ul.outerWidth( Math.max(
6358			// Firefox wraps long text (possibly a rounding bug)
6359			// so we add 1px to avoid the wrapping (#7513)
6360			ul.width( "" ).outerWidth() + 1,
6361			this.element.outerWidth()
6362		) );
6363	},
6364
6365	_renderMenu: function( ul, items ) {
6366		var self = this;
6367		$.each( items, function( index, item ) {
6368			self._renderItem( ul, item );
6369		});
6370	},
6371
6372	_renderItem: function( ul, item) {
6373		return $( "<li></li>" )
6374			.data( "item.autocomplete", item )
6375			.append( $( "<a></a>" ).text( item.label ) )
6376			.appendTo( ul );
6377	},
6378
6379	_move: function( direction, event ) {
6380		if ( !this.menu.element.is(":visible") ) {
6381			this.search( null, event );
6382			return;
6383		}
6384		if ( this.menu.first() && /^previous/.test(direction) ||
6385				this.menu.last() && /^next/.test(direction) ) {
6386			this.element.val( this.term );
6387			this.menu.deactivate();
6388			return;
6389		}
6390		this.menu[ direction ]( event );
6391	},
6392
6393	widget: function() {
6394		return this.menu.element;
6395	},
6396	_keyEvent: function( keyEvent, event ) {
6397		if ( !this.isMultiLine || this.menu.element.is( ":visible" ) ) {
6398			this._move( keyEvent, event );
6399
6400			// prevents moving cursor to beginning/end of the text field in some browsers
6401			event.preventDefault();
6402		}
6403	}
6404});
6405
6406$.extend( $.ui.autocomplete, {
6407	escapeRegex: function( value ) {
6408		return value.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, "\\$&");
6409	},
6410	filter: function(array, term) {
6411		var matcher = new RegExp( $.ui.autocomplete.escapeRegex(term), "i" );
6412		return $.grep( array, function(value) {
6413			return matcher.test( value.label || value.value || value );
6414		});
6415	}
6416});
6417
6418}( jQuery ));
6419
6420/*
6421 * jQuery UI Menu (not officially released)
6422 * 
6423 * This widget isn't yet finished and the API is subject to change. We plan to finish
6424 * it for the next release. You're welcome to give it a try anyway and give us feedback,
6425 * as long as you're okay with migrating your code later on. We can help with that, too.
6426 *
6427 * Copyright 2010, AUTHORS.txt (http://jqueryui.com/about)
6428 * Dual licensed under the MIT or GPL Version 2 licenses.
6429 * http://jquery.org/license
6430 *
6431 * http://docs.jquery.com/UI/Menu
6432 *
6433 * Depends:
6434 *	jquery.ui.core.js
6435 *  jquery.ui.widget.js
6436 */
6437(function($) {
6438
6439$.widget("ui.menu", {
6440	_create: function() {
6441		var self = this;
6442		this.element
6443			.addClass("ui-menu ui-widget ui-widget-content ui-corner-all")
6444			.attr({
6445				role: "listbox",
6446				"aria-activedescendant": "ui-active-menuitem"
6447			})
6448			.click(function( event ) {
6449				if ( !$( event.target ).closest( ".ui-menu-item a" ).length ) {
6450					return;
6451				}
6452				// temporary
6453				event.preventDefault();
6454				self.select( event );
6455			});
6456		this.refresh();
6457	},
6458	
6459	refresh: function() {
6460		var self = this;
6461
6462		// don't refresh list items that are already adapted
6463		var items = this.element.children("li:not(.ui-menu-item):has(a)")
6464			.addClass("ui-menu-item")
6465			.attr("role", "menuitem");
6466		
6467		items.children("a")
6468			.addClass("ui-corner-all")
6469			.attr("tabindex", -1)
6470			// mouseenter doesn't work with event delegation
6471			.mouseenter(function( event ) {
6472				self.activate( event, $(this).parent() );
6473			})
6474			.mouseleave(function() {
6475				self.deactivate();
6476			});
6477	},
6478
6479	activate: function( event, item ) {
6480		this.deactivate();
6481		if (this.hasScroll()) {
6482			var offset = item.offset().top - this.element.offset().top,
6483				scroll = this.element.scrollTop(),
6484				elementHeight = this.element.height();
6485			if (offset < 0) {
6486				this.element.scrollTop( scroll + offset);
6487			} else if (offset >= elementHeight) {
6488				this.element.scrollTop( scroll + offset - elementHeight + item.height());
6489			}
6490		}
6491		this.active = item.eq(0)
6492			.children("a")
6493				.addClass("ui-state-hover")
6494				.attr("id", "ui-active-menuitem")
6495			.end();
6496		this._trigger("focus", event, { item: item });
6497	},
6498
6499	deactivate: function() {
6500		if (!this.active) { return; }
6501
6502		this.active.children("a")
6503			.removeClass("ui-state-hover")
6504			.removeAttr("id");
6505		this._trigger("blur");
6506		this.active = null;
6507	},
6508
6509	next: function(event) {
6510		this.move("next", ".ui-menu-item:first", event);
6511	},
6512
6513	previous: function(event) {
6514		this.move("prev", ".ui-menu-item:last", event);
6515	},
6516
6517	first: function() {
6518		return this.active && !this.active.prevAll(".ui-menu-item").length;
6519	},
6520
6521	last: function() {
6522		return this.active && !this.active.nextAll(".ui-menu-item").length;
6523	},
6524
6525	move: function(direction, edge, event) {
6526		if (!this.active) {
6527			this.activate(event, this.element.children(edge));
6528			return;
6529		}
6530		var next = this.active[direction + "All"](".ui-menu-item").eq(0);
6531		if (next.length) {
6532			this.activate(event, next);
6533		} else {
6534			this.activate(event, this.element.children(edge));
6535		}
6536	},
6537
6538	// TODO merge with previousPage
6539	nextPage: function(event) {
6540		if (this.hasScroll()) {
6541			// TODO merge with no-scroll-else
6542			if (!this.active || this.last()) {
6543				this.activate(event, this.element.children(".ui-menu-item:first"));
6544				return;
6545			}
6546			var base = this.active.offset().top,
6547				height = this.element.height(),
6548				result = this.element.children(".ui-menu-item").filter(function() {
6549					var close = $(this).offset().top - base - height + $(this).height();
6550					// TODO improve approximation
6551					return close < 10 && close > -10;
6552				});
6553
6554			// TODO try to catch this earlier when scrollTop indicates the last page anyway
6555			if (!result.length) {
6556				result = this.element.children(".ui-menu-item:last");
6557			}
6558			this.activate(event, result);
6559		} else {
6560			this.activate(event, this.element.children(".ui-menu-item")
6561				.filter(!this.active || this.last() ? ":first" : ":last"));
6562		}
6563	},
6564
6565	// TODO merge with nextPage
6566	previousPage: function(event) {
6567		if (this.hasScroll()) {
6568			// TODO merge with no-scroll-else
6569			if (!this.active || this.first()) {
6570				this.activate(event, this.element.children(".ui-menu-item:last"));
6571				return;
6572			}
6573
6574			var base = this.active.offset().top,
6575				height = this.element.height(),
6576				result = this.element.children(".ui-menu-item").filter(function() {
6577					var close = $(this).offset().top - base + height - $(this).height();
6578					// TODO improve approximation
6579					return close < 10 && close > -10;
6580				});
6581
6582			// TODO try to catch this earlier when scrollTop indicates the last page anyway
6583			if (!result.length) {
6584				result = this.element.children(".ui-menu-item:first");
6585			}
6586			this.activate(event, result);
6587		} else {
6588			this.activate(event, this.element.children(".ui-menu-item")
6589				.filter(!this.active || this.first() ? ":last" : ":first"));
6590		}
6591	},
6592
6593	hasScroll: function() {
6594		return this.element.height() < this.element[ $.fn.prop ? "prop" : "attr" ]("scrollHeight");
6595	},
6596
6597	select: function( event ) {
6598		this._trigger("selected", event, { item: this.active });
6599	}
6600});
6601
6602}(jQuery));
6603
6604(function( $, undefined ) {
6605
6606var lastActive, startXPos, startYPos, clickDragged,
6607	baseClasses = "ui-button ui-widget ui-state-default ui-corner-all",
6608	stateClasses = "ui-state-hover ui-state-active ",
6609	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",
6610	formResetHandler = function() {
6611		var buttons = $( this ).find( ":ui-button" );
6612		setTimeout(function() {
6613			buttons.button( "refresh" );
6614		}, 1 );
6615	},
6616	radioGroup = function( radio ) {
6617		var name = radio.name,
6618			form = radio.form,
6619			radios = $( [] );
6620		if ( name ) {
6621			if ( form ) {
6622				radios = $( form ).find( "[name='" + name + "']" );
6623			} else {
6624				radios = $( "[name='" + name + "']", radio.ownerDocument )
6625					.filter(function() {
6626						return !this.form;
6627					});
6628			}
6629		}
6630		return radios;
6631	};
6632
6633$.widget( "ui.button", {
6634	options: {
6635		disabled: null,
6636		text: true,
6637		label: null,
6638		icons: {
6639			primary: null,
6640			secondary: null
6641		}
6642	},
6643	_create: function() {
6644		this.element.closest( "form" )
6645			.unbind( "reset.button" )
6646			.bind( "reset.button", formResetHandler );
6647
6648		if ( typeof this.options.disabled !== "boolean" ) {
6649			this.options.disabled = !!this.element.propAttr( "disabled" );
6650		} else {
6651			this.element.propAttr( "disabled", this.options.disabled );
6652		}
6653
6654		this._determineButtonType();
6655		this.hasTitle = !!this.buttonElement.attr( "title" );
6656
6657		var self = this,
6658			options = this.options,
6659			toggleButton = this.type === "checkbox" || this.type === "radio",
6660			hoverClass = "ui-state-hover" + ( !toggleButton ? " ui-state-active" : "" ),
6661			focusClass = "ui-state-focus";
6662
6663		if ( options.label === null ) {
6664			options.label = this.buttonElement.html();
6665		}
6666
6667		this.buttonElement
6668			.addClass( baseClasses )
6669			.attr( "role", "button" )
6670			.bind( "mouseenter.button", function() {
6671				if ( options.disabled ) {
6672					return;
6673				}
6674				$( this ).addClass( "ui-state-hover" );
6675				if ( this === lastActive ) {
6676					$( this ).addClass( "ui-state-active" );
6677				}
6678			})
6679			.bind( "mouseleave.button", function() {
6680				if ( options.disabled ) {
6681					return;
6682				}
6683				$( this ).removeClass( hoverClass );
6684			})
6685			.bind( "click.button", function( event ) {
6686				if ( options.disabled ) {
6687					event.preventDefault();
6688					event.stopImmediatePropagation();
6689				}
6690			});
6691
6692		this.element
6693			.bind( "focus.button", function() {
6694				// no need to check disabled, focus won't be triggered anyway
6695				self.buttonElement.addClass( focusClass );
6696			})
6697			.bind( "blur.button", function() {
6698				self.buttonElement.removeClass( focusClass );
6699			});
6700
6701		if ( toggleButton ) {
6702			this.element.bind( "change.button", function() {
6703				if ( clickDragged ) {
6704					return;
6705				}
6706				self.refresh();
6707			});
6708			// if mouse moves between mousedown and mouseup (drag) set clickDragged flag
6709			// prevents issue where button state changes but checkbox/radio checked state
6710			// does not in Firefox (see ticket #6970)
6711			this.buttonElement
6712				.bind( "mousedown.button", function( event ) {
6713					if ( options.disabled ) {
6714						return;
6715					}
6716					clickDragged = false;
6717					startXPos = event.pageX;
6718					startYPos = event.pageY;
6719				})
6720				.bind( "mouseup.button", function( event ) {
6721					if ( options.disabled ) {
6722						return;
6723					}
6724					if ( startXPos !== event.pageX || startYPos !== event.pageY ) {
6725						clickDragged = true;
6726					}
6727			});
6728		}
6729
6730		if ( this.type === "checkbox" ) {
6731			this.buttonElement.bind( "click.button", function() {
6732				if ( options.disabled || clickDragged ) {
6733					return false;
6734				}
6735				$( this ).toggleClass( "ui-state-active" );
6736				self.buttonElement.attr( "aria-pressed", self.element[0].checked );
6737			});
6738		} else if ( this.type === "radio" ) {
6739			this.buttonElement.bind( "click.button", function() {
6740				if ( options.disabled || clickDragged ) {
6741					return false;
6742				}
6743				$( this ).addClass( "ui-state-active" );
6744				self.buttonElement.attr( "aria-pressed", "true" );
6745
6746				var radio = self.element[ 0 ];
6747				radioGroup( radio )
6748					.not( radio )
6749					.map(function() {
6750						return $( this ).button( "widget" )[ 0 ];
6751					})
6752					.removeClass( "ui-state-active" )
6753					.attr( "aria-pressed", "false" );
6754			});
6755		} else {
6756			this.buttonElement
6757				.bind( "mousedown.button", function() {
6758					if ( options.disabled ) {
6759						return false;
6760					}
6761					$( this ).addClass( "ui-state-active" );
6762					lastActive = this;
6763					$( document ).one( "mouseup", function() {
6764						lastActive = null;
6765					});
6766				})
6767				.bind( "mouseup.button", function() {
6768					if ( options.disabled ) {
6769						return false;
6770					}
6771					$( this ).removeClass( "ui-state-active" );
6772				})
6773				.bind( "keydown.button", function(event) {
6774					if ( options.disabled ) {
6775						return false;
6776					}
6777					if ( event.keyCode == $.ui.keyCode.SPACE || event.keyCode == $.ui.keyCode.ENTER ) {
6778						$( this ).addClass( "ui-state-active" );
6779					}
6780				})
6781				.bind( "keyup.button", function() {
6782					$( this ).removeClass( "ui-state-active" );
6783				});
6784
6785			if ( this.buttonElement.is("a") ) {
6786				this.buttonElement.keyup(function(event) {
6787					if ( event.keyCode === $.ui.keyCode.SPACE ) {
6788						// TODO pass through original event correctly (just as 2nd argument doesn't work)
6789						$( this ).click();
6790					}
6791				});
6792			}
6793		}
6794
6795		// TODO: pull out $.Widget's handling for the disabled option into
6796		// $.Widget.prototype._setOptionDisabled so it's easy to proxy and can
6797		// be overridden by individual plugins
6798		this._setOption( "disabled", options.disabled );
6799		this._resetButton();
6800	},
6801
6802	_determineButtonType: function() {
6803
6804		if ( this.element.is(":checkbox") ) {
6805			this.type = "checkbox";
6806		} else if ( this.element.is(":radio") ) {
6807			this.type = "radio";
6808		} else if ( this.element.is("input") ) {
6809			this.type = "input";
6810		} else {
6811			this.type = "button";
6812		}
6813
6814		if ( this.type === "checkbox" || this.type === "radio" ) {
6815			// we don't search against the document in case the element
6816			// is disconnected from the DOM
6817			var ancestor = this.element.parents().filter(":last"),
6818				labelSelector = "label[for='" + this.element.attr("id") + "']";
6819			this.buttonElement = ancestor.find( labelSelector );
6820			if ( !this.buttonElement.length ) {
6821				ancestor = ancestor.length ? ancestor.siblings() : this.element.siblings();
6822				this.buttonElement = ancestor.filter( labelSelector );
6823				if ( !this.buttonElement.length ) {
6824					this.buttonElement = ancestor.find( labelSelector );
6825				}
6826			}
6827			this.element.addClass( "ui-helper-hidden-accessible" );
6828
6829			var checked = this.element.is( ":checked" );
6830			if ( checked ) {
6831				this.buttonElement.addClass( "ui-state-active" );
6832			}
6833			this.buttonElement.attr( "aria-pressed", checked );
6834		} else {
6835			this.buttonElement = this.element;
6836		}
6837	},
6838
6839	widget: function() {
6840		return this.buttonElement;
6841	},
6842
6843	destroy: function() {
6844		this.element
6845			.removeClass( "ui-helper-hidden-accessible" );
6846		this.buttonElement
6847			.removeClass( baseClasses + " " + stateClasses + " " + typeClasses )
6848			.removeAttr( "role" )
6849			.removeAttr( "aria-pressed" )
6850			.html( this.buttonElement.find(".ui-button-text").html() );
6851
6852		if ( !this.hasTitle ) {
6853			this.buttonElement.removeAttr( "title" );
6854		}
6855
6856		$.Widget.prototype.destroy.call( this );
6857	},
6858
6859	_setOption: function( key, value ) {
6860		$.Widget.prototype._setOption.apply( this, arguments );
6861		if ( key === "disabled" ) {
6862			if ( value ) {
6863				this.element.propAttr( "disabled", true );
6864			} else {
6865				this.element.propAttr( "disabled", false );
6866			}
6867			return;
6868		}
6869		this._resetButton();
6870	},
6871
6872	refresh: function() {
6873		var isDisabled = this.element.is( ":disabled" );
6874		if ( isDisabled !== this.options.disabled ) {
6875			this._setOption( "disabled", isDisabled );
6876		}
6877		if ( this.type === "radio" ) {
6878			radioGroup( this.element[0] ).each(function() {
6879				if ( $( this ).is( ":checked" ) ) {
6880					$( this ).button( "widget" )
6881						.addClass( "ui-state-active" )
6882						.attr( "aria-pressed", "true" );
6883				} else {
6884					$( this ).button( "widget" )
6885						.removeClass( "ui-state-active" )
6886						.attr( "aria-pressed", "false" );
6887				}
6888			});
6889		} else if ( this.type === "checkbox" ) {
6890			if ( this.element.is( ":checked" ) ) {
6891				this.buttonElement
6892					.addClass( "ui-state-active" )
6893					.attr( "aria-pressed", "true" );
6894			} else {
6895				this.buttonElement
6896					.removeClass( "ui-state-active" )
6897					.attr( "aria-pressed", "false" );
6898			}
6899		}
6900	},
6901
6902	_resetButton: function() {
6903		if ( this.type === "input" ) {
6904			if ( this.options.label ) {
6905				this.element.val( this.options.label );
6906			}
6907			return;
6908		}
6909		var buttonElement = this.buttonElement.removeClass( typeClasses ),
6910			buttonText = $( "<span></span>", this.element[0].ownerDocument )
6911				.addClass( "ui-button-text" )
6912				.html( this.options.label )
6913				.appendTo( buttonElement.empty() )
6914				.text(),
6915			icons = this.options.icons,
6916			multipleIcons = icons.primary && icons.secondary,
6917			buttonClasses = [];  
6918
6919		if ( icons.primary || icons.secondary ) {
6920			if ( this.options.text ) {
6921				buttonClasses.push( "ui-button-text-icon" + ( multipleIcons ? "s" : ( icons.primary ? "-primary" : "-secondary" ) ) );
6922			}
6923
6924			if ( icons.primary ) {
6925				buttonElement.prepend( "<span class='ui-button-icon-primary ui-icon " + icons.primary + "'></span>" );
6926			}
6927
6928			if ( icons.secondary ) {
6929				buttonElement.append( "<span class='ui-button-icon-secondary ui-icon " + icons.secondary + "'></span>" );
6930			}
6931
6932			if ( !this.options.text ) {
6933				buttonClasses.push( multipleIcons ? "ui-button-icons-only" : "ui-button-icon-only" );
6934
6935				if ( !this.hasTitle ) {
6936					buttonElement.attr( "title", buttonText );
6937				}
6938			}
6939		} else {
6940			buttonClasses.push( "ui-button-text-only" );
6941		}
6942		buttonElement.addClass( buttonClasses.join( " " ) );
6943	}
6944});
6945
6946$.widget( "ui.buttonset", {
6947	options: {
6948		items: ":button, :submit, :reset, :checkbox, :radio, a, :data(button)"
6949	},
6950
6951	_create: function() {
6952		this.element.addClass( "ui-buttonset" );
6953	},
6954	
6955	_init: function() {
6956		this.refresh();
6957	},
6958
6959	_setOption: function( key, value ) {
6960		if ( key === "disabled" ) {
6961			this.buttons.button( "option", key, value );
6962		}
6963
6964		$.Widget.prototype._setOption.apply( this, arguments );
6965	},
6966	
6967	refresh: function() {
6968		var rtl = this.element.css( "direction" ) === "rtl";
6969		
6970		this.buttons = this.element.find( this.options.items )
6971			.filter( ":ui-button" )
6972				.button( "refresh" )
6973			.end()
6974			.not( ":ui-button" )
6975				.button()
6976			.end()
6977			.map(function() {
6978				return $( this ).button( "widget" )[ 0 ];
6979			})
6980				.removeClass( "ui-corner-all ui-corner-left ui-corner-right" )
6981				.filter( ":first" )
6982					.addClass( rtl ? "ui-corner-right" : "ui-corner-left" )
6983				.end()
6984				.filter( ":last" )
6985					.addClass( rtl ? "ui-corner-left" : "ui-corner-right" )
6986				.end()
6987			.end();
6988	},
6989
6990	destroy: function() {
6991		this.element.removeClass( "ui-buttonset" );
6992		this.buttons
6993			.map(function() {
6994				return $( this ).button( "widget" )[ 0 ];
6995			})
6996				.removeClass( "ui-corner-left ui-corner-right" )
6997			.end()
6998			.button( "destroy" );
6999
7000		$.Widget.prototype.destroy.call( this );
7001	}
7002});
7003
7004}( jQuery ) );
7005
7006(function( $, undefined ) {
7007
7008$.extend($.ui, { datepicker: { version: "@VERSION" } });
7009
7010var PROP_NAME = 'datepicker';
7011var dpuuid = new Date().getTime();
7012var instActive;
7013
7014/* Date picker manager.
7015   Use the singleton instance of this class, $.datepicker, to interact with the date picker.
7016   Settings for (groups of) date pickers are maintained in an instance object,
7017   allowing multiple different settings on the same page. */
7018
7019function Datepicker() {
7020	this.debug = false; // Change this to true to start debugging
7021	this._curInst = null; // The current instance in use
7022	this._keyEvent = false; // If the last event was a key event
7023	this._disabledInputs = []; // List of date picker inputs that have been disabled
7024	this._datepickerShowing = false; // True if the popup picker is showing , false if not
7025	this._inDialog = false; // True if showing within a "dialog", false if not
7026	this._mainDivId = 'ui-datepicker-div'; // The ID of the main datepicker division
7027	this._inlineClass = 'ui-datepicker-inline'; // The name of the inline marker class
7028	this._appendClass = 'ui-datepicker-append'; // The name of the append marker class
7029	this._triggerClass = 'ui-datepicker-trigger'; // The name of the trigger marker class
7030	this._dialogClass = 'ui-datepicker-dialog'; // The name of the dialog marker class
7031	this._disableClass = 'ui-datepicker-disabled'; // The name of the disabled covering marker class
7032	this._unselectableClass = 'ui-datepicker-unselectable'; // The name of the unselectable cell marker class
7033	this._currentClass = 'ui-datepicker-current-day'; // The name of the current day marker class
7034	this._dayOverClass = 'ui-datepicker-days-cell-over'; // The name of the day hover marker class
7035	this.regional = []; // Available regional settings, indexed by language code
7036	this.regional[''] = { // Default regional settings
7037		closeText: 'Done', // Display text for close link
7038		prevText: 'Prev', // Display text for previous month link
7039		nextText: 'Next', // Display text for next month link
7040		currentText: 'Today', // Display text for current month link
7041		monthNames: ['January','February','March','April','May','June',
7042			'July','August','September','October','November','December'], // Names of months for drop-down and formatting
7043		monthNamesShort: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'], // For formatting
7044		dayNames: ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'], // For formatting
7045		dayNamesShort: ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'], // For formatting
7046		dayNamesMin: ['Su','Mo','Tu','We','Th','Fr','Sa'], // Column headings for days starting at Sunday
7047		weekHeader: 'Wk', // Column header for week of the year
7048		dateFormat: 'mm/dd/yy', // See format options on parseDate
7049		firstDay: 0, // The first day of the week, Sun = 0, Mon = 1, ...
7050		isRTL: false, // True if right-to-left language, false if left-to-right
7051		showMonthAfterYear: false, // True if the year select precedes month, false for month then year
7052		yearSuffix: '' // Additional text to append to the year in the month headers
7053	};
7054	this._defaults = { // Global defaults for all the date picker instances
7055		showOn: 'focus', // 'focus' for popup on focus,
7056			// 'button' for trigger button, or 'both' for either
7057		showAnim: 'fadeIn', // Name of jQuery animation for popup
7058		showOptions: {}, // Options for enhanced animations
7059		defaultDate: null, // Used when field is blank: actual date,
7060			// +/-number for offset from today, null for today
7061		appendText: '', // Display text following the input box, e.g. showing the format
7062		buttonText: '...', // Text for trigger button
7063		buttonImage: '', // URL for trigger button image
7064		buttonImageOnly: false, // True if the image appears alone, false if it appears on a button
7065		hideIfNoPrevNext: false, // True to hide next/previous month links
7066			// if not applicable, false to just disable them
7067		navigationAsDateFormat: false, // True if date formatting applied to prev/today/next links
7068		gotoCurrent: false, // True if today link goes back to current selection instead
7069		changeMonth: false, // True if month can be selected directly, false if only prev/next
7070		changeYear: false, // True if year can be selected directly, false if only prev/next
7071		yearRange: 'c-10:c+10', // Range of years to display in drop-down,
7072			// either relative to today's year (-nn:+nn), relative to currently displayed year
7073			// (c-nn:c+nn), absolute (nnnn:nnnn), or a combination of the above (nnnn:-n)
7074		showOtherMonths: false, // True to show dates in other months, false to leave blank
7075		selectOtherMonths: false, // True to allow selection of dates in other months, false for unselectable
7076		showWeek: false, // True to show week of the year, false to not show it
7077		calculateWeek: this.iso8601Week, // How to calculate the week of the year,
7078			// takes a Date and returns the number of the week for it
7079		shortYearCutoff: '+10', // Short year values < this are in the current century,
7080			// > this are in the previous century,
7081			// string value starting with '+' for current year + value
7082		minDate: null, // The earliest selectable date, or null for no limit
7083		maxDate: null, // The latest selectable date, or null for no limit
7084		duration: 'fast', // Duration of display/closure
7085		beforeShowDay: null, // Function that takes a date and returns an array with
7086			// [0] = true if selectable, false if not, [1] = custom CSS class name(s) or '',
7087			// [2] = cell title (optional), e.g. $.datepicker.noWeekends
7088		beforeShow: null, // Function that takes an input field and
7089			// returns a set of custom settings for the date picker
7090		onSelect: null, // Define a callback function when a date is selected
7091		onChangeMonthYear: null, // Define a callback function when the month or year is changed
7092		onClose: null, // Define a callback function when the datepicker is closed
7093		numberOfMonths: 1, // Number of months to show at a time
7094		showCurrentAtPos: 0, // The position in multipe months at which to show the current month (starting at 0)
7095		stepMonths: 1, // Number of months to step back/forward
7096		stepBigMonths: 12, // Number of months to step back/forward for the big links
7097		altField: '', // Selector for an alternate field to store selected dates into
7098		altFormat: '', // The date format to use for the alternate field
7099		constrainInput: true, // The input is constrained by the current date format
7100		showButtonPanel: false, // True to show button panel, false to not show it
7101		autoSize: false, // True to size the input for the date format, false to leave as is
7102		disabled: false // The initial disabled state
7103	};
7104	$.extend(this._defaults, this.regional['']);
7105	this.dpDiv = bindHover($('<div id="' + this._mainDivId + '" class="ui-datepicker ui-widget ui-widget-content ui-helper-clearfix ui-corner-all"></div>'));
7106}
7107
7108$.extend(Datepicker.prototype, {
7109	/* Class name added to elements to indicate already configured with a date picker. */
7110	markerClassName: 'hasDatepicker',
7111	
7112	//Keep track of the maximum number of rows displayed (see #7043)
7113	maxRows: 4,
7114
7115	/* Debug logging (if enabled). */
7116	log: function () {
7117		if (this.debug)
7118			console.log.apply('', arguments);
7119	},
7120	
7121	// TODO rename to "widget" when switching to widget factory
7122	_widgetDatepicker: function() {
7123		return this.dpDiv;
7124	},
7125
7126	/* Override the default settings for all instances of the date picker.
7127	   @param  settings  object - the new settings to use as defaults (anonymous object)
7128	   @return the manager object */
7129	setDefaults: function(settings) {
7130		extendRemove(this._defaults, settings || {});
7131		return this;
7132	},
7133
7134	/* Attach the date picker to a jQuery selection.
7135	   @param  target    element - the target input field or division or span
7136	   @param  settings  object - the new settings to use for this date picker instance (anonymous) */
7137	_attachDatepicker: function(target, settings) {
7138		// check for settings on the control itself - in namespace 'date:'
7139		var inlineSettings = null;
7140		for (var attrName in this._defaults) {
7141			var attrValue = target.getAttribute('date:' + attrName);
7142			if (attrValue) {
7143				inlineSettings = inlineSettings || {};
7144				try {
7145					inlineSettings[attrName] = eval(attrValue);
7146				} catch (err) {
7147					inlineSettings[attrName] = attrValue;
7148				}
7149			}
7150		}
7151		var nodeName = target.nodeName.toLowerCase();
7152		var inline = (nodeName == 'div' || nodeName == 'span');
7153		if (!target.id) {
7154			this.uuid += 1;
7155			target.id = 'dp' + this.uuid;
7156		}
7157		var inst = this._newInst($(target), inline);
7158		inst.settings = $.extend({}, settings || {}, inlineSettings || {});
7159		if (nodeName == 'input') {
7160			this._connectDatepicker(target, inst);
7161		} else if (inline) {
7162			this._inlineDatepicker(target, inst);
7163		}
7164	},
7165
7166	/* Create a new instance object. */
7167	_newInst: function(target, inline) {
7168		var id = target[0].id.replace(/([^A-Za-z0-9_-])/g, '\\\\$1'); // escape jQuery meta chars
7169		return {id: id, input: target, // associated target
7170			selectedDay: 0, selectedMonth: 0, selectedYear: 0, // current selection
7171			drawMonth: 0, drawYear: 0, // month being drawn
7172			inline: inline, // is datepicker inline or not
7173			dpDiv: (!inline ? this.dpDiv : // presentation div
7174			bindHover($('<div class="' + this._inlineClass + ' ui-datepicker ui-widget ui-widget-content ui-helper-clearfix ui-corner-all"></div>')))};
7175	},
7176
7177	/* Attach the date picker to an input field. */
7178	_connectDatepicker: function(target, inst) {
7179		var input = $(target);
7180		inst.append = $([]);
7181		inst.trigger = $([]);
7182		if (input.hasClass(this.markerClassName))
7183			return;
7184		this._attachments(input, inst);
7185		input.addClass(this.markerClassName).keydown(this._doKeyDown).
7186			keypress(this._doKeyPress).keyup(this._doKeyUp).
7187			bind("setData.datepicker", function(event, key, value) {
7188				inst.settings[key] = value;
7189			}).bind("getData.datepicker", function(event, key) {
7190				return this._get(inst, key);
7191			});
7192		this._autoSize(inst);
7193		$.data(target, PROP_NAME, inst);
7194		//If disabled option is true, disable the datepicker once it has been attached to the input (see ticket #5665)
7195		if( inst.settings.disabled ) {
7196			this._disableDatepicker( target );
7197		}
7198	},
7199
7200	/* Make attachments based on settings. */
7201	_attachments: function(input, inst) {
7202		var appendText = this._get(inst, 'appendText');
7203		var isRTL = this._get(inst, 'isRTL');
7204		if (inst.append)
7205			inst.append.remove();
7206		if (appendText) {
7207			inst.append = $('<span class="' + this._appendClass + '">' + appendText + '</span>');
7208			input[isRTL ? 'before' : 'after'](inst.append);
7209		}
7210		input.unbind('focus', this._showDatepicker);
7211		if (inst.trigger)
7212			inst.trigger.remove();
7213		var showOn = this._get(inst, 'showOn');
7214		if (showOn == 'focus' || showOn == 'both') // pop-up date picker when in the marked field
7215			input.focus(this._showDatepicker);
7216		if (showOn == 'button' || showOn == 'both') { // pop-up date picker when button clicked
7217			var buttonText = this._get(inst, 'buttonText');
7218			var buttonImage = this._get(inst, 'buttonImage');
7219			inst.trigger = $(this._get(inst, 'buttonImageOnly') ?
7220				$('<img/>').addClass(this._triggerClass).
7221					attr({ src: buttonImage, alt: buttonText, title: buttonText }) :
7222				$('<button type="button"></button>').addClass(this._triggerClass).
7223					html(buttonImage == '' ? buttonText : $('<img/>').attr(
7224					{ src:buttonImage, alt:buttonText, title:buttonText })));
7225			input[isRTL ? 'before' : 'after'](inst.trigger);
7226			inst.trigger.click(function() {
7227				if ($.datepicker._datepickerShowing && $.datepicker._lastInput == input[0])
7228					$.datepicker._hideDatepicker();
7229				else if ($.datepicker._datepickerShowing && $.datepicker._lastInput != input[0]) {
7230					$.datepicker._hideDatepicker(); 
7231					$.datepicker._showDatepicker(input[0]);
7232				} else
7233					$.datepicker._showDatepicker(input[0]);
7234				return false;
7235			});
7236		}
7237	},
7238
7239	/* Apply the maximum length for the date format. */
7240	_autoSize: function(inst) {
7241		if (this._get(inst, 'autoSize') && !inst.inline) {
7242			var date = new Date(2009, 12 - 1, 20); // Ensure double digits
7243			var dateFormat = this._get(inst, 'dateFormat');
7244			if (dateFormat.match(/[DM]/)) {
7245				var findMax = function(names) {
7246					var max = 0;
7247					var maxI = 0;
7248					for (var i = 0; i < names.length; i++) {
7249						if (names[i].length > max) {
7250							max = names[i].length;
7251							maxI = i;
7252						}
7253					}
7254					return maxI;
7255				};
7256				date.setMonth(findMax(this._get(inst, (dateFormat.match(/MM/) ?
7257					'monthNames' : 'monthNamesShort'))));
7258				date.setDate(findMax(this._get(inst, (dateFormat.match(/DD/) ?
7259					'dayNames' : 'dayNamesShort'))) + 20 - date.getDay());
7260			}
7261			inst.input.attr('size', this._formatDate(inst, date).length);
7262		}
7263	},
7264
7265	/* Attach an inline date picker to a div. */
7266	_inlineDatepicker: function(target, inst) {
7267		var divSpan = $(target);
7268		if (divSpan.hasClass(this.markerClassName))
7269			return;
7270		divSpan.addClass(this.markerClassName).append(inst.dpDiv).
7271			bind("setData.datepicker", function(event, key, value){
7272				inst.settings[key] = value;
7273			}).bind("getData.datepicker", function(event, key){
7274				return this._get(inst, key);
7275			});
7276		$.data(target, PROP_NAME, inst);
7277		this._setDate(inst, this._getDefaultDate(inst), true);
7278		this._updateDatepicker(inst);
7279		this._updateAlternate(inst);
7280		//If disabled option is true, disable the datepicker before showing it (see ticket #5665)
7281		if( inst.settings.disabled ) {
7282			this._disableDatepicker( target );
7283		}
7284		// Set display:block in place of inst.dpDiv.show() which won't work on disconnected elements
7285		// http://bugs.jqueryui.com/ticket/7552 - A Datepicker created on a detached div has zero height
7286		inst.dpDiv.css( "display", "block" );
7287	},
7288
7289	/* Pop-up the date picker in a "dialog" box.
7290	   @param  input     element - ignored
7291	   @param  date      string or Date - the initial date to display
7292	   @param  onSelect  function - the function to call when a date is selected
7293	   @param  settings  object - update the dialog date picker instance's settings (anonymous object)
7294	   @param  pos       int[2] - coordinates for the dialog's position within the screen or
7295	                     event - with x/y coordinates or
7296	                     leave empty for default (screen centre)
7297	   @return the manager object */
7298	_dialogDatepicker: function(input, date, onSelect, settings, pos) {
7299		var inst = this._dialogInst; // internal instance
7300		if (!inst) {
7301			this.uuid += 1;
7302			var id = 'dp' + this.uuid;
7303			this._dialogInput = $('<input type="text" id="' + id +
7304				'" style="position: absolute; top: -100px; width: 0px; z-index: -10;"/>');
7305			this._dialogInput.keydown(this._doKeyDown);
7306			$('body').append(this._dialogInput);
7307			inst = this._dialogInst = this._newInst(this._dialogInput, false);
7308			inst.settings = {};
7309			$.data(this._dialogInput[0], PROP_NAME, inst);
7310		}
7311		extendRemove(inst.settings, settings || {});
7312		date = (date && date.constructor == Date ? this._formatDate(inst, date) : date);
7313		this._dialogInput.val(date);
7314
7315		this._pos = (pos ? (pos.length ? pos : [pos.pageX, pos.pageY]) : null);
7316		if (!this._pos) {
7317			var browserWidth = document.documentElement.clientWidth;
7318			var browserHeight = document.documentElement.clientHeight;
7319			var scrollX = document.documentElement.scrollLeft || document.body.scrollLeft;
7320			var scrollY = document.documentElement.scrollTop || document.body.scrollTop;
7321			this._pos = // should use actual width/height below
7322				[(browserWidth / 2) - 100 + scrollX, (browserHeight / 2) - 150 + scrollY];
7323		}
7324
7325		// move input on screen for focus, but hidden behind dialog
7326		this._dialogInput.css('left', (this._pos[0] + 20) + 'px').css('top', this._pos[1] + 'px');
7327		inst.settings.onSelect = onSelect;
7328		this._inDialog = true;
7329		this.dpDiv.addClass(this._dialogClass);
7330		this._showDatepicker(this._dialogInput[0]);
7331		if ($.blockUI)
7332			$.blockUI(this.dpDiv);
7333		$.data(this._dialogInput[0], PROP_NAME, inst);
7334		return this;
7335	},
7336
7337	/* Detach a datepicker from its control.
7338	   @param  target    element - the target input field or division or span */
7339	_destroyDatepicker: function(target) {
7340		var $target = $(target);
7341		var inst = $.data(target, PROP_NAME);
7342		if (!$target.hasClass(this.markerClassName)) {
7343			return;
7344		}
7345		var nodeName = target.nodeName.toLowerCase();
7346		$.removeData(target, PROP_NAME);
7347		if (nodeName == 'input') {
7348			inst.append.remove();
7349			inst.trigger.remove();
7350			$target.removeClass(this.markerClassName).
7351				unbind('focus', this._showDatepicker).
7352				unbind('keydown', this._doKeyDown).
7353				unbind('keypress', this._doKeyPress).
7354				unbind('keyup', this._doKeyUp);
7355		} else if (nodeName == 'div' || nodeName == 'span')
7356			$target.removeClass(this.markerClassName).empty();
7357	},
7358
7359	/* Enable the date picker to a jQuery selection.
7360	   @param  target    element - the target input field or division or span */
7361	_enableDatepicker: function(target) {
7362		var $target = $(target);
7363		var inst = $.data(target, PROP_NAME);
7364		if (!$target.hasClass(this.markerClassName)) {
7365			return;
7366		}
7367		var nodeName = target.nodeName.toLowerCase();
7368		if (nodeName == 'input') {
7369			target.disabled = false;
7370			inst.trigger.filter('button').
7371				each(function() { this.disabled = false; }).end().
7372				filter('img').css({opacity: '1.0', cursor: ''});
7373		}
7374		else if (nodeName == 'div' || nodeName == 'span') {
7375			var inline = $target.children('.' + this._inlineClass);
7376			inline.children().removeClass('ui-state-disabled');
7377			inline.find("select.ui-datepicker-month, select.ui-datepicker-year").
7378				removeAttr("disabled");
7379		}
7380		this._disabledInputs = $.map(this._disabledInputs,
7381			function(value) { return (value == target ? null : value); }); // delete entry
7382	},
7383
7384	/* Disable the date picker to a jQuery selection.
7385	   @param  target    element - the target input field or division or span */
7386	_disableDatepicker: function(target) {
7387		var $target = $(target);
7388		var inst = $.data(target, PROP_NAME);
7389		if (!$target.hasClass(this.markerClassName)) {
7390			return;
7391		}
7392		var nodeName = target.nodeName.toLowerCase();
7393		if (nodeName == 'input') {
7394			target.disabled = true;
7395			inst.trigger.filter('button').
7396				each(function() { this.disabled = true; }).end().
7397				filter('img').css({opacity: '0.5', cursor: 'default'});
7398		}
7399		else if (nodeName == 'div' || nodeName == 'span') {
7400			var inline = $target.children('.' + this._inlineClass);
7401			inline.children().addClass('ui-state-disabled');
7402			inline.find("select.ui-datepicker-month, select.ui-datepicker-year").
7403				attr("disabled", "disabled");
7404		}
7405		this._disabledInputs = $.map(this._disabledInputs,
7406			function(value) { return (value == target ? null : value); }); // delete entry
7407		this._disabledInputs[this._disabledInputs.length] = target;
7408	},
7409
7410	/* Is the first field in a jQuery collection disabled as a datepicker?
7411	   @param  target    element - the target input field or division or span
7412	   @return boolean - true if disabled, false if enabled */
7413	_isDisabledDatepicker: function(target) {
7414		if (!target) {
7415			return false;
7416		}
7417		for (var i = 0; i < this._disabledInputs.length; i++) {
7418			if (this._disabledInputs[i] == target)
7419				return true;
7420		}
7421		return false;
7422	},
7423
7424	/* Retrieve the instance data for the target control.
7425	   @param  target  element - the target input field or division or span
7426	   @return  object - the associated instance data
7427	   @throws  error if a jQuery problem getting data */
7428	_getInst: function(target) {
7429		try {
7430			return $.data(target, PROP_NAME);
7431		}
7432		catch (err) {
7433			throw 'Missing instance data for this datepicker';
7434		}
7435	},
7436
7437	/* Update or retrieve the settings for a date picker attached to an input field or division.
7438	   @param  target  element - the target input field or division or span
7439	   @param  name    object - the new settings to update or
7440	                   string - the name of the setting to change or retrieve,
7441	                   when retrieving also 'all' for all instance settings or
7442	                   'defaults' for all global defaults
7443	   @param  value   any - the new value for the setting
7444	                   (omit if above is an object or to retrieve a value) */
7445	_optionDatepicker: function(target, name, value) {
7446		var inst = this._getInst(target);
7447		if (arguments.length == 2 && typeof name == 'string') {
7448			return (name == 'defaults' ? $.extend({}, $.datepicker._defaults) :
7449				(inst ? (name == 'all' ? $.extend({}, inst.settings) :
7450				this._get(inst, name)) : null));
7451		}
7452		var settings = name || {};
7453		if (typeof name == 'string') {
7454			settings = {};
7455			settings[name] = value;
7456		}
7457		if (inst) {
7458			if (this._curInst == inst) {
7459				this._hideDatepicker();
7460			}
7461			var date = this._getDateDatepicker(target, true);
7462			var minDate = this._getMinMaxDate(inst, 'min');
7463			var maxDate = this._getMinMaxDate(inst, 'max');
7464			extendRemove(inst.settings, settings);
7465			// reformat the old minDate/maxDate values if dateFormat changes and a new minDate/maxDate isn't provided
7466			if (minDate !== null && settings['dateFormat'] !== undefined && settings['minDate'] === undefined)
7467				inst.settings.minDate = this._formatDate(inst, minDate);
7468			if (maxDate !== null && settings['dateFormat'] !== undefined && settings['maxDate'] === undefined)
7469				inst.settings.maxDate = this._formatDate(inst, maxDate);
7470			this._attachments($(target), inst);
7471			this._autoSize(inst);
7472			this._setDate(inst, date);
7473			this._updateAlternate(inst);
7474			this._updateDatepicker(inst);
7475		}
7476	},
7477
7478	// change method deprecated
7479	_changeDatepicker: function(target, name, value) {
7480		this._optionDatepicker(target, name, value);
7481	},
7482
7483	/* Redraw the date picker attached to an input field or division.
7484	   @param  target  element - the target input field or division or span */
7485	_refreshDatepicker: function(target) {
7486		var inst = this._getInst(target);
7487		if (inst) {
7488			this._updateDatepicker(inst);
7489		}
7490	},
7491
7492	/* Set the dates for a jQuery selection.
7493	   @param  target   element - the target input field or division or span
7494	   @param  date     Date - the new date */
7495	_setDateDatepicker: function(target, date) {
7496		var inst = this._getInst(target);
7497		if (inst) {
7498			this._setDate(inst, date);
7499			this._updateDatepicker(inst);
7500			this._updateAlternate(inst);
7501		}
7502	},
7503
7504	/* Get the date(s) for the first entry in a jQuery selection.
7505	   @param  target     element - the target input field or division or span
7506	   @param  noDefault  boolean - true if no default date is to be used
7507	   @return Date - the current date */
7508	_getDateDatepicker: function(target, noDefault) {
7509		var inst = this._getInst(target);
7510		if (inst && !inst.inline)
7511			this._setDateFromField(inst, noDefault);
7512		return (inst ? this._getDate(inst) : null);
7513	},
7514
7515	/* Handle keystrokes. */
7516	_doKeyDown: function(event) {
7517		var inst = $.datepicker._getInst(event.target);
7518		var handled = true;
7519		var isRTL = inst.dpDiv.is('.ui-datepicker-rtl');
7520		inst._keyEvent = true;
7521		if ($.datepicker._datepickerShowing)
7522			switch (event.keyCode) {
7523				case 9: $.datepicker._hideDatepicker();
7524						handled = false;
7525						break; // hide on tab out
7526				case 13: var sel = $('td.' + $.datepicker._dayOverClass + ':not(.' + 
7527									$.datepicker._currentClass + ')', inst.dpDiv);
7528						if (sel[0])
7529							$.datepicker._selectDay(event.target, inst.selectedMonth, inst.selectedYear, sel[0]);
7530							var onSelect = $.datepicker._get(inst, 'onSelect');
7531							if (onSelect) {
7532								var dateStr = $.datepicker._formatDate(inst);
7533
7534								// trigger custom callback
7535								onSelect.apply((inst.input ? inst.input[0] : null), [dateStr, inst]);
7536							}
7537						else
7538							$.datepicker._hideDatepicker();
7539						return false; // don't submit the form
7540						break; // select the value on enter
7541				case 27: $.datepicker._hideDatepicker();
7542						break; // hide on escape
7543				case 33: $.datepicker._adjustDate(event.target, (event.ctrlKey ?
7544							-$.datepicker._get(inst, 'stepBigMonths') :
7545							-$.datepicker._get(inst, 'stepMonths')), 'M');
7546						break; // previous month/year on page up/+ ctrl
7547				case 34: $.datepicker._adjustDate(event.target, (event.ctrlKey ?
7548							+$.datepicker._get(inst, 'stepBigMonths') :
7549							+$.datepicker._get(inst, 'stepMonths')), 'M');
7550						break; // next month/year on page down/+ ctrl
7551				case 35: if (event.ctrlKey || event.metaKey) $.datepicker._clearDate(event.target);
7552						handled = event.ctrlKey || event.metaKey;
7553						break; // clear on ctrl or command +end
7554				case 36: if (event.ctrlKey || event.metaKey) $.datepicker._gotoToday(event.target);
7555						handled = event.ctrlKey || event.metaKey;
7556						break; // current on ctrl or command +home
7557				case 37: if (event.ctrlKey || event.metaKey) $.datepicker._adjustDate(event.target, (isRTL ? +1 : -1), 'D');
7558						handled = event.ctrlKey || event.metaKey;
7559						// -1 day on ctrl or command +left
7560						if (event.originalEvent.altKey) $.datepicker._adjustDate(event.target, (event.ctrlKey ?
7561									-$.datepicker._get(inst, 'stepBigMonths') :
7562									-$.datepicker._get(inst, 'stepMonths')), 'M');
7563						// next month/year on alt +left on Mac
7564						break;
7565				case 38: if (event.ctrlKey || event.metaKey) $.datepicker._adjustDate(event.target, -7, 'D');
7566						handled = event.ctrlKey || event.metaKey;
7567						break; // -1 week on ctrl or command +up
7568				case 39: if (event.ctrlKey || event.metaKey) $.datepicker._adjustDate(event.target, (isRTL ? -1 : +1), 'D');
7569						handled = event.ctrlKey || event.metaKey;
7570						// +1 day on ctrl or command +right
7571						if (event.originalEvent.altKey) $.datepicker._adjustDate(event.target, (event.ctrlKey ?
7572									+$.datepicker._get(inst, 'stepBigMonths') :
7573									+$.datepicker._get(inst, 'stepMonths')), 'M');
7574						// next month/year on alt +right
7575						break;
7576				case 40: if (event.ctrlKey || event.metaKey) $.datepicker._adjustDate(event.target, +7, 'D');
7577						handled = event.ctrlKey || event.metaKey;
7578						break; // +1 week on ctrl or command +down
7579				default: handled = false;
7580			}
7581		else if (event.keyCode == 36 && event.ctrlKey) // display the date picker on ctrl+home
7582			$.datepicker._showDatepicker(this);
7583		else {
7584			handled = false;
7585		}
7586		if (handled) {
7587			event.preventDefault();
7588			event.stopPropagation();
7589		}
7590	},
7591
7592	/* Filter entered characters - based on date format. */
7593	_doKeyPress: function(event) {
7594		var inst = $.datepicker._getInst(event.target);
7595		if ($.datepicker._get(inst, 'constrainInput')) {
7596			var chars = $.datepicker._possibleChars($.datepicker._get(inst, 'dateFormat'));
7597			var chr = String.fromCharCode(event.charCode == undefined ? event.keyCode : event.charCode);
7598			return event.ctrlKey || event.metaKey || (chr < ' ' || !chars || chars.indexOf(chr) > -1);
7599		}
7600	},
7601
7602	/* Synchronise manual entry and field/alternate field. */
7603	_doKeyUp: function(event) {
7604		var inst = $.datepicker._getInst(event.target);
7605		if (inst.input.val() != inst.lastVal) {
7606			try {
7607				var date = $.datepicker.parseDate($.datepicker._get(inst, 'dateFormat'),
7608					(inst.input ? inst.input.val() : null),
7609					$.datepicker._getFormatConfig(inst));
7610				if (date) { // only if valid
7611					$.datepicker._setDateFromField(inst);
7612					$.datepicker._updateAlternate(inst);
7613					$.datepicker._updateDatepicker(inst);
7614				}
7615			}
7616			catch (err) {
7617				$.datepicker.log(err);
7618			}
7619		}
7620		return true;
7621	},
7622
7623	/* Pop-up the date picker for a given input field.
7624       If false returned from beforeShow event handler do not show. 
7625	   @param  input  element - the input field attached to the date picker or
7626	                  event - if triggered by focus */
7627	_showDatepicker: function(input) {
7628		input = input.target || input;
7629		if (input.nodeName.toLowerCase() != 'input') // find from button/image trigger
7630			input = $('input', input.parentNode)[0];
7631		if ($.datepicker._isDisabledDatepicker(input) || $.datepicker._lastInput == input) // already here
7632			return;
7633		var inst = $.datepicker._getInst(input);
7634		if ($.datepicker._curInst && $.datepicker._curInst != inst) {
7635			$.datepicker._curInst.dpDiv.stop(true, true);
7636			if ( inst && $.datepicker._datepickerShowing ) {
7637				$.datepicker._hideDatepicker( $.datepicker._curInst.input[0] );
7638			}
7639		}
7640		var beforeShow = $.datepicker._get(inst, 'beforeShow');
7641		var beforeShowSettings = beforeShow ? beforeShow.apply(input, [input, inst]) : {};
7642		if(beforeShowSettings === false){
7643            //false
7644			return;
7645		}
7646		extendRemove(inst.settings, beforeShowSettings);
7647		inst.lastVal = null;
7648		$.datepicker._lastInput = input;
7649		$.datepicker._setDateFromField(inst);
7650		if ($.datepicker._inDialog) // hide cursor
7651			input.value = '';
7652		if (!$.datepicker._pos) { // position below input
7653			$.datepicker._pos = $.datepicker._findPos(input);
7654			$.datepicker._pos[1] += input.offsetHeight; // add the height
7655		}
7656		var isFixed = false;
7657		$(input).parents().each(function() {
7658			isFixed |= $(this).css('position') == 'fixed';
7659			return !isFixed;
7660		});
7661		if (isFixed && $.browser.opera) { // correction for Opera when fixed and scrolled
7662			$.datepicker._pos[0] -= document.documentElement.scrollLeft;
7663			$.datepicker._pos[1] -= document.documentElement.scrollTop;
7664		}
7665		var offset = {left: $.datepicker._pos[0], top: $.datepicker._pos[1]};
7666		$.datepicker._pos = null;
7667		//to avoid flashes on Firefox
7668		inst.dpDiv.empty();
7669		// determine sizing offscreen
7670		inst.dpDiv.css({position: 'absolute', display: 'block', top: '-1000px'});
7671		$.datepicker._updateDatepicker(inst);
7672		// fix width for dynamic number of date pickers
7673		// and adjust position before showing
7674		offset = $.datepicker._checkOffset(inst, offset, isFixed);
7675		inst.dpDiv.css({position: ($.datepicker._inDialog && $.blockUI ?
7676			'static' : (isFixed ? 'fixed' : 'absolute')), display: 'none',
7677			left: offset.left + 'px', top: offset.top + 'px'});
7678		if (!inst.inline) {
7679			var showAnim = $.datepicker._get(inst, 'showAnim');
7680			var duration = $.datepicker._get(inst, 'duration');
7681			var postProcess = function() {
7682				var cover = inst.dpDiv.find('iframe.ui-datepicker-cover'); // IE6- only
7683				if( !! cover.length ){
7684					var borders = $.datepicker._getBorders(inst.dpDiv);
7685					cover.css({left: -borders[0], top: -borders[1],
7686						width: inst.dpDiv.outerWidth(), height: inst.dpDiv.outerHeight()});
7687				}
7688			};
7689			inst.dpDiv.css('zindex', $(input).css('zindex')+1);
7690			$.datepicker._datepickerShowing = true;
7691			if ($.effects && $.effects[showAnim])
7692				inst.dpDiv.show(showAnim, $.datepicker._get(inst, 'showOptions'), duration, postProcess);
7693			else
7694				inst.dpDiv[showAnim || 'show']((showAnim ? duration : null), postProcess);
7695			if (!showAnim || !duration)
7696				postProcess();
7697			if (inst.input.is(':visible') && !inst.input.is(':disabled'))
7698				inst.input.focus();
7699			$.datepicker._curInst = inst;
7700		}
7701	},
7702
7703	/* Generate the date picker content. */
7704	_updateDatepicker: function(inst) {
7705		var self = this;
7706		self.maxRows = 4; //Reset the max number of rows being displayed (see #7043)
7707		var borders = $.datepicker._getBorders(inst.dpDiv);
7708		instActive = inst; // for delegate hover events
7709		inst.dpDiv.empty().append(this._generateHTML(inst));
7710		var cover = inst.dpDiv.find('iframe.ui-datepicker-cover'); // IE6- only
7711		if( !!cover.length ){ //avoid call to outerXXXX() when not in IE6
7712			cover.css({left: -borders[0], top: -borders[1], width: inst.dpDiv.outerWidth(), height: inst.dpDiv.outerHeight()})
7713		}
7714		inst.dpDiv.find('.' + this._dayOverClass + ' a').mouseover();
7715		var numMonths = this._getNumberOfMonths(inst);
7716		var cols = numMonths[1];
7717		var width = 17;
7718		inst.dpDiv.removeClass('ui-datepicker-multi-2 ui-datepicker-multi-3 ui-datepicker-multi-4').width('');
7719		if (cols > 1)
7720			inst.dpDiv.addClass('ui-datepicker-multi-' + cols).css('width', (width * cols) + 'em');
7721		inst.dpDiv[(numMonths[0] != 1 || numMonths[1] != 1 ? 'add' : 'remove') +
7722			'Class']('ui-datepicker-multi');
7723		inst.dpDiv[(this._get(inst, 'isRTL') ? 'add' : 'remove') +
7724			'Class']('ui-datepicker-rtl');
7725		if (inst == $.datepicker._curInst && $.datepicker._datepickerShowing && inst.input &&
7726				// #6694 - don't focus the input if it's already focused
7727				// this breaks the change event in IE
7728				inst.input.is(':visible') && !inst.input.is(':disabled') && inst.input[0] != document.activeElement)
7729			inst.input.focus();
7730		// deffered render of the years select (to avoid flashes on Firefox) 
7731		if( inst.yearshtml ){
7732			var origyearshtml = inst.yearshtml;
7733			setTimeout(function(){
7734				//assure that inst.yearshtml didn't change.
7735				if( origyearshtml === inst.yearshtml && inst.yearshtml ){
7736					inst.dpDiv.find('select.ui-datepicker-year:first').replaceWith(inst.yearshtml);
7737				}
7738				origyearshtml = inst.yearshtml = null;
7739			}, 0);
7740		}
7741	},
7742
7743	/* Retrieve the size of left and top borders for an element.
7744	   @param  elem  (jQuery object) the element of interest
7745	   @return  (number[2]) the left and top borders */
7746	_getBorders: function(elem) {
7747		var convert = function(value) {
7748			return {thin: 1, medium: 2, thick: 3}[value] || value;
7749		};
7750		return [parseFloat(convert(elem.css('border-left-width'))),
7751			parseFloat(convert(elem.css('border-top-width')))];
7752	},
7753
7754	/* Check positioning to remain on screen. */
7755	_checkOffset: function(inst, offset, isFixed) {
7756		var dpWidth = inst.dpDiv.outerWidth();
7757		var dpHeight = inst.dpDiv.outerHeight();
7758		var inputWidth = inst.input ? inst.input.outerWidth() : 0;
7759		var inputHeight = inst.input ? inst.input.outerHeight() : 0;
7760		var viewWidth = document.documentElement.clientWidth + $(document).scrollLeft();
7761		var viewHeight = document.documentElement.clientHeight + $(document).scrollTop();
7762
7763		offset.left -= (this._get(inst, 'isRTL') ? (dpWidth - inputWidth) : 0);
7764		offset.left -= (isFixed && offset.left == inst.input.offset().left) ? $(document).scrollLeft() : 0;
7765		offset.top -= (isFixed && offset.top == (inst.input.offset().top + inputHeight)) ? $(document).scrollTop() : 0;
7766
7767		// now check if datepicker is showing outside window viewport - move to a better place if so.
7768		offset.left -= Math.min(offset.left, (offset.left + dpWidth > viewWidth && viewWidth > dpWidth) ?
7769			Math.abs(offset.left + dpWidth - viewWidth) : 0);
7770		offset.top -= Math.min(offset.top, (offset.top + dpHeight > viewHeight && viewHeight > dpHeight) ?
7771			Math.abs(dpHeight + inputHeight) : 0);
7772
7773		return offset;
7774	},
7775
7776	/* Find an object's position on the screen. */
7777	_findPos: function(obj) {
7778		var inst = this._getInst(obj);
7779		var isRTL = this._get(inst, 'isRTL');
7780        while (obj && (obj.type == 'hidden' || obj.nodeType != 1 || $.expr.filters.hidden(obj))) {
7781            obj = obj[isRTL ? 'previousSibling' : 'nextSibling'];
7782        }
7783        var position = $(obj).offset();
7784	    return [position.left, position.top];
7785	},
7786
7787	/* Hide the date picker from view.
7788	   @param  input  element - the input field attached to the date picker */
7789	_hideDatepicker: function(input) {
7790		var inst = this._curInst;
7791		if (!inst || (input && inst != $.data(input, PROP_NAME)))
7792			return;
7793		if (this._datepickerShowing) {
7794			var showAnim = this._get(inst, 'showAnim');
7795			var duration = this._get(inst, 'duration');
7796			var postProcess = function() {
7797				$.datepicker._tidyDialog(inst);
7798			};
7799			if ($.effects && $.effects[showAnim])
7800				inst.dpDiv.hide(showAnim, $.datepicker._get(inst, 'showOptions'), duration, postProcess);
7801			else
7802				inst.dpDiv[(showAnim == 'slideDown' ? 'slideUp' :
7803					(showAnim == 'fadeIn' ? 'fadeOut' : 'hide'))]((showAnim ? duration : null), postProcess);
7804			if (!showAnim)
7805				postProcess();
7806			this._datepickerShowing = false;
7807			var onClose = this._get(inst, 'onClose');
7808			if (onClose)
7809				onClose.apply((inst.input ? inst.input[0] : null),
7810					[(inst.input ? inst.input.val() : ''), inst]);
7811			this._lastInput = null;
7812			if (this._inDialog) {
7813				this._dialogInput.css({ position: 'absolute', left: '0', top: '-100px' });
7814				if ($.blockUI) {
7815					$.unblockUI();
7816					$('body').append(this.dpDiv);
7817				}
7818			}
7819			this._inDialog = false;
7820		}
7821	},
7822
7823	/* Tidy up after a dialog display. */
7824	_tidyDialog: function(inst) {
7825		inst.dpDiv.removeClass(this._dialogClass).unbind('.ui-datepicker-calendar');
7826	},
7827
7828	/* Close date picker if clicked elsewhere. */
7829	_checkExternalClick: function(event) {
7830		if (!$.datepicker._curInst)
7831			return;
7832
7833		var $target = $(event.target),
7834			inst = $.datepicker._getInst($target[0]);
7835
7836		if ( ( ( $target[0].id != $.datepicker._mainDivId &&
7837				$target.parents('#' + $.datepicker._mainDivId).length == 0 &&
7838				!$target.hasClass($.datepicker.markerClassName) &&
7839				!$target.closest("." + $.datepicker._triggerClass).length &&
7840				$.datepicker._datepickerShowing && !($.datepicker._inDialog && $.blockUI) ) ) ||
7841			( $target.hasClass($.datepicker.markerClassName) && $.datepicker._curInst != inst ) )
7842			$.datepicker._hideDatepicker();
7843	},
7844
7845	/* Adjust one of the date sub-fields. */
7846	_adjustDate: function(id, offset, period) {
7847		var target = $(id);
7848		var inst = this._getInst(target[0]);
7849		if (this._isDisabledDatepicker(target[0])) {
7850			return;
7851		}
7852		this._adjustInstDate(inst, offset +
7853			(period == 'M' ? this._get(inst, 'showCurrentAtPos') : 0), // undo positioning
7854			period);
7855		this._updateDatepicker(inst);
7856	},
7857
7858	/* Action for current link. */
7859	_gotoToday: function(id) {
7860		var target = $(id);
7861		var inst = this._getInst(target[0]);
7862		if (this._get(inst, 'gotoCurrent') && inst.currentDay) {
7863			inst.selectedDay = inst.currentDay;
7864			inst.drawMonth = inst.selectedMonth = inst.currentMonth;
7865			inst.drawYear = inst.selectedYear = inst.currentYear;
7866		}
7867		else {
7868			var date = new Date();
7869			inst.selectedDay = date.getDate();
7870			inst.drawMonth = inst.selectedMonth = date.getMonth();
7871			inst.drawYear = inst.selectedYear = date.getFullYear();
7872		}
7873		this._notifyChange(inst);
7874		this._adjustDate(target);
7875	},
7876
7877	/* Action for selecting a new month/year. */
7878	_selectMonthYear: function(id, select, period) {
7879		var target = $(id);
7880		var inst = this._getInst(target[0]);
7881		inst['selected' + (period == 'M' ? 'Month' : 'Year')] =
7882		inst['draw' + (period == 'M' ? 'Month' : 'Year')] =
7883			parseInt(select.options[select.selectedIndex].value,10);
7884		this._notifyChange(inst);
7885		this._adjustDate(target);
7886	},
7887
7888	/* Action for selecting a day. */
7889	_selectDay: function(id, month, year, td) {
7890		var target = $(id);
7891		if ($(td).hasClass(this._unselectableClass) || this._isDisabledDatepicker(target[0])) {
7892			return;
7893		}
7894		var inst = this._getInst(target[0]);
7895		inst.selectedDay = inst.currentDay = $('a', td).html();
7896		inst.selectedMonth = inst.currentMonth = month;
7897		inst.selectedYear = inst.currentYear = year;
7898		this._selectDate(id, this._formatDate(inst,
7899			inst.currentDay, inst.currentMonth, inst.currentYear));
7900	},
7901
7902	/* Erase the input field and hide the date picker. */
7903	_clearDate: function(id) {
7904		var target = $(id);
7905		var inst = this._getInst(target[0]);
7906		this._selectDate(target, '');
7907	},
7908
7909	/* Update the input field with the selected date. */
7910	_selectDate: function(id, dateStr) {
7911		var target = $(id);
7912		var inst = this._getInst(target[0]);
7913		dateStr = (dateStr != null ? dateStr : this._formatDate(inst));
7914		if (inst.input)
7915			inst.input.val(dateStr);
7916		this._updateAlternate(inst);
7917		var onSelect = this._get(inst, 'onSelect');
7918		if (onSelect)
7919			onSelect.apply((inst.input ? inst.input[0] : null), [dateStr, inst]);  // trigger custom callback
7920		else if (inst.input)
7921			inst.input.trigger('change'); // fire the change event
7922		if (inst.inline)
7923			this._updateDatepicker(inst);
7924		else {
7925			this._hideDatepicker();
7926			this._lastInput = inst.input[0];
7927			if (typeof(inst.input[0]) != 'object')
7928				inst.input.focus(); // restore focus
7929			this._lastInput = null;
7930		}
7931	},
7932
7933	/* Update any alternate field to synchronise with the main field. */
7934	_updateAlternate: function(inst) {
7935		var altField = this._get(inst, 'altField');
7936		if (altField) { // update alternate field too
7937			var altFormat = this._get(inst, 'altFormat') || this._get(inst, 'dateFormat');
7938			var date = this._getDate(inst);
7939			var dateStr = this.formatDate(altFormat, date, this._getFormatConfig(inst));
7940			$(altField).each(function() { $(this).val(dateStr); });
7941		}
7942	},
7943
7944	/* Set as beforeShowDay function to prevent selection of weekends.
7945	   @param  date  Date - the date to customise
7946	   @return [boolean, string] - is this date selectable?, what is its CSS class? */
7947	noWeekends: function(date) {
7948		var day = date.getDay();
7949		return [(day > 0 && day < 6), ''];
7950	},
7951
7952	/* Set as calculateWeek to determine the week of the year based on the ISO 8601 definition.
7953	   @param  date  Date - the date to get the week for
7954	   @return  number - the number of the week within the year that contains this date */
7955	iso8601Week: function(date) {
7956		var checkDate = new Date(date.getTime());
7957		// Find Thursday of this week starting on Monday
7958		checkDate.setDate(checkDate.getDate() + 4 - (checkDate.getDay() || 7));
7959		var time = checkDate.getTime();
7960		checkDate.setMonth(0); // Compare with Jan 1
7961		checkDate.setDate(1);
7962		return Math.floor(Math.round((time - checkDate) / 86400000) / 7) + 1;
7963	},
7964
7965	/* Parse a string value into a date object.
7966	   See formatDate below for the possible formats.
7967
7968	   @param  format    string - the expected format of the date
7969	   @param  value     string - the date in the above format
7970	   @param  settings  Object - attributes include:
7971	                     shortYearCutoff  number - the cutoff year for determining the century (optional)
7972	                     dayNamesShort    string[7] - abbreviated names of the days from Sunday (optional)
7973	                     dayNames         string[7] - names of the days from Sunday (optional)
7974	                     monthNamesShort  string[12] - abbreviated names of the months (optional)
7975	                     monthNames       string[12] - names of the months (optional)
7976	   @return  Date - the extracted date value or null if value is blank */
7977	parseDate: function (format, value, settings) {
7978		if (format == null || value == null)
7979			throw 'Invalid arguments';
7980		value = (typeof value == 'object' ? value.toString() : value + '');
7981		if (value == '')
7982			return null;
7983		var shortYearCutoff = (settings ? settings.shortYearCutoff : null) || this._defaults.shortYearCutoff;
7984		shortYearCutoff = (typeof shortYearCutoff != 'string' ? shortYearCutoff :
7985				new Date().getFullYear() % 100 + parseInt(shortYearCutoff, 10));
7986		var dayNamesShort = (settings ? settings.dayNamesShort : null) || this._defaults.dayNamesShort;
7987		var dayNames = (settings ? settings.dayNames : null) || this._defaults.dayNames;
7988		var monthNamesShort = (settings ? settings.monthNamesShort : null) || this._defaults.monthNamesShort;
7989		var monthNames = (settings ? settings.monthNames : null) || this._defaults.monthNames;
7990		var year = -1;
7991		var month = -1;
7992		var day = -1;
7993		var doy = -1;
7994		var literal = false;
7995		// Check whether a format character is doubled
7996		var lookAhead = function(match) {
7997			var matches = (iFormat + 1 < format.length && format.charAt(iFormat + 1) == match);
7998			if (matches)
7999				iFormat++;
8000			return matches;
8001		};
8002		// Extract a number from the string value
8003		var getNumber = function(match) {
8004			var isDoubled = lookAhead(match);
8005			var size = (match == '@' ? 14 : (match == '!' ? 20 :
8006				(match == 'y' && isDoubled ? 4 : (match == 'o' ? 3 : 2))));
8007			var digits = new RegExp('^\\d{1,' + size + '}');
8008			var num = value.substring(iValue).match(digits);
8009			if (!num)
8010				throw 'Missing number at position ' + iValue;
8011			iValue += num[0].length;
8012			return parseInt(num[0], 10);
8013		};
8014		// Extract a name from the string value and convert to an index
8015		var getName = function(match, shortNames, longNames) {
8016			var names = $.map(lookAhead(match) ? longNames : shortNames, function (v, k) {
8017				return [ [k, v] ];
8018			}).sort(function (a, b) {
8019				return -(a[1].length - b[1].length);
8020			});
8021			var index = -1;
8022			$.each(names, function (i, pair) {
8023				var name = pair[1];
8024				if (value.substr(iValue, name.length).toLowerCase() == name.toLowerCase()) {
8025					index = pair[0];
8026					iValue += name.length;
8027					return false;
8028				}
8029			});
8030			if (index != -1)
8031				return index + 1;
8032			else
8033				throw 'Unknown name at position ' + iValue;
8034		};
8035		// Confirm that a literal character matches the string value
8036		var checkLiteral = function() {
8037			if (value.charAt(iValue) != format.charAt(iFormat))
8038				throw 'Unexpected literal at position ' + iValue;
8039			iValue++;
8040		};
8041		var iValue = 0;
8042		for (var iFormat = 0; iFormat < format.length; iFormat++) {
8043			if (literal)
8044				if (format.charAt(iFormat) == "'" && !lookAhead("'"))
8045					literal = false;
8046				else
8047					checkLiteral();
8048			else
8049				switch (format.charAt(iFormat)) {
8050					case 'd':
8051						day = getNumber('d');
8052						break;
8053					case 'D':
8054						getName('D', dayNamesShort, dayNames);
8055						break;
8056					case 'o':
8057						doy = getNumber('o');
8058						break;
8059					case 'm':
8060						month = getNumber('m');
8061						break;
8062					case 'M':
8063						month = getName('M', monthNamesShort, monthNames);
8064						break;
8065					case 'y':
8066						year = getNumber('y');
8067						break;
8068					case '@':
8069						var date = new Date(getNumber('@'));
8070						year = date.getFullYear();
8071						month = date.getMonth() + 1;
8072						day = date.getDate();
8073						break;
8074					case '!':
8075						var date = new Date((getNumber('!') - this._ticksTo1970) / 10000);
8076						year = date.getFullYear();
8077						month = date.getMonth() + 1;
8078						day = date.getDate();
8079						break;
8080					case "'":
8081						if (lookAhead("'"))
8082							checkLiteral();
8083						else
8084							literal = true;
8085						break;
8086					default:
8087						checkLiteral();
8088				}
8089		}
8090		if (iValue < value.length){
8091			throw "Extra/unparsed characters found in date: " + value.substring(iValue);
8092		}
8093		if (year == -1)
8094			year = new Date().getFullYear();
8095		else if (year < 100)
8096			year += new Date().getFullYear() - new Date().getFullYear() % 100 +
8097				(year <= shortYearCutoff ? 0 : -100);
8098		if (doy > -1) {
8099			month = 1;
8100			day = doy;
8101			do {
8102				var dim = this._getDaysInMonth(year, month - 1);
8103				if (day <= dim)
8104					break;
8105				month++;
8106				day -= dim;
8107			} while (true);
8108		}
8109		var date = this._daylightSavingAdjust(new Date(year, month - 1, day));
8110		if (date.getFullYear() != year || date.getMonth() + 1 != month || date.getDate() != day)
8111			throw 'Invalid date'; // E.g. 31/02/00
8112		return date;
8113	},
8114
8115	/* Standard date formats. */
8116	ATOM: 'yy-mm-dd', // RFC 3339 (ISO 8601)
8117	COOKIE: 'D, dd M yy',
8118	ISO_8601: 'yy-mm-dd',
8119	RFC_822: 'D, d M y',
8120	RFC_850: 'DD, dd-M-y',
8121	RFC_1036: 'D, d M y',
8122	RFC_1123: 'D, d M yy',
8123	RFC_2822: 'D, d M yy',
8124	RSS: 'D, d M y', // RFC 822
8125	TICKS: '!',
8126	TIMESTAMP: '@',
8127	W3C: 'yy-mm-dd', // ISO 8601
8128
8129	_ticksTo1970: (((1970 - 1) * 365 + Math.floor(1970 / 4) - Math.floor(1970 / 100) +
8130		Math.floor(1970 / 400)) * 24 * 60 * 60 * 10000000),
8131
8132	/* Format a date object into a string value.
8133	   The format can be combinations of the following:
8134	   d  - day of month (no leading zero)
8135	   dd - day of month (two digit)
8136	   o  - day of year (no leading zeros)
8137	   oo - day of year (three digit)
8138	   D  - day name short
8139	   DD - day name long
8140	   m  - month of year (no leading zero)
8141	   mm - month of year (two digit)
8142	   M  - month name short
8143	   MM - month name long
8144	   y  - year (two digit)
8145	   yy - year (four digit)
8146	   @ - Unix timestamp (ms since 01/01/1970)
8147	   ! - Windows ticks (100ns since 01/01/0001)
8148	   '...' - literal text
8149	   '' - single quote
8150
8151	   @param  format    string - the desired format of the date
8152	   @param  date      Date - the date value to format
8153	   @param  settings  Object - attributes include:
8154	                     dayNamesShort    string[7] - abbreviated names of the days from Sunday (optional)
8155	                     dayNames         string[7] - names of the days from Sunday (optional)
8156	                     monthNamesShort  string[12] - abbreviated names of the months (optional)
8157	                     monthNames       string[12] - names of the months (optional)
8158	   @return  string - the date in the above format */
8159	formatDate: function (format, date, settings) {
8160		if (!date)
8161			return '';
8162		var dayNamesShort = (settings ? settings.dayNamesShort : null) || this._defaults.dayNamesShort;
8163		var dayNames = (settings ? settings.dayNames : null) || this._defaults.dayNames;
8164		var monthNamesShort = (settings ? settings.monthNamesShort : null) || this._defaults.monthNamesShort;
8165		var monthNames = (settings ? settings.monthNames : null) || this._defaults.monthNames;
8166		// Check whether a format character is doubled
8167		var lookAhead = function(match) {
8168			var matches = (iFormat + 1 < format.length && format.charAt(iFormat + 1) == match);
8169			if (matches)
8170				iFormat++;
8171			return matches;
8172		};
8173		// Format a number, with leading zero if necessary
8174		var formatNumber = function(match, value, len) {
8175			var num = '' + value;
8176			if (lookAhead(match))
8177				while (num.length < len)
8178					num = '0' + num;
8179			return num;
8180		};
8181		// Format a name, short or long as requested
8182		var formatName = function(match, value, shortNames, longNames) {
8183			return (lookAhead(match) ? longNames[value] : shortNames[value]);
8184		};
8185		var output = '';
8186		var literal = false;
8187		if (date)
8188			for (var iFormat = 0; iFormat < format.length; iFormat++) {
8189				if (literal)
8190					if (format.charAt(iFormat) == "'" && !lookAhead("'"))
8191						literal = false;
8192					else
8193						output += format.charAt(iFormat);
8194				else
8195					switch (format.charAt(iFormat)) {
8196						case 'd':
8197							output += formatNumber('d', date.getDate(), 2);
8198							break;
8199						case 'D':
8200							output += formatName('D', date.getDay(), dayNamesShort, dayNames);
8201							break;
8202						case 'o':
8203							output += formatNumber('o',
8204								Math.round((new Date(date.getFullYear(), date.getMonth(), date.getDate()).getTime() - new Date(date.getFullYear(), 0, 0).getTime()) / 86400000), 3);
8205							break;
8206						case 'm':
8207							output += formatNumber('m', date.getMonth() + 1, 2);
8208							break;
8209						case 'M':
8210							output += formatName('M', date.getMonth(), monthNamesShort, monthNames);
8211							break;
8212						case 'y':
8213							output += (lookAhead('y') ? date.getFullYear() :
8214								(date.getYear() % 100 < 10 ? '0' : '') + date.getYear() % 100);
8215							break;
8216						case '@':
8217							output += date.getTime();
8218							break;
8219						case '!':
8220							output += date.getTime() * 10000 + this._ticksTo1970;
8221							break;
8222						case "'":
8223							if (lookAhead("'"))
8224								output += "'";
8225							else
8226								literal = true;
8227							break;
8228						default:
8229							output += format.charAt(iFormat);
8230					}
8231			}
8232		return output;
8233	},
8234
8235	/* Extract all possible characters from the date format. */
8236	_possibleChars: function (format) {
8237		var chars = '';
8238		var literal = false;
8239		// Check whether a format character is doubled
8240		var lookAhead = function(match) {
8241			var matches = (iFormat + 1 < format.length && format.charAt(iFormat + 1) == match);
8242			if (matches)
8243				iFormat++;
8244			return matches;
8245		};
8246		for (var iFormat = 0; iFormat < format.length; iFormat++)
8247			if (literal)
8248				if (format.charAt(iFormat) == "'" && !lookAhead("'"))
8249					literal = false;
8250				else
8251					chars += format.charAt(iFormat);
8252			else
8253				switch (format.charAt(iFormat)) {
8254					case 'd': case 'm': case 'y': case '@':
8255						chars += '0123456789';
8256						break;
8257					case 'D': case 'M':
8258						return null; // Accept anything
8259					case "'":
8260						if (lookAhead("'"))
8261							chars += "'";
8262						else
8263							literal = true;
8264						break;
8265					default:
8266						chars += format.charAt(iFormat);
8267				}
8268		return chars;
8269	},
8270
8271	/* Get a setting value, defaulting if necessary. */
8272	_get: function(inst, name) {
8273		return inst.settings[name] !== undefined ?
8274			inst.settings[name] : this._defaults[name];
8275	},
8276
8277	/* Parse existing date and initialise date picker. */
8278	_setDateFromField: function(inst, noDefault) {
8279		if (inst.input.val() == inst.lastVal) {
8280			return;
8281		}
8282		var dateFormat = this._get(inst, 'dateFormat');
8283		var dates = inst.lastVal = inst.input ? inst.input.val() : null;
8284		var date, defaultDate;
8285		date = defaultDate = this._getDefaultDate(inst);
8286		var settings = this._getFormatConfig(inst);
8287		try {
8288			date = this.parseDate(dateFormat, dates, settings) || defaultDate;
8289		} catch (event) {
8290			this.log(event);
8291			dates = (noDefault ? '' : dates);
8292		}
8293		inst.selectedDay = date.getDate();
8294		inst.drawMonth = inst.selectedMonth = date.getMonth();
8295		inst.drawYear = inst.selectedYear = date.getFullYear();
8296		inst.currentDay = (dates ? date.getDate() : 0);
8297		inst.currentMonth = (dates ? date.getMonth() : 0);
8298		inst.currentYear = (dates ? date.getFullYear() : 0);
8299		this._adjustInstDate(inst);
8300	},
8301
8302	/* Retrieve the default date shown on opening. */
8303	_getDefaultDate: function(inst) {
8304		return this._restrictMinMax(inst,
8305			this._determineDate(inst, this._get(inst, 'defaultDate'), new Date()));
8306	},
8307
8308	/* A date may be specified as an exact value or a relative one. */
8309	_determineDate: function(inst, date, defaultDate) {
8310		var offsetNumeric = function(offset) {
8311			var date = new Date();
8312			date.setDate(date.getDate() + offset);
8313			return date;
8314		};
8315		var offsetString = function(offset) {
8316			try {
8317				return $.datepicker.parseDate($.datepicker._get(inst, 'dateFormat'),
8318					offset, $.datepicker._getFormatConfig(inst));
8319			}
8320			catch (e) {
8321				// Ignore
8322			}
8323			var date = (offset.toLowerCase().match(/^c/) ?
8324				$.datepicker._getDate(inst) : null) || new Date();
8325			var year = date.getFullYear();
8326			var month = date.getMonth();
8327			var day = date.getDate();
8328			var pattern = /([+-]?[0-9]+)\s*(d|D|w|W|m|M|y|Y)?/g;
8329			var matches = pattern.exec(offset);
8330			while (matches) {
8331				switch (matches[2] || 'd') {
8332					case 'd' : case 'D' :
8333						day += parseInt(matches[1],10); break;
8334					case 'w' : case 'W' :
8335						day += parseInt(matches[1],10) * 7; break;
8336					case 'm' : case 'M' :
8337						month += parseInt(matches[1],10);
8338						day = Math.min(day, $.datepicker._getDaysInMonth(year, month));
8339						break;
8340					case 'y': case 'Y' :
8341						year += parseInt(matches[1],10);
8342						day = Math.min(day, $.datepicker._getDaysInMonth(year, month));
8343						break;
8344				}
8345				matches = pattern.exec(offset);
8346			}
8347			return new Date(year, month, day);
8348		};
8349		var newDate = (date == null || date === '' ? defaultDate : (typeof date == 'string' ? offsetString(date) :
8350			(typeof date == 'number' ? (isNaN(date) ? defaultDate : offsetNumeric(date)) : new Date(date.getTime()))));
8351		newDate = (newDate && newDate.toString() == 'Invalid Date' ? defaultDate : newDate);
8352		if (newDate) {
8353			newDate.setHours(0);
8354			newDate.setMinutes(0);
8355			newDate.setSeconds(0);
8356			newDate.setMilliseconds(0);
8357		}
8358		return this._daylightSavingAdjust(newDate);
8359	},
8360
8361	/* Handle switch to/from daylight saving.
8362	   Hours may be non-zero on daylight saving cut-over:
8363	   > 12 when midnight changeover, but then cannot generate
8364	   midnight datetime, so jump to 1AM, otherwise reset.
8365	   @param  date  (Date) the date to check
8366	   @return  (Date) the corrected date */
8367	_daylightSavingAdjust: function(date) {
8368		if (!date) return null;
8369		date.setHours(date.getHours() > 12 ? date.getHours() + 2 : 0);
8370		return date;
8371	},
8372
8373	/* Set the date(s) directly. */
8374	_setDate: function(inst, date, noChange) {
8375		var clear = !date;
8376		var origMonth = inst.selectedMonth;
8377		var origYear = inst.selectedYear;
8378		var newDate = this._restrictMinMax(inst, this._determineDate(inst, date, new Date()));
8379		inst.selectedDay = inst.currentDay = newDate.getDate();
8380		inst.drawMonth = inst.selectedMonth = inst.currentMonth = newDate.getMonth();
8381		inst.drawYear = inst.selectedYear = inst.currentYear = newDate.getFullYear();
8382		if ((origMonth != inst.selectedMonth || origYear != inst.selectedYear) && !noChange)
8383			this._notifyChange(inst);
8384		this._adjustInstDate(inst);
8385		if (inst.input) {
8386			inst.input.val(clear ? '' : this._formatDate(inst));
8387		}
8388	},
8389
8390	/* Retrieve the date(s) directly. */
8391	_getDate: function(inst) {
8392		var startDate = (!inst.currentYear || (inst.input && inst.input.val() == '') ? null :
8393			this._daylightSavingAdjust(new Date(
8394			inst.currentYear, inst.currentMonth, inst.currentDay)));
8395			return startDate;
8396	},
8397
8398	/* Generate the HTML for the current state of the date picker. */
8399	_generateHTML: function(inst) {
8400		var today = new Date();
8401		today = this._daylightSavingAdjust(
8402			new Date(today.getFullYear(), today.getMonth(), today.getDate())); // clear time
8403		var isRTL = this._get(inst, 'isRTL');
8404		var showButtonPanel = this._get(inst, 'showButtonPanel');
8405		var hideIfNoPrevNext = this._get(inst, 'hideIfNoPrevNext');
8406		var navigationAsDateFormat = this._get(inst, 'navigationAsDateFormat');
8407		var numMonths = this._getNumberOfMonths(inst);
8408		var showCurrentAtPos = this._get(inst, 'showCurrentAtPos');
8409		var stepMonths = this._get(inst, 'stepMonths');
8410		var isMultiMonth = (numMonths[0] != 1 || numMonths[1] != 1);
8411		var currentDate = this._daylightSavingAdjust((!inst.currentDay ? new Date(9999, 9, 9) :
8412			new Date(inst.currentYear, inst.currentMonth, inst.currentDay)));
8413		var minDate = this._getMinMaxDate(inst, 'min');
8414		var maxDate = this._getMinMaxDate(inst, 'max');
8415		var drawMonth = inst.drawMonth - showCurrentAtPos;
8416		var drawYear = inst.drawYear;
8417		if (drawMonth < 0) {
8418			drawMonth += 12;
8419			drawYear--;
8420		}
8421		if (maxDate) {
8422			var maxDraw = this._daylightSavingAdjust(new Date(maxDate.getFullYear(),
8423				maxDate.getMonth() - (numMonths[0] * numMonths[1]) + 1, maxDate.getDate()));
8424			maxDraw = (minDate && maxDraw < minDate ? minDate : maxDraw);
8425			while (this._daylightSavingAdjust(new Date(drawYear, drawMonth, 1)) > maxDraw) {
8426				drawMonth--;
8427				if (drawMonth < 0) {
8428					drawMonth = 11;
8429					drawYear--;
8430				}
8431			}
8432		}
8433		inst.drawMonth = drawMonth;
8434		inst.drawYear = drawYear;
8435		var prevText = this._get(inst, 'prevText');
8436		prevText = (!navigationAsDateFormat ? prevText : this.formatDate(prevText,
8437			this._daylightSavingAdjust(new Date(drawYear, drawMonth - stepMonths, 1)),
8438			this._getFormatConfig(inst)));
8439		var prev = (this._canAdjustMonth(inst, -1, drawYear, drawMonth) ?
8440			'<a class="ui-datepicker-prev ui-corner-all" onclick="DP_jQuery_' + dpuuid +
8441			'.datepicker._adjustDate(\'#' + inst.id + '\', -' + stepMonths + ', \'M\');"' +
8442			' title="' + prevText + '"><span class="ui-icon ui-icon-circle-triangle-' + ( isRTL ? 'e' : 'w') + '">' + prevText + '</span></a>' :
8443			(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>'));
8444		var nextText = this._get(inst, 'nextText');
8445		nextText = (!navigationAsDateFormat ? nextText : this.formatDate(nextText,
8446			this._daylightSavingAdjust(new Date(drawYear, drawMonth + stepMonths, 1)),
8447			this._getFormatConfig(inst)));
8448		var next = (this._canAdjustMonth(inst, +1, drawYear, drawMonth) ?
8449			'<a class="ui-datepicker-next ui-corner-all" onclick="DP_jQuery_' + dpuuid +
8450			'.datepicker._adjustDate(\'#' + inst.id + '\', +' + stepMonths + ', \'M\');"' +
8451			' title="' + nextText + '"><span class="ui-icon ui-icon-circle-triangle-' + ( isRTL ? 'w' : 'e') + '">' + nextText + '</span></a>' :
8452			(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>'));
8453		var currentText = this._get(inst, 'currentText');
8454		var gotoDate = (this._get(inst, 'gotoCurrent') && inst.currentDay ? currentDate : today);
8455		currentText = (!navigationAsDateFormat ? currentText :
8456			this.formatDate(currentText, gotoDate, this._getFormatConfig(inst)));
8457		var controls = (!inst.inline ? '<button type="button" class="ui-datepicker-close ui-state-default ui-priority-primary ui-corner-all" onclick="DP_jQuery_' + dpuuid +
8458			'.datepicker._hideDatepicker();">' + this._get(inst, 'closeText') + '</button>' : '');
8459		var buttonPanel = (showButtonPanel) ? '<div class="ui-datepicker-buttonpane ui-widget-content">' + (isRTL ? controls : '') +
8460			(this._isInRange(inst, gotoDate) ? '<button type="button" class="ui-datepicker-current ui-state-default ui-priority-secondary ui-corner-all" onclick="DP_jQuery_' + dpuuid +
8461			'.datepicker._gotoToday(\'#' + inst.id + '\');"' +
8462			'>' + currentText + '</button>' : '') + (isRTL ? '' : controls) + '</div>' : '';
8463		var firstDay = parseInt(this._get(inst, 'firstDay'),10);
8464		firstDay = (isNaN(firstDay) ? 0 : firstDay);
8465		var showWeek = this._get(inst, 'showWeek');
8466		var dayNames = this._get(inst, 'dayNames');
8467		var dayNamesShort = this._get(inst, 'dayNamesShort');
8468		var dayNamesMin = this._get(inst, 'dayNamesMin');
8469		var monthNames = this._get(inst, 'monthNames');
8470		var monthNamesShort = this._get(inst, 'monthNamesShort');
8471		var beforeShowDay = this._get(inst, 'beforeShowDay');
8472		var showOtherMonths = this._get(inst, 'showOtherMonths');
8473		var selectOtherMonths = this._get(inst, 'selectOtherMonths');
8474		var calculateWeek = this._get(inst, 'calculateWeek') || this.iso8601Week;
8475		var defaultDate = this._getDefaultDate(inst);
8476		var html = '';
8477		for (var row = 0; row < numMonths[0]; row++) {
8478			var group = '';
8479			this.maxRows = 4;
8480			for (var col = 0; col < numMonths[1]; col++) {
8481				var selectedDate = this._daylightSavingAdjust(new Date(drawYear, drawMonth, inst.selectedDay));
8482				var cornerClass = ' ui-corner-all';
8483				var calender = '';
8484				if (isMultiMonth) {
8485					calender += '<div class="ui-datepicker-group';
8486					if (numMonths[1] > 1)
8487						switch (col) {
8488							case 0: calender += ' ui-datepicker-group-first';
8489								cornerClass = ' ui-corner-' + (isRTL ? 'right' : 'left'); break;
8490							case numMonths[1]-1: calender += ' ui-datepicker-group-last';
8491								cornerClass = ' ui-corner-' + (isRTL ? 'left' : 'right'); break;
8492							default: calender += ' ui-datepicker-group-middle'; cornerClass = ''; break;
8493						}
8494					calender += '">';
8495				}
8496				calender += '<div class="ui-datepicker-header ui-widget-header ui-helper-clearfix' + cornerClass + '">' +
8497					(/all|left/.test(cornerClass) && row == 0 ? (isRTL ? next : prev) : '') +
8498					(/all|right/.test(cornerClass) && row == 0 ? (isRTL ? prev : next) : '') +
8499					this._generateMonthYearHeader(inst, drawMonth, drawYear, minDate, maxDate,
8500					row > 0 || col > 0, monthNames, monthNamesShort) + // draw month headers
8501					'</div><table class="ui-datepicker-calendar"><thead>' +
8502					'<tr>';
8503				var thead = (showWeek ? '<th class="ui-datepicker-week-col">' + this._get(inst, 'weekHeader') + '</th>' : '');
8504				for (var dow = 0; dow < 7; dow++) { // days of the week
8505					var day = (dow + firstDay) % 7;
8506					thead += '<th' + ((dow + firstDay + 6) % 7 >= 5 ? ' class="ui-datepicker-week-end"' : '') + '>
8506' +
8507						'<span title="' + dayNames[day] + '">' + dayNamesMin[day] + '</span></th>';
8508				}
8509				calender += thead + '</tr></thead><tbody>';
8510				var daysInMonth = this._getDaysInMonth(drawYear, drawMonth);
8511				if (drawYear == inst.selectedYear && drawMonth == inst.selectedMonth)
8512					inst.selectedDay = Math.min(inst.selectedDay, daysInMonth);
8513				var leadDays = (this._getFirstDayOfMonth(drawYear, drawMonth) - firstDay + 7) % 7;
8514				var curRows = Math.ceil((leadDays + daysInMonth) / 7); // calculate the number of rows to generate
8515				var numRows = (isMultiMonth ? this.maxRows > curRows ? this.maxRows : curRows : curRows); //If multiple months, use the higher number of rows (see #7043)
8516				this.maxRows = numRows;
8517				var printDate = this._daylightSavingAdjust(new Date(drawYear, drawMonth, 1 - leadDays));
8518				for (var dRow = 0; dRow < numRows; dRow++) { // create date picker rows
8519					calender += '<tr>';
8520					var tbody = (!showWeek ? '' : '<td class="ui-datepicker-week-col">' +
8521						this._get(inst, 'calculateWeek')(printDate) + '</td>');
8522					for (var dow = 0; dow < 7; dow++) { // create date picker days
8523						var daySettings = (beforeShowDay ?
8524							beforeShowDay.apply((inst.input ? inst.input[0] : null), [printDate]) : [true, '']);
8525						var otherMonth = (printDate.getMonth() != drawMonth);
8526						var unselectable = (otherMonth && !selectOtherMonths) || !daySettings[0] ||
8527							(minDate && printDate < minDate) || (maxDate && printDate > maxDate);
8528						tbody += '<td class="' +
8529							((dow + firstDay + 6) % 7 >= 5 ? ' ui-datepicker-week-end' : '') + // highlight weekends
8530							(otherMonth ? ' ui-datepicker-other-month' : '') + // highlight days from other months
8531							((printDate.getTime() == selectedDate.getTime() && drawMonth == inst.selectedMonth && inst._keyEvent) || // user pressed key
8532							(defaultDate.getTime() == printDate.getTime() && defaultDate.getTime() == selectedDate.getTime()) ?
8533							// or defaultDate is current printedDate and defaultDate is selectedDate
8534							' ' + this._dayOverClass : '') + // highlight selected day
8535							(unselectable ? ' ' + this._unselectableClass + ' ui-state-disabled': '') +  // highlight unselectable days
8536							(otherMonth && !showOtherMonths ? '' : ' ' + daySettings[1] + // highlight custom dates
8537							(printDate.getTime() == currentDate.getTime() ? ' ' + this._currentClass : '') + // highlight selected day
8538							(printDate.getTime() == today.getTime() ? ' ui-datepicker-today' : '')) + '"' + // highlight today (if different)
8539							((!otherMonth || showOtherMonths) && daySettings[2] ? ' title="' + daySettings[2] + '"' : '') + // cell title
8540							(unselectable ? '' : ' onclick="DP_jQuery_' + dpuuid + '.datepicker._selectDay(\'#' +
8541							inst.id + '\',' + printDate.getMonth() + ',' + printDate.getFullYear() + ', this);return false;"') + '>' + // actions
8542							(otherMonth && !showOtherMonths ? '&#xa0;' : // display for other months
8543							(unselectable ? '<span class="ui-state-default">' + printDate.getDate() + '</span>' : '<a class="ui-state-default' +
8544							(printDate.getTime() == today.getTime() ? ' ui-state-highlight' : '') +
8545							(printDate.getTime() == currentDate.getTime() ? ' ui-state-active' : '') + // highlight selected day
8546							(otherMonth ? ' ui-priority-secondary' : '') + // distinguish dates from other months
8547							'" href="#">' + printDate.getDate() + '</a>')) + '</td>'; // display selectable date
8548						printDate.setDate(printDate.getDate() + 1);
8549						printDate = this._daylightSavingAdjust(printDate);
8550					}
8551					calender += tbody + '</tr>';
8552				}
8553				drawMonth++;
8554				if (drawMonth > 11) {
8555					drawMonth = 0;
8556					drawYear++;
8557				}
8558				calender += '</tbody></table>' + (isMultiMonth ? '</div>' + 
8559							((numMonths[0] > 0 && col == numMonths[1]-1) ? '<div class="ui-datepicker-row-break"></div>' : '') : '');
8560				group += calender;
8561			}
8562			html += group;
8563		}
8564		html += buttonPanel + ($.browser.msie && parseInt($.browser.version,10) < 7 && !inst.inline ?
8565			'<iframe src="javascript:false;" class="ui-datepicker-cover" frameborder="0"></iframe>' : '');
8566		inst._keyEvent = false;
8567		return html;
8568	},
8569
8570	/* Generate the month and year header. */
8571	_generateMonthYearHeader: function(inst, drawMonth, drawYear, minDate, maxDate,
8572			secondary, monthNames, monthNamesShort) {
8573		var changeMonth = this._get(inst, 'changeMonth');
8574		var changeYear = this._get(inst, 'changeYear');
8575		var showMonthAfterYear = this._get(inst, 'showMonthAfterYear');
8576		var html = '<div class="ui-datepicker-title">';
8577		var monthHtml = '';
8578		// month selection
8579		if (secondary || !changeMonth)
8580			monthHtml += '<span class="ui-datepicker-month">' + monthNames[drawMonth] + '</span>';
8581		else {
8582			var inMinYear = (minDate && minDate.getFullYear() == drawYear);
8583			var inMaxYear = (maxDate && maxDate.getFullYear() == drawYear);
8584			monthHtml += '<select class="ui-datepicker-month" ' +
8585				'onchange="DP_jQuery_' + dpuuid + '.datepicker._selectMonthYear(\'#' + inst.id + '\', this, \'M\');" ' +
8586			 	'>';
8587			for (var month = 0; month < 12; month++) {
8588				if ((!inMinYear || month >= minDate.getMonth()) &&
8589						(!inMaxYear || month <= maxDate.getMonth()))
8590					monthHtml += '<option value="' + month + '"' +
8591						(month == drawMonth ? ' selected="selected"' : '') +
8592						'>' + monthNamesShort[month] + '</option>';
8593			}
8594			monthHtml += '</select>';
8595		}
8596		if (!showMonthAfterYear)
8597			html += monthHtml + (secondary || !(changeMonth && changeYear) ? '&#xa0;' : '');
8598		// year selection
8599		if ( !inst.yearshtml ) {
8600			inst.yearshtml = '';
8601			if (secondary || !changeYear)
8602				html += '<span class="ui-datepicker-year">' + drawYear + '</span>';
8603			else {
8604				// determine range of years to display
8605				var years = this._get(inst, 'yearRange').split(':');
8606				var thisYear = new Date().getFullYear();
8607				var determineYear = function(value) {
8608					var year = (value.match(/c[+-].*/) ? drawYear + parseInt(value.substring(1), 10) :
8609						(value.match(/[+-].*/) ? thisYear + parseInt(value, 10) :
8610						parseInt(value, 10)));
8611					return (isNaN(year) ? thisYear : year);
8612				};
8613				var year = determineYear(years[0]);
8614				var endYear = Math.max(year, determineYear(years[1] || ''));
8615				year = (minDate ? Math.max(year, minDate.getFullYear()) : year);
8616				endYear = (maxDate ? Math.min(endYear, maxDate.getFullYear()) : endYear);
8617				inst.yearshtml += '<select class="ui-datepicker-year" ' +
8618					'onchange="DP_jQuery_' + dpuuid + '.datepicker._selectMonthYear(\'#' + inst.id + '\', this, \'Y\');" ' +
8619					'>';
8620				for (; year <= endYear; year++) {
8621					inst.yearshtml += '<option value="' + year + '"' +
8622						(year == drawYear ? ' selected="selected"' : '') +
8623						'>' + year + '</option>';
8624				}
8625				inst.yearshtml += '</select>';
8626				
8627				html += inst.yearshtml;
8628				inst.yearshtml = null;
8629			}
8630		}
8631		html += this._get(inst, 'yearSuffix');
8632		if (showMonthAfterYear)
8633			html += (secondary || !(changeMonth && changeYear) ? '&#xa0;' : '') + monthHtml;
8634		html += '</div>'; // Close datepicker_header
8635		return html;
8636	},
8637
8638	/* Adjust one of the date sub-fields. */
8639	_adjustInstDate: function(inst, offset, period) {
8640		var year = inst.drawYear + (period == 'Y' ? offset : 0);
8641		var month = inst.drawMonth + (period == 'M' ? offset : 0);
8642		var day = Math.min(inst.selectedDay, this._getDaysInMonth(year, month)) +
8643			(period == 'D' ? offset : 0);
8644		var date = this._restrictMinMax(inst,
8645			this._daylightSavingAdjust(new Date(year, month, day)));
8646		inst.selectedDay = date.getDate();
8647		inst.drawMonth = inst.selectedMonth = date.getMonth();
8648		inst.drawYear = inst.selectedYear = date.getFullYear();
8649		if (period == 'M' || period == 'Y')
8650			this._notifyChange(inst);
8651	},
8652
8653	/* Ensure a date is within any min/max bounds. */
8654	_restrictMinMax: function(inst, date) {
8655		var minDate = this._getMinMaxDate(inst, 'min');
8656		var maxDate = this._getMinMaxDate(inst, 'max');
8657		var newDate = (minDate && date < minDate ? minDate : date);
8658		newDate = (maxDate && newDate > maxDate ? maxDate : newDate);
8659		return newDate;
8660	},
8661
8662	/* Notify change of month/year. */
8663	_notifyChange: function(inst) {
8664		var onChange = this._get(inst, 'onChangeMonthYear');
8665		if (onChange)
8666			onChange.apply((inst.input ? inst.input[0] : null),
8667				[inst.selectedYear, inst.selectedMonth + 1, inst]);
8668	},
8669
8670	/* Determine the number of months to show. */
8671	_getNumberOfMonths: function(inst) {
8672		var numMonths = this._get(inst, 'numberOfMonths');
8673		return (numMonths == null ? [1, 1] : (typeof numMonths == 'number' ? [1, numMonths] : numMonths));
8674	},
8675
8676	/* Determine the current maximum date - ensure no time components are set. */
8677	_getMinMaxDate: function(inst, minMax) {
8678		return this._determineDate(inst, this._get(inst, minMax + 'Date'), null);
8679	},
8680
8681	/* Find the number of days in a given month. */
8682	_getDaysInMonth: function(year, month) {
8683		return 32 - this._daylightSavingAdjust(new Date(year, month, 32)).getDate();
8684	},
8685
8686	/* Find the day of the week of the first of a month. */
8687	_getFirstDayOfMonth: function(year, month) {
8688		return new Date(year, month, 1).getDay();
8689	},
8690
8691	/* Determines if we should allow a "next/prev" month display change. */
8692	_canAdjustMonth: function(inst, offset, curYear, curMonth) {
8693		var numMonths = this._getNumberOfMonths(inst);
8694		var date = this._daylightSavingAdjust(new Date(curYear,
8695			curMonth + (offset < 0 ? offset : numMonths[0] * numMonths[1]), 1));
8696		if (offset < 0)
8697			date.setDate(this._getDaysInMonth(date.getFullYear(), date.getMonth()));
8698		return this._isInRange(inst, date);
8699	},
8700
8701	/* Is the given date in the accepted range? */
8702	_isInRange: function(inst, date) {
8703		var minDate = this._getMinMaxDate(inst, 'min');
8704		var maxDate = this._getMinMaxDate(inst, 'max');
8705		return ((!minDate || date.getTime() >= minDate.getTime()) &&
8706			(!maxDate || date.getTime() <= maxDate.getTime()));
8707	},
8708
8709	/* Provide the configuration settings for formatting/parsing. */
8710	_getFormatConfig: function(inst) {
8711		var shortYearCutoff = this._get(inst, 'shortYearCutoff');
8712		shortYearCutoff = (typeof shortYearCutoff != 'string' ? shortYearCutoff :
8713			new Date().getFullYear() % 100 + parseInt(shortYearCutoff, 10));
8714		return {shortYearCutoff: shortYearCutoff,
8715			dayNamesShort: this._get(inst, 'dayNamesShort'), dayNames: this._get(inst, 'dayNames'),
8716			monthNamesShort: this._get(inst, 'monthNamesShort'), monthNames: this._get(inst, 'monthNames')};
8717	},
8718
8719	/* Format the given date for display. */
8720	_formatDate: function(inst, day, month, year) {
8721		if (!day) {
8722			inst.currentDay = inst.selectedDay;
8723			inst.currentMonth = inst.selectedMonth;
8724			inst.currentYear = inst.selectedYear;
8725		}
8726		var date = (day ? (typeof day == 'object' ? day :
8727			this._daylightSavingAdjust(new Date(year, month, day))) :
8728			this._daylightSavingAdjust(new Date(inst.currentYear, inst.currentMonth, inst.currentDay)));
8729		return this.formatDate(this._get(inst, 'dateFormat'), date, this._getFormatConfig(inst));
8730	}
8731});
8732
8733/*
8734 * Bind hover events for datepicker elements.
8735 * Done via delegate so the binding only occurs once in the lifetime of the parent div.
8736 * Global instActive, set by _updateDatepicker allows the handlers to find their way back to the active picker.
8737 */ 
8738function bindHover(dpDiv) {
8739	var selector = 'button, .ui-datepicker-prev, .ui-datepicker-next, .ui-datepicker-calendar td a';
8740	return dpDiv.bind('mouseout', function(event) {
8741			var elem = $( event.target ).closest( selector );
8742			if ( !elem.length ) {
8743				return;
8744			}
8745			elem.removeClass( "ui-state-hover ui-datepicker-prev-hover ui-datepicker-next-hover" );
8746		})
8747		.bind('mouseover', function(event) {
8748			var elem = $( event.target ).closest( selector );
8749			if ($.datepicker._isDisabledDatepicker( instActive.inline ? dpDiv.parent()[0] : instActive.input[0]) ||
8750					!elem.length ) {
8751				return;
8752			}
8753			elem.parents('.ui-datepicker-calendar').find('a').removeClass('ui-state-hover');
8754			elem.addClass('ui-state-hover');
8755			if (elem.hasClass('ui-datepicker-prev')) elem.addClass('ui-datepicker-prev-hover');
8756			if (elem.hasClass('ui-datepicker-next')) elem.addClass('ui-datepicker-next-hover');
8757		});
8758}
8759
8760/* jQuery extend now ignores nulls! */
8761function extendRemove(target, props) {
8762	$.extend(target, props);
8763	for (var name in props)
8764		if (props[name] == null || props[name] == undefined)
8765			target[name] = props[name];
8766	return target;
8767};
8768
8769/* Determine whether an object is an array. */
8770function isArray(a) {
8771	return (a && (($.browser.safari && typeof a == 'object' && a.length) ||
8772		(a.constructor && a.constructor.toString().match(/\Array\(\)/))));
8773};
8774
8775/* Invoke the datepicker functionality.
8776   @param  options  string - a command, optionally followed by additional parameters or
8777                    Object - settings for attaching new datepicker functionality
8778   @return  jQuery object */
8779$.fn.datepicker = function(options){
8780	
8781	/* Verify an empty collection wasn't passed - Fixes #6976 */
8782	if ( !this.length ) {
8783		return this;
8784	}
8785	
8786	/* Initialise the date picker. */
8787	if (!$.datepicker.initialized) {
8788		$(document).mousedown($.datepicker._checkExternalClick).
8789			find('body').append($.datepicker.dpDiv);
8790		$.datepicker.initialized = true;
8791	}
8792
8793	var otherArgs = Array.prototype.slice.call(arguments, 1);
8794	if (typeof options == 'string' && (options == 'isDisabled' || options == 'getDate' || options == 'widget'))
8795		return $.datepicker['_' + options + 'Datepicker'].
8796			apply($.datepicker, [this[0]].concat(otherArgs));
8797	if (options == 'option' && arguments.length == 2 && typeof arguments[1] == 'string')
8798		return $.datepicker['_' + options + 'Datepicker'].
8799			apply($.datepicker, [this[0]].concat(otherArgs));
8800	return this.each(function() {
8801		typeof options == 'string' ?
8802			$.datepicker['_' + options + 'Datepicker'].
8803				apply($.datepicker, [this].concat(otherArgs)) :
8804			$.datepicker._attachDatepicker(this, options);
8805	});
8806};
8807
8808$.datepicker = new Datepicker(); // singleton instance
8809$.datepicker.initialized = false;
8810$.datepicker.uuid = new Date().getTime();
8811$.datepicker.version = "@VERSION";
8812
8813// Workaround for #4055
8814// Add another global to avoid noConflict issues with inline event handlers
8815window['DP_jQuery_' + dpuuid] = $;
8816
8817})(jQuery);
8818
8819(function( $, undefined ) {
8820
8821var uiDialogClasses =
8822		'ui-dialog ' +
8823		'ui-widget ' +
8824		'ui-widget-content ' +
8825		'ui-corner-all ',
8826	sizeRelatedOptions = {
8827		buttons: true,
8828		height: true,
8829		maxHeight: true,
8830		maxWidth: true,
8831		minHeight: true,
8832		minWidth: true,
8833		width: true
8834	},
8835	resizableRelatedOptions = {
8836		maxHeight: true,
8837		maxWidth: true,
8838		minHeight: true,
8839		minWidth: true
8840	},
8841	// support for jQuery 1.3.2 - handle common attrFn methods for dialog
8842	attrFn = $.attrFn || {
8843		val: true,
8844		css: true,
8845		html: true,
8846		text: true,
8847		data: true,
8848		width: true,
8849		height: true,
8850		offset: true,
8851		click: true
8852	};
8853
8854$.widget("ui.dialog", {
8855	options: {
8856		autoOpen: true,
8857		buttons: {},
8858		closeOnEscape: true,
8859		closeText: 'close',
8860		dialogClass: '',
8861		draggable: true,
8862		hide: null,
8863		height: 'auto',
8864		maxHeight: false,
8865		maxWidth: false,
8866		minHeight: 150,
8867		minWidth: 150,
8868		modal: false,
8869		position: {
8870			my: 'center',
8871			at: 'center',
8872			collision: 'fit',
8873			// ensure that the titlebar is never outside the document
8874			using: function(pos) {
8875				var topOffset = $(this).css(pos).offset().top;
8876				if (topOffset < 0) {
8877					$(this).css('top', pos.top - topOffset);
8878				}
8879			}
8880		},
8881		resizable: true,
8882		show: null,
8883		stack: true,
8884		title: '',
8885		width: 300,
8886		zIndex: 1000
8887	},
8888
8889	_create: function() {
8890		this.originalTitle = this.element.attr('title');
8891		// #5742 - .attr() might return a DOMElement
8892		if ( typeof this.originalTitle !== "string" ) {
8893			this.originalTitle = "";
8894		}
8895
8896		this.options.title = this.options.title || this.originalTitle;
8897		var self = this,
8898			options = self.options,
8899
8900			title = options.title || '&#160;',
8901			titleId = $.ui.dialog.getTitleId(self.element),
8902
8903			uiDialog = (self.uiDialog = $('<div></div>'))
8904				.appendTo(document.body)
8905				.hide()
8906				.addClass(uiDialogClasses + options.dialogClass)
8907				.css({
8908					zIndex: options.zIndex
8909				})
8910				// setting tabIndex makes the div focusable
8911				// setting outline to 0 prevents a border on focus in Mozilla
8912				.attr('tabIndex', -1).css('outline', 0).keydown(function(event) {
8913					if (options.closeOnEscape && !event.isDefaultPrevented() && event.keyCode &&
8914						event.keyCode === $.ui.keyCode.ESCAPE) {
8915						
8916						self.close(event);
8917						event.preventDefault();
8918					}
8919				})
8920				.attr({
8921					role: 'dialog',
8922					'aria-labelledby': titleId
8923				})
8924				.mousedown(function(event) {
8925					self.moveToTop(false, event);
8926				}),
8927
8928			uiDialogContent = self.element
8929				.show()
8930				.removeAttr('title')
8931				.addClass(
8932					'ui-dialog-content ' +
8933					'ui-widget-content')
8934				.appendTo(uiDialog),
8935
8936			uiDialogTitlebar = (self.uiDialogTitlebar = $('<div></div>'))
8937				.addClass(
8938					'ui-dialog-titlebar ' +
8939					'ui-widget-header ' +
8940					'ui-corner-all ' +
8941					'ui-helper-clearfix'
8942				)
8943				.prependTo(uiDialog),
8944
8945			uiDialogTitlebarClose = $('<a href="#"></a>')
8946				.addClass(
8947					'ui-dialog-titlebar-close ' +
8948					'ui-corner-all'
8949				)
8950				.attr('role', 'button')
8951				.hover(
8952					function() {
8953						uiDialogTitlebarClose.addClass('ui-state-hover');
8954					},
8955					function() {
8956						uiDialogTitlebarClose.removeClass('ui-state-hover');
8957					}
8958				)
8959				.focus(function() {
8960					uiDialogTitlebarClose.addClass('ui-state-focus');
8961				})
8962				.blur(function() {
8963					uiDialogTitlebarClose.removeClass('ui-state-focus');
8964				})
8965				.click(function(event) {
8966					self.close(event);
8967					return false;
8968				})
8969				.appendTo(uiDialogTitlebar),
8970
8971			uiDialogTitlebarCloseText = (self.uiDialogTitlebarCloseText = $('<span></span>'))
8972				.addClass(
8973					'ui-icon ' +
8974					'ui-icon-closethick'
8975				)
8976				.text(options.closeText)
8977				.appendTo(uiDialogTitlebarClose),
8978
8979			uiDialogTitle = $('<span></span>')
8980				.addClass('ui-dialog-title')
8981				.attr('id', titleId)
8982				.html(title)
8983				.prependTo(uiDialogTitlebar);
8984
8985		//handling of deprecated beforeclose (vs beforeClose) option
8986		//Ticket #4669 http://dev.jqueryui.com/ticket/4669
8987		//TODO: remove in 1.9pre
8988		if ($.isFunction(options.beforeclose) && !$.isFunction(options.beforeClose)) {
8989			options.beforeClose = options.beforeclose;
8990		}
8991
8992		uiDialogTitlebar.find("*").add(uiDialogTitlebar).disableSelection();
8993
8994		if (options.draggable && $.fn.draggable) {
8995			self._makeDraggable();
8996		}
8997		if (options.resizable && $.fn.resizable) {
8998			self._makeResizable();
8999		}
9000
9001		self._createButtons(options.buttons);
9002		self._isOpen = false;
9003
9004		if ($.fn.bgiframe) {
9005			uiDialog.bgiframe();
9006		}
9007	},
9008
9009	_init: function() {
9010		if ( this.options.autoOpen ) {
9011			this.open();
9012		}
9013	},
9014
9015	destroy: function() {
9016		var self = this;
9017		
9018		if (self.overlay) {
9019			self.overlay.destroy();
9020		}
9021		self.uiDialog.hide();
9022		self.element
9023			.unbind('.dialog')
9024			.removeData('dialog')
9025			.removeClass('ui-dialog-content ui-widget-content')
9026			.hide().appendTo('body');
9027		self.uiDialog.remove();
9028
9029		if (self.originalTitle) {
9030			self.element.attr('title', self.originalTitle);
9031		}
9032
9033		return self;
9034	},
9035
9036	widget: function() {
9037		return this.uiDialog;
9038	},
9039
9040	close: function(event) {
9041		var self = this,
9042			maxZ, thisZ;
9043		
9044		if (false === self._trigger('beforeClose', event)) {
9045			return;
9046		}
9047
9048		if (self.overlay) {
9049			self.overlay.destroy();
9050		}
9051		self.uiDialog.unbind('keypress.ui-dialog');
9052
9053		self._isOpen = false;
9054
9055		if (self.options.hide) {
9056			self.uiDialog.hide(self.options.hide, function() {
9057				self._trigger('close', event);
9058			});
9059		} else {
9060			self.uiDialog.hide();
9061			self._trigger('close', event);
9062		}
9063
9064		$.ui.dialog.overlay.resize();
9065
9066		// adjust the maxZ to allow other modal dialogs to continue to work (see #4309)
9067		if (self.options.modal) {
9068			maxZ = 0;
9069			$('.ui-dialog').each(function() {
9070				if (this !== self.uiDialog[0]) {
9071					thisZ = $(this).css('z-index');
9072					if(!isNaN(thisZ)) {
9073						maxZ = Math.max(maxZ, thisZ);
9074					}
9075				}
9076			});
9077			$.ui.dialog.maxZ = maxZ;
9078		}
9079
9080		return self;
9081	},
9082
9083	isOpen: function() {
9084		return this._isOpen;
9085	},
9086
9087	// the force parameter allows us to move modal dialogs to their correct
9088	// position on open
9089	moveToTop: function(force, event) {
9090		var self = this,
9091			options = self.options,
9092			saveScroll;
9093
9094		if ((options.modal && !force) ||
9095			(!options.stack && !options.modal)) {
9096			return self._trigger('focus', event);
9097		}
9098
9099		if (options.zIndex > $.ui.dialog.maxZ) {
9100			$.ui.dialog.maxZ = options.zIndex;
9101		}
9102		if (self.overlay) {
9103			$.ui.dialog.maxZ += 1;
9104			self.overlay.$el.css('z-index', $.ui.dialog.overlay.maxZ = $.ui.dialog.maxZ);
9105		}
9106
9107		//Save and then restore scroll since Opera 9.5+ resets when parent z-Index is changed.
9108		//  http://ui.jquery.com/bugs/ticket/3193
9109		saveScroll = { scrollTop: self.element.scrollTop(), scrollLeft: self.element.scrollLeft() };
9110		$.ui.dialog.maxZ += 1;
9111		self.uiDialog.css('z-index', $.ui.dialog.maxZ);
9112		self.element.attr(saveScroll);
9113		self._trigger('focus', event);
9114
9115		return self;
9116	},
9117
9118	open: function() {
9119		if (this._isOpen) { return; }
9120
9121		var self = this,
9122			options = self.options,
9123			uiDialog = self.uiDialog;
9124
9125		self.overlay = options.modal ? new $.ui.dialog.overlay(self) : null;
9126		self._size();
9127		self._position(options.position);
9128		uiDialog.show(options.show);
9129		self.moveToTop(true);
9130
9131		// prevent tabbing out of modal dialogs
9132		if ( options.modal ) {
9133			uiDialog.bind( "keydown.ui-dialog", function( event ) {
9134				if ( event.keyCode !== $.ui.keyCode.TAB ) {
9135					return;
9136				}
9137
9138				var tabbables = $(':tabbable', this),
9139					first = tabbables.filter(':first'),
9140					last  = tabbables.filter(':last');
9141
9142				if (event.target === last[0] && !event.shiftKey) {
9143					first.focus(1);
9144					return false;
9145				} else if (event.target === first[0] && event.shiftKey) {
9146					last.focus(1);
9147					return false;
9148				}
9149			});
9150		}
9151
9152		// set focus to the first tabbable element in the content area or the first button
9153		// if there are no tabbable elements, set focus on the dialog itself
9154		$(self.element.find(':tabbable').get().concat(
9155			uiDialog.find('.ui-dialog-buttonpane :tabbable').get().concat(
9156				uiDialog.get()))).eq(0).focus();
9157
9158		self._isOpen = true;
9159		self._trigger('open');
9160
9161		return self;
9162	},
9163
9164	_createButtons: function(buttons) {
9165		var self = this,
9166			hasButtons = false,
9167			uiDialogButtonPane = $('<div></div>')
9168				.addClass(
9169					'ui-dialog-buttonpane ' +
9170					'ui-widget-content ' +
9171					'ui-helper-clearfix'
9172				),
9173			uiButtonSet = $( "<div></div>" )
9174				.addClass( "ui-dialog-buttonset" )
9175				.appendTo( uiDialogButtonPane );
9176
9177		// if we already have a button pane, remove it
9178		self.uiDialog.find('.ui-dialog-buttonpane').remove();
9179
9180		if (typeof buttons === 'object' && buttons !== null) {
9181			$.each(buttons, function() {
9182				return !(hasButtons = true);
9183			});
9184		}
9185		if (hasButtons) {
9186			$.each(buttons, function(name, props) {
9187				props = $.isFunction( props ) ?
9188					{ click: props, text: name } :
9189					props;
9190				var button = $('<button type="button"></button>')
9191					.click(function() {
9192						props.click.apply(self.element[0], arguments);
9193					})
9194					.appendTo(uiButtonSet);
9195				// can't use .attr( props, true ) with jQuery 1.3.2.
9196				$.each( props, function( key, value ) {
9197					if ( key === "click" ) {
9198						return;
9199					}
9200					if ( key in attrFn ) {
9201						button[ key ]( value );
9202					} else {
9203						button.attr( key, value );
9204					}
9205				});
9206				if ($.fn.button) {
9207					button.button();
9208				}
9209			});
9210			uiDialogButtonPane.appendTo(self.uiDialog);
9211		}
9212	},
9213
9214	_makeDraggable: function() {
9215		var self = this,
9216			options = self.options,
9217			doc = $(document),
9218			heightBeforeDrag;
9219
9220		function filteredUi(ui) {
9221			return {
9222				position: ui.position,
9223				offset: ui.offset
9224			};
9225		}
9226
9227		self.uiDialog.draggable({
9228			cancel: '.ui-dialog-content, .ui-dialog-titlebar-close',
9229			handle: '.ui-dialog-titlebar',
9230			containment: 'document',
9231			start: function(event, ui) {
9232				heightBeforeDrag = options.height === "auto" ? "auto" : $(this).height();
9233				$(this).height($(this).height()).addClass("ui-dialog-dragging");
9234				self._trigger('dragStart', event, filteredUi(ui));
9235			},
9236			drag: function(event, ui) {
9237				self._trigger('drag', event, filteredUi(ui));
9238			},
9239			stop: function(event, ui) {
9240				options.position = [ui.position.left - doc.scrollLeft(),
9241					ui.position.top - doc.scrollTop()];
9242				$(this).removeClass("ui-dialog-dragging").height(heightBeforeDrag);
9243				self._trigger('dragStop', event, filteredUi(ui));
9244				$.ui.dialog.overlay.resize();
9245			}
9246		});
9247	},
9248
9249	_makeResizable: function(handles) {
9250		handles = (handles === undefined ? this.options.resizable : handles);
9251		var self = this,
9252			options = self.options,
9253			// .ui-resizable has position: relative defined in the stylesheet
9254			// but dialogs have to use absolute or fixed positioning
9255			position = self.uiDialog.css('position'),
9256			resizeHandles = (typeof handles === 'string' ?
9257				handles	:
9258				'n,e,s,w,se,sw,ne,nw'
9259			);
9260
9261		function filteredUi(ui) {
9262			return {
9263				originalPosition: ui.originalPosition,
9264				originalSize: ui.originalSize,
9265				position: ui.position,
9266				size: ui.size
9267			};
9268		}
9269
9270		self.uiDialog.resizable({
9271			cancel: '.ui-dialog-content',
9272			containment: 'document',
9273			alsoResize: self.element,
9274			maxWidth: options.maxWidth,
9275			maxHeight: options.maxHeight,
9276			minWidth: options.minWidth,
9277			minHeight: self._minHeight(),
9278			handles: resizeHandles,
9279			start: function(event, ui) {
9280				$(this).addClass("ui-dialog-resizing");
9281				self._trigger('resizeStart', event, filteredUi(ui));
9282			},
9283			resize: function(event, ui) {
9284				self._trigger('resize', event, filteredUi(ui));
9285			},
9286			stop: function(event, ui) {
9287				$(this).removeClass("ui-dialog-resizing");
9288				options.height = $(this).height();
9289				options.width = $(this).width();
9290				self._trigger('resizeStop', event, filteredUi(ui));
9291				$.ui.dialog.overlay.resize();
9292			}
9293		})
9294		.css('position', position)
9295		.find('.ui-resizable-se').addClass('ui-icon ui-icon-grip-diagonal-se');
9296	},
9297
9298	_minHeight: function() {
9299		var options = this.options;
9300
9301		if (options.height === 'auto') {
9302			return options.minHeight;
9303		} else {
9304			return Math.min(options.minHeight, options.height);
9305		}
9306	},
9307
9308	_position: function(position) {
9309		var myAt = [],
9310			offset = [0, 0],
9311			isVisible;
9312
9313		if (position) {
9314			// deep extending converts arrays to objects in jQuery <= 1.3.2 :-(
9315	//		if (typeof position == 'string' || $.isArray(position)) {
9316	//			myAt = $.isArray(position) ? position : position.split(' ');
9317
9318			if (typeof position === 'string' || (typeof position === 'object' && '0' in position)) {
9319				myAt = position.split ? position.split(' ') : [position[0], position[1]];
9320				if (myAt.length === 1) {
9321					myAt[1] = myAt[0];
9322				}
9323
9324				$.each(['left', 'top'], function(i, offsetPosition) {
9325					if (+myAt[i] === myAt[i]) {
9326						offset[i] = myAt[i];
9327						myAt[i] = offsetPosition;
9328					}
9329				});
9330
9331				position = {
9332					my: myAt.join(" "),
9333					at: myAt.join(" "),
9334					offset: offset.join(" ")
9335				};
9336			} 
9337
9338			position = $.extend({}, $.ui.dialog.prototype.options.position, position);
9339		} else {
9340			position = $.ui.dialog.prototype.options.position;
9341		}
9342
9343		// need to show the dialog to get the actual offset in the position plugin
9344		isVisible = this.uiDialog.is(':visible');
9345		if (!isVisible) {
9346			this.uiDialog.show();
9347		}
9348		this.uiDialog
9349			// workaround for jQuery bug #5781 http://dev.jquery.com/ticket/5781
9350			.css({ top: 0, left: 0 })
9351			.position($.extend({ of: window }, position));
9352		if (!isVisible) {
9353			this.uiDialog.hide();
9354		}
9355	},
9356
9357	_setOptions: function( options ) {
9358		var self = this,
9359			resizableOptions = {},
9360			resize = false;
9361
9362		$.each( options, function( key, value ) {
9363			self._setOption( key, value );
9364			
9365			if ( key in sizeRelatedOptions ) {
9366				resize = true;
9367			}
9368			if ( key in resizableRelatedOptions ) {
9369				resizableOptions[ key ] = value;
9370			}
9371		});
9372
9373		if ( resize ) {
9374			this._size();
9375		}
9376		if ( this.uiDialog.is( ":data(resizable)" ) ) {
9377			this.uiDialog.resizable( "option", resizableOptions );
9378		}
9379	},
9380
9381	_setOption: function(key, value){
9382		var self = this,
9383			uiDialog = self.uiDialog;
9384
9385		switch (key) {
9386			//handling of deprecated beforeclose (vs beforeClose) option
9387			//Ticket #4669 http://dev.jqueryui.com/ticket/4669
9388			//TODO: remove in 1.9pre
9389			case "beforeclose":
9390				key = "beforeClose";
9391				break;
9392			case "buttons":
9393				self._createButtons(value);
9394				break;
9395			case "closeText":
9396				// ensure that we always pass a string
9397				self.uiDialogTitlebarCloseText.text("" + value);
9398				break;
9399			case "dialogClass":
9400				uiDialog
9401					.removeClass(self.options.dialogClass)
9402					.addClass(uiDialogClasses + value);
9403				break;
9404			case "disabled":
9405				if (value) {
9406					uiDialog.addClass('ui-dialog-disabled');
9407				} else {
9408					uiDialog.removeClass('ui-dialog-disabled');
9409				}
9410				break;
9411			case "draggable":
9412				var isDraggable = uiDialog.is( ":data(draggable)" );
9413				if ( isDraggable && !value ) {
9414					uiDialog.draggable( "destroy" );
9415				}
9416				
9417				if ( !isDraggable && value ) {
9418					self._makeDraggable();
9419				}
9420				break;
9421			case "position":
9422				self._position(value);
9423				break;
9424			case "resizable":
9425				// currently resizable, becoming non-resizable
9426				var isResizable = uiDialog.is( ":data(resizable)" );
9427				if (isResizable && !value) {
9428					uiDialog.resizable('destroy');
9429				}
9430
9431				// currently resizable, changing handles
9432				if (isResizable && typeof value === 'string') {
9433					uiDialog.resizable('option', 'handles', value);
9434				}
9435
9436				// currently non-resizable, becoming resizable
9437				if (!isResizable && value !== false) {
9438					self._makeResizable(value);
9439				}
9440				break;
9441			case "title":
9442				// convert whatever was passed in o a string, for html() to not throw up
9443				$(".ui-dialog-title", self.uiDialogTitlebar).html("" + (value || '&#160;'));
9444				break;
9445		}
9446
9447		$.Widget.prototype._setOption.apply(self, arguments);
9448	},
9449
9450	_size: function() {
9451		/* If the user has resized the dialog, the .ui-dialog and .ui-dialog-content
9452		 * divs will both have width and height set, so we need to reset them
9453		 */
9454		var options = this.options,
9455			nonContentHeight,
9456			minContentHeight,
9457			isVisible = this.uiDialog.is( ":visible" );
9458
9459		// reset content sizing
9460		this.element.show().css({
9461			width: 'auto',
9462			minHeight: 0,
9463			height: 0
9464		});
9465
9466		if (options.minWidth > options.width) {
9467			options.width = options.minWidth;
9468		}
9469
9470		// reset wrapper sizing
9471		// determine the height of all the non-content elements
9472		nonContentHeight = this.uiDialog.css({
9473				height: 'auto',
9474				width: options.width
9475			})
9476			.height();
9477		minContentHeight = Math.max( 0, options.minHeight - nonContentHeight );
9478		
9479		if ( options.height === "auto" ) {
9480			// only needed for IE6 support
9481			if ( $.support.minHeight ) {
9482				this.element.css({
9483					minHeight: minContentHeight,
9484					height: "auto"
9485				});
9486			} else {
9487				this.uiDialog.show();
9488				var autoHeight = this.element.css( "height", "auto" ).height();
9489				if ( !isVisible ) {
9490					this.uiDialog.hide();
9491				}
9492				this.element.height( Math.max( autoHeight, minContentHeight ) );
9493			}
9494		} else {
9495			this.element.height( Math.max( options.height - nonContentHeight, 0 ) );
9496		}
9497
9498		if (this.uiDialog.is(':data(resizable)')) {
9499			this.uiDialog.resizable('option', 'minHeight', this._minHeight());
9500		}
9501	}
9502});
9503
9504$.extend($.ui.dialog, {
9505	version: "@VERSION",
9506
9507	uuid: 0,
9508	maxZ: 0,
9509
9510	getTitleId: function($el) {
9511		var id = $el.attr('id');
9512		if (!id) {
9513			this.uuid += 1;
9514			id = this.uuid;
9515		}
9516		return 'ui-dialog-title-' + id;
9517	},
9518
9519	overlay: function(dialog) {
9520		this.$el = $.ui.dialog.overlay.create(dialog);
9521	}
9522});
9523
9524$.extend($.ui.dialog.overlay, {
9525	instances: [],
9526	// reuse old instances due to IE memory leak with alpha transparency (see #5185)
9527	oldInstances: [],
9528	maxZ: 0,
9529	events: $.map('focus,mousedown,mouseup,keydown,keypress,click'.split(','),
9530		function(event) { return event + '.dialog-overlay'; }).join(' '),
9531	create: function(dialog) {
9532		if (this.instances.length === 0) {
9533			// prevent use of anchors and inputs
9534			// we use a setTimeout in case the overlay is created from an
9535			// event that we're going to be cancelling (see #2804)
9536			setTimeout(function() {
9537				// handle $(el).dialog().dialog('close') (see #4065)
9538				if ($.ui.dialog.overlay.instances.length) {
9539					$(document).bind($.ui.dialog.overlay.events, function(event) {
9540						// stop events if the z-index of the target is < the z-index of the overlay
9541						// we cannot return true when we don't want to cancel the event (#3523)
9542						if ($(event.target).css('zindex') < $.ui.dialog.overlay.maxZ) {
9543							return false;
9544						}
9545					});
9546				}
9547			}, 1);
9548
9549			// allow closing by pressing the escape key
9550			$(document).bind('keydown.dialog-overlay', function(event) {
9551				if (dialog.options.closeOnEscape && !event.isDefaultPrevented() && event.keyCode &&
9552					event.keyCode === $.ui.keyCode.ESCAPE) {
9553					
9554					dialog.close(event);
9555					event.preventDefault();
9556				}
9557			});
9558
9559			// handle window resize
9560			$(window).bind('resize.dialog-overlay', $.ui.dialog.overlay.resize);
9561		}
9562
9563		var $el = (this.oldInstances.pop() || $('<div></div>').addClass('ui-widget-overlay'))
9564			.appendTo(document.body)
9565			.css({
9566				width: this.width(),
9567				height: this.height()
9568			});
9569
9570		if ($.fn.bgiframe) {
9571			$el.bgiframe();
9572		}
9573
9574		this.instances.push($el);
9575		return $el;
9576	},
9577
9578	destroy: function($el) {
9579		var indexOf = $.inArray($el, this.instances);
9580		if (indexOf != -1){
9581			this.oldInstances.push(this.instances.splice(indexOf, 1)[0]);
9582		}
9583
9584		if (this.instances.length === 0) {
9585			$([document, window]).unbind('.dialog-overlay');
9586		}
9587
9588		$el.remove();
9589		
9590		// adjust the maxZ to allow other modal dialogs to continue to work (see #4309)
9591		var maxZ = 0;
9592		$.each(this.instances, function() {
9593			maxZ = Math.max(maxZ, this.css('z-index'));
9594		});
9595		this.maxZ = maxZ;
9596	},
9597
9598	height: function() {
9599		var scrollHeight,
9600			offsetHeight;
9601		// handle IE 6
9602		if ($.browser.msie && $.browser.version < 7) {
9603			scrollHeight = Math.max(
9604				document.documentElement.scrollHeight,
9605				document.body.scrollHeight
9606			);
9607			offsetHeight = Math.max(
9608				document.documentElement.offsetHeight,
9609				document.body.offsetHeight
9610			);
9611
9612			if (scrollHeight < offsetHeight) {
9613				return $(window).height() + 'px';
9614			} else {
9615				return scrollHeight + 'px';
9616			}
9617		// handle "good" browsers
9618		} else {
9619			return $(document).height() + 'px';
9620		}
9621	},
9622
9623	width: function() {
9624		var scrollWidth,
9625			offsetWidth;
9626		// handle IE
9627		if ( $.browser.msie ) {
9628			scrollWidth = Math.max(
9629				document.documentElement.scrollWidth,
9630				document.body.scrollWidth
9631			);
9632			offsetWidth = Math.max(
9633				document.documentElement.offsetWidth,
9634				document.body.offsetWidth
9635			);
9636
9637			if (scrollWidth < offsetWidth) {
9638				return $(window).width() + 'px';
9639			} else {
9640				return scrollWidth + 'px';
9641			}
9642		// handle "good" browsers
9643		} else {
9644			return $(document).width() + 'px';
9645		}
9646	},
9647
9648	resize: function() {
9649		/* If the dialog is draggable and the user drags it past the
9650		 * right edge of the window, the document becomes wider so we
9651		 * need to stretch the overlay. If the user then drags the
9652		 * dialog back to the left, the document will become narrower,
9653		 * so we need to shrink the overlay to the appropriate size.
9654		 * This is handled by shrinking the overlay before setting it
9655		 * to the full document size.
9656		 */
9657		var $overlays = $([]);
9658		$.each($.ui.dialog.overlay.instances, function() {
9659			$overlays = $overlays.add(this);
9660		});
9661
9662		$overlays.css({
9663			width: 0,
9664			height: 0
9665		}).css({
9666			width: $.ui.dialog.overlay.width(),
9667			height: $.ui.dialog.overlay.height()
9668		});
9669	}
9670});
9671
9672$.extend($.ui.dialog.overlay.prototype, {
9673	destroy: function() {
9674		$.ui.dialog.overlay.destroy(this.$el);
9675	}
9676});
9677
9678}(jQuery));
9679
9680(function( $, undefined ) {
9681
9682$.ui = $.ui || {};
9683
9684var horizontalPositions = /left|center|right/,
9685	verticalPositions = /top|center|bottom/,
9686	center = "center",
9687	support = {},
9688	_position = $.fn.position,
9689	_offset = $.fn.offset;
9690
9691$.fn.position = function( options ) {
9692	if ( !options || !options.of ) {
9693		return _position.apply( this, arguments );
9694	}
9695
9696	// make a copy, we don't want to modify arguments
9697	options = $.extend( {}, options );
9698
9699	var target = $( options.of ),
9700		targetElem = target[0],
9701		collision = ( options.collision || "flip" ).split( " " ),
9702		offset = options.offset ? options.offset.split( " " ) : [ 0, 0 ],
9703		targetWidth,
9704		targetHeight,
9705		basePosition;
9706
9707	if ( targetElem.nodeType === 9 ) {
9708		targetWidth = target.width();
9709		targetHeight = target.height();
9710		basePosition = { top: 0, left: 0 };
9711	// TODO: use $.isWindow() in 1.9
9712	} else if ( targetElem.setTimeout ) {
9713		targetWidth = target.width();
9714		targetHeight = target.height();
9715		basePosition = { top: target.scrollTop(), left: target.scrollLeft() };
9716	} else if ( targetElem.preventDefault ) {
9717		// force left top to allow flipping
9718		options.at = "left top";
9719		targetWidth = targetHeight = 0;
9720		basePosition = { top: options.of.pageY, left: options.of.pageX };
9721	} else {
9722		targetWidth = target.outerWidth();
9723		targetHeight = target.outerHeight();
9724		basePosition = target.offset();
9725	}
9726
9727	// force my and at to have valid horizontal and veritcal positions
9728	// if a value is missing or invalid, it will be converted to center 
9729	$.each( [ "my", "at" ], function() {
9730		var pos = ( options[this] || "" ).split( " " );
9731		if ( pos.length === 1) {
9732			pos = horizontalPositions.test( pos[0] ) ?
9733				pos.concat( [center] ) :
9734				verticalPositions.test( pos[0] ) ?
9735					[ center ].concat( pos ) :
9736					[ center, center ];
9737		}
9738		pos[ 0 ] = horizontalPositions.test( pos[0] ) ? pos[ 0 ] : center;
9739		pos[ 1 ] = verticalPositions.test( pos[1] ) ? pos[ 1 ] : center;
9740		options[ this ] = pos;
9741	});
9742
9743	// normalize collision option
9744	if ( collision.length === 1 ) {
9745		collision[ 1 ] = collision[ 0 ];
9746	}
9747
9748	// normalize offset option
9749	offset[ 0 ] = parseInt( offset[0], 10 ) || 0;
9750	if ( offset.length === 1 ) {
9751		offset[ 1 ] = offset[ 0 ];
9752	}
9753	offset[ 1 ] = parseInt( offset[1], 10 ) || 0;
9754
9755	if ( options.at[0] === "right" ) {
9756		basePosition.left += targetWidth;
9757	} else if ( options.at[0] === center ) {
9758		basePosition.left += targetWidth / 2;
9759	}
9760
9761	if ( options.at[1] === "bottom" ) {
9762		basePosition.top += targetHeight;
9763	} else if ( options.at[1] === center ) {
9764		basePosition.top += targetHeight / 2;
9765	}
9766
9767	basePosition.left += offset[ 0 ];
9768	basePosition.top += offset[ 1 ];
9769
9770	return this.each(function() {
9771		var elem = $( this ),
9772			elemWidth = elem.outerWidth(),
9773			elemHeight = elem.outerHeight(),
9774			marginLeft = parseInt( $.curCSS( this, "marginLeft", true ) ) || 0,
9775			marginTop = parseInt( $.curCSS( this, "marginTop", true ) ) || 0,
9776			collisionWidth = elemWidth + marginLeft +
9777				( parseInt( $.curCSS( this, "marginRight", true ) ) || 0 ),
9778			collisionHeight = elemHeight + marginTop +
9779				( parseInt( $.curCSS( this, "marginBottom", true ) ) || 0 ),
9780			position = $.extend( {}, basePosition ),
9781			collisionPosition;
9782
9783		if ( options.my[0] === "right" ) {
9784			position.left -= elemWidth;
9785		} else if ( options.my[0] === center ) {
9786			position.left -= elemWidth / 2;
9787		}
9788
9789		if ( options.my[1] === "bottom" ) {
9790			position.top -= elemHeight;
9791		} else if ( options.my[1] === center ) {
9792			position.top -= elemHeight / 2;
9793		}
9794
9795		// prevent fractions if jQuery version doesn't support them (see #5280)
9796		if ( !support.fractions ) {
9797			position.left = Math.round( position.left );
9798			position.top = Math.round( position.top );
9799		}
9800
9801		collisionPosition = {
9802			left: position.left - marginLeft,
9803			top: position.top - marginTop
9804		};
9805
9806		$.each( [ "left", "top" ], function( i, dir ) {
9807			if ( $.ui.position[ collision[i] ] ) {
9808				$.ui.position[ collision[i] ][ dir ]( position, {
9809					targetWidth: targetWidth,
9810					targetHeight: targetHeight,
9811					elemWidth: elemWidth,
9812					elemHeight: elemHeight,
9813					collisionPosition: collisionPosition,
9814					collisionWidth: collisionWidth,
9815					collisionHeight: collisionHeight,
9816					offset: offset,
9817					my: options.my,
9818					at: options.at
9819				});
9820			}
9821		});
9822
9823		if ( $.fn.bgiframe ) {
9824			elem.bgiframe();
9825		}
9826		elem.offset( $.extend( position, { using: options.using } ) );
9827	});
9828};
9829
9830$.ui.position = {
9831	fit: {
9832		left: function( position, data ) {
9833			var win = $( window ),
9834				over = data.collisionPosition.left + data.collisionWidth - win.width() - win.scrollLeft();
9835			position.left = over > 0 ? position.left - over : Math.max( position.left - data.collisionPosition.left, position.left );
9836		},
9837		top: function( position, data ) {
9838			var win = $( window ),
9839				over = data.collisionPosition.top + data.collisionHeight - win.height() - win.scrollTop();
9840			position.top = over > 0 ? position.top - over : Math.max( position.top - data.collisionPosition.top, position.top );
9841		}
9842	},
9843
9844	flip: {
9845		left: function( position, data ) {
9846			if ( data.at[0] === center ) {
9847				return;
9848			}
9849			var win = $( window ),
9850				over = data.collisionPosition.left + data.collisionWidth - win.width() - win.scrollLeft(),
9851				myOffset = data.my[ 0 ] === "left" ?
9852					-data.elemWidth :
9853					data.my[ 0 ] === "right" ?
9854						data.elemWidth :
9855						0,
9856				atOffset = data.at[ 0 ] === "left" ?
9857					data.targetWidth :
9858					-data.targetWidth,
9859				offset = -2 * data.offset[ 0 ];
9860			position.left += data.collisionPosition.left < 0 ?
9861				myOffset + atOffset + offset :
9862				over > 0 ?
9863					myOffset + atOffset + offset :
9864					0;
9865		},
9866		top: function( position, data ) {
9867			if ( data.at[1] === center ) {
9868				return;
9869			}
9870			var win = $( window ),
9871				over = data.collisionPosition.top + data.collisionHeight - win.height() - win.scrollTop(),
9872				myOffset = data.my[ 1 ] === "top" ?
9873					-data.elemHeight :
9874					data.my[ 1 ] === "bottom" ?
9875						data.elemHeight :
9876						0,
9877				atOffset = data.at[ 1 ] === "top" ?
9878					data.targetHeight :
9879					-data.targetHeight,
9880				offset = -2 * data.offset[ 1 ];
9881			position.top += data.collisionPosition.top < 0 ?
9882				myOffset + atOffset + offset :
9883				over > 0 ?
9884					myOffset + atOffset + offset :
9885					0;
9886		}
9887	}
9888};
9889
9890// offset setter from jQuery 1.4
9891if ( !$.offset.setOffset ) {
9892	$.offset.setOffset = function( elem, options ) {
9893		// set position first, in-case top/left are set even on static elem
9894		if ( /static/.test( $.curCSS( elem, "position" ) ) ) {
9895			elem.style.position = "relative";
9896		}
9897		var curElem   = $( elem ),
9898			curOffset = curElem.offset(),
9899			curTop    = parseInt( $.curCSS( elem, "top",  true ), 10 ) || 0,
9900			curLeft   = parseInt( $.curCSS( elem, "left", true ), 10)  || 0,
9901			props     = {
9902				top:  (options.top  - curOffset.top)  + curTop,
9903				left: (options.left - curOffset.left) + curLeft
9904			};
9905		
9906		if ( 'using' in options ) {
9907			options.using.call( elem, props );
9908		} else {
9909			curElem.css( props );
9910		}
9911	};
9912
9913	$.fn.offset = function( options ) {
9914		var elem = this[ 0 ];
9915		if ( !elem || !elem.ownerDocument ) { return null; }
9916		if ( options ) { 
9917			return this.each(function() {
9918				$.offset.setOffset( this, options );
9919			});
9920		}
9921		return _offset.call( this );
9922	};
9923}
9924
9925// fraction support test (older versions of jQuery don't support fractions)
9926(function () {
9927	var body = document.getElementsByTagName( "body" )[ 0 ], 
9928		div = document.createElement( "div" ),
9929		testElement, testElementParent, testElementStyle, offset, offsetTotal;
9930
9931	//Create a "fake body" for testing based on method used in jQuery.support
9932	testElement = document.createElement( body ? "div" : "body" );
9933	testElementStyle = {
9934		visibility: "hidden",
9935		width: 0,
9936		height: 0,
9937		border: 0,
9938		margin: 0,
9939		background: "none"
9940	};
9941	if ( body ) {
9942		$.extend( testElementStyle, {
9943			position: "absolute",
9944			left: "-1000px",
9945			top: "-1000px"
9946		});
9947	}
9948	for ( var i in testElementStyle ) {
9949		testElement.style[ i ] = testElementStyle[ i ];
9950	}
9951	testElement.appendChild( div );
9952	testElementParent = body || document.documentElement;
9953	testElementParent.insertBefore( testElement, testElementParent.firstChild );
9954
9955	div.style.cssText = "position: absolute; left: 10.7432222px; top: 10.432325px; height: 30px; width: 201px;";
9956
9957	offset = $( div ).offset( function( _, offset ) {
9958		return offset;
9959	}).offset();
9960
9961	testElement.innerHTML = "";
9962	testElementParent.removeChild( testElement );
9963
9964	offsetTotal = offset.top + offset.left + ( body ? 2000 : 0 );
9965	support.fractions = offsetTotal > 21 && offsetTotal < 22;
9966})();
9967
9968}( jQuery ));
9969
9970(function( $, undefined ) {
9971
9972$.widget( "ui.progressbar", {
9973	options: {
9974		value: 0,
9975		max: 100
9976	},
9977
9978	min: 0,
9979
9980	_create: function() {
9981		this.element
9982			.addClass( "ui-progressbar ui-widget ui-widget-content ui-corner-all" )
9983			.attr({
9984				role: "progressbar",
9985				"aria-valuemin": this.min,
9986				"aria-valuemax": this.options.max,
9987				"aria-valuenow": this._value()
9988			});
9989
9990		this.valueDiv = $( "<div class='ui-progressbar-value ui-widget-header ui-corner-left'></div>" )
9991			.appendTo( this.element );
9992
9993		this.oldValue = this._value();
9994		this._refreshValue();
9995	},
9996
9997	destroy: function() {
9998		this.element
9999			.removeClass( "ui-progressbar ui-widget ui-widget-content ui-corner-all" )
10000			.removeAttr( "role" )
10001			.removeAttr( "aria-valuemin" )
10002			.removeAttr( "aria-valuemax" )
10003			.removeAttr( "aria-valuenow" );
10004
10005		this.valueDiv.remove();
10006
10007		$.Widget.prototype.destroy.apply( this, arguments );
10008	},
10009
10010	value: function( newValue ) {
10011		if ( newValue === undefined ) {
10012			return this._value();
10013		}
10014
10015		this._setOption( "value", newValue );
10016		return this;
10017	},
10018
10019	_setOption: function( key, value ) {
10020		if ( key === "value" ) {
10021			this.options.value = value;
10022			this._refreshValue();
10023			if ( this._value() === this.options.max ) {
10024				this._trigger( "complete" );
10025			}
10026		}
10027
10028		$.Widget.prototype._setOption.apply( this, arguments );
10029	},
10030
10031	_value: function() {
10032		var val = this.options.value;
10033		// normalize invalid value
10034		if ( typeof val !== "number" ) {
10035			val = 0;
10036		}
10037		return Math.min( this.options.max, Math.max( this.min, val ) );
10038	},
10039
10040	_percentage: function() {
10041		return 100 * this._value() / this.options.max;
10042	},
10043
10044	_refreshValue: function() {
10045		var value = this.value();
10046		var percentage = this._percentage();
10047
10048		if ( this.oldValue !== value ) {
10049			this.oldValue = value;
10050			this._trigger( "change" );
10051		}
10052
10053		this.valueDiv
10054			.toggle( value > this.min )
10055			.toggleClass( "ui-corner-right", value === this.options.max )
10056			.width( percentage.toFixed(0) + "%" );
10057		this.element.attr( "aria-valuenow", value );
10058	}
10059});
10060
10061$.extend( $.ui.progressbar, {
10062	version: "@VERSION"
10063});
10064
10065})( jQuery );
10066
10067(function( $, undefined ) {
10068
10069// number of pages in a slider
10070// (how many times can you page up/down to go through the whole range)
10071var numPages = 5;
10072
10073$.widget( "ui.slider", $.ui.mouse, {
10074
10075	widgetEventPrefix: "slide",
10076
10077	options: {
10078		animate: false,
10079		distance: 0,
10080		max: 100,
10081		min: 0,
10082		orientation: "horizontal",
10083		range: false,
10084		step: 1,
10085		value: 0,
10086		values: null
10087	},
10088
10089	_create: function() {
10090		var self = this,
10091			o = this.options,
10092			existingHandles = this.element.find( ".ui-slider-handle" ).addClass( "ui-state-default ui-corner-all" ),
10093			handle = "<a class='ui-slider-handle ui-state-default ui-corner-all' href='#'></a>",
10094			handleCount = ( o.values && o.values.length ) || 1,
10095			handles = [];
10096
10097		this._keySliding = false;
10098		this._mouseSliding = false;
10099		this._animateOff = true;
10100		this._handleIndex = null;
10101		this._detectOrientation();
10102		this._mouseInit();
10103
10104		this.element
10105			.addClass( "ui-slider" +
10106				" ui-slider-" + this.orientation +
10107				" ui-widget" +
10108				" ui-widget-content" +
10109				" ui-corner-all" +
10110				( o.disabled ? " ui-slider-disabled ui-disabled" : "" ) );
10111
10112		this.range = $([]);
10113
10114		if ( o.range ) {
10115			if ( o.range === true ) {
10116				if ( !o.values ) {
10117					o.values = [ this._valueMin(), this._valueMin() ];
10118				}
10119				if ( o.values.length && o.values.length !== 2 ) {
10120					o.values = [ o.values[0], o.values[0] ];
10121				}
10122			}
10123
10124			this.range = $( "<div></div>" )
10125				.appendTo( this.element )
10126				.addClass( "ui-slider-range" +
10127				// note: this isn't the most fittingly semantic framework class for this element,
10128				// but worked best visually with a variety of themes
10129				" ui-widget-header" + 
10130				( ( o.range === "min" || o.range === "max" ) ? " ui-slider-range-" + o.range : "" ) );
10131		}
10132
10133		for ( var i = existingHandles.length; i < handleCount; i += 1 ) {
10134			handles.push( handle );
10135		}
10136
10137		this.handles = existingHandles.add( $( handles.join( "" ) ).appendTo( self.element ) );
10138
10139		this.handle = this.handles.eq( 0 );
10140
10141		this.handles.add( this.range ).filter( "a" )
10142			.click(function( event ) {
10143				event.preventDefault();
10144			})
10145			.hover(function() {
10146				if ( !o.disabled ) {
10147					$( this ).addClass( "ui-state-hover" );
10148				}
10149			}, function() {
10150				$( this ).removeClass( "ui-state-hover" );
10151			})
10152			.focus(function() {
10153				if ( !o.disabled ) {
10154					$( ".ui-slider .ui-state-focus" ).removeClass( "ui-state-focus" );
10155					$( this ).addClass( "ui-state-focus" );
10156				} else {
10157					$( this ).blur();
10158				}
10159			})
10160			.blur(function() {
10161				$( this ).removeClass( "ui-state-focus" );
10162			});
10163
10164		this.handles.each(function( i ) {
10165			$( this ).data( "index.ui-slider-handle", i );
10166		});
10167
10168		this.handles
10169			.keydown(function( event ) {
10170				var index = $( this ).data( "index.ui-slider-handle" ),
10171					allowed,
10172					curVal,
10173					newVal,
10174					step;
10175	
10176				if ( self.options.disabled ) {
10177					return;
10178				}
10179	
10180				switch ( event.keyCode ) {
10181					case $.ui.keyCode.HOME:
10182					case $.ui.keyCode.END:
10183					case $.ui.keyCode.PAGE_UP:
10184					case $.ui.keyCode.PAGE_DOWN:
10185					case $.ui.keyCode.UP:
10186					case $.ui.keyCode.RIGHT:
10187					case $.ui.keyCode.DOWN:
10188					case $.ui.keyCode.LEFT:
10189						event.preventDefault();
10190						if ( !self._keySliding ) {
10191							self._keySliding = true;
10192							$( this ).addClass( "ui-state-active" );
10193							allowed = self._start( event, index );
10194							if ( allowed === false ) {
10195								return;
10196							}
10197						}
10198						break;
10199				}
10200	
10201				step = self.options.step;
10202				if ( self.options.values && self.options.values.length ) {
10203					curVal = newVal = self.values( index );
10204				} else {
10205					curVal = newVal = self.value();
10206				}
10207	
10208				switch ( event.keyCode ) {
10209					case $.ui.keyCode.HOME:
10210						newVal = self._valueMin();
10211						break;
10212					case $.ui.keyCode.END:
10213						newVal = self._valueMax();
10214						break;
10215					case $.ui.keyCode.PAGE_UP:
10216						newVal = self._trimAlignValue( curVal + ( (self._valueMax() - self._valueMin()) / numPages ) );
10217						break;
10218					case $.ui.keyCode.PAGE_DOWN:
10219						newVal = self._trimAlignValue( curVal - ( (self._valueMax() - self._valueMin()) / numPages ) );
10220						break;
10221					case $.ui.keyCode.UP:
10222					case $.ui.keyCode.RIGHT:
10223						if ( curVal === self._valueMax() ) {
10224							return;
10225						}
10226						newVal = self._trimAlignValue( curVal + step );
10227						break;
10228					case $.ui.keyCode.DOWN:
10229					case $.ui.keyCode.LEFT:
10230						if ( curVal === self._valueMin() ) {
10231							return;
10232						}
10233						newVal = self._trimAlignValue( curVal - step );
10234						break;
10235				}
10236	
10237				self._slide( event, index, newVal );
10238			})
10239			.keyup(function( event ) {
10240				var index = $( this ).data( "index.ui-slider-handle" );
10241	
10242				if ( self._keySliding ) {
10243					self._keySliding = false;
10244					self._stop( event, index );
10245					self._change( event, index );
10246					$( this ).removeClass( "ui-state-active" );
10247				}
10248	
10249			});
10250
10251		this._refreshValue();
10252
10253		this._animateOff = false;
10254	},
10255
10256	destroy: function() {
10257		this.handles.remove();
10258		this.range.remove();
10259
10260		this.element
10261			.removeClass( "ui-slider" +
10262				" ui-slider-horizontal" +
10263				" ui-slider-vertical" +
10264				" ui-slider-disabled" +
10265				" ui-widget" +
10266				" ui-widget-content" +
10267				" ui-corner-all" )
10268			.removeData( "slider" )
10269			.unbind( ".slider" );
10270
10271		this._mouseDestroy();
10272
10273		return this;
10274	},
10275
10276	_mouseCapture: function( event ) {
10277		var o = this.options,
10278			position,
10279			normValue,
10280			distance,
10281			closestHandle,
10282			self,
10283			index,
10284			allowed,
10285			offset,
10286			mouseOverHandle;
10287
10288		if ( o.disabled ) {
10289			return false;
10290		}
10291
10292		this.elementSize = {
10293			width: this.element.outerWidth(),
10294			height: this.element.outerHeight()
10295		};
10296		this.elementOffset = this.element.offset();
10297
10298		position = { x: event.pageX, y: event.pageY };
10299		normValue = this._normValueFromMouse( position );
10300		distance = this._valueMax() - this._valueMin() + 1;
10301		self = this;
10302		this.handles.each(function( i ) {
10303			var thisDistance = Math.abs( normValue - self.values(i) );
10304			if ( distance > thisDistance ) {
10305				distance = thisDistance;
10306				closestHandle = $( this );
10307				index = i;
10308			}
10309		});
10310
10311		// workaround for bug #3736 (if both handles of a range are at 0,
10312		// the first is always used as the one with least distance,
10313		// and moving it is obviously prevented by preventing negative ranges)
10314		if( o.range === true && this.values(1) === o.min ) {
10315			index += 1;
10316			closestHandle = $( this.handles[index] );
10317		}
10318
10319		allowed = this._start( event, index );
10320		if ( allowed === false ) {
10321			return false;
10322		}
10323		this._mouseSliding = true;
10324
10325		self._handleIndex = index;
10326
10327		closestHandle
10328			.addClass( "ui-state-active" )
10329			.focus();
10330		
10331		offset = closestHandle.offset();
10332		mouseOverHandle = !$( event.target ).parents().andSelf().is( ".ui-slider-handle" );
10333		this._clickOffset = mouseOverHandle ? { left: 0, top: 0 } : {
10334			left: event.pageX - offset.left - ( closestHandle.width() / 2 ),
10335			top: event.pageY - offset.top -
10336				( closestHandle.height() / 2 ) -
10337				( parseInt( closestHandle.css("borderTopWidth"), 10 ) || 0 ) -
10338				( parseInt( closestHandle.css("borderBottomWidth"), 10 ) || 0) +
10339				( parseInt( closestHandle.css("marginTop"), 10 ) || 0)
10340		};
10341
10342		if ( !this.handles.hasClass( "ui-state-hover" ) ) {
10343			this._slide( event, index, normValue );
10344		}
10345		this._animateOff = true;
10346		return true;
10347	},
10348
10349	_mouseStart: function( event ) {
10350		return true;
10351	},
10352
10353	_mouseDrag: function( event ) {
10354		var position = { x: event.pageX, y: event.pageY },
10355			normValue = this._normValueFromMouse( position );
10356		
10357		this._slide( event, this._handleIndex, normValue );
10358
10359		return false;
10360	},
10361
10362	_mouseStop: function( event ) {
10363		this.handles.removeClass( "ui-state-active" );
10364		this._mouseSliding = false;
10365
10366		this._stop( event, this._handleIndex );
10367		this._change( event, this._handleIndex );
10368
10369		this._handleIndex = null;
10370		this._clickOffset = null;
10371		this._animateOff = false;
10372
10373		return false;
10374	},
10375	
10376	_detectOrientation: function() {
10377		this.orientation = ( this.options.orientation === "vertical" ) ? "vertical" : "horizontal";
10378	},
10379
10380	_normValueFromMouse: function( position ) {
10381		var pixelTotal,
10382			pixelMouse,
10383			percentMouse,
10384			valueTotal,
10385			valueMouse;
10386
10387		if ( this.orientation === "horizontal" ) {
10388			pixelTotal = this.elementSize.width;
10389			pixelMouse = position.x - this.elementOffset.left - ( this._clickOffset ? this._clickOffset.left : 0 );
10390		} else {
10391			pixelTotal = this.elementSize.height;
10392			pixelMouse = position.y - this.elementOffset.top - ( this._clickOffset ? this._clickOffset.top : 0 );
10393		}
10394
10395		percentMouse = ( pixelMouse / pixelTotal );
10396		if ( percentMouse > 1 ) {
10397			percentMouse = 1;
10398		}
10399		if ( percentMouse < 0 ) {
10400			percentMouse = 0;
10401		}
10402		if ( this.orientation === "vertical" ) {
10403			percentMouse = 1 - percentMouse;
10404		}
10405
10406		valueTotal = this._valueMax() - this._valueMin();
10407		valueMouse = this._valueMin() + percentMouse * valueTotal;
10408
10409		return this._trimAlignValue( valueMouse );
10410	},
10411
10412	_start: function( event, index ) {
10413		var uiHash = {
10414			handle: this.handles[ index ],
10415			value: this.value()
10416		};
10417		if ( this.options.values && this.options.values.length ) {
10418			uiHash.value = this.values( index );
10419			uiHash.values = this.values();
10420		}
10421		return this._trigger( "start", event, uiHash );
10422	},
10423
10424	_slide: function( event, index, newVal ) {
10425		var otherVal,
10426			newValues,
10427			allowed;
10428
10429		if ( this.options.values && this.options.values.length ) {
10430			otherVal = this.values( index ? 0 : 1 );
10431
10432			if ( ( this.options.values.length === 2 && this.options.range === true ) && 
10433					( ( index === 0 && newVal > otherVal) || ( index === 1 && newVal < otherVal ) )
10434				) {
10435				newVal = otherVal;
10436			}
10437
10438			if ( newVal !== this.values( index ) ) {
10439				newValues = this.values();
10440				newValues[ index ] = newVal;
10441				// A slide can be canceled by returning false from the slide callback
10442				allowed = this._trigger( "slide", event, {
10443					handle: this.handles[ index ],
10444					value: newVal,
10445					values: newValues
10446				} );
10447				otherVal = this.values( index ? 0 : 1 );
10448				if ( allowed !== false ) {
10449					this.values( index, newVal, true );
10450				}
10451			}
10452		} else {
10453			if ( newVal !== this.value() ) {
10454				// A slide can be canceled by returning false from the slide callback
10455				allowed = this._trigger( "slide", event, {
10456					handle: this.handles[ index ],
10457					value: newVal
10458				} );
10459				if ( allowed !== false ) {
10460					this.value( newVal );
10461				}
10462			}
10463		}
10464	},
10465
10466	_stop: function( event, index ) {
10467		var uiHash = {
10468			handle: this.handles[ index ],
10469			value: this.value()
10470		};
10471		if ( this.options.values && this.options.values.length ) {
10472			uiHash.value = this.values( index );
10473			uiHash.values = this.values();
vendor: 5,764 bytes, lines 10474-10680
10474		}
10475
10476		this._trigger( "stop", event, uiHash );
10477	},
10478
10479	_change: function( event, index ) {
10480		if ( !this._keySliding && !this._mouseSliding ) {
10481			var uiHash = {
10482				handle: this.handles[ index ],
10483				value: this.value()
10484			};
10485			if ( this.options.values && this.options.values.length ) {
10486				uiHash.value = this.values( index );
10487				uiHash.values = this.values();
10488			}
10489
10490			this._trigger( "change", event, uiHash );
10491		}
10492	},
10493
10494	value: function( newValue ) {
10495		if ( arguments.length ) {
10496			this.options.value = this._trimAlignValue( newValue );
10497			this._refreshValue();
10498			this._change( null, 0 );
10499			return;
10500		}
10501
10502		return this._value();
10503	},
10504
10505	values: function( index, newValue ) {
10506		var vals,
10507			newValues,
10508			i;
10509
10510		if ( arguments.length > 1 ) {
10511			this.options.values[ index ] = this._trimAlignValue( newValue );
10512			this._refreshValue();
10513			this._change( null, index );
10514			return;
10515		}
10516
10517		if ( arguments.length ) {
10518			if ( $.isArray( arguments[ 0 ] ) ) {
10519				vals = this.options.values;
10520				newValues = arguments[ 0 ];
10521				for ( i = 0; i < vals.length; i += 1 ) {
10522					vals[ i ] = this._trimAlignValue( newValues[ i ] );
10523					this._change( null, i );
10524				}
10525				this._refreshValue();
10526			} else {
10527				if ( this.options.values && this.options.values.length ) {
10528					return this._values( index );
10529				} else {
10530					return this.value();
10531				}
10532			}
10533		} else {
10534			return this._values();
10535		}
10536	},
10537
10538	_setOption: function( key, value ) {
10539		var i,
10540			valsLength = 0;
10541
10542		if ( $.isArray( this.options.values ) ) {
10543			valsLength = this.options.values.length;
10544		}
10545
10546		$.Widget.prototype._setOption.apply( this, arguments );
10547
10548		switch ( key ) {
10549			case "disabled":
10550				if ( value ) {
10551					this.handles.filter( ".ui-state-focus" ).blur();
10552					this.handles.removeClass( "ui-state-hover" );
10553					this.handles.propAttr( "disabled", true );
10554					this.element.addClass( "ui-disabled" );
10555				} else {
10556					this.handles.propAttr( "disabled", false );
10557					this.element.removeClass( "ui-disabled" );
10558				}
10559				break;
10560			case "orientation":
10561				this._detectOrientation();
10562				this.element
10563					.removeClass( "ui-slider-horizontal ui-slider-vertical" )
10564					.addClass( "ui-slider-" + this.orientation );
10565				this._refreshValue();
10566				break;
10567			case "value":
10568				this._animateOff = true;
10569				this._refreshValue();
10570				this._change( null, 0 );
10571				this._animateOff = false;
10572				break;
10573			case "values":
10574				this._animateOff = true;
10575				this._refreshValue();
10576				for ( i = 0; i < valsLength; i += 1 ) {
10577					this._change( null, i );
10578				}
10579				this._animateOff = false;
10580				break;
10581		}
10582	},
10583
10584	//internal value getter
10585	// _value() returns value trimmed by min and max, aligned by step
10586	_value: function() {
10587		var val = this.options.value;
10588		val = this._trimAlignValue( val );
10589
10590		return val;
10591	},
10592
10593	//internal values getter
10594	// _values() returns array of values trimmed by min and max, aligned by step
10595	// _values( index ) returns single value trimmed by min and max, aligned by step
10596	_values: function( index ) {
10597		var val,
10598			vals,
10599			i;
10600
10601		if ( arguments.length ) {
10602			val = this.options.values[ index ];
10603			val = this._trimAlignValue( val );
10604
10605			return val;
10606		} else {
10607			// .slice() creates a copy of the array
10608			// this copy gets trimmed by min and max and then returned
10609			vals = this.options.values.slice();
10610			for ( i = 0; i < vals.length; i+= 1) {
10611				vals[ i ] = this._trimAlignValue( vals[ i ] );
10612			}
10613
10614			return vals;
10615		}
10616	},
10617	
10618	// returns the step-aligned value that val is closest to, between (inclusive) min and max
10619	_trimAlignValue: function( val ) {
10620		if ( val <= this._valueMin() ) {
10621			return this._valueMin();
10622		}
10623		if ( val >= this._valueMax() ) {
10624			return this._valueMax();
10625		}
10626		var step = ( this.options.step > 0 ) ? this.options.step : 1,
10627			valModStep = (val - this._valueMin()) % step,
10628			alignValue = val - valModStep;
10629
10630		if ( Math.abs(valModStep) * 2 >= step ) {
10631			alignValue += ( valModStep > 0 ) ? step : ( -step );
10632		}
10633
10634		// Since JavaScript has problems with large floats, round
10635		// the final value to 5 digits after the decimal point (see #4124)
10636		return parseFloat( alignValue.toFixed(5) );
10637	},
10638
10639	_valueMin: function() {
10640		return this.options.min;
10641	},
10642
10643	_valueMax: function() {
10644		return this.options.max;
10645	},
10646	
10647	_refreshValue: function() {
10648		var oRange = this.options.range,
10649			o = this.options,
10650			self = this,
10651			animate = ( !this._animateOff ) ? o.animate : false,
10652			valPercent,
10653			_set = {},
10654			lastValPercent,
10655			value,
10656			valueMin,
10657			valueMax;
10658
10659		if ( this.options.values && this.options.values.length ) {
10660			this.handles.each(function( i, j ) {
10661				valPercent = ( self.values(i) - self._valueMin() ) / ( self._valueMax() - self._valueMin() ) * 100;
10662				_set[ self.orientation === "horizontal" ? "left" : "bottom" ] = valPercent + "%";
10663				$( this ).stop( 1, 1 )[ animate ? "animate" : "css" ]( _set, o.animate );
10664				if ( self.options.range === true ) {
10665					if ( self.orientation === "horizontal" ) {
10666						if ( i === 0 ) {
10667							self.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { left: valPercent + "%" }, o.animate );
10668						}
10669						if ( i === 1 ) {
10670							self.range[ animate ? "animate" : "css" ]( { width: ( valPercent - lastValPercent ) + "%" }, { queue: false, duration: o.animate } );
10671						}
10672					} else {
10673						if ( i === 0 ) {
10674							self.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { bottom: ( valPercent ) + "%" }, o.animate );
10675						}
10676						if ( i === 1 ) {
10677							self.range[ animate ? "animate" : "css" ]( { height: ( valPercent - lastValPercent ) + "%" }, { queue: false, duration: o.animate } );
10678						}
10679					}
10680				}
10681				lastValPercent = valPercent;
10682			});
10683		} else {
10684			value = this.value();
10685			valueMin = this._valueMin();
10686			valueMax = this._valueMax();
10687			valPercent = ( valueMax !== valueMin ) ?
10688					( value - valueMin ) / ( valueMax - valueMin ) * 100 :
10689					0;
10690			_set[ self.orientation === "horizontal" ? "left" : "bottom" ] = valPercent + "%";
10691			this.handle.stop( 1, 1 )[ animate ? "animate" : "css" ]( _set, o.animate );
10692
10693			if ( oRange === "min" && this.orientation === "horizontal" ) {
10694				this.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { width: valPercent + "%" }, o.animate );
10695			}
10696			if ( oRange === "max" && this.orientation === "horizontal" ) {
10697				this.range[ animate ? "animate" : "css" ]( { width: ( 100 - valPercent ) + "%" }, { queue: false, duration: o.animate } );
10698			}
10699			if ( oRange === "min" && this.orientation === "vertical" ) {
10700				this.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { height: valPercent + "%" }, o.animate );
10701			}
10702			if ( oRange === "max" && this.orientation === "vertical" ) {
10703				this.range[ animate ? "animate" : "css" ]( { height: ( 100 - valPercent ) + "%" }, { queue: false, duration: o.animate } );
10704			}
10705		}
10706	}
10707
10708});
10709
10710$.extend( $.ui.slider, {
10711	version: "@VERSION"
10712});
10713
10714}(jQuery));
10715
10716(function( $, undefined ) {
10717
10718var tabId = 0,
10719	listId = 0;
10720
10721function getNextTabId() {
10722	return ++tabId;
10723}
10724
10725function getNextListId() {
10726	return ++listId;
10727}
10728
10729$.widget( "ui.tabs", {
10730	options: {
10731		add: null,
10732		ajaxOptions: null,
10733		cache: false,
10734		cookie: null, // e.g. { expires: 7, path: '/', domain: 'jquery.com', secure: true }
10735		collapsible: false,
10736		disable: null,
10737		disabled: [],
10738		enable: null,
10739		event: "click",
10740		fx: null, // e.g. { height: 'toggle', opacity: 'toggle', duration: 200 }
10741		idPrefix: "ui-tabs-",
10742		load: null,
10743		panelTemplate: "<div></div>",
10744		remove: null,
10745		select: null,
10746		show: null,
10747		spinner: "<em>Loading&#8230;</em>",
10748		tabTemplate: "<li><a href='#{href}'><span>#{label}</span></a></li>"
10749	},
10750
10751	_create: function() {
10752		this._tabify( true );
10753	},
10754
10755	_setOption: function( key, value ) {
10756		if ( key == "selected" ) {
10757			if (this.options.collapsible && value == this.options.selected ) {
10758				return;
10759			}
10760			this.select( value );
10761		} else {
10762			this.options[ key ] = value;
10763			this._tabify();
10764		}
10765	},
10766
10767	_tabId: function( a ) {
10768		return a.title && a.title.replace( /\s/g, "_" ).replace( /[^\w\u00c0-\uFFFF-]/g, "" ) ||
10769			this.options.idPrefix + getNextTabId();
10770	},
10771
10772	_sanitizeSelector: function( hash ) {
10773		// we need this because an id may contain a ":"
10774		return hash.replace( /:/g, "\\:" );
10775	},
10776
10777	_cookie: function() {
10778		var cookie = this.cookie ||
10779			( this.cookie = this.options.cookie.name || "ui-tabs-" + getNextListId() );
10780		return $.cookie.apply( null, [ cookie ].concat( $.makeArray( arguments ) ) );
10781	},
10782
10783	_ui: function( tab, panel ) {
10784		return {
10785			tab: tab,
10786			panel: panel,
10787			index: this.anchors.index( tab )
10788		};
10789	},
10790
10791	_cleanup: function() {
10792		// restore all former loading tabs labels
10793		this.lis.filter( ".ui-state-processing" )
10794			.removeClass( "ui-state-processing" )
10795			.find( "span:data(label.tabs)" )
10796				.each(function() {
10797					var el = $( this );
10798					el.html( el.data( "label.tabs" ) ).removeData( "label.tabs" );
10799				});
10800	},
10801
10802	_tabify: function( init ) {
10803		var self = this,
10804			o = this.options,
10805			fragmentId = /^#.+/; // Safari 2 reports '#' for an empty hash
10806
10807		this.list = this.element.find( "ol,ul" ).eq( 0 );
10808		this.lis = $( " > li:has(a[href])", this.list );
10809		this.anchors = this.lis.map(function() {
10810			return $( "a", this )[ 0 ];
10811		});
10812		this.panels = $( [] );
10813
10814		this.anchors.each(function( i, a ) {
10815			var href = $( a ).attr( "href" );
10816			// For dynamically created HTML that contains a hash as href IE < 8 expands
10817			// such href to the full page url with hash and then misinterprets tab as ajax.
10818			// Same consideration applies for an added tab with a fragment identifier
10819			// since a[href=#fragment-identifier] does unexpectedly not match.
10820			// Thus normalize href attribute...
10821			var hrefBase = href.split( "#" )[ 0 ],
10822				baseEl;
10823			if ( hrefBase && ( hrefBase === location.toString().split( "#" )[ 0 ] ||
10824					( baseEl = $( "base" )[ 0 ]) && hrefBase === baseEl.href ) ) {
10825				href = a.hash;
10826				a.href = href;
10827			}
10828
10829			// inline tab
10830			if ( fragmentId.test( href ) ) {
10831				self.panels = self.panels.add( self.element.find( self._sanitizeSelector( href ) ) );
10832			// remote tab
10833			// prevent loading the page itself if href is just "#"
10834			} else if ( href && href !== "#" ) {
10835				// required for restore on destroy
10836				$.data( a, "href.tabs", href );
10837
10838				// TODO until #3808 is fixed strip fragment identifier from url
10839				// (IE fails to load from such url)
10840				$.data( a, "load.tabs", href.replace( /#.*$/, "" ) );
10841
10842				var id = self._tabId( a );
10843				a.href = "#" + id;
10844				var $panel = self.element.find( "#" + id );
10845				if ( !$panel.length ) {
10846					$panel = $( o.panelTemplate )
10847						.attr( "id", id )
10848						.addClass( "ui-tabs-panel ui-widget-content ui-corner-bottom" )
10849						.insertAfter( self.panels[ i - 1 ] || self.list );
10850					$panel.data( "destroy.tabs", true );
10851				}
10852				self.panels = self.panels.add( $panel );
10853			// invalid tab href
10854			} else {
10855				o.disabled.push( i );
10856			}
10857		});
10858
10859		// initialization from scratch
10860		if ( init ) {
10861			// attach necessary classes for styling
10862			this.element.addClass( "ui-tabs ui-widget ui-widget-content ui-corner-all" );
10863			this.list.addClass( "ui-tabs-nav ui-helper-reset ui-helper-clearfix ui-widget-header ui-corner-all" );
10864			this.lis.addClass( "ui-state-default ui-corner-top" );
10865			this.panels.addClass( "ui-tabs-panel ui-widget-content ui-corner-bottom" );
10866
10867			// Selected tab
10868			// use "selected" option or try to retrieve:
10869			// 1. from fragment identifier in url
10870			// 2. from cookie
10871			// 3. from selected class attribute on <li>
10872			if ( o.selected === undefined ) {
10873				if ( location.hash ) {
10874					this.anchors.each(function( i, a ) {
10875						if ( a.hash == location.hash ) {
10876							o.selected = i;
10877							return false;
10878						}
10879					});
10880				}
10881				if ( typeof o.selected !== "number" && o.cookie ) {
10882					o.selected = parseInt( self._cookie(), 10 );
10883				}
10884				if ( typeof o.selected !== "number" && this.lis.filter( ".ui-tabs-selected" ).length ) {
10885					o.selected = this.lis.index( this.lis.filter( ".ui-tabs-selected" ) );
10886				}
10887				o.selected = o.selected || ( this.lis.length ? 0 : -1 );
10888			} else if ( o.selected === null ) { // usage of null is deprecated, TODO remove in next release
10889				o.selected = -1;
10890			}
10891
10892			// sanity check - default to first tab...
10893			o.selected = ( ( o.selected >= 0 && this.anchors[ o.selected ] ) || o.selected < 0 )
10894				? o.selected
10895				: 0;
10896
10897			// Take disabling tabs via class attribute from HTML
10898			// into account and update option properly.
10899			// A selected tab cannot become disabled.
10900			o.disabled = $.unique( o.disabled.concat(
10901				$.map( this.lis.filter( ".ui-state-disabled" ), function( n, i ) {
10902					return self.lis.index( n );
10903				})
10904			) ).sort();
10905
10906			if ( $.inArray( o.selected, o.disabled ) != -1 ) {
10907				o.disabled.splice( $.inArray( o.selected, o.disabled ), 1 );
10908			}
10909
10910			// highlight selected tab
10911			this.panels.addClass( "ui-tabs-hide" );
10912			this.lis.removeClass( "ui-tabs-selected ui-state-active" );
10913			// check for length avoids error when initializing empty list
10914			if ( o.selected >= 0 && this.anchors.length ) {
10915				self.element.find( self._sanitizeSelector( self.anchors[ o.selected ].hash ) ).removeClass( "ui-tabs-hide" );
10916				this.lis.eq( o.selected ).addClass( "ui-tabs-selected ui-state-active" );
10917
10918				// seems to be expected behavior that the show callback is fired
10919				self.element.queue( "tabs", function() {
10920					self._trigger( "show", null,
10921						self._ui( self.anchors[ o.selected ], self.element.find( self._sanitizeSelector( self.anchors[ o.selected ].hash ) )[ 0 ] ) );
10922				});
10923
10924				this.load( o.selected );
10925			}
10926
10927			// clean up to avoid memory leaks in certain versions of IE 6
10928			// TODO: namespace this event
10929			$( window ).bind( "unload", function() {
10930				self.lis.add( self.anchors ).unbind( ".tabs" );
10931				self.lis = self.anchors = self.panels = null;
10932			});
10933		// update selected after add/remove
10934		} else {
10935			o.selected = this.lis.index( this.lis.filter( ".ui-tabs-selected" ) );
10936		}
10937
10938		// update collapsible
10939		// TODO: use .toggleClass()
10940		this.element[ o.collapsible ? "addClass" : "removeClass" ]( "ui-tabs-collapsible" );
10941
10942		// set or update cookie after init and add/remove respectively
10943		if ( o.cookie ) {
10944			this._cookie( o.selected, o.cookie );
10945		}
10946
10947		// disable tabs
10948		for ( var i = 0, li; ( li = this.lis[ i ] ); i++ ) {
10949			$( li )[ $.inArray( i, o.disabled ) != -1 &&
10950				// TODO: use .toggleClass()
10951				!$( li ).hasClass( "ui-tabs-selected" ) ? "addClass" : "removeClass" ]( "ui-state-disabled" );
10952		}
10953
10954		// reset cache if switching from cached to not cached
10955		if ( o.cache === false ) {
10956			this.anchors.removeData( "cache.tabs" );
10957		}
10958
10959		// remove all handlers before, tabify may run on existing tabs after add or option change
10960		this.lis.add( this.anchors ).unbind( ".tabs" );
10961
10962		if ( o.event !== "mouseover" ) {
10963			var addState = function( state, el ) {
10964				if ( el.is( ":not(.ui-state-disabled)" ) ) {
10965					el.addClass( "ui-state-" + state );
10966				}
10967			};
10968			var removeState = function( state, el ) {
10969				el.removeClass( "ui-state-" + state );
10970			};
10971			this.lis.bind( "mouseover.tabs" , function() {
10972				addState( "hover", $( this ) );
10973			});
10974			this.lis.bind( "mouseout.tabs", function() {
10975				removeState( "hover", $( this ) );
10976			});
10977			this.anchors.bind( "focus.tabs", function() {
10978				addState( "focus", $( this ).closest( "li" ) );
10979			});
10980			this.anchors.bind( "blur.tabs", function() {
10981				removeState( "focus", $( this ).closest( "li" ) );
10982			});
10983		}
10984
10985		// set up animations
10986		var hideFx, showFx;
10987		if ( o.fx ) {
10988			if ( $.isArray( o.fx ) ) {
10989				hideFx = o.fx[ 0 ];
10990				showFx = o.fx[ 1 ];
10991			} else {
10992				hideFx = showFx = o.fx;
10993			}
10994		}
10995
10996		// Reset certain styles left over from animation
10997		// and prevent IE's ClearType bug...
10998		function resetStyle( $el, fx ) {
10999			$el.css( "display", "" );
11000			if ( !$.support.opacity && fx.opacity ) {
11001				$el[ 0 ].style.removeAttribute( "filter" );
11002			}
11003		}
11004
11005		// Show a tab...
11006		var showTab = showFx
11007			? function( clicked, $show ) {
11008				$( clicked ).closest( "li" ).addClass( "ui-tabs-selected ui-state-active" );
11009				$show.hide().removeClass( "ui-tabs-hide" ) // avoid flicker that way
11010					.animate( showFx, showFx.duration || "normal", function() {
11011						resetStyle( $show, showFx );
11012						self._trigger( "show", null, self._ui( clicked, $show[ 0 ] ) );
11013					});
11014			}
11015			: function( clicked, $show ) {
11016				$( clicked ).closest( "li" ).addClass( "ui-tabs-selected ui-state-active" );
11017				$show.removeClass( "ui-tabs-hide" );
11018				self._trigger( "show", null, self._ui( clicked, $show[ 0 ] ) );
11019			};
11020
11021		// Hide a tab, $show is optional...
11022		var hideTab = hideFx
11023			? function( clicked, $hide ) {
11024				$hide.animate( hideFx, hideFx.duration || "normal", function() {
11025					self.lis.removeClass( "ui-tabs-selected ui-state-active" );
11026					$hide.addClass( "ui-tabs-hide" );
11027					resetStyle( $hide, hideFx );
11028					self.element.dequeue( "tabs" );
11029				});
11030			}
11031			: function( clicked, $hide, $show ) {
11032				self.lis.removeClass( "ui-tabs-selected ui-state-active" );
11033				$hide.addClass( "ui-tabs-hide" );
11034				self.element.dequeue( "tabs" );
11035			};
11036
11037		// attach tab event handler, unbind to avoid duplicates from former tabifying...
11038		this.anchors.bind( o.event + ".tabs", function() {
11039			var el = this,
11040				$li = $(el).closest( "li" ),
11041				$hide = self.panels.filter( ":not(.ui-tabs-hide)" ),
11042				$show = self.element.find( self._sanitizeSelector( el.hash ) );
11043
11044			// If tab is already selected and not collapsible or tab disabled or
11045			// or is already loading or click callback returns false stop here.
11046			// Check if click handler returns false last so that it is not executed
11047			// for a disabled or loading tab!
11048			if ( ( $li.hasClass( "ui-tabs-selected" ) && !o.collapsible) ||
11049				$li.hasClass( "ui-state-disabled" ) ||
11050				$li.hasClass( "ui-state-processing" ) ||
11051				self.panels.filter( ":animated" ).length ||
11052				self._trigger( "select", null, self._ui( this, $show[ 0 ] ) ) === false ) {
11053				this.blur();
11054				return false;
11055			}
11056
11057			o.selected = self.anchors.index( this );
11058
11059			self.abort();
11060
11061			// if tab may be closed
11062			if ( o.collapsible ) {
11063				if ( $li.hasClass( "ui-tabs-selected" ) ) {
11064					o.selected = -1;
11065
11066					if ( o.cookie ) {
11067						self._cookie( o.selected, o.cookie );
11068					}
11069
11070					self.element.queue( "tabs", function() {
11071						hideTab( el, $hide );
11072					}).dequeue( "tabs" );
11073
11074					this.blur();
11075					return false;
11076				} else if ( !$hide.length ) {
11077					if ( o.cookie ) {
11078						self._cookie( o.selected, o.cookie );
11079					}
11080
11081					self.element.queue( "tabs", function() {
11082						showTab( el, $show );
11083					});
11084
11085					// TODO make passing in node possible, see also http://dev.jqueryui.com/ticket/3171
11086					self.load( self.anchors.index( this ) );
11087
11088					this.blur();
11089					return false;
11090				}
11091			}
11092
11093			if ( o.cookie ) {
11094				self._cookie( o.selected, o.cookie );
11095			}
11096
11097			// show new tab
11098			if ( $show.length ) {
11099				if ( $hide.length ) {
11100					self.element.queue( "tabs", function() {
11101						hideTab( el, $hide );
11102					});
11103				}
11104				self.element.queue( "tabs", function() {
11105					showTab( el, $show );
11106				});
11107
11108				self.load( self.anchors.index( this ) );
11109			} else {
11110				throw "jQuery UI Tabs: Mismatching fragment identifier.";
11111			}
11112
11113			// Prevent IE from keeping other link focussed when using the back button
11114			// and remove dotted border from clicked link. This is controlled via CSS
11115			// in modern browsers; blur() removes focus from address bar in Firefox
11116			// which can become a usability and annoying problem with tabs('rotate').
11117			if ( $.browser.msie ) {
11118				this.blur();
11119			}
11120		});
11121
11122		// disable click in any case
11123		this.anchors.bind( "click.tabs", function(){
11124			return false;
11125		});
11126	},
11127
11128    _getIndex: function( index ) {
11129		// meta-function to give users option to provide a href string instead of a numerical index.
11130		// also sanitizes numerical indexes to valid values.
11131		if ( typeof index == "string" ) {
11132			index = this.anchors.index( this.anchors.filter( "[href$='" + index + "']" ) );
11133		}
11134
11135		return index;
11136	},
11137
11138	destroy: function() {
11139		var o = this.options;
11140
11141		this.abort();
11142
11143		this.element
11144			.unbind( ".tabs" )
11145			.removeClass( "ui-tabs ui-widget ui-widget-content ui-corner-all ui-tabs-collapsible" )
11146			.removeData( "tabs" );
11147
11148		this.list.removeClass( "ui-tabs-nav ui-helper-reset ui-helper-clearfix ui-widget-header ui-corner-all" );
11149
11150		this.anchors.each(function() {
11151			var href = $.data( this, "href.tabs" );
11152			if ( href ) {
11153				this.href = href;
11154			}
11155			var $this = $( this ).unbind( ".tabs" );
11156			$.each( [ "href", "load", "cache" ], function( i, prefix ) {
11157				$this.removeData( prefix + ".tabs" );
11158			});
11159		});
11160
11161		this.lis.unbind( ".tabs" ).add( this.panels ).each(function() {
11162			if ( $.data( this, "destroy.tabs" ) ) {
11163				$( this ).remove();
11164			} else {
11165				$( this ).removeClass([
11166					"ui-state-default",
11167					"ui-corner-top",
11168					"ui-tabs-selected",
11169					"ui-state-active",
11170					"ui-state-hover",
11171					"ui-state-focus",
11172					"ui-state-disabled",
11173					"ui-tabs-panel",
11174					"ui-widget-content",
11175					"ui-corner-bottom",
11176					"ui-tabs-hide"
11177				].join( " " ) );
11178			}
11179		});
11180
11181		if ( o.cookie ) {
11182			this._cookie( null, o.cookie );
11183		}
11184
11185		return this;
11186	},
11187
11188	add: function( url, label, index ) {
11189		if ( index === undefined ) {
11190			index = this.anchors.length;
11191		}
11192
11193		var self = this,
11194			o = this.options,
11195			$li = $( o.tabTemplate.replace( /#\{href\}/g, url ).replace( /#\{label\}/g, label ) ),
11196			id = !url.indexOf( "#" ) ? url.replace( "#", "" ) : this._tabId( $( "a", $li )[ 0 ] );
11197
11198		$li.addClass( "ui-state-default ui-corner-top" ).data( "destroy.tabs", true );
11199
11200		// try to find an existing element before creating a new one
11201		var $panel = self.element.find( "#" + id );
11202		if ( !$panel.length ) {
11203			$panel = $( o.panelTemplate )
11204				.attr( "id", id )
11205				.data( "destroy.tabs", true );
11206		}
11207		$panel.addClass( "ui-tabs-panel ui-widget-content ui-corner-bottom ui-tabs-hide" );
11208
11209		if ( index >= this.lis.length ) {
11210			$li.appendTo( this.list );
11211			$panel.appendTo( this.list[ 0 ].parentNode );
11212		} else {
11213			$li.insertBefore( this.lis[ index ] );
11214			$panel.insertBefore( this.panels[ index ] );
11215		}
11216
11217		o.disabled = $.map( o.disabled, function( n, i ) {
11218			return n >= index ? ++n : n;
11219		});
11220
11221		this._tabify();
11222
11223		if ( this.anchors.length == 1 ) {
11224			o.selected = 0;
11225			$li.addClass( "ui-tabs-selected ui-state-active" );
11226			$panel.removeClass( "ui-tabs-hide" );
11227			this.element.queue( "tabs", function() {
11228				self._trigger( "show", null, self._ui( self.anchors[ 0 ], self.panels[ 0 ] ) );
11229			});
11230
11231			this.load( 0 );
11232		}
11233
11234		this._trigger( "add", null, this._ui( this.anchors[ index ], this.panels[ index ] ) );
11235		return this;
11236	},
11237
11238	remove: function( index ) {
11239		index = this._getIndex( index );
11240		var o = this.options,
11241			$li = this.lis.eq( index ).remove(),
11242			$panel = this.panels.eq( index ).remove();
11243
11244		// If selected tab was removed focus tab to the right or
11245		// in case the last tab was removed the tab to the left.
11246		if ( $li.hasClass( "ui-tabs-selected" ) && this.anchors.length > 1) {
11247			this.select( index + ( index + 1 < this.anchors.length ? 1 : -1 ) );
11248		}
11249
11250		o.disabled = $.map(
11251			$.grep( o.disabled, function(n, i) {
11252				return n != index;
11253			}),
11254			function( n, i ) {
11255				return n >= index ? --n : n;
11256			});
11257
11258		this._tabify();
11259
11260		this._trigger( "remove", null, this._ui( $li.find( "a" )[ 0 ], $panel[ 0 ] ) );
11261		return this;
11262	},
11263
11264	enable: function( index ) {
11265		index = this._getIndex( index );
11266		var o = this.options;
11267		if ( $.inArray( index, o.disabled ) == -1 ) {
11268			return;
11269		}
11270
11271		this.lis.eq( index ).removeClass( "ui-state-disabled" );
11272		o.disabled = $.grep( o.disabled, function( n, i ) {
11273			return n != index;
11274		});
11275
11276		this._trigger( "enable", null, this._ui( this.anchors[ index ], this.panels[ index ] ) );
11277		return this;
11278	},
11279
11280	disable: function( index ) {
11281		index = this._getIndex( index );
11282		var self = this, o = this.options;
11283		// cannot disable already selected tab
11284		if ( index != o.selected ) {
11285			this.lis.eq( index ).addClass( "ui-state-disabled" );
11286
11287			o.disabled.push( index );
11288			o.disabled.sort();
11289
11290			this._trigger( "disable", null, this._ui( this.anchors[ index ], this.panels[ index ] ) );
11291		}
11292
11293		return this;
11294	},
11295
11296	select: function( index ) {
11297		index = this._getIndex( index );
11298		if ( index == -1 ) {
11299			if ( this.options.collapsible && this.options.selected != -1 ) {
11300				index = this.options.selected;
11301			} else {
11302				return this;
11303			}
11304		}
11305		this.anchors.eq( index ).trigger( this.options.event + ".tabs" );
11306		return this;
11307	},
11308
11309	load: function( index ) {
11310		index = this._getIndex( index );
11311		var self = this,
11312			o = this.options,
11313			a = this.anchors.eq( index )[ 0 ],
11314			url = $.data( a, "load.tabs" );
11315
11316		this.abort();
11317
11318		// not remote or from cache
11319		if ( !url || this.element.queue( "tabs" ).length !== 0 && $.data( a, "cache.tabs" ) ) {
11320			this.element.dequeue( "tabs" );
11321			return;
11322		}
11323
11324		// load remote from here on
11325		this.lis.eq( index ).addClass( "ui-state-processing" );
11326
11327		if ( o.spinner ) {
11328			var span = $( "span", a );
11329			span.data( "label.tabs", span.html() ).html( o.spinner );
11330		}
11331
11332		this.xhr = $.ajax( $.extend( {}, o.ajaxOptions, {
11333			url: url,
11334			success: function( r, s ) {
11335				self.element.find( self._sanitizeSelector( a.hash ) ).html( r );
11336
11337				// take care of tab labels
11338				self._cleanup();
11339
11340				if ( o.cache ) {
11341					$.data( a, "cache.tabs", true );
11342				}
11343
11344				self._trigger( "load", null, self._ui( self.anchors[ index ], self.panels[ index ] ) );
11345				try {
11346					o.ajaxOptions.success( r, s );
11347				}
11348				catch ( e ) {}
11349			},
11350			error: function( xhr, s, e ) {
11351				// take care of tab labels
11352				self._cleanup();
11353
11354				self._trigger( "load", null, self._ui( self.anchors[ index ], self.panels[ index ] ) );
11355				try {
11356					// Passing index avoid a race condition when this method is
11357					// called after the user has selected another tab.
11358					// Pass the anchor that initiated this request allows
11359					// loadError to manipulate the tab content panel via $(a.hash)
11360					o.ajaxOptions.error( xhr, s, index, a );
11361				}
11362				catch ( e ) {}
11363			}
11364		} ) );
11365
11366		// last, so that load event is fired before show...
11367		self.element.dequeue( "tabs" );
11368
11369		return this;
11370	},
11371
11372	abort: function() {
11373		// stop possibly running animations
11374		this.element.queue( [] );
11375		this.panels.stop( false, true );
11376
11377		// "tabs" queue must not contain more than two elements,
11378		// which are the callbacks for the latest clicked tab...
11379		this.element.queue( "tabs", this.element.queue( "tabs" ).splice( -2, 2 ) );
11380
11381		// terminate pending requests from other tabs
11382		if ( this.xhr ) {
11383			this.xhr.abort();
11384			delete this.xhr;
11385		}
11386
11387		// take care of tab labels
11388		this._cleanup();
11389		return this;
11390	},
11391
11392	url: function( index, url ) {
11393		this.anchors.eq( index ).removeData( "cache.tabs" ).data( "load.tabs", url );
11394		return this;
11395	},
11396
11397	length: function() {
11398		return this.anchors.length;
11399	}
11400});
11401
11402$.extend( $.ui.tabs, {
11403	version: "@VERSION"
11404});
11405
11406/*
11407 * Tabs Extensions
11408 */
11409
11410/*
11411 * Rotate
11412 */
11413$.extend( $.ui.tabs.prototype, {
11414	rotation: null,
11415	rotate: function( ms, continuing ) {
11416		var self = this,
11417			o = this.options;
11418
11419		var rotate = self._rotate || ( self._rotate = function( e ) {
11420			clearTimeout( self.rotation );
11421			self.rotation = setTimeout(function() {
11422				var t = o.selected;
11423				self.select( ++t < self.anchors.length ? t : 0 );
11424			}, ms );
11425			
11426			if ( e ) {
11427				e.stopPropagation();
11428			}
11429		});
11430
11431		var stop = self._unrotate || ( self._unrotate = !continuing
11432			? function(e) {
11433				if (e.clientX) { // in case of a true click
11434					self.rotate(null);
11435				}
11436			}
11437			: function( e ) {
11438				rotate();
11439			});
11440
11441		// start rotation
11442		if ( ms ) {
11443			this.element.bind( "tabsshow", rotate );
11444			this.anchors.bind( o.event + ".tabs", stop );
11445			rotate();
11446		// stop rotation
11447		} else {
11448			clearTimeout( self.rotation );
11449			this.element.unbind( "tabsshow", rotate );
11450			this.anchors.unbind( o.event + ".tabs", stop );
11451			delete this._rotate;
11452			delete this._unrotate;
11453		}
11454
11455		return this;
11456	}
11457});
11458
11459})( 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.