and a note on manual changes in dataTables.bootstrap.css
[myslice.git] / third-party / jquery-ui-1.10.2 / ui / jquery-ui.js
1 /*! jQuery UI - v1.10.2 - 2013-03-14
2 * http://jqueryui.com
3 * Includes: jquery.ui.core.js, jquery.ui.widget.js, jquery.ui.mouse.js, jquery.ui.draggable.js, jquery.ui.droppable.js, jquery.ui.resizable.js, jquery.ui.selectable.js, jquery.ui.sortable.js, jquery.ui.effect.js, jquery.ui.accordion.js, jquery.ui.autocomplete.js, jquery.ui.button.js, jquery.ui.datepicker.js, jquery.ui.dialog.js, jquery.ui.effect-blind.js, jquery.ui.effect-bounce.js, jquery.ui.effect-clip.js, jquery.ui.effect-drop.js, jquery.ui.effect-explode.js, jquery.ui.effect-fade.js, jquery.ui.effect-fold.js, jquery.ui.effect-highlight.js, jquery.ui.effect-pulsate.js, jquery.ui.effect-scale.js, jquery.ui.effect-shake.js, jquery.ui.effect-slide.js, jquery.ui.effect-transfer.js, jquery.ui.menu.js, jquery.ui.position.js, jquery.ui.progressbar.js, jquery.ui.slider.js, jquery.ui.spinner.js, jquery.ui.tabs.js, jquery.ui.tooltip.js
4 * Copyright 2013 jQuery Foundation and other contributors; Licensed MIT */
5 (function( $, undefined ) {
6
7 var uuid = 0,
8         runiqueId = /^ui-id-\d+$/;
9
10 // $.ui might exist from components with no dependencies, e.g., $.ui.position
11 $.ui = $.ui || {};
12
13 $.extend( $.ui, {
14         version: "1.10.2",
15
16         keyCode: {
17                 BACKSPACE: 8,
18                 COMMA: 188,
19                 DELETE: 46,
20                 DOWN: 40,
21                 END: 35,
22                 ENTER: 13,
23                 ESCAPE: 27,
24                 HOME: 36,
25                 LEFT: 37,
26                 NUMPAD_ADD: 107,
27                 NUMPAD_DECIMAL: 110,
28                 NUMPAD_DIVIDE: 111,
29                 NUMPAD_ENTER: 108,
30                 NUMPAD_MULTIPLY: 106,
31                 NUMPAD_SUBTRACT: 109,
32                 PAGE_DOWN: 34,
33                 PAGE_UP: 33,
34                 PERIOD: 190,
35                 RIGHT: 39,
36                 SPACE: 32,
37                 TAB: 9,
38                 UP: 38
39         }
40 });
41
42 // plugins
43 $.fn.extend({
44         focus: (function( orig ) {
45                 return function( delay, fn ) {
46                         return typeof delay === "number" ?
47                                 this.each(function() {
48                                         var elem = this;
49                                         setTimeout(function() {
50                                                 $( elem ).focus();
51                                                 if ( fn ) {
52                                                         fn.call( elem );
53                                                 }
54                                         }, delay );
55                                 }) :
56                                 orig.apply( this, arguments );
57                 };
58         })( $.fn.focus ),
59
60         scrollParent: function() {
61                 var scrollParent;
62                 if (($.ui.ie && (/(static|relative)/).test(this.css("position"))) || (/absolute/).test(this.css("position"))) {
63                         scrollParent = this.parents().filter(function() {
64                                 return (/(relative|absolute|fixed)/).test($.css(this,"position")) && (/(auto|scroll)/).test($.css(this,"overflow")+$.css(this,"overflow-y")+$.css(this,"overflow-x"));
65                         }).eq(0);
66                 } else {
67                         scrollParent = this.parents().filter(function() {
68                                 return (/(auto|scroll)/).test($.css(this,"overflow")+$.css(this,"overflow-y")+$.css(this,"overflow-x"));
69                         }).eq(0);
70                 }
71
72                 return (/fixed/).test(this.css("position")) || !scrollParent.length ? $(document) : scrollParent;
73         },
74
75         zIndex: function( zIndex ) {
76                 if ( zIndex !== undefined ) {
77                         return this.css( "zIndex", zIndex );
78                 }
79
80                 if ( this.length ) {
81                         var elem = $( this[ 0 ] ), position, value;
82                         while ( elem.length && elem[ 0 ] !== document ) {
83                                 // Ignore z-index if position is set to a value where z-index is ignored by the browser
84                                 // This makes behavior of this function consistent across browsers
85                                 // WebKit always returns auto if the element is positioned
86                                 position = elem.css( "position" );
87                                 if ( position === "absolute" || position === "relative" || position === "fixed" ) {
88                                         // IE returns 0 when zIndex is not specified
89                                         // other browsers return a string
90                                         // we ignore the case of nested elements with an explicit value of 0
91                                         // <div style="z-index: -10;"><div style="z-index: 0;"></div></div>
92                                         value = parseInt( elem.css( "zIndex" ), 10 );
93                                         if ( !isNaN( value ) && value !== 0 ) {
94                                                 return value;
95                                         }
96                                 }
97                                 elem = elem.parent();
98                         }
99                 }
100
101                 return 0;
102         },
103
104         uniqueId: function() {
105                 return this.each(function() {
106                         if ( !this.id ) {
107                                 this.id = "ui-id-" + (++uuid);
108                         }
109                 });
110         },
111
112         removeUniqueId: function() {
113                 return this.each(function() {
114                         if ( runiqueId.test( this.id ) ) {
115                                 $( this ).removeAttr( "id" );
116                         }
117                 });
118         }
119 });
120
121 // selectors
122 function focusable( element, isTabIndexNotNaN ) {
123         var map, mapName, img,
124                 nodeName = element.nodeName.toLowerCase();
125         if ( "area" === nodeName ) {
126                 map = element.parentNode;
127                 mapName = map.name;
128                 if ( !element.href || !mapName || map.nodeName.toLowerCase() !== "map" ) {
129                         return false;
130                 }
131                 img = $( "img[usemap=#" + mapName + "]" )[0];
132                 return !!img && visible( img );
133         }
134         return ( /input|select|textarea|button|object/.test( nodeName ) ?
135                 !element.disabled :
136                 "a" === nodeName ?
137                         element.href || isTabIndexNotNaN :
138                         isTabIndexNotNaN) &&
139                 // the element and all of its ancestors must be visible
140                 visible( element );
141 }
142
143 function visible( element ) {
144         return $.expr.filters.visible( element ) &&
145                 !$( element ).parents().addBack().filter(function() {
146                         return $.css( this, "visibility" ) === "hidden";
147                 }).length;
148 }
149
150 $.extend( $.expr[ ":" ], {
151         data: $.expr.createPseudo ?
152                 $.expr.createPseudo(function( dataName ) {
153                         return function( elem ) {
154                                 return !!$.data( elem, dataName );
155                         };
156                 }) :
157                 // support: jQuery <1.8
158                 function( elem, i, match ) {
159                         return !!$.data( elem, match[ 3 ] );
160                 },
161
162         focusable: function( element ) {
163                 return focusable( element, !isNaN( $.attr( element, "tabindex" ) ) );
164         },
165
166         tabbable: function( element ) {
167                 var tabIndex = $.attr( element, "tabindex" ),
168                         isTabIndexNaN = isNaN( tabIndex );
169                 return ( isTabIndexNaN || tabIndex >= 0 ) && focusable( element, !isTabIndexNaN );
170         }
171 });
172
173 // support: jQuery <1.8
174 if ( !$( "<a>" ).outerWidth( 1 ).jquery ) {
175         $.each( [ "Width", "Height" ], function( i, name ) {
176                 var side = name === "Width" ? [ "Left", "Right" ] : [ "Top", "Bottom" ],
177                         type = name.toLowerCase(),
178                         orig = {
179                                 innerWidth: $.fn.innerWidth,
180                                 innerHeight: $.fn.innerHeight,
181                                 outerWidth: $.fn.outerWidth,
182                                 outerHeight: $.fn.outerHeight
183                         };
184
185                 function reduce( elem, size, border, margin ) {
186                         $.each( side, function() {
187                                 size -= parseFloat( $.css( elem, "padding" + this ) ) || 0;
188                                 if ( border ) {
189                                         size -= parseFloat( $.css( elem, "border" + this + "Width" ) ) || 0;
190                                 }
191                                 if ( margin ) {
192                                         size -= parseFloat( $.css( elem, "margin" + this ) ) || 0;
193                                 }
194                         });
195                         return size;
196                 }
197
198                 $.fn[ "inner" + name ] = function( size ) {
199                         if ( size === undefined ) {
200                                 return orig[ "inner" + name ].call( this );
201                         }
202
203                         return this.each(function() {
204                                 $( this ).css( type, reduce( this, size ) + "px" );
205                         });
206                 };
207
208                 $.fn[ "outer" + name] = function( size, margin ) {
209                         if ( typeof size !== "number" ) {
210                                 return orig[ "outer" + name ].call( this, size );
211                         }
212
213                         return this.each(function() {
214                                 $( this).css( type, reduce( this, size, true, margin ) + "px" );
215                         });
216                 };
217         });
218 }
219
220 // support: jQuery <1.8
221 if ( !$.fn.addBack ) {
222         $.fn.addBack = function( selector ) {
223                 return this.add( selector == null ?
224                         this.prevObject : this.prevObject.filter( selector )
225                 );
226         };
227 }
228
229 // support: jQuery 1.6.1, 1.6.2 (http://bugs.jquery.com/ticket/9413)
230 if ( $( "<a>" ).data( "a-b", "a" ).removeData( "a-b" ).data( "a-b" ) ) {
231         $.fn.removeData = (function( removeData ) {
232                 return function( key ) {
233                         if ( arguments.length ) {
234                                 return removeData.call( this, $.camelCase( key ) );
235                         } else {
236                                 return removeData.call( this );
237                         }
238                 };
239         })( $.fn.removeData );
240 }
241
242
243
244
245
246 // deprecated
247 $.ui.ie = !!/msie [\w.]+/.exec( navigator.userAgent.toLowerCase() );
248
249 $.support.selectstart = "onselectstart" in document.createElement( "div" );
250 $.fn.extend({
251         disableSelection: function() {
252                 return this.bind( ( $.support.selectstart ? "selectstart" : "mousedown" ) +
253                         ".ui-disableSelection", function( event ) {
254                                 event.preventDefault();
255                         });
256         },
257
258         enableSelection: function() {
259                 return this.unbind( ".ui-disableSelection" );
260         }
261 });
262
263 $.extend( $.ui, {
264         // $.ui.plugin is deprecated.  Use the proxy pattern instead.
265         plugin: {
266                 add: function( module, option, set ) {
267                         var i,
268                                 proto = $.ui[ module ].prototype;
269                         for ( i in set ) {
270                                 proto.plugins[ i ] = proto.plugins[ i ] || [];
271                                 proto.plugins[ i ].push( [ option, set[ i ] ] );
272                         }
273                 },
274                 call: function( instance, name, args ) {
275                         var i,
276                                 set = instance.plugins[ name ];
277                         if ( !set || !instance.element[ 0 ].parentNode || instance.element[ 0 ].parentNode.nodeType === 11 ) {
278                                 return;
279                         }
280
281                         for ( i = 0; i < set.length; i++ ) {
282                                 if ( instance.options[ set[ i ][ 0 ] ] ) {
283                                         set[ i ][ 1 ].apply( instance.element, args );
284                                 }
285                         }
286                 }
287         },
288
289         // only used by resizable
290         hasScroll: function( el, a ) {
291
292                 //If overflow is hidden, the element might have extra content, but the user wants to hide it
293                 if ( $( el ).css( "overflow" ) === "hidden") {
294                         return false;
295                 }
296
297                 var scroll = ( a && a === "left" ) ? "scrollLeft" : "scrollTop",
298                         has = false;
299
300                 if ( el[ scroll ] > 0 ) {
301                         return true;
302                 }
303
304                 // TODO: determine which cases actually cause this to happen
305                 // if the element doesn't have the scroll set, see if it's possible to
306                 // set the scroll
307                 el[ scroll ] = 1;
308                 has = ( el[ scroll ] > 0 );
309                 el[ scroll ] = 0;
310                 return has;
311         }
312 });
313
314 })( jQuery );
315
316 (function( $, undefined ) {
317
318 var uuid = 0,
319         slice = Array.prototype.slice,
320         _cleanData = $.cleanData;
321 $.cleanData = function( elems ) {
322         for ( var i = 0, elem; (elem = elems[i]) != null; i++ ) {
323                 try {
324                         $( elem ).triggerHandler( "remove" );
325                 // http://bugs.jquery.com/ticket/8235
326                 } catch( e ) {}
327         }
328         _cleanData( elems );
329 };
330
331 $.widget = function( name, base, prototype ) {
332         var fullName, existingConstructor, constructor, basePrototype,
333                 // proxiedPrototype allows the provided prototype to remain unmodified
334                 // so that it can be used as a mixin for multiple widgets (#8876)
335                 proxiedPrototype = {},
336                 namespace = name.split( "." )[ 0 ];
337
338         name = name.split( "." )[ 1 ];
339         fullName = namespace + "-" + name;
340
341         if ( !prototype ) {
342                 prototype = base;
343                 base = $.Widget;
344         }
345
346         // create selector for plugin
347         $.expr[ ":" ][ fullName.toLowerCase() ] = function( elem ) {
348                 return !!$.data( elem, fullName );
349         };
350
351         $[ namespace ] = $[ namespace ] || {};
352         existingConstructor = $[ namespace ][ name ];
353         constructor = $[ namespace ][ name ] = function( options, element ) {
354                 // allow instantiation without "new" keyword
355                 if ( !this._createWidget ) {
356                         return new constructor( options, element );
357                 }
358
359                 // allow instantiation without initializing for simple inheritance
360                 // must use "new" keyword (the code above always passes args)
361                 if ( arguments.length ) {
362                         this._createWidget( options, element );
363                 }
364         };
365         // extend with the existing constructor to carry over any static properties
366         $.extend( constructor, existingConstructor, {
367                 version: prototype.version,
368                 // copy the object used to create the prototype in case we need to
369                 // redefine the widget later
370                 _proto: $.extend( {}, prototype ),
371                 // track widgets that inherit from this widget in case this widget is
372                 // redefined after a widget inherits from it
373                 _childConstructors: []
374         });
375
376         basePrototype = new base();
377         // we need to make the options hash a property directly on the new instance
378         // otherwise we'll modify the options hash on the prototype that we're
379         // inheriting from
380         basePrototype.options = $.widget.extend( {}, basePrototype.options );
381         $.each( prototype, function( prop, value ) {
382                 if ( !$.isFunction( value ) ) {
383                         proxiedPrototype[ prop ] = value;
384                         return;
385                 }
386                 proxiedPrototype[ prop ] = (function() {
387                         var _super = function() {
388                                         return base.prototype[ prop ].apply( this, arguments );
389                                 },
390                                 _superApply = function( args ) {
391                                         return base.prototype[ prop ].apply( this, args );
392                                 };
393                         return function() {
394                                 var __super = this._super,
395                                         __superApply = this._superApply,
396                                         returnValue;
397
398                                 this._super = _super;
399                                 this._superApply = _superApply;
400
401                                 returnValue = value.apply( this, arguments );
402
403                                 this._super = __super;
404                                 this._superApply = __superApply;
405
406                                 return returnValue;
407                         };
408                 })();
409         });
410         constructor.prototype = $.widget.extend( basePrototype, {
411                 // TODO: remove support for widgetEventPrefix
412                 // always use the name + a colon as the prefix, e.g., draggable:start
413                 // don't prefix for widgets that aren't DOM-based
414                 widgetEventPrefix: existingConstructor ? basePrototype.widgetEventPrefix : name
415         }, proxiedPrototype, {
416                 constructor: constructor,
417                 namespace: namespace,
418                 widgetName: name,
419                 widgetFullName: fullName
420         });
421
422         // If this widget is being redefined then we need to find all widgets that
423         // are inheriting from it and redefine all of them so that they inherit from
424         // the new version of this widget. We're essentially trying to replace one
425         // level in the prototype chain.
426         if ( existingConstructor ) {
427                 $.each( existingConstructor._childConstructors, function( i, child ) {
428                         var childPrototype = child.prototype;
429
430                         // redefine the child widget using the same prototype that was
431                         // originally used, but inherit from the new version of the base
432                         $.widget( childPrototype.namespace + "." + childPrototype.widgetName, constructor, child._proto );
433                 });
434                 // remove the list of existing child constructors from the old constructor
435                 // so the old child constructors can be garbage collected
436                 delete existingConstructor._childConstructors;
437         } else {
438                 base._childConstructors.push( constructor );
439         }
440
441         $.widget.bridge( name, constructor );
442 };
443
444 $.widget.extend = function( target ) {
445         var input = slice.call( arguments, 1 ),
446                 inputIndex = 0,
447                 inputLength = input.length,
448                 key,
449                 value;
450         for ( ; inputIndex < inputLength; inputIndex++ ) {
451                 for ( key in input[ inputIndex ] ) {
452                         value = input[ inputIndex ][ key ];
453                         if ( input[ inputIndex ].hasOwnProperty( key ) && value !== undefined ) {
454                                 // Clone objects
455                                 if ( $.isPlainObject( value ) ) {
456                                         target[ key ] = $.isPlainObject( target[ key ] ) ?
457                                                 $.widget.extend( {}, target[ key ], value ) :
458                                                 // Don't extend strings, arrays, etc. with objects
459                                                 $.widget.extend( {}, value );
460                                 // Copy everything else by reference
461                                 } else {
462                                         target[ key ] = value;
463                                 }
464                         }
465                 }
466         }
467         return target;
468 };
469
470 $.widget.bridge = function( name, object ) {
471         var fullName = object.prototype.widgetFullName || name;
472         $.fn[ name ] = function( options ) {
473                 var isMethodCall = typeof options === "string",
474                         args = slice.call( arguments, 1 ),
475                         returnValue = this;
476
477                 // allow multiple hashes to be passed on init
478                 options = !isMethodCall && args.length ?
479                         $.widget.extend.apply( null, [ options ].concat(args) ) :
480                         options;
481
482                 if ( isMethodCall ) {
483                         this.each(function() {
484                                 var methodValue,
485                                         instance = $.data( this, fullName );
486                                 if ( !instance ) {
487                                         return $.error( "cannot call methods on " + name + " prior to initialization; " +
488                                                 "attempted to call method '" + options + "'" );
489                                 }
490                                 if ( !$.isFunction( instance[options] ) || options.charAt( 0 ) === "_" ) {
491                                         return $.error( "no such method '" + options + "' for " + name + " widget instance" );
492                                 }
493                                 methodValue = instance[ options ].apply( instance, args );
494                                 if ( methodValue !== instance && methodValue !== undefined ) {
495                                         returnValue = methodValue && methodValue.jquery ?
496                                                 returnValue.pushStack( methodValue.get() ) :
497                                                 methodValue;
498                                         return false;
499                                 }
500                         });
501                 } else {
502                         this.each(function() {
503                                 var instance = $.data( this, fullName );
504                                 if ( instance ) {
505                                         instance.option( options || {} )._init();
506                                 } else {
507                                         $.data( this, fullName, new object( options, this ) );
508                                 }
509                         });
510                 }
511
512                 return returnValue;
513         };
514 };
515
516 $.Widget = function( /* options, element */ ) {};
517 $.Widget._childConstructors = [];
518
519 $.Widget.prototype = {
520         widgetName: "widget",
521         widgetEventPrefix: "",
522         defaultElement: "<div>",
523         options: {
524                 disabled: false,
525
526                 // callbacks
527                 create: null
528         },
529         _createWidget: function( options, element ) {
530                 element = $( element || this.defaultElement || this )[ 0 ];
531                 this.element = $( element );
532                 this.uuid = uuid++;
533                 this.eventNamespace = "." + this.widgetName + this.uuid;
534                 this.options = $.widget.extend( {},
535                         this.options,
536                         this._getCreateOptions(),
537                         options );
538
539                 this.bindings = $();
540                 this.hoverable = $();
541                 this.focusable = $();
542
543                 if ( element !== this ) {
544                         $.data( element, this.widgetFullName, this );
545                         this._on( true, this.element, {
546                                 remove: function( event ) {
547                                         if ( event.target === element ) {
548                                                 this.destroy();
549                                         }
550                                 }
551                         });
552                         this.document = $( element.style ?
553                                 // element within the document
554                                 element.ownerDocument :
555                                 // element is window or document
556                                 element.document || element );
557                         this.window = $( this.document[0].defaultView || this.document[0].parentWindow );
558                 }
559
560                 this._create();
561                 this._trigger( "create", null, this._getCreateEventData() );
562                 this._init();
563         },
564         _getCreateOptions: $.noop,
565         _getCreateEventData: $.noop,
566         _create: $.noop,
567         _init: $.noop,
568
569         destroy: function() {
570                 this._destroy();
571                 // we can probably remove the unbind calls in 2.0
572                 // all event bindings should go through this._on()
573                 this.element
574                         .unbind( this.eventNamespace )
575                         // 1.9 BC for #7810
576                         // TODO remove dual storage
577                         .removeData( this.widgetName )
578                         .removeData( this.widgetFullName )
579                         // support: jquery <1.6.3
580                         // http://bugs.jquery.com/ticket/9413
581                         .removeData( $.camelCase( this.widgetFullName ) );
582                 this.widget()
583                         .unbind( this.eventNamespace )
584                         .removeAttr( "aria-disabled" )
585                         .removeClass(
586                                 this.widgetFullName + "-disabled " +
587                                 "ui-state-disabled" );
588
589                 // clean up events and states
590                 this.bindings.unbind( this.eventNamespace );
591                 this.hoverable.removeClass( "ui-state-hover" );
592                 this.focusable.removeClass( "ui-state-focus" );
593         },
594         _destroy: $.noop,
595
596         widget: function() {
597                 return this.element;
598         },
599
600         option: function( key, value ) {
601                 var options = key,
602                         parts,
603                         curOption,
604                         i;
605
606                 if ( arguments.length === 0 ) {
607                         // don't return a reference to the internal hash
608                         return $.widget.extend( {}, this.options );
609                 }
610
611                 if ( typeof key === "string" ) {
612                         // handle nested keys, e.g., "foo.bar" => { foo: { bar: ___ } }
613                         options = {};
614                         parts = key.split( "." );
615                         key = parts.shift();
616                         if ( parts.length ) {
617                                 curOption = options[ key ] = $.widget.extend( {}, this.options[ key ] );
618                                 for ( i = 0; i < parts.length - 1; i++ ) {
619                                         curOption[ parts[ i ] ] = curOption[ parts[ i ] ] || {};
620                                         curOption = curOption[ parts[ i ] ];
621                                 }
622                                 key = parts.pop();
623                                 if ( value === undefined ) {
624                                         return curOption[ key ] === undefined ? null : curOption[ key ];
625                                 }
626                                 curOption[ key ] = value;
627                         } else {
628                                 if ( value === undefined ) {
629                                         return this.options[ key ] === undefined ? null : this.options[ key ];
630                                 }
631                                 options[ key ] = value;
632                         }
633                 }
634
635                 this._setOptions( options );
636
637                 return this;
638         },
639         _setOptions: function( options ) {
640                 var key;
641
642                 for ( key in options ) {
643                         this._setOption( key, options[ key ] );
644                 }
645
646                 return this;
647         },
648         _setOption: function( key, value ) {
649                 this.options[ key ] = value;
650
651                 if ( key === "disabled" ) {
652                         this.widget()
653                                 .toggleClass( this.widgetFullName + "-disabled ui-state-disabled", !!value )
654                                 .attr( "aria-disabled", value );
655                         this.hoverable.removeClass( "ui-state-hover" );
656                         this.focusable.removeClass( "ui-state-focus" );
657                 }
658
659                 return this;
660         },
661
662         enable: function() {
663                 return this._setOption( "disabled", false );
664         },
665         disable: function() {
666                 return this._setOption( "disabled", true );
667         },
668
669         _on: function( suppressDisabledCheck, element, handlers ) {
670                 var delegateElement,
671                         instance = this;
672
673                 // no suppressDisabledCheck flag, shuffle arguments
674                 if ( typeof suppressDisabledCheck !== "boolean" ) {
675                         handlers = element;
676                         element = suppressDisabledCheck;
677                         suppressDisabledCheck = false;
678                 }
679
680                 // no element argument, shuffle and use this.element
681                 if ( !handlers ) {
682                         handlers = element;
683                         element = this.element;
684                         delegateElement = this.widget();
685                 } else {
686                         // accept selectors, DOM elements
687                         element = delegateElement = $( element );
688                         this.bindings = this.bindings.add( element );
689                 }
690
691                 $.each( handlers, function( event, handler ) {
692                         function handlerProxy() {
693                                 // allow widgets to customize the disabled handling
694                                 // - disabled as an array instead of boolean
695                                 // - disabled class as method for disabling individual parts
696                                 if ( !suppressDisabledCheck &&
697                                                 ( instance.options.disabled === true ||
698                                                         $( this ).hasClass( "ui-state-disabled" ) ) ) {
699                                         return;
700                                 }
701                                 return ( typeof handler === "string" ? instance[ handler ] : handler )
702                                         .apply( instance, arguments );
703                         }
704
705                         // copy the guid so direct unbinding works
706                         if ( typeof handler !== "string" ) {
707                                 handlerProxy.guid = handler.guid =
708                                         handler.guid || handlerProxy.guid || $.guid++;
709                         }
710
711                         var match = event.match( /^(\w+)\s*(.*)$/ ),
712                                 eventName = match[1] + instance.eventNamespace,
713                                 selector = match[2];
714                         if ( selector ) {
715                                 delegateElement.delegate( selector, eventName, handlerProxy );
716                         } else {
717                                 element.bind( eventName, handlerProxy );
718                         }
719                 });
720         },
721
722         _off: function( element, eventName ) {
723                 eventName = (eventName || "").split( " " ).join( this.eventNamespace + " " ) + this.eventNamespace;
724                 element.unbind( eventName ).undelegate( eventName );
725         },
726
727         _delay: function( handler, delay ) {
728                 function handlerProxy() {
729                         return ( typeof handler === "string" ? instance[ handler ] : handler )
730                                 .apply( instance, arguments );
731                 }
732                 var instance = this;
733                 return setTimeout( handlerProxy, delay || 0 );
734         },
735
736         _hoverable: function( element ) {
737                 this.hoverable = this.hoverable.add( element );
738                 this._on( element, {
739                         mouseenter: function( event ) {
740                                 $( event.currentTarget ).addClass( "ui-state-hover" );
741                         },
742                         mouseleave: function( event ) {
743                                 $( event.currentTarget ).removeClass( "ui-state-hover" );
744                         }
745                 });
746         },
747
748         _focusable: function( element ) {
749                 this.focusable = this.focusable.add( element );
750                 this._on( element, {
751                         focusin: function( event ) {
752                                 $( event.currentTarget ).addClass( "ui-state-focus" );
753                         },
754                         focusout: function( event ) {
755                                 $( event.currentTarget ).removeClass( "ui-state-focus" );
756                         }
757                 });
758         },
759
760         _trigger: function( type, event, data ) {
761                 var prop, orig,
762                         callback = this.options[ type ];
763
764                 data = data || {};
765                 event = $.Event( event );
766                 event.type = ( type === this.widgetEventPrefix ?
767                         type :
768                         this.widgetEventPrefix + type ).toLowerCase();
769                 // the original event may come from any element
770                 // so we need to reset the target on the new event
771                 event.target = this.element[ 0 ];
772
773                 // copy original event properties over to the new event
774                 orig = event.originalEvent;
775                 if ( orig ) {
776                         for ( prop in orig ) {
777                                 if ( !( prop in event ) ) {
778                                         event[ prop ] = orig[ prop ];
779                                 }
780                         }
781                 }
782
783                 this.element.trigger( event, data );
784                 return !( $.isFunction( callback ) &&
785                         callback.apply( this.element[0], [ event ].concat( data ) ) === false ||
786                         event.isDefaultPrevented() );
787         }
788 };
789
790 $.each( { show: "fadeIn", hide: "fadeOut" }, function( method, defaultEffect ) {
791         $.Widget.prototype[ "_" + method ] = function( element, options, callback ) {
792                 if ( typeof options === "string" ) {
793                         options = { effect: options };
794                 }
795                 var hasOptions,
796                         effectName = !options ?
797                                 method :
798                                 options === true || typeof options === "number" ?
799                                         defaultEffect :
800                                         options.effect || defaultEffect;
801                 options = options || {};
802                 if ( typeof options === "number" ) {
803                         options = { duration: options };
804                 }
805                 hasOptions = !$.isEmptyObject( options );
806                 options.complete = callback;
807                 if ( options.delay ) {
808                         element.delay( options.delay );
809                 }
810                 if ( hasOptions && $.effects && $.effects.effect[ effectName ] ) {
811                         element[ method ]( options );
812                 } else if ( effectName !== method && element[ effectName ] ) {
813                         element[ effectName ]( options.duration, options.easing, callback );
814                 } else {
815                         element.queue(function( next ) {
816                                 $( this )[ method ]();
817                                 if ( callback ) {
818                                         callback.call( element[ 0 ] );
819                                 }
820                                 next();
821                         });
822                 }
823         };
824 });
825
826 })( jQuery );
827
828 (function( $, undefined ) {
829
830 var mouseHandled = false;
831 $( document ).mouseup( function() {
832         mouseHandled = false;
833 });
834
835 $.widget("ui.mouse", {
836         version: "1.10.2",
837         options: {
838                 cancel: "input,textarea,button,select,option",
839                 distance: 1,
840                 delay: 0
841         },
842         _mouseInit: function() {
843                 var that = this;
844
845                 this.element
846                         .bind("mousedown."+this.widgetName, function(event) {
847                                 return that._mouseDown(event);
848                         })
849                         .bind("click."+this.widgetName, function(event) {
850                                 if (true === $.data(event.target, that.widgetName + ".preventClickEvent")) {
851                                         $.removeData(event.target, that.widgetName + ".preventClickEvent");
852                                         event.stopImmediatePropagation();
853                                         return false;
854                                 }
855                         });
856
857                 this.started = false;
858         },
859
860         // TODO: make sure destroying one instance of mouse doesn't mess with
861         // other instances of mouse
862         _mouseDestroy: function() {
863                 this.element.unbind("."+this.widgetName);
864                 if ( this._mouseMoveDelegate ) {
865                         $(document)
866                                 .unbind("mousemove."+this.widgetName, this._mouseMoveDelegate)
867                                 .unbind("mouseup."+this.widgetName, this._mouseUpDelegate);
868                 }
869         },
870
871         _mouseDown: function(event) {
872                 // don't let more than one widget handle mouseStart
873                 if( mouseHandled ) { return; }
874
875                 // we may have missed mouseup (out of window)
876                 (this._mouseStarted && this._mouseUp(event));
877
878                 this._mouseDownEvent = event;
879
880                 var that = this,
881                         btnIsLeft = (event.which === 1),
882                         // event.target.nodeName works around a bug in IE 8 with
883                         // disabled inputs (#7620)
884                         elIsCancel = (typeof this.options.cancel === "string" && event.target.nodeName ? $(event.target).closest(this.options.cancel).length : false);
885                 if (!btnIsLeft || elIsCancel || !this._mouseCapture(event)) {
886                         return true;
887                 }
888
889                 this.mouseDelayMet = !this.options.delay;
890                 if (!this.mouseDelayMet) {
891                         this._mouseDelayTimer = setTimeout(function() {
892                                 that.mouseDelayMet = true;
893                         }, this.options.delay);
894                 }
895
896                 if (this._mouseDistanceMet(event) && this._mouseDelayMet(event)) {
897                         this._mouseStarted = (this._mouseStart(event) !== false);
898                         if (!this._mouseStarted) {
899                                 event.preventDefault();
900                                 return true;
901                         }
902                 }
903
904                 // Click event may never have fired (Gecko & Opera)
905                 if (true === $.data(event.target, this.widgetName + ".preventClickEvent")) {
906                         $.removeData(event.target, this.widgetName + ".preventClickEvent");
907                 }
908
909                 // these delegates are required to keep context
910                 this._mouseMoveDelegate = function(event) {
911                         return that._mouseMove(event);
912                 };
913                 this._mouseUpDelegate = function(event) {
914                         return that._mouseUp(event);
915                 };
916                 $(document)
917                         .bind("mousemove."+this.widgetName, this._mouseMoveDelegate)
918                         .bind("mouseup."+this.widgetName, this._mouseUpDelegate);
919
920                 event.preventDefault();
921
922                 mouseHandled = true;
923                 return true;
924         },
925
926         _mouseMove: function(event) {
927                 // IE mouseup check - mouseup happened when mouse was out of window
928                 if ($.ui.ie && ( !document.documentMode || document.documentMode < 9 ) && !event.button) {
929                         return this._mouseUp(event);
930                 }
931
932                 if (this._mouseStarted) {
933                         this._mouseDrag(event);
934                         return event.preventDefault();
935                 }
936
937                 if (this._mouseDistanceMet(event) && this._mouseDelayMet(event)) {
938                         this._mouseStarted =
939                                 (this._mouseStart(this._mouseDownEvent, event) !== false);
940                         (this._mouseStarted ? this._mouseDrag(event) : this._mouseUp(event));
941                 }
942
943                 return !this._mouseStarted;
944         },
945
946         _mouseUp: function(event) {
947                 $(document)
948                         .unbind("mousemove."+this.widgetName, this._mouseMoveDelegate)
949                         .unbind("mouseup."+this.widgetName, this._mouseUpDelegate);
950
951                 if (this._mouseStarted) {
952                         this._mouseStarted = false;
953
954                         if (event.target === this._mouseDownEvent.target) {
955                                 $.data(event.target, this.widgetName + ".preventClickEvent", true);
956                         }
957
958                         this._mouseStop(event);
959                 }
960
961                 return false;
962         },
963
964         _mouseDistanceMet: function(event) {
965                 return (Math.max(
966                                 Math.abs(this._mouseDownEvent.pageX - event.pageX),
967                                 Math.abs(this._mouseDownEvent.pageY - event.pageY)
968                         ) >= this.options.distance
969                 );
970         },
971
972         _mouseDelayMet: function(/* event */) {
973                 return this.mouseDelayMet;
974         },
975
976         // These are placeholder methods, to be overriden by extending plugin
977         _mouseStart: function(/* event */) {},
978         _mouseDrag: function(/* event */) {},
979         _mouseStop: function(/* event */) {},
980         _mouseCapture: function(/* event */) { return true; }
981 });
982
983 })(jQuery);
984
985 (function( $, undefined ) {
986
987 $.widget("ui.draggable", $.ui.mouse, {
988         version: "1.10.2",
989         widgetEventPrefix: "drag",
990         options: {
991                 addClasses: true,
992                 appendTo: "parent",
993                 axis: false,
994                 connectToSortable: false,
995                 containment: false,
996                 cursor: "auto",
997                 cursorAt: false,
998                 grid: false,
999                 handle: false,
1000                 helper: "original",
1001                 iframeFix: false,
1002                 opacity: false,
1003                 refreshPositions: false,
1004                 revert: false,
1005                 revertDuration: 500,
1006                 scope: "default",
1007                 scroll: true,
1008                 scrollSensitivity: 20,
1009                 scrollSpeed: 20,
1010                 snap: false,
1011                 snapMode: "both",
1012                 snapTolerance: 20,
1013                 stack: false,
1014                 zIndex: false,
1015
1016                 // callbacks
1017                 drag: null,
1018                 start: null,
1019                 stop: null
1020         },
1021         _create: function() {
1022
1023                 if (this.options.helper === "original" && !(/^(?:r|a|f)/).test(this.element.css("position"))) {
1024                         this.element[0].style.position = "relative";
1025                 }
1026                 if (this.options.addClasses){
1027                         this.element.addClass("ui-draggable");
1028                 }
1029                 if (this.options.disabled){
1030                         this.element.addClass("ui-draggable-disabled");
1031                 }
1032
1033                 this._mouseInit();
1034
1035         },
1036
1037         _destroy: function() {
1038                 this.element.removeClass( "ui-draggable ui-draggable-dragging ui-draggable-disabled" );
1039                 this._mouseDestroy();
1040         },
1041
1042         _mouseCapture: function(event) {
1043
1044                 var o = this.options;
1045
1046                 // among others, prevent a drag on a resizable-handle
1047                 if (this.helper || o.disabled || $(event.target).closest(".ui-resizable-handle").length > 0) {
1048                         return false;
1049                 }
1050
1051                 //Quit if we're not on a valid handle
1052                 this.handle = this._getHandle(event);
1053                 if (!this.handle) {
1054                         return false;
1055                 }
1056
1057                 $(o.iframeFix === true ? "iframe" : o.iframeFix).each(function() {
1058                         $("<div class='ui-draggable-iframeFix' style='background: #fff;'></div>")
1059                         .css({
1060                                 width: this.offsetWidth+"px", height: this.offsetHeight+"px",
1061                                 position: "absolute", opacity: "0.001", zIndex: 1000
1062                         })
1063                         .css($(this).offset())
1064                         .appendTo("body");
1065                 });
1066
1067                 return true;
1068
1069         },
1070
1071         _mouseStart: function(event) {
1072
1073                 var o = this.options;
1074
1075                 //Create and append the visible helper
1076                 this.helper = this._createHelper(event);
1077
1078                 this.helper.addClass("ui-draggable-dragging");
1079
1080                 //Cache the helper size
1081                 this._cacheHelperProportions();
1082
1083                 //If ddmanager is used for droppables, set the global draggable
1084                 if($.ui.ddmanager) {
1085                         $.ui.ddmanager.current = this;
1086                 }
1087
1088                 /*
1089                  * - Position generation -
1090                  * This block generates everything position related - it's the core of draggables.
1091                  */
1092
1093                 //Cache the margins of the original element
1094                 this._cacheMargins();
1095
1096                 //Store the helper's css position
1097                 this.cssPosition = this.helper.css("position");
1098                 this.scrollParent = this.helper.scrollParent();
1099
1100                 //The element's absolute position on the page minus margins
1101                 this.offset = this.positionAbs = this.element.offset();
1102                 this.offset = {
1103                         top: this.offset.top - this.margins.top,
1104                         left: this.offset.left - this.margins.left
1105                 };
1106
1107                 $.extend(this.offset, {
1108                         click: { //Where the click happened, relative to the element
1109                                 left: event.pageX - this.offset.left,
1110                                 top: event.pageY - this.offset.top
1111                         },
1112                         parent: this._getParentOffset(),
1113                         relative: this._getRelativeOffset() //This is a relative to absolute position minus the actual position calculation - only used for relative positioned helper
1114                 });
1115
1116                 //Generate the original position
1117                 this.originalPosition = this.position = this._generatePosition(event);
1118                 this.originalPageX = event.pageX;
1119                 this.originalPageY = event.pageY;
1120
1121                 //Adjust the mouse offset relative to the helper if "cursorAt" is supplied
1122                 (o.cursorAt && this._adjustOffsetFromHelper(o.cursorAt));
1123
1124                 //Set a containment if given in the options
1125                 if(o.containment) {
1126                         this._setContainment();
1127                 }
1128
1129                 //Trigger event + callbacks
1130                 if(this._trigger("start", event) === false) {
1131                         this._clear();
1132                         return false;
1133                 }
1134
1135                 //Recache the helper size
1136                 this._cacheHelperProportions();
1137
1138                 //Prepare the droppable offsets
1139                 if ($.ui.ddmanager && !o.dropBehaviour) {
1140                         $.ui.ddmanager.prepareOffsets(this, event);
1141                 }
1142
1143
1144                 this._mouseDrag(event, true); //Execute the drag once - this causes the helper not to be visible before getting its correct position
1145
1146                 //If the ddmanager is used for droppables, inform the manager that dragging has started (see #5003)
1147                 if ( $.ui.ddmanager ) {
1148                         $.ui.ddmanager.dragStart(this, event);
1149                 }
1150
1151                 return true;
1152         },
1153
1154         _mouseDrag: function(event, noPropagation) {
1155
1156                 //Compute the helpers position
1157                 this.position = this._generatePosition(event);
1158                 this.positionAbs = this._convertPositionTo("absolute");
1159
1160                 //Call plugins and callbacks and use the resulting position if something is returned
1161                 if (!noPropagation) {
1162                         var ui = this._uiHash();
1163                         if(this._trigger("drag", event, ui) === false) {
1164                                 this._mouseUp({});
1165                                 return false;
1166                         }
1167                         this.position = ui.position;
1168                 }
1169
1170                 if(!this.options.axis || this.options.axis !== "y") {
1171                         this.helper[0].style.left = this.position.left+"px";
1172                 }
1173                 if(!this.options.axis || this.options.axis !== "x") {
1174                         this.helper[0].style.top = this.position.top+"px";
1175                 }
1176                 if($.ui.ddmanager) {
1177                         $.ui.ddmanager.drag(this, event);
1178                 }
1179
1180                 return false;
1181         },
1182
1183         _mouseStop: function(event) {
1184
1185                 //If we are using droppables, inform the manager about the drop
1186                 var element,
1187                         that = this,
1188                         elementInDom = false,
1189                         dropped = false;
1190                 if ($.ui.ddmanager && !this.options.dropBehaviour) {
1191                         dropped = $.ui.ddmanager.drop(this, event);
1192                 }
1193
1194                 //if a drop comes from outside (a sortable)
1195                 if(this.dropped) {
1196                         dropped = this.dropped;
1197                         this.dropped = false;
1198                 }
1199
1200                 //if the original element is no longer in the DOM don't bother to continue (see #8269)
1201                 element = this.element[0];
1202                 while ( element && (element = element.parentNode) ) {
1203                         if (element === document ) {
1204                                 elementInDom = true;
1205                         }
1206                 }
1207                 if ( !elementInDom && this.options.helper === "original" ) {
1208                         return false;
1209                 }
1210
1211                 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))) {
1212                         $(this.helper).animate(this.originalPosition, parseInt(this.options.revertDuration, 10), function() {
1213                                 if(that._trigger("stop", event) !== false) {
1214                                         that._clear();
1215                                 }
1216                         });
1217                 } else {
1218                         if(this._trigger("stop", event) !== false) {
1219                                 this._clear();
1220                         }
1221                 }
1222
1223                 return false;
1224         },
1225
1226         _mouseUp: function(event) {
1227                 //Remove frame helpers
1228                 $("div.ui-draggable-iframeFix").each(function() {
1229                         this.parentNode.removeChild(this);
1230                 });
1231
1232                 //If the ddmanager is used for droppables, inform the manager that dragging has stopped (see #5003)
1233                 if( $.ui.ddmanager ) {
1234                         $.ui.ddmanager.dragStop(this, event);
1235                 }
1236
1237                 return $.ui.mouse.prototype._mouseUp.call(this, event);
1238         },
1239
1240         cancel: function() {
1241
1242                 if(this.helper.is(".ui-draggable-dragging")) {
1243                         this._mouseUp({});
1244                 } else {
1245                         this._clear();
1246                 }
1247
1248                 return this;
1249
1250         },
1251
1252         _getHandle: function(event) {
1253                 return this.options.handle ?
1254                         !!$( event.target ).closest( this.element.find( this.options.handle ) ).length :
1255                         true;
1256         },
1257
1258         _createHelper: function(event) {
1259
1260                 var o = this.options,
1261                         helper = $.isFunction(o.helper) ? $(o.helper.apply(this.element[0], [event])) : (o.helper === "clone" ? this.element.clone().removeAttr("id") : this.element);
1262
1263                 if(!helper.parents("body").length) {
1264                         helper.appendTo((o.appendTo === "parent" ? this.element[0].parentNode : o.appendTo));
1265                 }
1266
1267                 if(helper[0] !== this.element[0] && !(/(fixed|absolute)/).test(helper.css("position"))) {
1268                         helper.css("position", "absolute");
1269                 }
1270
1271                 return helper;
1272
1273         },
1274
1275         _adjustOffsetFromHelper: function(obj) {
1276                 if (typeof obj === "string") {
1277                         obj = obj.split(" ");
1278                 }
1279                 if ($.isArray(obj)) {
1280                         obj = {left: +obj[0], top: +obj[1] || 0};
1281                 }
1282                 if ("left" in obj) {
1283                         this.offset.click.left = obj.left + this.margins.left;
1284                 }
1285                 if ("right" in obj) {
1286                         this.offset.click.left = this.helperProportions.width - obj.right + this.margins.left;
1287                 }
1288                 if ("top" in obj) {
1289                         this.offset.click.top = obj.top + this.margins.top;
1290                 }
1291                 if ("bottom" in obj) {
1292                         this.offset.click.top = this.helperProportions.height - obj.bottom + this.margins.top;
1293                 }
1294         },
1295
1296         _getParentOffset: function() {
1297
1298                 //Get the offsetParent and cache its position
1299                 this.offsetParent = this.helper.offsetParent();
1300                 var po = this.offsetParent.offset();
1301
1302                 // This is a special case where we need to modify a offset calculated on start, since the following happened:
1303                 // 1. The position of the helper is absolute, so it's position is calculated based on the next positioned parent
1304                 // 2. The actual offset parent is a child of the scroll parent, and the scroll parent isn't the document, which means that
1305                 //    the scroll is included in the initial calculation of the offset of the parent, and never recalculated upon drag
1306                 if(this.cssPosition === "absolute" && this.scrollParent[0] !== document && $.contains(this.scrollParent[0], this.offsetParent[0])) {
1307                         po.left += this.scrollParent.scrollLeft();
1308                         po.top += this.scrollParent.scrollTop();
1309                 }
1310
1311                 //This needs to be actually done for all browsers, since pageX/pageY includes this information
1312                 //Ugly IE fix
1313                 if((this.offsetParent[0] === document.body) ||
1314                         (this.offsetParent[0].tagName && this.offsetParent[0].tagName.toLowerCase() === "html" && $.ui.ie)) {
1315                         po = { top: 0, left: 0 };
1316                 }
1317
1318                 return {
1319                         top: po.top + (parseInt(this.offsetParent.css("borderTopWidth"),10) || 0),
1320                         left: po.left + (parseInt(this.offsetParent.css("borderLeftWidth"),10) || 0)
1321                 };
1322
1323         },
1324
1325         _getRelativeOffset: function() {
1326
1327                 if(this.cssPosition === "relative") {
1328                         var p = this.element.position();
1329                         return {
1330                                 top: p.top - (parseInt(this.helper.css("top"),10) || 0) + this.scrollParent.scrollTop(),
1331                                 left: p.left - (parseInt(this.helper.css("left"),10) || 0) + this.scrollParent.scrollLeft()
1332                         };
1333                 } else {
1334                         return { top: 0, left: 0 };
1335                 }
1336
1337         },
1338
1339         _cacheMargins: function() {
1340                 this.margins = {
1341                         left: (parseInt(this.element.css("marginLeft"),10) || 0),
1342                         top: (parseInt(this.element.css("marginTop"),10) || 0),
1343                         right: (parseInt(this.element.css("marginRight"),10) || 0),
1344                         bottom: (parseInt(this.element.css("marginBottom"),10) || 0)
1345                 };
1346         },
1347
1348         _cacheHelperProportions: function() {
1349                 this.helperProportions = {
1350                         width: this.helper.outerWidth(),
1351                         height: this.helper.outerHeight()
1352                 };
1353         },
1354
1355         _setContainment: function() {
1356
1357                 var over, c, ce,
1358                         o = this.options;
1359
1360                 if(o.containment === "parent") {
1361                         o.containment = this.helper[0].parentNode;
1362                 }
1363                 if(o.containment === "document" || o.containment === "window") {
1364                         this.containment = [
1365                                 o.containment === "document" ? 0 : $(window).scrollLeft() - this.offset.relative.left - this.offset.parent.left,
1366                                 o.containment === "document" ? 0 : $(window).scrollTop() - this.offset.relative.top - this.offset.parent.top,
1367                                 (o.containment === "document" ? 0 : $(window).scrollLeft()) + $(o.containment === "document" ? document : window).width() - this.helperProportions.width - this.margins.left,
1368                                 (o.containment === "document" ? 0 : $(window).scrollTop()) + ($(o.containment === "document" ? document : window).height() || document.body.parentNode.scrollHeight) - this.helperProportions.height - this.margins.top
1369                         ];
1370                 }
1371
1372                 if(!(/^(document|window|parent)$/).test(o.containment) && o.containment.constructor !== Array) {
1373                         c = $(o.containment);
1374                         ce = c[0];
1375
1376                         if(!ce) {
1377                                 return;
1378                         }
1379
1380                         over = ($(ce).css("overflow") !== "hidden");
1381
1382                         this.containment = [
1383                                 (parseInt($(ce).css("borderLeftWidth"),10) || 0) + (parseInt($(ce).css("paddingLeft"),10) || 0),
1384                                 (parseInt($(ce).css("borderTopWidth"),10) || 0) + (parseInt($(ce).css("paddingTop"),10) || 0),
1385                                 (over ? Math.max(ce.scrollWidth,ce.offsetWidth) : ce.offsetWidth) - (parseInt($(ce).css("borderRightWidth"),10) || 0) - (parseInt($(ce).css("paddingRight"),10) || 0) - this.helperProportions.width - this.margins.left - this.margins.right,
1386                                 (over ? Math.max(ce.scrollHeight,ce.offsetHeight) : ce.offsetHeight) - (parseInt($(ce).css("borderBottomWidth"),10) || 0) - (parseInt($(ce).css("paddingBottom"),10) || 0) - this.helperProportions.height - this.margins.top  - this.margins.bottom
1387                         ];
1388                         this.relative_container = c;
1389
1390                 } else if(o.containment.constructor === Array) {
1391                         this.containment = o.containment;
1392                 }
1393
1394         },
1395
1396         _convertPositionTo: function(d, pos) {
1397
1398                 if(!pos) {
1399                         pos = this.position;
1400                 }
1401
1402                 var mod = d === "absolute" ? 1 : -1,
1403                         scroll = this.cssPosition === "absolute" && !(this.scrollParent[0] !== document && $.contains(this.scrollParent[0], this.offsetParent[0])) ? this.offsetParent : this.scrollParent, scrollIsRootNode = (/(html|body)/i).test(scroll[0].tagName);
1404
1405                 return {
1406                         top: (
1407                                 pos.top +                                                                                                                               // The absolute mouse position
1408                                 this.offset.relative.top * mod +                                                                                // Only for relative positioned nodes: Relative offset from element to offset parent
1409                                 this.offset.parent.top * mod -                                                                          // The offsetParent's offset without borders (offset + border)
1410                                 ( ( this.cssPosition === "fixed" ? -this.scrollParent.scrollTop() : ( scrollIsRootNode ? 0 : scroll.scrollTop() ) ) * mod)
1411                         ),
1412                         left: (
1413                                 pos.left +                                                                                                                              // The absolute mouse position
1414                                 this.offset.relative.left * mod +                                                                               // Only for relative positioned nodes: Relative offset from element to offset parent
1415                                 this.offset.parent.left * mod   -                                                                               // The offsetParent's offset without borders (offset + border)
1416                                 ( ( this.cssPosition === "fixed" ? -this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 : scroll.scrollLeft() ) * mod)
1417                         )
1418                 };
1419
1420         },
1421
1422         _generatePosition: function(event) {
1423
1424                 var containment, co, top, left,
1425                         o = this.options,
1426                         scroll = this.cssPosition === "absolute" && !(this.scrollParent[0] !== document && $.contains(this.scrollParent[0], this.offsetParent[0])) ? this.offsetParent : this.scrollParent,
1427                         scrollIsRootNode = (/(html|body)/i).test(scroll[0].tagName),
1428                         pageX = event.pageX,
1429                         pageY = event.pageY;
1430
1431                 /*
1432                  * - Position constraining -
1433                  * Constrain the position to a mix of grid, containment.
1434                  */
1435
1436                 if(this.originalPosition) { //If we are not dragging yet, we won't check for options
1437                         if(this.containment) {
1438                         if (this.relative_container){
1439                                 co = this.relative_container.offset();
1440                                 containment = [ this.containment[0] + co.left,
1441                                         this.containment[1] + co.top,
1442                                         this.containment[2] + co.left,
1443                                         this.containment[3] + co.top ];
1444                         }
1445                         else {
1446                                 containment = this.containment;
1447                         }
1448
1449                                 if(event.pageX - this.offset.click.left < containment[0]) {
1450                                         pageX = containment[0] + this.offset.click.left;
1451                                 }
1452                                 if(event.pageY - this.offset.click.top < containment[1]) {
1453                                         pageY = containment[1] + this.offset.click.top;
1454                                 }
1455                                 if(event.pageX - this.offset.click.left > containment[2]) {
1456                                         pageX = containment[2] + this.offset.click.left;
1457                                 }
1458                                 if(event.pageY - this.offset.click.top > containment[3]) {
1459                                         pageY = containment[3] + this.offset.click.top;
1460                                 }
1461                         }
1462
1463                         if(o.grid) {
1464                                 //Check for grid elements set to 0 to prevent divide by 0 error causing invalid argument errors in IE (see ticket #6950)
1465                                 top = o.grid[1] ? this.originalPageY + Math.round((pageY - this.originalPageY) / o.grid[1]) * o.grid[1] : this.originalPageY;
1466                                 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;
1467
1468                                 left = o.grid[0] ? this.originalPageX + Math.round((pageX - this.originalPageX) / o.grid[0]) * o.grid[0] : this.originalPageX;
1469                                 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;
1470                         }
1471
1472                 }
1473
1474                 return {
1475                         top: (
1476                                 pageY -                                                                                                                                 // The absolute mouse position
1477                                 this.offset.click.top   -                                                                                               // Click offset (relative to the element)
1478                                 this.offset.relative.top -                                                                                              // Only for relative positioned nodes: Relative offset from element to offset parent
1479                                 this.offset.parent.top +                                                                                                // The offsetParent's offset without borders (offset + border)
1480                                 ( ( this.cssPosition === "fixed" ? -this.scrollParent.scrollTop() : ( scrollIsRootNode ? 0 : scroll.scrollTop() ) ))
1481                         ),
1482                         left: (
1483                                 pageX -                                                                                                                                 // The absolute mouse position
1484                                 this.offset.click.left -                                                                                                // Click offset (relative to the element)
1485                                 this.offset.relative.left -                                                                                             // Only for relative positioned nodes: Relative offset from element to offset parent
1486                                 this.offset.parent.left +                                                                                               // The offsetParent's offset without borders (offset + border)
1487                                 ( ( this.cssPosition === "fixed" ? -this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 : scroll.scrollLeft() ))
1488                         )
1489                 };
1490
1491         },
1492
1493         _clear: function() {
1494                 this.helper.removeClass("ui-draggable-dragging");
1495                 if(this.helper[0] !== this.element[0] && !this.cancelHelperRemoval) {
1496                         this.helper.remove();
1497                 }
1498                 this.helper = null;
1499                 this.cancelHelperRemoval = false;
1500         },
1501
1502         // From now on bulk stuff - mainly helpers
1503
1504         _trigger: function(type, event, ui) {
1505                 ui = ui || this._uiHash();
1506                 $.ui.plugin.call(this, type, [event, ui]);
1507                 //The absolute position has to be recalculated after plugins
1508                 if(type === "drag") {
1509                         this.positionAbs = this._convertPositionTo("absolute");
1510                 }
1511                 return $.Widget.prototype._trigger.call(this, type, event, ui);
1512         },
1513
1514         plugins: {},
1515
1516         _uiHash: function() {
1517                 return {
1518                         helper: this.helper,
1519                         position: this.position,
1520                         originalPosition: this.originalPosition,
1521                         offset: this.positionAbs
1522                 };
1523         }
1524
1525 });
1526
1527 $.ui.plugin.add("draggable", "connectToSortable", {
1528         start: function(event, ui) {
1529
1530                 var inst = $(this).data("ui-draggable"), o = inst.options,
1531                         uiSortable = $.extend({}, ui, { item: inst.element });
1532                 inst.sortables = [];
1533                 $(o.connectToSortable).each(function() {
1534                         var sortable = $.data(this, "ui-sortable");
1535                         if (sortable && !sortable.options.disabled) {
1536                                 inst.sortables.push({
1537                                         instance: sortable,
1538                                         shouldRevert: sortable.options.revert
1539                                 });
1540                                 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).
1541                                 sortable._trigger("activate", event, uiSortable);
1542                         }
1543                 });
1544
1545         },
1546         stop: function(event, ui) {
1547
1548                 //If we are still over the sortable, we fake the stop event of the sortable, but also remove helper
1549                 var inst = $(this).data("ui-draggable"),
1550                         uiSortable = $.extend({}, ui, { item: inst.element });
1551
1552                 $.each(inst.sortables, function() {
1553                         if(this.instance.isOver) {
1554
1555                                 this.instance.isOver = 0;
1556
1557                                 inst.cancelHelperRemoval = true; //Don't remove the helper in the draggable instance
1558                                 this.instance.cancelHelperRemoval = false; //Remove it in the sortable instance (so sortable plugins like revert still work)
1559
1560                                 //The sortable revert is supported, and we have to set a temporary dropped variable on the draggable to support revert: "valid/invalid"
1561                                 if(this.shouldRevert) {
1562                                         this.instance.options.revert = this.shouldRevert;
1563                                 }
1564
1565                                 //Trigger the stop of the sortable
1566                                 this.instance._mouseStop(event);
1567
1568                                 this.instance.options.helper = this.instance.options._helper;
1569
1570                                 //If the helper has been the original item, restore properties in the sortable
1571                                 if(inst.options.helper === "original") {
1572                                         this.instance.currentItem.css({ top: "auto", left: "auto" });
1573                                 }
1574
1575                         } else {
1576                                 this.instance.cancelHelperRemoval = false; //Remove the helper in the sortable instance
1577                                 this.instance._trigger("deactivate", event, uiSortable);
1578                         }
1579
1580                 });
1581
1582         },
1583         drag: function(event, ui) {
1584
1585                 var inst = $(this).data("ui-draggable"), that = this;
1586
1587                 $.each(inst.sortables, function() {
1588
1589                         var innermostIntersecting = false,
1590                                 thisSortable = this;
1591
1592                         //Copy over some variables to allow calling the sortable's native _intersectsWith
1593                         this.instance.positionAbs = inst.positionAbs;
1594                         this.instance.helperProportions = inst.helperProportions;
1595                         this.instance.offset.click = inst.offset.click;
1596
1597                         if(this.instance._intersectsWith(this.instance.containerCache)) {
1598                                 innermostIntersecting = true;
1599                                 $.each(inst.sortables, function () {
1600                                         this.instance.positionAbs = inst.positionAbs;
1601                                         this.instance.helperProportions = inst.helperProportions;
1602                                         this.instance.offset.click = inst.offset.click;
1603                                         if (this !== thisSortable &&
1604                                                 this.instance._intersectsWith(this.instance.containerCache) &&
1605                                                 $.contains(thisSortable.instance.element[0], this.instance.element[0])
1606                                         ) {
1607                                                 innermostIntersecting = false;
1608                                         }
1609                                         return innermostIntersecting;
1610                                 });
1611                         }
1612
1613
1614                         if(innermostIntersecting) {
1615                                 //If it intersects, we use a little isOver variable and set it once, so our move-in stuff gets fired only once
1616                                 if(!this.instance.isOver) {
1617
1618                                         this.instance.isOver = 1;
1619                                         //Now we fake the start of dragging for the sortable instance,
1620                                         //by cloning the list group item, appending it to the sortable and using it as inst.currentItem
1621                                         //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)
1622                                         this.instance.currentItem = $(that).clone().removeAttr("id").appendTo(this.instance.element).data("ui-sortable-item", true);
1623                                         this.instance.options._helper = this.instance.options.helper; //Store helper option to later restore it
1624                                         this.instance.options.helper = function() { return ui.helper[0]; };
1625
1626                                         event.target = this.instance.currentItem[0];
1627                                         this.instance._mouseCapture(event, true);
1628                                         this.instance._mouseStart(event, true, true);
1629
1630                                         //Because the browser event is way off the new appended portlet, we modify a couple of variables to reflect the changes
1631                                         this.instance.offset.click.top = inst.offset.click.top;
1632                                         this.instance.offset.click.left = inst.offset.click.left;
1633                                         this.instance.offset.parent.left -= inst.offset.parent.left - this.instance.offset.parent.left;
1634                                         this.instance.offset.parent.top -= inst.offset.parent.top - this.instance.offset.parent.top;
1635
1636                                         inst._trigger("toSortable", event);
1637                                         inst.dropped = this.instance.element; //draggable revert needs that
1638                                         //hack so receive/update callbacks work (mostly)
1639                                         inst.currentItem = inst.element;
1640                                         this.instance.fromOutside = inst;
1641
1642                                 }
1643
1644                                 //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
1645                                 if(this.instance.currentItem) {
1646                                         this.instance._mouseDrag(event);
1647                                 }
1648
1649                         } else {
1650
1651                                 //If it doesn't intersect with the sortable, and it intersected before,
1652                                 //we fake the drag stop of the sortable, but make sure it doesn't remove the helper by using cancelHelperRemoval
1653                                 if(this.instance.isOver) {
1654
1655                                         this.instance.isOver = 0;
1656                                         this.instance.cancelHelperRemoval = true;
1657
1658                                         //Prevent reverting on this forced stop
1659                                         this.instance.options.revert = false;
1660
1661                                         // The out event needs to be triggered independently
1662                                         this.instance._trigger("out", event, this.instance._uiHash(this.instance));
1663
1664                                         this.instance._mouseStop(event, true);
1665                                         this.instance.options.helper = this.instance.options._helper;
1666
1667                                         //Now we remove our currentItem, the list group clone again, and the placeholder, and animate the helper back to it's original size
1668                                         this.instance.currentItem.remove();
1669                                         if(this.instance.placeholder) {
1670                                                 this.instance.placeholder.remove();
1671                                         }
1672
1673                                         inst._trigger("fromSortable", event);
1674                                         inst.dropped = false; //draggable revert needs that
1675                                 }
1676
1677                         }
1678
1679                 });
1680
1681         }
1682 });
1683
1684 $.ui.plugin.add("draggable", "cursor", {
1685         start: function() {
1686                 var t = $("body"), o = $(this).data("ui-draggable").options;
1687                 if (t.css("cursor")) {
1688                         o._cursor = t.css("cursor");
1689                 }
1690                 t.css("cursor", o.cursor);
1691         },
1692         stop: function() {
1693                 var o = $(this).data("ui-draggable").options;
1694                 if (o._cursor) {
1695                         $("body").css("cursor", o._cursor);
1696                 }
1697         }
1698 });
1699
1700 $.ui.plugin.add("draggable", "opacity", {
1701         start: function(event, ui) {
1702                 var t = $(ui.helper), o = $(this).data("ui-draggable").options;
1703                 if(t.css("opacity")) {
1704                         o._opacity = t.css("opacity");
1705                 }
1706                 t.css("opacity", o.opacity);
1707         },
1708         stop: function(event, ui) {
1709                 var o = $(this).data("ui-draggable").options;
1710                 if(o._opacity) {
1711                         $(ui.helper).css("opacity", o._opacity);
1712                 }
1713         }
1714 });
1715
1716 $.ui.plugin.add("draggable", "scroll", {
1717         start: function() {
1718                 var i = $(this).data("ui-draggable");
1719                 if(i.scrollParent[0] !== document && i.scrollParent[0].tagName !== "HTML") {
1720                         i.overflowOffset = i.scrollParent.offset();
1721                 }
1722         },
1723         drag: function( event ) {
1724
1725                 var i = $(this).data("ui-draggable"), o = i.options, scrolled = false;
1726
1727                 if(i.scrollParent[0] !== document && i.scrollParent[0].tagName !== "HTML") {
1728
1729                         if(!o.axis || o.axis !== "x") {
1730                                 if((i.overflowOffset.top + i.scrollParent[0].offsetHeight) - event.pageY < o.scrollSensitivity) {
1731                                         i.scrollParent[0].scrollTop = scrolled = i.scrollParent[0].scrollTop + o.scrollSpeed;
1732                                 } else if(event.pageY - i.overflowOffset.top < o.scrollSensitivity) {
1733                                         i.scrollParent[0].scrollTop = scrolled = i.scrollParent[0].scrollTop - o.scrollSpeed;
1734                                 }
1735                         }
1736
1737                         if(!o.axis || o.axis !== "y") {
1738                                 if((i.overflowOffset.left + i.scrollParent[0].offsetWidth) - event.pageX < o.scrollSensitivity) {
1739                                         i.scrollParent[0].scrollLeft = scrolled = i.scrollParent[0].scrollLeft + o.scrollSpeed;
1740                                 } else if(event.pageX - i.overflowOffset.left < o.scrollSensitivity) {
1741                                         i.scrollParent[0].scrollLeft = scrolled = i.scrollParent[0].scrollLeft - o.scrollSpeed;
1742                                 }
1743                         }
1744
1745                 } else {
1746
1747                         if(!o.axis || o.axis !== "x") {
1748                                 if(event.pageY - $(document).scrollTop() < o.scrollSensitivity) {
1749                                         scrolled = $(document).scrollTop($(document).scrollTop() - o.scrollSpeed);
1750                                 } else if($(window).height() - (event.pageY - $(document).scrollTop()) < o.scrollSensitivity) {
1751                                         scrolled = $(document).scrollTop($(document).scrollTop() + o.scrollSpeed);
1752                                 }
1753                         }
1754
1755                         if(!o.axis || o.axis !== "y") {
1756                                 if(event.pageX - $(document).scrollLeft() < o.scrollSensitivity) {
1757                                         scrolled = $(document).scrollLeft($(document).scrollLeft() - o.scrollSpeed);
1758                                 } else if($(window).width() - (event.pageX - $(document).scrollLeft()) < o.scrollSensitivity) {
1759                                         scrolled = $(document).scrollLeft($(document).scrollLeft() + o.scrollSpeed);
1760                                 }
1761                         }
1762
1763                 }
1764
1765                 if(scrolled !== false && $.ui.ddmanager && !o.dropBehaviour) {
1766                         $.ui.ddmanager.prepareOffsets(i, event);
1767                 }
1768
1769         }
1770 });
1771
1772 $.ui.plugin.add("draggable", "snap", {
1773         start: function() {
1774
1775                 var i = $(this).data("ui-draggable"),
1776                         o = i.options;
1777
1778                 i.snapElements = [];
1779
1780                 $(o.snap.constructor !== String ? ( o.snap.items || ":data(ui-draggable)" ) : o.snap).each(function() {
1781                         var $t = $(this),
1782                                 $o = $t.offset();
1783                         if(this !== i.element[0]) {
1784                                 i.snapElements.push({
1785                                         item: this,
1786                                         width: $t.outerWidth(), height: $t.outerHeight(),
1787                                         top: $o.top, left: $o.left
1788                                 });
1789                         }
1790                 });
1791
1792         },
1793         drag: function(event, ui) {
1794
1795                 var ts, bs, ls, rs, l, r, t, b, i, first,
1796                         inst = $(this).data("ui-draggable"),
1797                         o = inst.options,
1798                         d = o.snapTolerance,
1799                         x1 = ui.offset.left, x2 = x1 + inst.helperProportions.width,
1800                         y1 = ui.offset.top, y2 = y1 + inst.helperProportions.height;
1801
1802                 for (i = inst.snapElements.length - 1; i >= 0; i--){
1803
1804                         l = inst.snapElements[i].left;
1805                         r = l + inst.snapElements[i].width;
1806                         t = inst.snapElements[i].top;
1807                         b = t + inst.snapElements[i].height;
1808
1809                         //Yes, I know, this is insane ;)
1810                         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))) {
1811                                 if(inst.snapElements[i].snapping) {
1812                                         (inst.options.snap.release && inst.options.snap.release.call(inst.element, event, $.extend(inst._uiHash(), { snapItem: inst.snapElements[i].item })));
1813                                 }
1814                                 inst.snapElements[i].snapping = false;
1815                                 continue;
1816                         }
1817
1818                         if(o.snapMode !== "inner") {
1819                                 ts = Math.abs(t - y2) <= d;
1820                                 bs = Math.abs(b - y1) <= d;
1821                                 ls = Math.abs(l - x2) <= d;
1822                                 rs = Math.abs(r - x1) <= d;
1823                                 if(ts) {
1824                                         ui.position.top = inst._convertPositionTo("relative", { top: t - inst.helperProportions.height, left: 0 }).top - inst.margins.top;
1825                                 }
1826                                 if(bs) {
1827                                         ui.position.top = inst._convertPositionTo("relative", { top: b, left: 0 }).top - inst.margins.top;
1828                                 }
1829                                 if(ls) {
1830                                         ui.position.left = inst._convertPositionTo("relative", { top: 0, left: l - inst.helperProportions.width }).left - inst.margins.left;
1831                                 }
1832                                 if(rs) {
1833                                         ui.position.left = inst._convertPositionTo("relative", { top: 0, left: r }).left - inst.margins.left;
1834                                 }
1835                         }
1836
1837                         first = (ts || bs || ls || rs);
1838
1839                         if(o.snapMode !== "outer") {
1840                                 ts = Math.abs(t - y1) <= d;
1841                                 bs = Math.abs(b - y2) <= d;
1842                                 ls = Math.abs(l - x1) <= d;
1843                                 rs = Math.abs(r - x2) <= d;
1844                                 if(ts) {
1845                                         ui.position.top = inst._convertPositionTo("relative", { top: t, left: 0 }).top - inst.margins.top;
1846                                 }
1847                                 if(bs) {
1848                                         ui.position.top = inst._convertPositionTo("relative", { top: b - inst.helperProportions.height, left: 0 }).top - inst.margins.top;
1849                                 }
1850                                 if(ls) {
1851                                         ui.position.left = inst._convertPositionTo("relative", { top: 0, left: l }).left - inst.margins.left;
1852                                 }
1853                                 if(rs) {
1854                                         ui.position.left = inst._convertPositionTo("relative", { top: 0, left: r - inst.helperProportions.width }).left - inst.margins.left;
1855                                 }
1856                         }
1857
1858                         if(!inst.snapElements[i].snapping && (ts || bs || ls || rs || first)) {
1859                                 (inst.options.snap.snap && inst.options.snap.snap.call(inst.element, event, $.extend(inst._uiHash(), { snapItem: inst.snapElements[i].item })));
1860                         }
1861                         inst.snapElements[i].snapping = (ts || bs || ls || rs || first);
1862
1863                 }
1864
1865         }
1866 });
1867
1868 $.ui.plugin.add("draggable", "stack", {
1869         start: function() {
1870                 var min,
1871                         o = this.data("ui-draggable").options,
1872                         group = $.makeArray($(o.stack)).sort(function(a,b) {
1873                                 return (parseInt($(a).css("zIndex"),10) || 0) - (parseInt($(b).css("zIndex"),10) || 0);
1874                         });
1875
1876                 if (!group.length) { return; }
1877
1878                 min = parseInt($(group[0]).css("zIndex"), 10) || 0;
1879                 $(group).each(function(i) {
1880                         $(this).css("zIndex", min + i);
1881                 });
1882                 this.css("zIndex", (min + group.length));
1883         }
1884 });
1885
1886 $.ui.plugin.add("draggable", "zIndex", {
1887         start: function(event, ui) {
1888                 var t = $(ui.helper), o = $(this).data("ui-draggable").options;
1889                 if(t.css("zIndex")) {
1890                         o._zIndex = t.css("zIndex");
1891                 }
1892                 t.css("zIndex", o.zIndex);
1893         },
1894         stop: function(event, ui) {
1895                 var o = $(this).data("ui-draggable").options;
1896                 if(o._zIndex) {
1897                         $(ui.helper).css("zIndex", o._zIndex);
1898                 }
1899         }
1900 });
1901
1902 })(jQuery);
1903
1904 (function( $, undefined ) {
1905
1906 function isOverAxis( x, reference, size ) {
1907         return ( x > reference ) && ( x < ( reference + size ) );
1908 }
1909
1910 $.widget("ui.droppable", {
1911         version: "1.10.2",
1912         widgetEventPrefix: "drop",
1913         options: {
1914                 accept: "*",
1915                 activeClass: false,
1916                 addClasses: true,
1917                 greedy: false,
1918                 hoverClass: false,
1919                 scope: "default",
1920                 tolerance: "intersect",
1921
1922                 // callbacks
1923                 activate: null,
1924                 deactivate: null,
1925                 drop: null,
1926                 out: null,
1927                 over: null
1928         },
1929         _create: function() {
1930
1931                 var o = this.options,
1932                         accept = o.accept;
1933
1934                 this.isover = false;
1935                 this.isout = true;
1936
1937                 this.accept = $.isFunction(accept) ? accept : function(d) {
1938                         return d.is(accept);
1939                 };
1940
1941                 //Store the droppable's proportions
1942                 this.proportions = { width: this.element[0].offsetWidth, height: this.element[0].offsetHeight };
1943
1944                 // Add the reference and positions to the manager
1945                 $.ui.ddmanager.droppables[o.scope] = $.ui.ddmanager.droppables[o.scope] || [];
1946                 $.ui.ddmanager.droppables[o.scope].push(this);
1947
1948                 (o.addClasses && this.element.addClass("ui-droppable"));
1949
1950         },
1951
1952         _destroy: function() {
1953                 var i = 0,
1954                         drop = $.ui.ddmanager.droppables[this.options.scope];
1955
1956                 for ( ; i < drop.length; i++ ) {
1957                         if ( drop[i] === this ) {
1958                                 drop.splice(i, 1);
1959                         }
1960                 }
1961
1962                 this.element.removeClass("ui-droppable ui-droppable-disabled");
1963         },
1964
1965         _setOption: function(key, value) {
1966
1967                 if(key === "accept") {
1968                         this.accept = $.isFunction(value) ? value : function(d) {
1969                                 return d.is(value);
1970                         };
1971                 }
1972                 $.Widget.prototype._setOption.apply(this, arguments);
1973         },
1974
1975         _activate: function(event) {
1976                 var draggable = $.ui.ddmanager.current;
1977                 if(this.options.activeClass) {
1978                         this.element.addClass(this.options.activeClass);
1979                 }
1980                 if(draggable){
1981                         this._trigger("activate", event, this.ui(draggable));
1982                 }
1983         },
1984
1985         _deactivate: function(event) {
1986                 var draggable = $.ui.ddmanager.current;
1987                 if(this.options.activeClass) {
1988                         this.element.removeClass(this.options.activeClass);
1989                 }
1990                 if(draggable){
1991                         this._trigger("deactivate", event, this.ui(draggable));
1992                 }
1993         },
1994
1995         _over: function(event) {
1996
1997                 var draggable = $.ui.ddmanager.current;
1998
1999                 // Bail if draggable and droppable are same element
2000                 if (!draggable || (draggable.currentItem || draggable.element)[0] === this.element[0]) {
2001                         return;
2002                 }
2003
2004                 if (this.accept.call(this.element[0],(draggable.currentItem || draggable.element))) {
2005                         if(this.options.hoverClass) {
2006                                 this.element.addClass(this.options.hoverClass);
2007                         }
2008                         this._trigger("over", event, this.ui(draggable));
2009                 }
2010
2011         },
2012
2013         _out: function(event) {
2014
2015                 var draggable = $.ui.ddmanager.current;
2016
2017                 // Bail if draggable and droppable are same element
2018                 if (!draggable || (draggable.currentItem || draggable.element)[0] === this.element[0]) {
2019                         return;
2020                 }
2021
2022                 if (this.accept.call(this.element[0],(draggable.currentItem || draggable.element))) {
2023                         if(this.options.hoverClass) {
2024                                 this.element.removeClass(this.options.hoverClass);
2025                         }
2026                         this._trigger("out", event, this.ui(draggable));
2027                 }
2028
2029         },
2030
2031         _drop: function(event,custom) {
2032
2033                 var draggable = custom || $.ui.ddmanager.current,
2034                         childrenIntersection = false;
2035
2036                 // Bail if draggable and droppable are same element
2037                 if (!draggable || (draggable.currentItem || draggable.element)[0] === this.element[0]) {
2038                         return false;
2039                 }
2040
2041                 this.element.find(":data(ui-droppable)").not(".ui-draggable-dragging").each(function() {
2042                         var inst = $.data(this, "ui-droppable");
2043                         if(
2044                                 inst.options.greedy &&
2045                                 !inst.options.disabled &&
2046                                 inst.options.scope === draggable.options.scope &&
2047                                 inst.accept.call(inst.element[0], (draggable.currentItem || draggable.element)) &&
2048                                 $.ui.intersect(draggable, $.extend(inst, { offset: inst.element.offset() }), inst.options.tolerance)
2049                         ) { childrenIntersection = true; return false; }
2050                 });
2051                 if(childrenIntersection) {
2052                         return false;
2053                 }
2054
2055                 if(this.accept.call(this.element[0],(draggable.currentItem || draggable.element))) {
2056                         if(this.options.activeClass) {
2057                                 this.element.removeClass(this.options.activeClass);
2058                         }
2059                         if(this.options.hoverClass) {
2060                                 this.element.removeClass(this.options.hoverClass);
2061                         }
2062                         this._trigger("drop", event, this.ui(draggable));
2063                         return this.element;
2064                 }
2065
2066                 return false;
2067
2068         },
2069
2070         ui: function(c) {
2071                 return {
2072                         draggable: (c.currentItem || c.element),
2073                         helper: c.helper,
2074                         position: c.position,
2075                         offset: c.positionAbs
2076                 };
2077         }
2078
2079 });
2080
2081 $.ui.intersect = function(draggable, droppable, toleranceMode) {
2082
2083         if (!droppable.offset) {
2084                 return false;
2085         }
2086
2087         var draggableLeft, draggableTop,
2088                 x1 = (draggable.positionAbs || draggable.position.absolute).left, x2 = x1 + draggable.helperProportions.width,
2089                 y1 = (draggable.positionAbs || draggable.position.absolute).top, y2 = y1 + draggable.helperProportions.height,
2090                 l = droppable.offset.left, r = l + droppable.proportions.width,
2091                 t = droppable.offset.top, b = t + droppable.proportions.height;
2092
2093         switch (toleranceMode) {
2094                 case "fit":
2095                         return (l <= x1 && x2 <= r && t <= y1 && y2 <= b);
2096                 case "intersect":
2097                         return (l < x1 + (draggable.helperProportions.width / 2) && // Right Half
2098                                 x2 - (draggable.helperProportions.width / 2) < r && // Left Half
2099                                 t < y1 + (draggable.helperProportions.height / 2) && // Bottom Half
2100                                 y2 - (draggable.helperProportions.height / 2) < b ); // Top Half
2101                 case "pointer":
2102                         draggableLeft = ((draggable.positionAbs || draggable.position.absolute).left + (draggable.clickOffset || draggable.offset.click).left);
2103                         draggableTop = ((draggable.positionAbs || draggable.position.absolute).top + (draggable.clickOffset || draggable.offset.click).top);
2104                         return isOverAxis( draggableTop, t, droppable.proportions.height ) && isOverAxis( draggableLeft, l, droppable.proportions.width );
2105                 case "touch":
2106                         return (
2107                                 (y1 >= t && y1 <= b) || // Top edge touching
2108                                 (y2 >= t && y2 <= b) || // Bottom edge touching
2109                                 (y1 < t && y2 > b)              // Surrounded vertically
2110                         ) && (
2111                                 (x1 >= l && x1 <= r) || // Left edge touching
2112                                 (x2 >= l && x2 <= r) || // Right edge touching
2113                                 (x1 < l && x2 > r)              // Surrounded horizontally
2114                         );
2115                 default:
2116                         return false;
2117                 }
2118
2119 };
2120
2121 /*
2122         This manager tracks offsets of draggables and droppables
2123 */
2124 $.ui.ddmanager = {
2125         current: null,
2126         droppables: { "default": [] },
2127         prepareOffsets: function(t, event) {
2128
2129                 var i, j,
2130                         m = $.ui.ddmanager.droppables[t.options.scope] || [],
2131                         type = event ? event.type : null, // workaround for #2317
2132                         list = (t.currentItem || t.element).find(":data(ui-droppable)").addBack();
2133
2134                 droppablesLoop: for (i = 0; i < m.length; i++) {
2135
2136                         //No disabled and non-accepted
2137                         if(m[i].options.disabled || (t && !m[i].accept.call(m[i].element[0],(t.currentItem || t.element)))) {
2138                                 continue;
2139                         }
2140
2141                         // Filter out elements in the current dragged item
2142                         for (j=0; j < list.length; j++) {
2143                                 if(list[j] === m[i].element[0]) {
2144                                         m[i].proportions.height = 0;
2145                                         continue droppablesLoop;
2146                                 }
2147                         }
2148
2149                         m[i].visible = m[i].element.css("display") !== "none";
2150                         if(!m[i].visible) {
2151                                 continue;
2152                         }
2153
2154                         //Activate the droppable if used directly from draggables
2155                         if(type === "mousedown") {
2156                                 m[i]._activate.call(m[i], event);
2157                         }
2158
2159                         m[i].offset = m[i].element.offset();
2160                         m[i].proportions = { width: m[i].element[0].offsetWidth, height: m[i].element[0].offsetHeight };
2161
2162                 }
2163
2164         },
2165         drop: function(draggable, event) {
2166
2167                 var dropped = false;
2168                 // Create a copy of the droppables in case the list changes during the drop (#9116)
2169                 $.each(($.ui.ddmanager.droppables[draggable.options.scope] || []).slice(), function() {
2170
2171                         if(!this.options) {
2172                                 return;
2173                         }
2174                         if (!this.options.disabled && this.visible && $.ui.intersect(draggable, this, this.options.tolerance)) {
2175                                 dropped = this._drop.call(this, event) || dropped;
2176                         }
2177
2178                         if (!this.options.disabled && this.visible && this.accept.call(this.element[0],(draggable.currentItem || draggable.element))) {
2179                                 this.isout = true;
2180                                 this.isover = false;
2181                                 this._deactivate.call(this, event);
2182                         }
2183
2184                 });
2185                 return dropped;
2186
2187         },
2188         dragStart: function( draggable, event ) {
2189                 //Listen for scrolling so that if the dragging causes scrolling the position of the droppables can be recalculated (see #5003)
2190                 draggable.element.parentsUntil( "body" ).bind( "scroll.droppable", function() {
2191                         if( !draggable.options.refreshPositions ) {
2192                                 $.ui.ddmanager.prepareOffsets( draggable, event );
2193                         }
2194                 });
2195         },
2196         drag: function(draggable, event) {
2197
2198                 //If you have a highly dynamic page, you might try this option. It renders positions every time you move the mouse.
2199                 if(draggable.options.refreshPositions) {
2200                         $.ui.ddmanager.prepareOffsets(draggable, event);
2201                 }
2202
2203                 //Run through all droppables and check their positions based on specific tolerance options
2204                 $.each($.ui.ddmanager.droppables[draggable.options.scope] || [], function() {
2205
2206                         if(this.options.disabled || this.greedyChild || !this.visible) {
2207                                 return;
2208                         }
2209
2210                         var parentInstance, scope, parent,
2211                                 intersects = $.ui.intersect(draggable, this, this.options.tolerance),
2212                                 c = !intersects && this.isover ? "isout" : (intersects && !this.isover ? "isover" : null);
2213                         if(!c) {
2214                                 return;
2215                         }
2216
2217                         if (this.options.greedy) {
2218                                 // find droppable parents with same scope
2219                                 scope = this.options.scope;
2220                                 parent = this.element.parents(":data(ui-droppable)").filter(function () {
2221                                         return $.data(this, "ui-droppable").options.scope === scope;
2222                                 });
2223
2224                                 if (parent.length) {
2225                                         parentInstance = $.data(parent[0], "ui-droppable");
2226                                         parentInstance.greedyChild = (c === "isover");
2227                                 }
2228                         }
2229
2230                         // we just moved into a greedy child
2231                         if (parentInstance && c === "isover") {
2232                                 parentInstance.isover = false;
2233                                 parentInstance.isout = true;
2234                                 parentInstance._out.call(parentInstance, event);
2235                         }
2236
2237                         this[c] = true;
2238                         this[c === "isout" ? "isover" : "isout"] = false;
2239                         this[c === "isover" ? "_over" : "_out"].call(this, event);
2240
2241                         // we just moved out of a greedy child
2242                         if (parentInstance && c === "isout") {
2243                                 parentInstance.isout = false;
2244                                 parentInstance.isover = true;
2245                                 parentInstance._over.call(parentInstance, event);
2246                         }
2247                 });
2248
2249         },
2250         dragStop: function( draggable, event ) {
2251                 draggable.element.parentsUntil( "body" ).unbind( "scroll.droppable" );
2252                 //Call prepareOffsets one final time since IE does not fire return scroll events when overflow was caused by drag (see #5003)
2253                 if( !draggable.options.refreshPositions ) {
2254                         $.ui.ddmanager.prepareOffsets( draggable, event );
2255                 }
2256         }
2257 };
2258
2259 })(jQuery);
2260
2261 (function( $, undefined ) {
2262
2263 function num(v) {
2264         return parseInt(v, 10) || 0;
2265 }
2266
2267 function isNumber(value) {
2268         return !isNaN(parseInt(value, 10));
2269 }
2270
2271 $.widget("ui.resizable", $.ui.mouse, {
2272         version: "1.10.2",
2273         widgetEventPrefix: "resize",
2274         options: {
2275                 alsoResize: false,
2276                 animate: false,
2277                 animateDuration: "slow",
2278                 animateEasing: "swing",
2279                 aspectRatio: false,
2280                 autoHide: false,
2281                 containment: false,
2282                 ghost: false,
2283                 grid: false,
2284                 handles: "e,s,se",
2285                 helper: false,
2286                 maxHeight: null,
2287                 maxWidth: null,
2288                 minHeight: 10,
2289                 minWidth: 10,
2290                 // See #7960
2291                 zIndex: 90,
2292
2293                 // callbacks
2294                 resize: null,
2295                 start: null,
2296                 stop: null
2297         },
2298         _create: function() {
2299
2300                 var n, i, handle, axis, hname,
2301                         that = this,
2302                         o = this.options;
2303                 this.element.addClass("ui-resizable");
2304
2305                 $.extend(this, {
2306                         _aspectRatio: !!(o.aspectRatio),
2307                         aspectRatio: o.aspectRatio,
2308                         originalElement: this.element,
2309                         _proportionallyResizeElements: [],
2310                         _helper: o.helper || o.ghost || o.animate ? o.helper || "ui-resizable-helper" : null
2311                 });
2312
2313                 //Wrap the element if it cannot hold child nodes
2314                 if(this.element[0].nodeName.match(/canvas|textarea|input|select|button|img/i)) {
2315
2316                         //Create a wrapper element and set the wrapper to the new current internal element
2317                         this.element.wrap(
2318                                 $("<div class='ui-wrapper' style='overflow: hidden;'></div>").css({
2319                                         position: this.element.css("position"),
2320                                         width: this.element.outerWidth(),
2321                                         height: this.element.outerHeight(),
2322                                         top: this.element.css("top"),
2323                                         left: this.element.css("left")
2324                                 })
2325                         );
2326
2327                         //Overwrite the original this.element
2328                         this.element = this.element.parent().data(
2329                                 "ui-resizable", this.element.data("ui-resizable")
2330                         );
2331
2332                         this.elementIsWrapper = true;
2333
2334                         //Move margins to the wrapper
2335                         this.element.css({ marginLeft: this.originalElement.css("marginLeft"), marginTop: this.originalElement.css("marginTop"), marginRight: this.originalElement.css("marginRight"), marginBottom: this.originalElement.css("marginBottom") });
2336                         this.originalElement.css({ marginLeft: 0, marginTop: 0, marginRight: 0, marginBottom: 0});
2337
2338                         //Prevent Safari textarea resize
2339                         this.originalResizeStyle = this.originalElement.css("resize");
2340                         this.originalElement.css("resize", "none");
2341
2342                         //Push the actual element to our proportionallyResize internal array
2343                         this._proportionallyResizeElements.push(this.originalElement.css({ position: "static", zoom: 1, display: "block" }));
2344
2345                         // avoid IE jump (hard set the margin)
2346                         this.originalElement.css({ margin: this.originalElement.css("margin") });
2347
2348                         // fix handlers offset
2349                         this._proportionallyResize();
2350
2351                 }
2352
2353                 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" });
2354                 if(this.handles.constructor === String) {
2355
2356                         if ( this.handles === "all") {
2357                                 this.handles = "n,e,s,w,se,sw,ne,nw";
2358                         }
2359
2360                         n = this.handles.split(",");
2361                         this.handles = {};
2362
2363                         for(i = 0; i < n.length; i++) {
2364
2365                                 handle = $.trim(n[i]);
2366                                 hname = "ui-resizable-"+handle;
2367                                 axis = $("<div class='ui-resizable-handle " + hname + "'></div>");
2368
2369                                 // Apply zIndex to all handles - see #7960
2370                                 axis.css({ zIndex: o.zIndex });
2371
2372                                 //TODO : What's going on here?
2373                                 if ("se" === handle) {
2374                                         axis.addClass("ui-icon ui-icon-gripsmall-diagonal-se");
2375                                 }
2376
2377                                 //Insert into internal handles object and append to element
2378                                 this.handles[handle] = ".ui-resizable-"+handle;
2379                                 this.element.append(axis);
2380                         }
2381
2382                 }
2383
2384                 this._renderAxis = function(target) {
2385
2386                         var i, axis, padPos, padWrapper;
2387
2388                         target = target || this.element;
2389
2390                         for(i in this.handles) {
2391
2392                                 if(this.handles[i].constructor === String) {
2393                                         this.handles[i] = $(this.handles[i], this.element).show();
2394                                 }
2395
2396                                 //Apply pad to wrapper element, needed to fix axis position (textarea, inputs, scrolls)
2397                                 if (this.elementIsWrapper && this.originalElement[0].nodeName.match(/textarea|input|select|button/i)) {
2398
2399                                         axis = $(this.handles[i], this.element);
2400
2401                                         //Checking the correct pad and border
2402                                         padWrapper = /sw|ne|nw|se|n|s/.test(i) ? axis.outerHeight() : axis.outerWidth();
2403
2404                                         //The padding type i have to apply...
2405                                         padPos = [ "padding",
2406                                                 /ne|nw|n/.test(i) ? "Top" :
2407                                                 /se|sw|s/.test(i) ? "Bottom" :
2408                                                 /^e$/.test(i) ? "Right" : "Left" ].join("");
2409
2410                                         target.css(padPos, padWrapper);
2411
2412                                         this._proportionallyResize();
2413
2414                                 }
2415
2416                                 //TODO: What's that good for? There's not anything to be executed left
2417                                 if(!$(this.handles[i]).length) {
2418                                         continue;
2419                                 }
2420                         }
2421                 };
2422
2423                 //TODO: make renderAxis a prototype function
2424                 this._renderAxis(this.element);
2425
2426                 this._handles = $(".ui-resizable-handle", this.element)
2427                         .disableSelection();
2428
2429                 //Matching axis name
2430                 this._handles.mouseover(function() {
2431                         if (!that.resizing) {
2432                                 if (this.className) {
2433                                         axis = this.className.match(/ui-resizable-(se|sw|ne|nw|n|e|s|w)/i);
2434                                 }
2435                                 //Axis, default = se
2436                                 that.axis = axis && axis[1] ? axis[1] : "se";
2437                         }
2438                 });
2439
2440                 //If we want to auto hide the elements
2441                 if (o.autoHide) {
2442                         this._handles.hide();
2443                         $(this.element)
2444                                 .addClass("ui-resizable-autohide")
2445                                 .mouseenter(function() {
2446                                         if (o.disabled) {
2447                                                 return;
2448                                         }
2449                                         $(this).removeClass("ui-resizable-autohide");
2450                                         that._handles.show();
2451                                 })
2452                                 .mouseleave(function(){
2453                                         if (o.disabled) {
2454                                                 return;
2455                                         }
2456                                         if (!that.resizing) {
2457                                                 $(this).addClass("ui-resizable-autohide");
2458                                                 that._handles.hide();
2459                                         }
2460                                 });
2461                 }
2462
2463                 //Initialize the mouse interaction
2464                 this._mouseInit();
2465
2466         },
2467
2468         _destroy: function() {
2469
2470                 this._mouseDestroy();
2471
2472                 var wrapper,
2473                         _destroy = function(exp) {
2474                                 $(exp).removeClass("ui-resizable ui-resizable-disabled ui-resizable-resizing")
2475                                         .removeData("resizable").removeData("ui-resizable").unbind(".resizable").find(".ui-resizable-handle").remove();
2476                         };
2477
2478                 //TODO: Unwrap at same DOM position
2479                 if (this.elementIsWrapper) {
2480                         _destroy(this.element);
2481                         wrapper = this.element;
2482                         this.originalElement.css({
2483                                 position: wrapper.css("position"),
2484                                 width: wrapper.outerWidth(),
2485                                 height: wrapper.outerHeight(),
2486                                 top: wrapper.css("top"),
2487                                 left: wrapper.css("left")
2488                         }).insertAfter( wrapper );
2489                         wrapper.remove();
2490                 }
2491
2492                 this.originalElement.css("resize", this.originalResizeStyle);
2493                 _destroy(this.originalElement);
2494
2495                 return this;
2496         },
2497
2498         _mouseCapture: function(event) {
2499                 var i, handle,
2500                         capture = false;
2501
2502                 for (i in this.handles) {
2503                         handle = $(this.handles[i])[0];
2504                         if (handle === event.target || $.contains(handle, event.target)) {
2505                                 capture = true;
2506                         }
2507                 }
2508
2509                 return !this.options.disabled && capture;
2510         },
2511
2512         _mouseStart: function(event) {
2513
2514                 var curleft, curtop, cursor,
2515                         o = this.options,
2516                         iniPos = this.element.position(),
2517                         el = this.element;
2518
2519                 this.resizing = true;
2520
2521                 // bugfix for http://dev.jquery.com/ticket/1749
2522                 if ( (/absolute/).test( el.css("position") ) ) {
2523                         el.css({ position: "absolute", top: el.css("top"), left: el.css("left") });
2524                 } else if (el.is(".ui-draggable")) {
2525                         el.css({ position: "absolute", top: iniPos.top, left: iniPos.left });
2526                 }
2527
2528                 this._renderProxy();
2529
2530                 curleft = num(this.helper.css("left"));
2531                 curtop = num(this.helper.css("top"));
2532
2533                 if (o.containment) {
2534                         curleft += $(o.containment).scrollLeft() || 0;
2535                         curtop += $(o.containment).scrollTop() || 0;
2536                 }
2537
2538                 //Store needed variables
2539                 this.offset = this.helper.offset();
2540                 this.position = { left: curleft, top: curtop };
2541                 this.size = this._helper ? { width: el.outerWidth(), height: el.outerHeight() } : { width: el.width(), height: el.height() };
2542                 this.originalSize = this._helper ? { width: el.outerWidth(), height: el.outerHeight() } : { width: el.width(), height: el.height() };
2543                 this.originalPosition = { left: curleft, top: curtop };
2544                 this.sizeDiff = { width: el.outerWidth() - el.width(), height: el.outerHeight() - el.height() };
2545                 this.originalMousePosition = { left: event.pageX, top: event.pageY };
2546
2547                 //Aspect Ratio
2548                 this.aspectRatio = (typeof o.aspectRatio === "number") ? o.aspectRatio : ((this.originalSize.width / this.originalSize.height) || 1);
2549
2550                 cursor = $(".ui-resizable-" + this.axis).css("cursor");
2551                 $("body").css("cursor", cursor === "auto" ? this.axis + "-resize" : cursor);
2552
2553                 el.addClass("ui-resizable-resizing");
2554                 this._propagate("start", event);
2555                 return true;
2556         },
2557
2558         _mouseDrag: function(event) {
2559
2560                 //Increase performance, avoid regex
2561                 var data,
2562                         el = this.helper, props = {},
2563                         smp = this.originalMousePosition,
2564                         a = this.axis,
2565                         prevTop = this.position.top,
2566                         prevLeft = this.position.left,
2567                         prevWidth = this.size.width,
2568                         prevHeight = this.size.height,
2569                         dx = (event.pageX-smp.left)||0,
2570                         dy = (event.pageY-smp.top)||0,
2571                         trigger = this._change[a];
2572
2573                 if (!trigger) {
2574                         return false;
2575                 }
2576
2577                 // Calculate the attrs that will be change
2578                 data = trigger.apply(this, [event, dx, dy]);
2579
2580                 // Put this in the mouseDrag handler since the user can start pressing shift while resizing
2581                 this._updateVirtualBoundaries(event.shiftKey);
2582                 if (this._aspectRatio || event.shiftKey) {
2583                         data = this._updateRatio(data, event);
2584                 }
2585
2586                 data = this._respectSize(data, event);
2587
2588                 this._updateCache(data);
2589
2590                 // plugins callbacks need to be called first
2591                 this._propagate("resize", event);
2592
2593                 if (this.position.top !== prevTop) {
2594                         props.top = this.position.top + "px";
2595                 }
2596                 if (this.position.left !== prevLeft) {
2597                         props.left = this.position.left + "px";
2598                 }
2599                 if (this.size.width !== prevWidth) {
2600                         props.width = this.size.width + "px";
2601                 }
2602                 if (this.size.height !== prevHeight) {
2603                         props.height = this.size.height + "px";
2604                 }
2605                 el.css(props);
2606
2607                 if (!this._helper && this._proportionallyResizeElements.length) {
2608                         this._proportionallyResize();
2609                 }
2610
2611                 // Call the user callback if the element was resized
2612                 if ( ! $.isEmptyObject(props) ) {
2613                         this._trigger("resize", event, this.ui());
2614                 }
2615
2616                 return false;
2617         },
2618
2619         _mouseStop: function(event) {
2620
2621                 this.resizing = false;
2622                 var pr, ista, soffseth, soffsetw, s, left, top,
2623                         o = this.options, that = this;
2624
2625                 if(this._helper) {
2626
2627                         pr = this._proportionallyResizeElements;
2628                         ista = pr.length && (/textarea/i).test(pr[0].nodeName);
2629                         soffseth = ista && $.ui.hasScroll(pr[0], "left") /* TODO - jump height */ ? 0 : that.sizeDiff.height;
2630                         soffsetw = ista ? 0 : that.sizeDiff.width;
2631
2632                         s = { width: (that.helper.width()  - soffsetw), height: (that.helper.height() - soffseth) };
2633                         left = (parseInt(that.element.css("left"), 10) + (that.position.left - that.originalPosition.left)) || null;
2634                         top = (parseInt(that.element.css("top"), 10) + (that.position.top - that.originalPosition.top)) || null;
2635
2636                         if (!o.animate) {
2637                                 this.element.css($.extend(s, { top: top, left: left }));
2638                         }
2639
2640                         that.helper.height(that.size.height);
2641                         that.helper.width(that.size.width);
2642
2643                         if (this._helper && !o.animate) {
2644                                 this._proportionallyResize();
2645                         }
2646                 }
2647
2648                 $("body").css("cursor", "auto");
2649
2650                 this.element.removeClass("ui-resizable-resizing");
2651
2652                 this._propagate("stop", event);
2653
2654                 if (this._helper) {
2655                         this.helper.remove();
2656                 }
2657
2658                 return false;
2659
2660         },
2661
2662         _updateVirtualBoundaries: function(forceAspectRatio) {
2663                 var pMinWidth, pMaxWidth, pMinHeight, pMaxHeight, b,
2664                         o = this.options;
2665
2666                 b = {
2667                         minWidth: isNumber(o.minWidth) ? o.minWidth : 0,
2668                         maxWidth: isNumber(o.maxWidth) ? o.maxWidth : Infinity,
2669                         minHeight: isNumber(o.minHeight) ? o.minHeight : 0,
2670                         maxHeight: isNumber(o.maxHeight) ? o.maxHeight : Infinity
2671                 };
2672
2673                 if(this._aspectRatio || forceAspectRatio) {
2674                         // We want to create an enclosing box whose aspect ration is the requested one
2675                         // First, compute the "projected" size for each dimension based on the aspect ratio and other dimension
2676                         pMinWidth = b.minHeight * this.aspectRatio;
2677                         pMinHeight = b.minWidth / this.aspectRatio;
2678                         pMaxWidth = b.maxHeight * this.aspectRatio;
2679                         pMaxHeight = b.maxWidth / this.aspectRatio;
2680
2681                         if(pMinWidth > b.minWidth) {
2682                                 b.minWidth = pMinWidth;
2683                         }
2684                         if(pMinHeight > b.minHeight) {
2685                                 b.minHeight = pMinHeight;
2686                         }
2687                         if(pMaxWidth < b.maxWidth) {
2688                                 b.maxWidth = pMaxWidth;
2689                         }
2690                         if(pMaxHeight < b.maxHeight) {
2691                                 b.maxHeight = pMaxHeight;
2692                         }
2693                 }
2694                 this._vBoundaries = b;
2695         },
2696
2697         _updateCache: function(data) {
2698                 this.offset = this.helper.offset();
2699                 if (isNumber(data.left)) {
2700                         this.position.left = data.left;
2701                 }
2702                 if (isNumber(data.top)) {
2703                         this.position.top = data.top;
2704                 }
2705                 if (isNumber(data.height)) {
2706                         this.size.height = data.height;
2707                 }
2708                 if (isNumber(data.width)) {
2709                         this.size.width = data.width;
2710                 }
2711         },
2712
2713         _updateRatio: function( data ) {
2714
2715                 var cpos = this.position,
2716                         csize = this.size,
2717                         a = this.axis;
2718
2719                 if (isNumber(data.height)) {
2720                         data.width = (data.height * this.aspectRatio);
2721                 } else if (isNumber(data.width)) {
2722                         data.height = (data.width / this.aspectRatio);
2723                 }
2724
2725                 if (a === "sw") {
2726                         data.left = cpos.left + (csize.width - data.width);
2727                         data.top = null;
2728                 }
2729                 if (a === "nw") {
2730                         data.top = cpos.top + (csize.height - data.height);
2731                         data.left = cpos.left + (csize.width - data.width);
2732                 }
2733
2734                 return data;
2735         },
2736
2737         _respectSize: function( data ) {
2738
2739                 var o = this._vBoundaries,
2740                         a = this.axis,
2741                         ismaxw = isNumber(data.width) && o.maxWidth && (o.maxWidth < data.width), ismaxh = isNumber(data.height) && o.maxHeight && (o.maxHeight < data.height),
2742                         isminw = isNumber(data.width) && o.minWidth && (o.minWidth > data.width), isminh = isNumber(data.height) && o.minHeight && (o.minHeight > data.height),
2743                         dw = this.originalPosition.left + this.originalSize.width,
2744                         dh = this.position.top + this.size.height,
2745                         cw = /sw|nw|w/.test(a), ch = /nw|ne|n/.test(a);
2746                 if (isminw) {
2747                         data.width = o.minWidth;
2748                 }
2749                 if (isminh) {
2750                         data.height = o.minHeight;
2751                 }
2752                 if (ismaxw) {
2753                         data.width = o.maxWidth;
2754                 }
2755                 if (ismaxh) {
2756                         data.height = o.maxHeight;
2757                 }
2758
2759                 if (isminw && cw) {
2760                         data.left = dw - o.minWidth;
2761                 }
2762                 if (ismaxw && cw) {
2763                         data.left = dw - o.maxWidth;
2764                 }
2765                 if (isminh && ch) {
2766                         data.top = dh - o.minHeight;
2767                 }
2768                 if (ismaxh && ch) {
2769                         data.top = dh - o.maxHeight;
2770                 }
2771
2772                 // fixing jump error on top/left - bug #2330
2773                 if (!data.width && !data.height && !data.left && data.top) {
2774                         data.top = null;
2775                 } else if (!data.width && !data.height && !data.top && data.left) {
2776                         data.left = null;
2777                 }
2778
2779                 return data;
2780         },
2781
2782         _proportionallyResize: function() {
2783
2784                 if (!this._proportionallyResizeElements.length) {
2785                         return;
2786                 }
2787
2788                 var i, j, borders, paddings, prel,
2789                         element = this.helper || this.element;
2790
2791                 for ( i=0; i < this._proportionallyResizeElements.length; i++) {
2792
2793                         prel = this._proportionallyResizeElements[i];
2794
2795                         if (!this.borderDif) {
2796                                 this.borderDif = [];
2797                                 borders = [prel.css("borderTopWidth"), prel.css("borderRightWidth"), prel.css("borderBottomWidth"), prel.css("borderLeftWidth")];
2798                                 paddings = [prel.css("paddingTop"), prel.css("paddingRight"), prel.css("paddingBottom"), prel.css("paddingLeft")];
2799
2800                                 for ( j = 0; j < borders.length; j++ ) {
2801                                         this.borderDif[ j ] = ( parseInt( borders[ j ], 10 ) || 0 ) + ( parseInt( paddings[ j ], 10 ) || 0 );
2802                                 }
2803                         }
2804
2805                         prel.css({
2806                                 height: (element.height() - this.borderDif[0] - this.borderDif[2]) || 0,
2807                                 width: (element.width() - this.borderDif[1] - this.borderDif[3]) || 0
2808                         });
2809
2810                 }
2811
2812         },
2813
2814         _renderProxy: function() {
2815
2816                 var el = this.element, o = this.options;
2817                 this.elementOffset = el.offset();
2818
2819                 if(this._helper) {
2820
2821                         this.helper = this.helper || $("<div style='overflow:hidden;'></div>");
2822
2823                         this.helper.addClass(this._helper).css({
2824                                 width: this.element.outerWidth() - 1,
2825                                 height: this.element.outerHeight() - 1,
2826                                 position: "absolute",
2827                                 left: this.elementOffset.left +"px",
2828                                 top: this.elementOffset.top +"px",
2829                                 zIndex: ++o.zIndex //TODO: Don't modify option
2830                         });
2831
2832                         this.helper
2833                                 .appendTo("body")
2834                                 .disableSelection();
2835
2836                 } else {
2837                         this.helper = this.element;
2838                 }
2839
2840         },
2841
2842         _change: {
2843                 e: function(event, dx) {
2844                         return { width: this.originalSize.width + dx };
2845                 },
2846                 w: function(event, dx) {
2847                         var cs = this.originalSize, sp = this.originalPosition;
2848                         return { left: sp.left + dx, width: cs.width - dx };
2849                 },
2850                 n: function(event, dx, dy) {
2851                         var cs = this.originalSize, sp = this.originalPosition;
2852                         return { top: sp.top + dy, height: cs.height - dy };
2853                 },
2854                 s: function(event, dx, dy) {
2855                         return { height: this.originalSize.height + dy };
2856                 },
2857                 se: function(event, dx, dy) {
2858                         return $.extend(this._change.s.apply(this, arguments), this._change.e.apply(this, [event, dx, dy]));
2859                 },
2860                 sw: function(event, dx, dy) {
2861                         return $.extend(this._change.s.apply(this, arguments), this._change.w.apply(this, [event, dx, dy]));
2862                 },
2863                 ne: function(event, dx, dy) {
2864                         return $.extend(this._change.n.apply(this, arguments), this._change.e.apply(this, [event, dx, dy]));
2865                 },
2866                 nw: function(event, dx, dy) {
2867                         return $.extend(this._change.n.apply(this, arguments), this._change.w.apply(this, [event, dx, dy]));
2868                 }
2869         },
2870
2871         _propagate: function(n, event) {
2872                 $.ui.plugin.call(this, n, [event, this.ui()]);
2873                 (n !== "resize" && this._trigger(n, event, this.ui()));
2874         },
2875
2876         plugins: {},
2877
2878         ui: function() {
2879                 return {
2880                         originalElement: this.originalElement,
2881                         element: this.element,
2882                         helper: this.helper,
2883                         position: this.position,
2884                         size: this.size,
2885                         originalSize: this.originalSize,
2886                         originalPosition: this.originalPosition
2887                 };
2888         }
2889
2890 });
2891
2892 /*
2893  * Resizable Extensions
2894  */
2895
2896 $.ui.plugin.add("resizable", "animate", {
2897
2898         stop: function( event ) {
2899                 var that = $(this).data("ui-resizable"),
2900                         o = that.options,
2901                         pr = that._proportionallyResizeElements,
2902                         ista = pr.length && (/textarea/i).test(pr[0].nodeName),
2903                         soffseth = ista && $.ui.hasScroll(pr[0], "left") /* TODO - jump height */ ? 0 : that.sizeDiff.height,
2904                         soffsetw = ista ? 0 : that.sizeDiff.width,
2905                         style = { width: (that.size.width - soffsetw), height: (that.size.height - soffseth) },
2906                         left = (parseInt(that.element.css("left"), 10) + (that.position.left - that.originalPosition.left)) || null,
2907                         top = (parseInt(that.element.css("top"), 10) + (that.position.top - that.originalPosition.top)) || null;
2908
2909                 that.element.animate(
2910                         $.extend(style, top && left ? { top: top, left: left } : {}), {
2911                                 duration: o.animateDuration,
2912                                 easing: o.animateEasing,
2913                                 step: function() {
2914
2915                                         var data = {
2916                                                 width: parseInt(that.element.css("width"), 10),
2917                                                 height: parseInt(that.element.css("height"), 10),
2918                                                 top: parseInt(that.element.css("top"), 10),
2919                                                 left: parseInt(that.element.css("left"), 10)
2920                                         };
2921
2922                                         if (pr && pr.length) {
2923                                                 $(pr[0]).css({ width: data.width, height: data.height });
2924                                         }
2925
2926                                         // propagating resize, and updating values for each animation step
2927                                         that._updateCache(data);
2928                                         that._propagate("resize", event);
2929
2930                                 }
2931                         }
2932                 );
2933         }
2934
2935 });
2936
2937 $.ui.plugin.add("resizable", "containment", {
2938
2939         start: function() {
2940                 var element, p, co, ch, cw, width, height,
2941                         that = $(this).data("ui-resizable"),
2942                         o = that.options,
2943                         el = that.element,
2944                         oc = o.containment,
2945                         ce = (oc instanceof $) ? oc.get(0) : (/parent/.test(oc)) ? el.parent().get(0) : oc;
2946
2947                 if (!ce) {
2948                         return;
2949                 }
2950
2951                 that.containerElement = $(ce);
2952
2953                 if (/document/.test(oc) || oc === document) {
2954                         that.containerOffset = { left: 0, top: 0 };
2955                         that.containerPosition = { left: 0, top: 0 };
2956
2957                         that.parentData = {
2958                                 element: $(document), left: 0, top: 0,
2959                                 width: $(document).width(), height: $(document).height() || document.body.parentNode.scrollHeight
2960                         };
2961                 }
2962
2963                 // i'm a node, so compute top, left, right, bottom
2964                 else {
2965                         element = $(ce);
2966                         p = [];
2967                         $([ "Top", "Right", "Left", "Bottom" ]).each(function(i, name) { p[i] = num(element.css("padding" + name)); });
2968
2969                         that.containerOffset = element.offset();
2970                         that.containerPosition = element.position();
2971                         that.containerSize = { height: (element.innerHeight() - p[3]), width: (element.innerWidth() - p[1]) };
2972
2973                         co = that.containerOffset;
2974                         ch = that.containerSize.height;
2975                         cw = that.containerSize.width;
2976                         width = ($.ui.hasScroll(ce, "left") ? ce.scrollWidth : cw );
2977                         height = ($.ui.hasScroll(ce) ? ce.scrollHeight : ch);
2978
2979                         that.parentData = {
2980                                 element: ce, left: co.left, top: co.top, width: width, height: height
2981                         };
2982                 }
2983         },
2984
2985         resize: function( event ) {
2986                 var woset, hoset, isParent, isOffsetRelative,
2987                         that = $(this).data("ui-resizable"),
2988                         o = that.options,
2989                         co = that.containerOffset, cp = that.position,
2990                         pRatio = that._aspectRatio || event.shiftKey,
2991                         cop = { top:0, left:0 }, ce = that.containerElement;
2992
2993                 if (ce[0] !== document && (/static/).test(ce.css("position"))) {
2994                         cop = co;
2995                 }
2996
2997                 if (cp.left < (that._helper ? co.left : 0)) {
2998                         that.size.width = that.size.width + (that._helper ? (that.position.left - co.left) : (that.position.left - cop.left));
2999                         if (pRatio) {
3000                                 that.size.height = that.size.width / that.aspectRatio;
3001                         }
3002                         that.position.left = o.helper ? co.left : 0;
3003                 }
3004
3005                 if (cp.top < (that._helper ? co.top : 0)) {
3006                         that.size.height = that.size.height + (that._helper ? (that.position.top - co.top) : that.position.top);
3007                         if (pRatio) {
3008                                 that.size.width = that.size.height * that.aspectRatio;
3009                         }
3010                         that.position.top = that._helper ? co.top : 0;
3011                 }
3012
3013                 that.offset.left = that.parentData.left+that.position.left;
3014                 that.offset.top = that.parentData.top+that.position.top;
3015
3016                 woset = Math.abs( (that._helper ? that.offset.left - cop.left : (that.offset.left - cop.left)) + that.sizeDiff.width );
3017                 hoset = Math.abs( (that._helper ? that.offset.top - cop.top : (that.offset.top - co.top)) + that.sizeDiff.height );
3018
3019                 isParent = that.containerElement.get(0) === that.element.parent().get(0);
3020                 isOffsetRelative = /relative|absolute/.test(that.containerElement.css("position"));
3021
3022                 if(isParent && isOffsetRelative) {
3023                         woset -= that.parentData.left;
3024                 }
3025
3026                 if (woset + that.size.width >= that.parentData.width) {
3027                         that.size.width = that.parentData.width - woset;
3028                         if (pRatio) {
3029                                 that.size.height = that.size.width / that.aspectRatio;
3030                         }
3031                 }
3032
3033                 if (hoset + that.size.height >= that.parentData.height) {
3034                         that.size.height = that.parentData.height - hoset;
3035                         if (pRatio) {
3036                                 that.size.width = that.size.height * that.aspectRatio;
3037                         }
3038                 }
3039         },
3040
3041         stop: function(){
3042                 var that = $(this).data("ui-resizable"),
3043                         o = that.options,
3044                         co = that.containerOffset,
3045                         cop = that.containerPosition,
3046                         ce = that.containerElement,
3047                         helper = $(that.helper),
3048                         ho = helper.offset(),
3049                         w = helper.outerWidth() - that.sizeDiff.width,
3050                         h = helper.outerHeight() - that.sizeDiff.height;
3051
3052                 if (that._helper && !o.animate && (/relative/).test(ce.css("position"))) {
3053                         $(this).css({ left: ho.left - cop.left - co.left, width: w, height: h });
3054                 }
3055
3056                 if (that._helper && !o.animate && (/static/).test(ce.css("position"))) {
3057                         $(this).css({ left: ho.left - cop.left - co.left, width: w, height: h });
3058                 }
3059
3060         }
3061 });
3062
3063 $.ui.plugin.add("resizable", "alsoResize", {
3064
3065         start: function () {
3066                 var that = $(this).data("ui-resizable"),
3067                         o = that.options,
3068                         _store = function (exp) {
3069                                 $(exp).each(function() {
3070                                         var el = $(this);
3071                                         el.data("ui-resizable-alsoresize", {
3072                                                 width: parseInt(el.width(), 10), height: parseInt(el.height(), 10),
3073                                                 left: parseInt(el.css("left"), 10), top: parseInt(el.css("top"), 10)
3074                                         });
3075                                 });
3076                         };
3077
3078                 if (typeof(o.alsoResize) === "object" && !o.alsoResize.parentNode) {
3079                         if (o.alsoResize.length) { o.alsoResize = o.alsoResize[0]; _store(o.alsoResize); }
3080                         else { $.each(o.alsoResize, function (exp) { _store(exp); }); }
3081                 }else{
3082                         _store(o.alsoResize);
3083                 }
3084         },
3085
3086         resize: function (event, ui) {
3087                 var that = $(this).data("ui-resizable"),
3088                         o = that.options,
3089                         os = that.originalSize,
3090                         op = that.originalPosition,
3091                         delta = {
3092                                 height: (that.size.height - os.height) || 0, width: (that.size.width - os.width) || 0,
3093                                 top: (that.position.top - op.top) || 0, left: (that.position.left - op.left) || 0
3094                         },
3095
3096                         _alsoResize = function (exp, c) {
3097                                 $(exp).each(function() {
3098                                         var el = $(this), start = $(this).data("ui-resizable-alsoresize"), style = {},
3099                                                 css = c && c.length ? c : el.parents(ui.originalElement[0]).length ? ["width", "height"] : ["width", "height", "top", "left"];
3100
3101                                         $.each(css, function (i, prop) {
3102                                                 var sum = (start[prop]||0) + (delta[prop]||0);
3103                                                 if (sum && sum >= 0) {
3104                                                         style[prop] = sum || null;
3105                                                 }
3106                                         });
3107
3108                                         el.css(style);
3109                                 });
3110                         };
3111
3112                 if (typeof(o.alsoResize) === "object" && !o.alsoResize.nodeType) {
3113                         $.each(o.alsoResize, function (exp, c) { _alsoResize(exp, c); });
3114                 }else{
3115                         _alsoResize(o.alsoResize);
3116                 }
3117         },
3118
3119         stop: function () {
3120                 $(this).removeData("resizable-alsoresize");
3121         }
3122 });
3123
3124 $.ui.plugin.add("resizable", "ghost", {
3125
3126         start: function() {
3127
3128                 var that = $(this).data("ui-resizable"), o = that.options, cs = that.size;
3129
3130                 that.ghost = that.originalElement.clone();
3131                 that.ghost
3132                         .css({ opacity: 0.25, display: "block", position: "relative", height: cs.height, width: cs.width, margin: 0, left: 0, top: 0 })
3133                         .addClass("ui-resizable-ghost")
3134                         .addClass(typeof o.ghost === "string" ? o.ghost : "");
3135
3136                 that.ghost.appendTo(that.helper);
3137
3138         },
3139
3140         resize: function(){
3141                 var that = $(this).data("ui-resizable");
3142                 if (that.ghost) {
3143                         that.ghost.css({ position: "relative", height: that.size.height, width: that.size.width });
3144                 }
3145         },
3146
3147         stop: function() {
3148                 var that = $(this).data("ui-resizable");
3149                 if (that.ghost && that.helper) {
3150                         that.helper.get(0).removeChild(that.ghost.get(0));
3151                 }
3152         }
3153
3154 });
3155
3156 $.ui.plugin.add("resizable", "grid", {
3157
3158         resize: function() {
3159                 var that = $(this).data("ui-resizable"),
3160                         o = that.options,
3161                         cs = that.size,
3162                         os = that.originalSize,
3163                         op = that.originalPosition,
3164                         a = that.axis,
3165                         grid = typeof o.grid === "number" ? [o.grid, o.grid] : o.grid,
3166                         gridX = (grid[0]||1),
3167                         gridY = (grid[1]||1),
3168                         ox = Math.round((cs.width - os.width) / gridX) * gridX,
3169                         oy = Math.round((cs.height - os.height) / gridY) * gridY,
3170                         newWidth = os.width + ox,
3171                         newHeight = os.height + oy,
3172                         isMaxWidth = o.maxWidth && (o.maxWidth < newWidth),
3173                         isMaxHeight = o.maxHeight && (o.maxHeight < newHeight),
3174                         isMinWidth = o.minWidth && (o.minWidth > newWidth),
3175                         isMinHeight = o.minHeight && (o.minHeight > newHeight);
3176
3177                 o.grid = grid;
3178
3179                 if (isMinWidth) {
3180                         newWidth = newWidth + gridX;
3181                 }
3182                 if (isMinHeight) {
3183                         newHeight = newHeight + gridY;
3184                 }
3185                 if (isMaxWidth) {
3186                         newWidth = newWidth - gridX;
3187                 }
3188                 if (isMaxHeight) {
3189                         newHeight = newHeight - gridY;
3190                 }
3191
3192                 if (/^(se|s|e)$/.test(a)) {
3193                         that.size.width = newWidth;
3194                         that.size.height = newHeight;
3195                 } else if (/^(ne)$/.test(a)) {
3196                         that.size.width = newWidth;
3197                         that.size.height = newHeight;
3198                         that.position.top = op.top - oy;
3199                 } else if (/^(sw)$/.test(a)) {
3200                         that.size.width = newWidth;
3201                         that.size.height = newHeight;
3202                         that.position.left = op.left - ox;
3203                 } else {
3204                         that.size.width = newWidth;
3205                         that.size.height = newHeight;
3206                         that.position.top = op.top - oy;
3207                         that.position.left = op.left - ox;
3208                 }
3209         }
3210
3211 });
3212
3213 })(jQuery);
3214
3215 (function( $, undefined ) {
3216
3217 $.widget("ui.selectable", $.ui.mouse, {
3218         version: "1.10.2",
3219         options: {
3220                 appendTo: "body",
3221                 autoRefresh: true,
3222                 distance: 0,
3223                 filter: "*",
3224                 tolerance: "touch",
3225
3226                 // callbacks
3227                 selected: null,
3228                 selecting: null,
3229                 start: null,
3230                 stop: null,
3231                 unselected: null,
3232                 unselecting: null
3233         },
3234         _create: function() {
3235                 var selectees,
3236                         that = this;
3237
3238                 this.element.addClass("ui-selectable");
3239
3240                 this.dragged = false;
3241
3242                 // cache selectee children based on filter
3243                 this.refresh = function() {
3244                         selectees = $(that.options.filter, that.element[0]);
3245                         selectees.addClass("ui-selectee");
3246                         selectees.each(function() {
3247                                 var $this = $(this),
3248                                         pos = $this.offset();
3249                                 $.data(this, "selectable-item", {
3250                                         element: this,
3251                                         $element: $this,
3252                                         left: pos.left,
3253                                         top: pos.top,
3254                                         right: pos.left + $this.outerWidth(),
3255                                         bottom: pos.top + $this.outerHeight(),
3256                                         startselected: false,
3257                                         selected: $this.hasClass("ui-selected"),
3258                                         selecting: $this.hasClass("ui-selecting"),
3259                                         unselecting: $this.hasClass("ui-unselecting")
3260                                 });
3261                         });
3262                 };
3263                 this.refresh();
3264
3265                 this.selectees = selectees.addClass("ui-selectee");
3266
3267                 this._mouseInit();
3268
3269                 this.helper = $("<div class='ui-selectable-helper'></div>");
3270         },
3271
3272         _destroy: function() {
3273                 this.selectees
3274                         .removeClass("ui-selectee")
3275                         .removeData("selectable-item");
3276                 this.element
3277                         .removeClass("ui-selectable ui-selectable-disabled");
3278                 this._mouseDestroy();
3279         },
3280
3281         _mouseStart: function(event) {
3282                 var that = this,
3283                         options = this.options;
3284
3285                 this.opos = [event.pageX, event.pageY];
3286
3287                 if (this.options.disabled) {
3288                         return;
3289                 }
3290
3291                 this.selectees = $(options.filter, this.element[0]);
3292
3293                 this._trigger("start", event);
3294
3295                 $(options.appendTo).append(this.helper);
3296                 // position helper (lasso)
3297                 this.helper.css({
3298                         "left": event.pageX,
3299                         "top": event.pageY,
3300                         "width": 0,
3301                         "height": 0
3302                 });
3303
3304                 if (options.autoRefresh) {
3305                         this.refresh();
3306                 }
3307
3308                 this.selectees.filter(".ui-selected").each(function() {
3309                         var selectee = $.data(this, "selectable-item");
3310                         selectee.startselected = true;
3311                         if (!event.metaKey && !event.ctrlKey) {
3312                                 selectee.$element.removeClass("ui-selected");
3313                                 selectee.selected = false;
3314                                 selectee.$element.addClass("ui-unselecting");
3315                                 selectee.unselecting = true;
3316                                 // selectable UNSELECTING callback
3317                                 that._trigger("unselecting", event, {
3318                                         unselecting: selectee.element
3319                                 });
3320                         }
3321                 });
3322
3323                 $(event.target).parents().addBack().each(function() {
3324                         var doSelect,
3325                                 selectee = $.data(this, "selectable-item");
3326                         if (selectee) {
3327                                 doSelect = (!event.metaKey && !event.ctrlKey) || !selectee.$element.hasClass("ui-selected");
3328                                 selectee.$element
3329                                         .removeClass(doSelect ? "ui-unselecting" : "ui-selected")
3330                                         .addClass(doSelect ? "ui-selecting" : "ui-unselecting");
3331                                 selectee.unselecting = !doSelect;
3332                                 selectee.selecting = doSelect;
3333                                 selectee.selected = doSelect;
3334                                 // selectable (UN)SELECTING callback
3335                                 if (doSelect) {
3336                                         that._trigger("selecting", event, {
3337                                                 selecting: selectee.element
3338                                         });
3339                                 } else {
3340                                         that._trigger("unselecting", event, {
3341                                                 unselecting: selectee.element
3342                                         });
3343                                 }
3344                                 return false;
3345                         }
3346                 });
3347
3348         },
3349
3350         _mouseDrag: function(event) {
3351
3352                 this.dragged = true;
3353
3354                 if (this.options.disabled) {
3355                         return;
3356                 }
3357
3358                 var tmp,
3359                         that = this,
3360                         options = this.options,
3361                         x1 = this.opos[0],
3362                         y1 = this.opos[1],
3363                         x2 = event.pageX,
3364                         y2 = event.pageY;
3365
3366                 if (x1 > x2) { tmp = x2; x2 = x1; x1 = tmp; }
3367                 if (y1 > y2) { tmp = y2; y2 = y1; y1 = tmp; }
3368                 this.helper.css({left: x1, top: y1, width: x2-x1, height: y2-y1});
3369
3370                 this.selectees.each(function() {
3371                         var selectee = $.data(this, "selectable-item"),
3372                                 hit = false;
3373
3374                         //prevent helper from being selected if appendTo: selectable
3375                         if (!selectee || selectee.element === that.element[0]) {
3376                                 return;
3377                         }
3378
3379                         if (options.tolerance === "touch") {
3380                                 hit = ( !(selectee.left > x2 || selectee.right < x1 || selectee.top > y2 || selectee.bottom < y1) );
3381                         } else if (options.tolerance === "fit") {
3382                                 hit = (selectee.left > x1 && selectee.right < x2 && selectee.top > y1 && selectee.bottom < y2);
3383                         }
3384
3385                         if (hit) {
3386                                 // SELECT
3387                                 if (selectee.selected) {
3388                                         selectee.$element.removeClass("ui-selected");
3389                                         selectee.selected = false;
3390                                 }
3391                                 if (selectee.unselecting) {
3392                                         selectee.$element.removeClass("ui-unselecting");
3393                                         selectee.unselecting = false;
3394                                 }
3395                                 if (!selectee.selecting) {
3396                                         selectee.$element.addClass("ui-selecting");
3397                                         selectee.selecting = true;
3398                                         // selectable SELECTING callback
3399                                         that._trigger("selecting", event, {
3400                                                 selecting: selectee.element
3401                                         });
3402                                 }
3403                         } else {
3404                                 // UNSELECT
3405                                 if (selectee.selecting) {
3406                                         if ((event.metaKey || event.ctrlKey) && selectee.startselected) {
3407                                                 selectee.$element.removeClass("ui-selecting");
3408                                                 selectee.selecting = false;
3409                                                 selectee.$element.addClass("ui-selected");
3410                                                 selectee.selected = true;
3411                                         } else {
3412                                                 selectee.$element.removeClass("ui-selecting");
3413                                                 selectee.selecting = false;
3414                                                 if (selectee.startselected) {
3415                                                         selectee.$element.addClass("ui-unselecting");
3416                                                         selectee.unselecting = true;
3417                                                 }
3418                                                 // selectable UNSELECTING callback
3419                                                 that._trigger("unselecting", event, {
3420                                                         unselecting: selectee.element
3421                                                 });
3422                                         }
3423                                 }
3424                                 if (selectee.selected) {
3425                                         if (!event.metaKey && !event.ctrlKey && !selectee.startselected) {
3426                                                 selectee.$element.removeClass("ui-selected");
3427                                                 selectee.selected = false;
3428
3429                                                 selectee.$element.addClass("ui-unselecting");
3430                                                 selectee.unselecting = true;
3431                                                 // selectable UNSELECTING callback
3432                                                 that._trigger("unselecting", event, {
3433                                                         unselecting: selectee.element
3434                                                 });
3435                                         }
3436                                 }
3437                         }
3438                 });
3439
3440                 return false;
3441         },
3442
3443         _mouseStop: function(event) {
3444                 var that = this;
3445
3446                 this.dragged = false;
3447
3448                 $(".ui-unselecting", this.element[0]).each(function() {
3449                         var selectee = $.data(this, "selectable-item");
3450                         selectee.$element.removeClass("ui-unselecting");
3451                         selectee.unselecting = false;
3452                         selectee.startselected = false;
3453                         that._trigger("unselected", event, {
3454                                 unselected: selectee.element
3455                         });
3456                 });
3457                 $(".ui-selecting", this.element[0]).each(function() {
3458                         var selectee = $.data(this, "selectable-item");
3459                         selectee.$element.removeClass("ui-selecting").addClass("ui-selected");
3460                         selectee.selecting = false;
3461                         selectee.selected = true;
3462                         selectee.startselected = true;
3463                         that._trigger("selected", event, {
3464                                 selected: selectee.element
3465                         });
3466                 });
3467                 this._trigger("stop", event);
3468
3469                 this.helper.remove();
3470
3471                 return false;
3472         }
3473
3474 });
3475
3476 })(jQuery);
3477
3478 (function( $, undefined ) {
3479
3480 /*jshint loopfunc: true */
3481
3482 function isOverAxis( x, reference, size ) {
3483         return ( x > reference ) && ( x < ( reference + size ) );
3484 }
3485
3486 function isFloating(item) {
3487         return (/left|right/).test(item.css("float")) || (/inline|table-cell/).test(item.css("display"));
3488 }
3489
3490 $.widget("ui.sortable", $.ui.mouse, {
3491         version: "1.10.2",
3492         widgetEventPrefix: "sort",
3493         ready: false,
3494         options: {
3495                 appendTo: "parent",
3496                 axis: false,
3497                 connectWith: false,
3498                 containment: false,
3499                 cursor: "auto",
3500                 cursorAt: false,
3501                 dropOnEmpty: true,
3502                 forcePlaceholderSize: false,
3503                 forceHelperSize: false,
3504                 grid: false,
3505                 handle: false,
3506                 helper: "original",
3507                 items: "> *",
3508                 opacity: false,
3509                 placeholder: false,
3510                 revert: false,
3511                 scroll: true,
3512                 scrollSensitivity: 20,
3513                 scrollSpeed: 20,
3514                 scope: "default",
3515                 tolerance: "intersect",
3516                 zIndex: 1000,
3517
3518                 // callbacks
3519                 activate: null,
3520                 beforeStop: null,
3521                 change: null,
3522                 deactivate: null,
3523                 out: null,
3524                 over: null,
3525                 receive: null,
3526                 remove: null,
3527                 sort: null,
3528                 start: null,
3529                 stop: null,
3530                 update: null
3531         },
3532         _create: function() {
3533
3534                 var o = this.options;
3535                 this.containerCache = {};
3536                 this.element.addClass("ui-sortable");
3537
3538                 //Get the items
3539                 this.refresh();
3540
3541                 //Let's determine if the items are being displayed horizontally
3542                 this.floating = this.items.length ? o.axis === "x" || isFloating(this.items[0].item) : false;
3543
3544                 //Let's determine the parent's offset
3545                 this.offset = this.element.offset();
3546
3547                 //Initialize mouse events for interaction
3548                 this._mouseInit();
3549
3550                 //We're ready to go
3551                 this.ready = true;
3552
3553         },
3554
3555         _destroy: function() {
3556                 this.element
3557                         .removeClass("ui-sortable ui-sortable-disabled");
3558                 this._mouseDestroy();
3559
3560                 for ( var i = this.items.length - 1; i >= 0; i-- ) {
3561                         this.items[i].item.removeData(this.widgetName + "-item");
3562                 }
3563
3564                 return this;
3565         },
3566
3567         _setOption: function(key, value){
3568                 if ( key === "disabled" ) {
3569                         this.options[ key ] = value;
3570
3571                         this.widget().toggleClass( "ui-sortable-disabled", !!value );
3572                 } else {
3573                         // Don't call widget base _setOption for disable as it adds ui-state-disabled class
3574                         $.Widget.prototype._setOption.apply(this, arguments);
3575                 }
3576         },
3577
3578         _mouseCapture: function(event, overrideHandle) {
3579                 var currentItem = null,
3580                         validHandle = false,
3581                         that = this;
3582
3583                 if (this.reverting) {
3584                         return false;
3585                 }
3586
3587                 if(this.options.disabled || this.options.type === "static") {
3588                         return false;
3589                 }
3590
3591                 //We have to refresh the items data once first
3592                 this._refreshItems(event);
3593
3594                 //Find out if the clicked node (or one of its parents) is a actual item in this.items
3595                 $(event.target).parents().each(function() {
3596                         if($.data(this, that.widgetName + "-item") === that) {
3597                                 currentItem = $(this);
3598                                 return false;
3599                         }
3600                 });
3601                 if($.data(event.target, that.widgetName + "-item") === that) {
3602                         currentItem = $(event.target);
3603                 }
3604
3605                 if(!currentItem) {
3606                         return false;
3607                 }
3608                 if(this.options.handle && !overrideHandle) {
3609                         $(this.options.handle, currentItem).find("*").addBack().each(function() {
3610                                 if(this === event.target) {
3611                                         validHandle = true;
3612                                 }
3613                         });
3614                         if(!validHandle) {
3615                                 return false;
3616                         }
3617                 }
3618
3619                 this.currentItem = currentItem;
3620                 this._removeCurrentsFromItems();
3621                 return true;
3622
3623         },
3624
3625         _mouseStart: function(event, overrideHandle, noActivation) {
3626
3627                 var i, body,
3628                         o = this.options;
3629
3630                 this.currentContainer = this;
3631
3632                 //We only need to call refreshPositions, because the refreshItems call has been moved to mouseCapture
3633                 this.refreshPositions();
3634
3635                 //Create and append the visible helper
3636                 this.helper = this._createHelper(event);
3637
3638                 //Cache the helper size
3639                 this._cacheHelperProportions();
3640
3641                 /*
3642                  * - Position generation -
3643                  * This block generates everything position related - it's the core of draggables.
3644                  */
3645
3646                 //Cache the margins of the original element
3647                 this._cacheMargins();
3648
3649                 //Get the next scrolling parent
3650                 this.scrollParent = this.helper.scrollParent();
3651
3652                 //The element's absolute position on the page minus margins
3653                 this.offset = this.currentItem.offset();
3654                 this.offset = {
3655                         top: this.offset.top - this.margins.top,
3656                         left: this.offset.left - this.margins.left
3657                 };
3658
3659                 $.extend(this.offset, {
3660                         click: { //Where the click happened, relative to the element
3661                                 left: event.pageX - this.offset.left,
3662                                 top: event.pageY - this.offset.top
3663                         },
3664                         parent: this._getParentOffset(),
3665                         relative: this._getRelativeOffset() //This is a relative to absolute position minus the actual position calculation - only used for relative positioned helper
3666                 });
3667
3668                 // Only after we got the offset, we can change the helper's position to absolute
3669                 // TODO: Still need to figure out a way to make relative sorting possible
3670                 this.helper.css("position", "absolute");
3671                 this.cssPosition = this.helper.css("position");
3672
3673                 //Generate the original position
3674                 this.originalPosition = this._generatePosition(event);
3675                 this.originalPageX = event.pageX;
3676                 this.originalPageY = event.pageY;
3677
3678                 //Adjust the mouse offset relative to the helper if "cursorAt" is supplied
3679                 (o.cursorAt && this._adjustOffsetFromHelper(o.cursorAt));
3680
3681                 //Cache the former DOM position
3682                 this.domPosition = { prev: this.currentItem.prev()[0], parent: this.currentItem.parent()[0] };
3683
3684                 //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
3685                 if(this.helper[0] !== this.currentItem[0]) {
3686                         this.currentItem.hide();
3687                 }
3688
3689                 //Create the placeholder
3690                 this._createPlaceholder();
3691
3692                 //Set a containment if given in the options
3693                 if(o.containment) {
3694                         this._setContainment();
3695                 }
3696
3697                 if( o.cursor && o.cursor !== "auto" ) { // cursor option
3698                         body = this.document.find( "body" );
3699
3700                         // support: IE
3701                         this.storedCursor = body.css( "cursor" );
3702                         body.css( "cursor", o.cursor );
3703
3704                         this.storedStylesheet = $( "<style>*{ cursor: "+o.cursor+" !important; }</style>" ).appendTo( body );
3705                 }
3706
3707                 if(o.opacity) { // opacity option
3708                         if (this.helper.css("opacity")) {
3709                                 this._storedOpacity = this.helper.css("opacity");
3710                         }
3711                         this.helper.css("opacity", o.opacity);
3712                 }
3713
3714                 if(o.zIndex) { // zIndex option
3715                         if (this.helper.css("zIndex")) {
3716                                 this._storedZIndex = this.helper.css("zIndex");
3717                         }
3718                         this.helper.css("zIndex", o.zIndex);
3719                 }
3720
3721                 //Prepare scrolling
3722                 if(this.scrollParent[0] !== document && this.scrollParent[0].tagName !== "HTML") {
3723                         this.overflowOffset = this.scrollParent.offset();
3724                 }
3725
3726                 //Call callbacks
3727                 this._trigger("start", event, this._uiHash());
3728
3729                 //Recache the helper size
3730                 if(!this._preserveHelperProportions) {
3731                         this._cacheHelperProportions();
3732                 }
3733
3734
3735                 //Post "activate" events to possible containers
3736                 if( !noActivation ) {
3737                         for ( i = this.containers.length - 1; i >= 0; i-- ) {
3738                                 this.containers[ i ]._trigger( "activate", event, this._uiHash( this ) );
3739                         }
3740                 }
3741
3742                 //Prepare possible droppables
3743                 if($.ui.ddmanager) {
3744                         $.ui.ddmanager.current = this;
3745                 }
3746
3747                 if ($.ui.ddmanager && !o.dropBehaviour) {
3748                         $.ui.ddmanager.prepareOffsets(this, event);
3749                 }
3750
3751                 this.dragging = true;
3752
3753                 this.helper.addClass("ui-sortable-helper");
3754                 this._mouseDrag(event); //Execute the drag once - this causes the helper not to be visible before getting its correct position
3755                 return true;
3756
3757         },
3758
3759         _mouseDrag: function(event) {
3760                 var i, item, itemElement, intersection,
3761                         o = this.options,
3762                         scrolled = false;
3763
3764                 //Compute the helpers position
3765                 this.position = this._generatePosition(event);
3766                 this.positionAbs = this._convertPositionTo("absolute");
3767
3768                 if (!this.lastPositionAbs) {
3769                         this.lastPositionAbs = this.positionAbs;
3770                 }
3771
3772                 //Do scrolling
3773                 if(this.options.scroll) {
3774                         if(this.scrollParent[0] !== document && this.scrollParent[0].tagName !== "HTML") {
3775
3776                                 if((this.overflowOffset.top + this.scrollParent[0].offsetHeight) - event.pageY < o.scrollSensitivity) {
3777                                         this.scrollParent[0].scrollTop = scrolled = this.scrollParent[0].scrollTop + o.scrollSpeed;
3778                                 } else if(event.pageY - this.overflowOffset.top < o.scrollSensitivity) {
3779                                         this.scrollParent[0].scrollTop = scrolled = this.scrollParent[0].scrollTop - o.scrollSpeed;
3780                                 }
3781
3782                                 if((this.overflowOffset.left + this.scrollParent[0].offsetWidth) - event.pageX < o.scrollSensitivity) {
3783                                         this.scrollParent[0].scrollLeft = scrolled = this.scrollParent[0].scrollLeft + o.scrollSpeed;
3784                                 } else if(event.pageX - this.overflowOffset.left < o.scrollSensitivity) {
3785                                         this.scrollParent[0].scrollLeft = scrolled = this.scrollParent[0].scrollLeft - o.scrollSpeed;
3786                                 }
3787
3788                         } else {
3789
3790                                 if(event.pageY - $(document).scrollTop() < o.scrollSensitivity) {
3791                                         scrolled = $(document).scrollTop($(document).scrollTop() - o.scrollSpeed);
3792                                 } else if($(window).height() - (event.pageY - $(document).scrollTop()) < o.scrollSensitivity) {
3793                                         scrolled = $(document).scrollTop($(document).scrollTop() + o.scrollSpeed);
3794                                 }
3795
3796                                 if(event.pageX - $(document).scrollLeft() < o.scrollSensitivity) {
3797                                         scrolled = $(document).scrollLeft($(document).scrollLeft() - o.scrollSpeed);
3798                                 } else if($(window).width() - (event.pageX - $(document).scrollLeft()) < o.scrollSensitivity) {
3799                                         scrolled = $(document).scrollLeft($(document).scrollLeft() + o.scrollSpeed);
3800                                 }
3801
3802                         }
3803
3804                         if(scrolled !== false && $.ui.ddmanager && !o.dropBehaviour) {
3805                                 $.ui.ddmanager.prepareOffsets(this, event);
3806                         }
3807                 }
3808
3809                 //Regenerate the absolute position used for position checks
3810                 this.positionAbs = this._convertPositionTo("absolute");
3811
3812                 //Set the helper position
3813                 if(!this.options.axis || this.options.axis !== "y") {
3814                         this.helper[0].style.left = this.position.left+"px";
3815                 }
3816                 if(!this.options.axis || this.options.axis !== "x") {
3817                         this.helper[0].style.top = this.position.top+"px";
3818                 }
3819
3820                 //Rearrange
3821                 for (i = this.items.length - 1; i >= 0; i--) {
3822
3823                         //Cache variables and intersection, continue if no intersection
3824                         item = this.items[i];
3825                         itemElement = item.item[0];
3826                         intersection = this._intersectsWithPointer(item);
3827                         if (!intersection) {
3828                                 continue;
3829                         }
3830
3831                         // Only put the placeholder inside the current Container, skip all
3832                         // items form other containers. This works because when moving
3833                         // an item from one container to another the
3834                         // currentContainer is switched before the placeholder is moved.
3835                         //
3836                         // Without this moving items in "sub-sortables" can cause the placeholder to jitter
3837                         // beetween the outer and inner container.
3838                         if (item.instance !== this.currentContainer) {
3839                                 continue;
3840                         }
3841
3842                         // cannot intersect with itself
3843                         // no useless actions that have been done before
3844                         // no action if the item moved is the parent of the item checked
3845                         if (itemElement !== this.currentItem[0] &&
3846                                 this.placeholder[intersection === 1 ? "next" : "prev"]()[0] !== itemElement &&
3847                                 !$.contains(this.placeholder[0], itemElement) &&
3848                                 (this.options.type === "semi-dynamic" ? !$.contains(this.element[0], itemElement) : true)
3849                         ) {
3850
3851                                 this.direction = intersection === 1 ? "down" : "up";
3852
3853                                 if (this.options.tolerance === "pointer" || this._intersectsWithSides(item)) {
3854                                         this._rearrange(event, item);
3855                                 } else {
3856                                         break;
3857                                 }
3858
3859                                 this._trigger("change", event, this._uiHash());
3860                                 break;
3861                         }
3862                 }
3863
3864                 //Post events to containers
3865                 this._contactContainers(event);
3866
3867                 //Interconnect with droppables
3868                 if($.ui.ddmanager) {
3869                         $.ui.ddmanager.drag(this, event);
3870                 }
3871
3872                 //Call callbacks
3873                 this._trigger("sort", event, this._uiHash());
3874
3875                 this.lastPositionAbs = this.positionAbs;
3876                 return false;
3877
3878         },
3879
3880         _mouseStop: function(event, noPropagation) {
3881
3882                 if(!event) {
3883                         return;
3884                 }
3885
3886                 //If we are using droppables, inform the manager about the drop
3887                 if ($.ui.ddmanager && !this.options.dropBehaviour) {
3888                         $.ui.ddmanager.drop(this, event);
3889                 }
3890
3891                 if(this.options.revert) {
3892                         var that = this,
3893                                 cur = this.placeholder.offset(),
3894                                 axis = this.options.axis,
3895                                 animation = {};
3896
3897                         if ( !axis || axis === "x" ) {
3898                                 animation.left = cur.left - this.offset.parent.left - this.margins.left + (this.offsetParent[0] === document.body ? 0 : this.offsetParent[0].scrollLeft);
3899                         }
3900                         if ( !axis || axis === "y" ) {
3901                                 animation.top = cur.top - this.offset.parent.top - this.margins.top + (this.offsetParent[0] === document.body ? 0 : this.offsetParent[0].scrollTop);
3902                         }
3903                         this.reverting = true;
3904                         $(this.helper).animate( animation, parseInt(this.options.revert, 10) || 500, function() {
3905                                 that._clear(event);
3906                         });
3907                 } else {
3908                         this._clear(event, noPropagation);
3909                 }
3910
3911                 return false;
3912
3913         },
3914
3915         cancel: function() {
3916
3917                 if(this.dragging) {
3918
3919                         this._mouseUp({ target: null });
3920
3921                         if(this.options.helper === "original") {
3922                                 this.currentItem.css(this._storedCSS).removeClass("ui-sortable-helper");
3923                         } else {
3924                                 this.currentItem.show();
3925                         }
3926
3927                         //Post deactivating events to containers
3928                         for (var i = this.containers.length - 1; i >= 0; i--){
3929                                 this.containers[i]._trigger("deactivate", null, this._uiHash(this));
3930                                 if(this.containers[i].containerCache.over) {
3931                                         this.containers[i]._trigger("out", null, this._uiHash(this));
3932                                         this.containers[i].containerCache.over = 0;
3933                                 }
3934                         }
3935
3936                 }
3937
3938                 if (this.placeholder) {
3939                         //$(this.placeholder[0]).remove(); would have been the jQuery way - unfortunately, it unbinds ALL events from the original node!
3940                         if(this.placeholder[0].parentNode) {
3941                                 this.placeholder[0].parentNode.removeChild(this.placeholder[0]);
3942                         }
3943                         if(this.options.helper !== "original" && this.helper && this.helper[0].parentNode) {
3944                                 this.helper.remove();
3945                         }
3946
3947                         $.extend(this, {
3948                                 helper: null,
3949                                 dragging: false,
3950                                 reverting: false,
3951                                 _noFinalSort: null
3952                         });
3953
3954                         if(this.domPosition.prev) {
3955                                 $(this.domPosition.prev).after(this.currentItem);
3956                         } else {
3957                                 $(this.domPosition.parent).prepend(this.currentItem);
3958                         }
3959                 }
3960
3961                 return this;
3962
3963         },
3964
3965         serialize: function(o) {
3966
3967                 var items = this._getItemsAsjQuery(o && o.connected),
3968                         str = [];
3969                 o = o || {};
3970
3971                 $(items).each(function() {
3972                         var res = ($(o.item || this).attr(o.attribute || "id") || "").match(o.expression || (/(.+)[\-=_](.+)/));
3973                         if (res) {
3974                                 str.push((o.key || res[1]+"[]")+"="+(o.key && o.expression ? res[1] : res[2]));
3975                         }
3976                 });
3977
3978                 if(!str.length && o.key) {
3979                         str.push(o.key + "=");
3980                 }
3981
3982                 return str.join("&");
3983
3984         },
3985
3986         toArray: function(o) {
3987
3988                 var items = this._getItemsAsjQuery(o && o.connected),
3989                         ret = [];
3990
3991                 o = o || {};
3992
3993                 items.each(function() { ret.push($(o.item || this).attr(o.attribute || "id") || ""); });
3994                 return ret;
3995
3996         },
3997
3998         /* Be careful with the following core functions */
3999         _intersectsWith: function(item) {
4000
4001                 var x1 = this.positionAbs.left,
4002                         x2 = x1 + this.helperProportions.width,
4003                         y1 = this.positionAbs.top,
4004                         y2 = y1 + this.helperProportions.height,
4005                         l = item.left,
4006                         r = l + item.width,
4007                         t = item.top,
4008                         b = t + item.height,
4009                         dyClick = this.offset.click.top,
4010                         dxClick = this.offset.click.left,
4011                         isOverElement = (y1 + dyClick) > t && (y1 + dyClick) < b && (x1 + dxClick) > l && (x1 + dxClick) < r;
4012
4013                 if ( this.options.tolerance === "pointer" ||
4014                         this.options.forcePointerForContainers ||
4015                         (this.options.tolerance !== "pointer" && this.helperProportions[this.floating ? "width" : "height"] > item[this.floating ? "width" : "height"])
4016                 ) {
4017                         return isOverElement;
4018                 } else {
4019
4020                         return (l < x1 + (this.helperProportions.width / 2) && // Right Half
4021                                 x2 - (this.helperProportions.width / 2) < r && // Left Half
4022                                 t < y1 + (this.helperProportions.height / 2) && // Bottom Half
4023                                 y2 - (this.helperProportions.height / 2) < b ); // Top Half
4024
4025                 }
4026         },
4027
4028         _intersectsWithPointer: function(item) {
4029
4030                 var isOverElementHeight = (this.options.axis === "x") || isOverAxis(this.positionAbs.top + this.offset.click.top, item.top, item.height),
4031                         isOverElementWidth = (this.options.axis === "y") || isOverAxis(this.positionAbs.left + this.offset.click.left, item.left, item.width),
4032                         isOverElement = isOverElementHeight && isOverElementWidth,
4033                         verticalDirection = this._getDragVerticalDirection(),
4034                         horizontalDirection = this._getDragHorizontalDirection();
4035
4036                 if (!isOverElement) {
4037                         return false;
4038                 }
4039
4040                 return this.floating ?
4041                         ( ((horizontalDirection && horizontalDirection === "right") || verticalDirection === "down") ? 2 : 1 )
4042                         : ( verticalDirection && (verticalDirection === "down" ? 2 : 1) );
4043
4044         },
4045
4046         _intersectsWithSides: function(item) {
4047
4048                 var isOverBottomHalf = isOverAxis(this.positionAbs.top + this.offset.click.top, item.top + (item.height/2), item.height),
4049                         isOverRightHalf = isOverAxis(this.positionAbs.left + this.offset.click.left, item.left + (item.width/2), item.width),
4050                         verticalDirection = this._getDragVerticalDirection(),
4051                         horizontalDirection = this._getDragHorizontalDirection();
4052
4053                 if (this.floating && horizontalDirection) {
4054                         return ((horizontalDirection === "right" && isOverRightHalf) || (horizontalDirection === "left" && !isOverRightHalf));
4055                 } else {
4056                         return verticalDirection && ((verticalDirection === "down" && isOverBottomHalf) || (verticalDirection === "up" && !isOverBottomHalf));
4057                 }
4058
4059         },
4060
4061         _getDragVerticalDirection: function() {
4062                 var delta = this.positionAbs.top - this.lastPositionAbs.top;
4063                 return delta !== 0 && (delta > 0 ? "down" : "up");
4064         },
4065
4066         _getDragHorizontalDirection: function() {
4067                 var delta = this.positionAbs.left - this.lastPositionAbs.left;
4068                 return delta !== 0 && (delta > 0 ? "right" : "left");
4069         },
4070
4071         refresh: function(event) {
4072                 this._refreshItems(event);
4073                 this.refreshPositions();
4074                 return this;
4075         },
4076
4077         _connectWith: function() {
4078                 var options = this.options;
4079                 return options.connectWith.constructor === String ? [options.connectWith] : options.connectWith;
4080         },
4081
4082         _getItemsAsjQuery: function(connected) {
4083
4084                 var i, j, cur, inst,
4085                         items = [],
4086                         queries = [],
4087                         connectWith = this._connectWith();
4088
4089                 if(connectWith && connected) {
4090                         for (i = connectWith.length - 1; i >= 0; i--){
4091                                 cur = $(connectWith[i]);
4092                                 for ( j = cur.length - 1; j >= 0; j--){
4093                                         inst = $.data(cur[j], this.widgetFullName);
4094                                         if(inst && inst !== this && !inst.options.disabled) {
4095                                                 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]);
4096                                         }
4097                                 }
4098                         }
4099                 }
4100
4101                 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]);
4102
4103                 for (i = queries.length - 1; i >= 0; i--){
4104                         queries[i][0].each(function() {
4105                                 items.push(this);
4106                         });
4107                 }
4108
4109                 return $(items);
4110
4111         },
4112
4113         _removeCurrentsFromItems: function() {
4114
4115                 var list = this.currentItem.find(":data(" + this.widgetName + "-item)");
4116
4117                 this.items = $.grep(this.items, function (item) {
4118                         for (var j=0; j < list.length; j++) {
4119                                 if(list[j] === item.item[0]) {
4120                                         return false;
4121                                 }
4122                         }
4123                         return true;
4124                 });
4125
4126         },
4127
4128         _refreshItems: function(event) {
4129
4130                 this.items = [];
4131                 this.containers = [this];
4132
4133                 var i, j, cur, inst, targetData, _queries, item, queriesLength,
4134                         items = this.items,
4135                         queries = [[$.isFunction(this.options.items) ? this.options.items.call(this.element[0], event, { item: this.currentItem }) : $(this.options.items, this.element), this]],
4136                         connectWith = this._connectWith();
4137
4138                 if(connectWith && this.ready) { //Shouldn't be run the first time through due to massive slow-down
4139                         for (i = connectWith.length - 1; i >= 0; i--){
4140                                 cur = $(connectWith[i]);
4141                                 for (j = cur.length - 1; j >= 0; j--){
4142                                         inst = $.data(cur[j], this.widgetFullName);
4143                                         if(inst && inst !== this && !inst.options.disabled) {
4144                                                 queries.push([$.isFunction(inst.options.items) ? inst.options.items.call(inst.element[0], event, { item: this.currentItem }) : $(inst.options.items, inst.element), inst]);
4145                                                 this.containers.push(inst);
4146                                         }
4147                                 }
4148                         }
4149                 }
4150
4151                 for (i = queries.length - 1; i >= 0; i--) {
4152                         targetData = queries[i][1];
4153                         _queries = queries[i][0];
4154
4155                         for (j=0, queriesLength = _queries.length; j < queriesLength; j++) {
4156                                 item = $(_queries[j]);
4157
4158                                 item.data(this.widgetName + "-item", targetData); // Data for target checking (mouse manager)
4159
4160                                 items.push({
4161                                         item: item,
4162                                         instance: targetData,
4163                                         width: 0, height: 0,
4164                                         left: 0, top: 0
4165                                 });
4166                         }
4167                 }
4168
4169         },
4170
4171         refreshPositions: function(fast) {
4172
4173                 //This has to be redone because due to the item being moved out/into the offsetParent, the offsetParent's position will change
4174                 if(this.offsetParent && this.helper) {
4175                         this.offset.parent = this._getParentOffset();
4176                 }
4177
4178                 var i, item, t, p;
4179
4180                 for (i = this.items.length - 1; i >= 0; i--){
4181                         item = this.items[i];
4182
4183                         //We ignore calculating positions of all connected containers when we're not over them
4184                         if(item.instance !== this.currentContainer && this.currentContainer && item.item[0] !== this.currentItem[0]) {
4185                                 continue;
4186                         }
4187
4188                         t = this.options.toleranceElement ? $(this.options.toleranceElement, item.item) : item.item;
4189
4190                         if (!fast) {
4191                                 item.width = t.outerWidth();
4192                                 item.height = t.outerHeight();
4193                         }
4194
4195                         p = t.offset();
4196                         item.left = p.left;
4197                         item.top = p.top;
4198                 }
4199
4200                 if(this.options.custom && this.options.custom.refreshContainers) {
4201                         this.options.custom.refreshContainers.call(this);
4202                 } else {
4203                         for (i = this.containers.length - 1; i >= 0; i--){
4204                                 p = this.containers[i].element.offset();
4205                                 this.containers[i].containerCache.left = p.left;
4206                                 this.containers[i].containerCache.top = p.top;
4207                                 this.containers[i].containerCache.width = this.containers[i].element.outerWidth();
4208                                 this.containers[i].containerCache.height = this.containers[i].element.outerHeight();
4209                         }
4210                 }
4211
4212                 return this;
4213         },
4214
4215         _createPlaceholder: function(that) {
4216                 that = that || this;
4217                 var className,
4218                         o = that.options;
4219
4220                 if(!o.placeholder || o.placeholder.constructor === String) {
4221                         className = o.placeholder;
4222                         o.placeholder = {
4223                                 element: function() {
4224
4225                                         var nodeName = that.currentItem[0].nodeName.toLowerCase(),
4226                                                 element = $( that.document[0].createElement( nodeName ) )
4227                                                         .addClass(className || that.currentItem[0].className+" ui-sortable-placeholder")
4228                                                         .removeClass("ui-sortable-helper");
4229
4230                                         if ( nodeName === "tr" ) {
4231                                                 // Use a high colspan to force the td to expand the full
4232                                                 // width of the table (browsers are smart enough to
4233                                                 // handle this properly)
4234                                                 element.append( "<td colspan='99'>&#160;</td>" );
4235                                         } else if ( nodeName === "img" ) {
4236                                                 element.attr( "src", that.currentItem.attr( "src" ) );
4237                                         }
4238
4239                                         if ( !className ) {
4240                                                 element.css( "visibility", "hidden" );
4241                                         }
4242
4243                                         return element;
4244                                 },
4245                                 update: function(container, p) {
4246
4247                                         // 1. If a className is set as 'placeholder option, we don't force sizes - the class is responsible for that
4248                                         // 2. The option 'forcePlaceholderSize can be enabled to force it even if a class name is specified
4249                                         if(className && !o.forcePlaceholderSize) {
4250                                                 return;
4251                                         }
4252
4253                                         //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
4254                                         if(!p.height()) { p.height(that.currentItem.innerHeight() - parseInt(that.currentItem.css("paddingTop")||0, 10) - parseInt(that.currentItem.css("paddingBottom")||0, 10)); }
4255                                         if(!p.width()) { p.width(that.currentItem.innerWidth() - parseInt(that.currentItem.css("paddingLeft")||0, 10) - parseInt(that.currentItem.css("paddingRight")||0, 10)); }
4256                                 }
4257                         };
4258                 }
4259
4260                 //Create the placeholder
4261                 that.placeholder = $(o.placeholder.element.call(that.element, that.currentItem));
4262
4263                 //Append it after the actual current item
4264                 that.currentItem.after(that.placeholder);
4265
4266                 //Update the size of the placeholder (TODO: Logic to fuzzy, see line 316/317)
4267                 o.placeholder.update(that, that.placeholder);
4268
4269         },
4270
4271         _contactContainers: function(event) {
4272                 var i, j, dist, itemWithLeastDistance, posProperty, sizeProperty, base, cur, nearBottom, floating,
4273                         innermostContainer = null,
4274                         innermostIndex = null;
4275
4276                 // get innermost container that intersects with item
4277                 for (i = this.containers.length - 1; i >= 0; i--) {
4278
4279                         // never consider a container that's located within the item itself
4280                         if($.contains(this.currentItem[0], this.containers[i].element[0])) {
4281                                 continue;
4282                         }
4283
4284                         if(this._intersectsWith(this.containers[i].containerCache)) {
4285
4286                                 // if we've already found a container and it's more "inner" than this, then continue
4287                                 if(innermostContainer && $.contains(this.containers[i].element[0], innermostContainer.element[0])) {
4288                                         continue;
4289                                 }
4290
4291                                 innermostContainer = this.containers[i];
4292                                 innermostIndex = i;
4293
4294                         } else {
4295                                 // container doesn't intersect. trigger "out" event if necessary
4296                                 if(this.containers[i].containerCache.over) {
4297                                         this.containers[i]._trigger("out", event, this._uiHash(this));
4298                                         this.containers[i].containerCache.over = 0;
4299                                 }
4300                         }
4301
4302                 }
4303
4304                 // if no intersecting containers found, return
4305                 if(!innermostContainer) {
4306                         return;
4307                 }
4308
4309                 // move the item into the container if it's not there already
4310                 if(this.containers.length === 1) {
4311                         if (!this.containers[innermostIndex].containerCache.over) {
4312                                 this.containers[innermostIndex]._trigger("over", event, this._uiHash(this));
4313                                 this.containers[innermostIndex].containerCache.over = 1;
4314                         }
4315                 } else {
4316
4317                         //When entering a new container, we will find the item with the least distance and append our item near it
4318                         dist = 10000;
4319                         itemWithLeastDistance = null;
4320                         floating = innermostContainer.floating || isFloating(this.currentItem);
4321                         posProperty = floating ? "left" : "top";
4322                         sizeProperty = floating ? "width" : "height";
4323                         base = this.positionAbs[posProperty] + this.offset.click[posProperty];
4324                         for (j = this.items.length - 1; j >= 0; j--) {
4325                                 if(!$.contains(this.containers[innermostIndex].element[0], this.items[j].item[0])) {
4326                                         continue;
4327                                 }
4328                                 if(this.items[j].item[0] === this.currentItem[0]) {
4329                                         continue;
4330                                 }
4331                                 if (floating && !isOverAxis(this.positionAbs.top + this.offset.click.top, this.items[j].top, this.items[j].height)) {
4332                                         continue;
4333                                 }
4334                                 cur = this.items[j].item.offset()[posProperty];
4335                                 nearBottom = false;
4336                                 if(Math.abs(cur - base) > Math.abs(cur + this.items[j][sizeProperty] - base)){
4337                                         nearBottom = true;
4338                                         cur += this.items[j][sizeProperty];
4339                                 }
4340
4341                                 if(Math.abs(cur - base) < dist) {
4342                                         dist = Math.abs(cur - base); itemWithLeastDistance = this.items[j];
4343                                         this.direction = nearBottom ? "up": "down";
4344                                 }
4345                         }
4346
4347                         //Check if dropOnEmpty is enabled
4348                         if(!itemWithLeastDistance && !this.options.dropOnEmpty) {
4349                                 return;
4350                         }
4351
4352                         if(this.currentContainer === this.containers[innermostIndex]) {
4353                                 return;
4354                         }
4355
4356                         itemWithLeastDistance ? this._rearrange(event, itemWithLeastDistance, null, true) : this._rearrange(event, null, this.containers[innermostIndex].element, true);
4357                         this._trigger("change", event, this._uiHash());
4358                         this.containers[innermostIndex]._trigger("change", event, this._uiHash(this));
4359                         this.currentContainer = this.containers[innermostIndex];
4360
4361                         //Update the placeholder
4362                         this.options.placeholder.update(this.currentContainer, this.placeholder);
4363
4364                         this.containers[innermostIndex]._trigger("over", event, this._uiHash(this));
4365                         this.containers[innermostIndex].containerCache.over = 1;
4366                 }
4367
4368
4369         },
4370
4371         _createHelper: function(event) {
4372
4373                 var o = this.options,
4374                         helper = $.isFunction(o.helper) ? $(o.helper.apply(this.element[0], [event, this.currentItem])) : (o.helper === "clone" ? this.currentItem.clone() : this.currentItem);
4375
4376                 //Add the helper to the DOM if that didn't happen already
4377                 if(!helper.parents("body").length) {
4378                         $(o.appendTo !== "parent" ? o.appendTo : this.currentItem[0].parentNode)[0].appendChild(helper[0]);
4379                 }
4380
4381                 if(helper[0] === this.currentItem[0]) {
4382                         this._storedCSS = { width: this.currentItem[0].style.width, height: this.currentItem[0].style.height, position: this.currentItem.css("position"), top: this.currentItem.css("top"), left: this.currentItem.css("left") };
4383                 }
4384
4385                 if(!helper[0].style.width || o.forceHelperSize) {
4386                         helper.width(this.currentItem.width());
4387                 }
4388                 if(!helper[0].style.height || o.forceHelperSize) {
4389                         helper.height(this.currentItem.height());
4390                 }
4391
4392                 return helper;
4393
4394         },
4395
4396         _adjustOffsetFromHelper: function(obj) {
4397                 if (typeof obj === "string") {
4398                         obj = obj.split(" ");
4399                 }
4400                 if ($.isArray(obj)) {
4401                         obj = {left: +obj[0], top: +obj[1] || 0};
4402                 }
4403                 if ("left" in obj) {
4404                         this.offset.click.left = obj.left + this.margins.left;
4405                 }
4406                 if ("right" in obj) {
4407                         this.offset.click.left = this.helperProportions.width - obj.right + this.margins.left;
4408                 }
4409                 if ("top" in obj) {
4410                         this.offset.click.top = obj.top + this.margins.top;
4411                 }
4412                 if ("bottom" in obj) {
4413                         this.offset.click.top = this.helperProportions.height - obj.bottom + this.margins.top;
4414                 }
4415         },
4416
4417         _getParentOffset: function() {
4418
4419
4420                 //Get the offsetParent and cache its position
4421                 this.offsetParent = this.helper.offsetParent();
4422                 var po = this.offsetParent.offset();
4423
4424                 // This is a special case where we need to modify a offset calculated on start, since the following happened:
4425                 // 1. The position of the helper is absolute, so it's position is calculated based on the next positioned parent
4426                 // 2. The actual offset parent is a child of the scroll parent, and the scroll parent isn't the document, which means that
4427                 //    the scroll is included in the initial calculation of the offset of the parent, and never recalculated upon drag
4428                 if(this.cssPosition === "absolute" && this.scrollParent[0] !== document && $.contains(this.scrollParent[0], this.offsetParent[0])) {
4429                         po.left += this.scrollParent.scrollLeft();
4430                         po.top += this.scrollParent.scrollTop();
4431                 }
4432
4433                 // This needs to be actually done for all browsers, since pageX/pageY includes this information
4434                 // with an ugly IE fix
4435                 if( this.offsetParent[0] === document.body || (this.offsetParent[0].tagName && this.offsetParent[0].tagName.toLowerCase() === "html" && $.ui.ie)) {
4436                         po = { top: 0, left: 0 };
4437                 }
4438
4439                 return {
4440                         top: po.top + (parseInt(this.offsetParent.css("borderTopWidth"),10) || 0),
4441                         left: po.left + (parseInt(this.offsetParent.css("borderLeftWidth"),10) || 0)
4442                 };
4443
4444         },
4445
4446         _getRelativeOffset: function() {
4447
4448                 if(this.cssPosition === "relative") {
4449                         var p = this.currentItem.position();
4450                         return {
4451                                 top: p.top - (parseInt(this.helper.css("top"),10) || 0) + this.scrollParent.scrollTop(),
4452                                 left: p.left - (parseInt(this.helper.css("left"),10) || 0) + this.scrollParent.scrollLeft()
4453                         };
4454                 } else {
4455                         return { top: 0, left: 0 };
4456                 }
4457
4458         },
4459
4460         _cacheMargins: function() {
4461                 this.margins = {
4462                         left: (parseInt(this.currentItem.css("marginLeft"),10) || 0),
4463                         top: (parseInt(this.currentItem.css("marginTop"),10) || 0)
4464                 };
4465         },
4466
4467         _cacheHelperProportions: function() {
4468                 this.helperProportions = {
4469                         width: this.helper.outerWidth(),
4470                         height: this.helper.outerHeight()
4471                 };
4472         },
4473
4474         _setContainment: function() {
4475
4476                 var ce, co, over,
4477                         o = this.options;
4478                 if(o.containment === "parent") {
4479                         o.containment = this.helper[0].parentNode;
4480                 }
4481                 if(o.containment === "document" || o.containment === "window") {
4482                         this.containment = [
4483                                 0 - this.offset.relative.left - this.offset.parent.left,
4484                                 0 - this.offset.relative.top - this.offset.parent.top,
4485                                 $(o.containment === "document" ? document : window).width() - this.helperProportions.width - this.margins.left,
4486                                 ($(o.containment === "document" ? document : window).height() || document.body.parentNode.scrollHeight) - this.helperProportions.height - this.margins.top
4487                         ];
4488                 }
4489
4490                 if(!(/^(document|window|parent)$/).test(o.containment)) {
4491                         ce = $(o.containment)[0];
4492                         co = $(o.containment).offset();
4493                         over = ($(ce).css("overflow") !== "hidden");
4494
4495                         this.containment = [
4496                                 co.left + (parseInt($(ce).css("borderLeftWidth"),10) || 0) + (parseInt($(ce).css("paddingLeft"),10) || 0) - this.margins.left,
4497                                 co.top + (parseInt($(ce).css("borderTopWidth"),10) || 0) + (parseInt($(ce).css("paddingTop"),10) || 0) - this.margins.top,
4498                                 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,
4499                                 co.top+(over ? Math.max(ce.scrollHeight,ce.offsetHeight) : ce.offsetHeight) - (parseInt($(ce).css("borderTopWidth"),10) || 0) - (parseInt($(ce).css("paddingBottom"),10) || 0) - this.helperProportions.height - this.margins.top
4500                         ];
4501                 }
4502
4503         },
4504
4505         _convertPositionTo: function(d, pos) {
4506
4507                 if(!pos) {
4508                         pos = this.position;
4509                 }
4510                 var mod = d === "absolute" ? 1 : -1,
4511                         scroll = this.cssPosition === "absolute" && !(this.scrollParent[0] !== document && $.contains(this.scrollParent[0], this.offsetParent[0])) ? this.offsetParent : this.scrollParent,
4512                         scrollIsRootNode = (/(html|body)/i).test(scroll[0].tagName);
4513
4514                 return {
4515                         top: (
4516                                 pos.top +                                                                                                                               // The absolute mouse position
4517                                 this.offset.relative.top * mod +                                                                                // Only for relative positioned nodes: Relative offset from element to offset parent
4518                                 this.offset.parent.top * mod -                                                                                  // The offsetParent's offset without borders (offset + border)
4519                                 ( ( this.cssPosition === "fixed" ? -this.scrollParent.scrollTop() : ( scrollIsRootNode ? 0 : scroll.scrollTop() ) ) * mod)
4520                         ),
4521                         left: (
4522                                 pos.left +                                                                                                                              // The absolute mouse position
4523                                 this.offset.relative.left * mod +                                                                               // Only for relative positioned nodes: Relative offset from element to offset parent
4524                                 this.offset.parent.left * mod   -                                                                               // The offsetParent's offset without borders (offset + border)
4525                                 ( ( this.cssPosition === "fixed" ? -this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 : scroll.scrollLeft() ) * mod)
4526                         )
4527                 };
4528
4529         },
4530
4531         _generatePosition: function(event) {
4532
4533                 var top, left,
4534                         o = this.options,
4535                         pageX = event.pageX,
4536                         pageY = event.pageY,
4537                         scroll = this.cssPosition === "absolute" && !(this.scrollParent[0] !== document && $.contains(this.scrollParent[0], this.offsetParent[0])) ? this.offsetParent : this.scrollParent, scrollIsRootNode = (/(html|body)/i).test(scroll[0].tagName);
4538
4539                 // This is another very weird special case that only happens for relative elements:
4540                 // 1. If the css position is relative
4541                 // 2. and the scroll parent is the document or similar to the offset parent
4542                 // we have to refresh the relative offset during the scroll so there are no jumps
4543                 if(this.cssPosition === "relative" && !(this.scrollParent[0] !== document && this.scrollParent[0] !== this.offsetParent[0])) {
4544                         this.offset.relative = this._getRelativeOffset();
4545                 }
4546
4547                 /*
4548                  * - Position constraining -
4549                  * Constrain the position to a mix of grid, containment.
4550                  */
4551
4552                 if(this.originalPosition) { //If we are not dragging yet, we won't check for options
4553
4554                         if(this.containment) {
4555                                 if(event.pageX - this.offset.click.left < this.containment[0]) {
4556                                         pageX = this.containment[0] + this.offset.click.left;
4557                                 }
4558                                 if(event.pageY - this.offset.click.top < this.containment[1]) {
4559                                         pageY = this.containment[1] + this.offset.click.top;
4560                                 }
4561                                 if(event.pageX - this.offset.click.left > this.containment[2]) {
4562                                         pageX = this.containment[2] + this.offset.click.left;
4563                                 }
4564                                 if(event.pageY - this.offset.click.top > this.containment[3]) {
4565                                         pageY = this.containment[3] + this.offset.click.top;
4566                                 }
4567                         }
4568
4569                         if(o.grid) {
4570                                 top = this.originalPageY + Math.round((pageY - this.originalPageY) / o.grid[1]) * o.grid[1];
4571                                 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;
4572
4573                                 left = this.originalPageX + Math.round((pageX - this.originalPageX) / o.grid[0]) * o.grid[0];
4574                                 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;
4575                         }
4576
4577                 }
4578
4579                 return {
4580                         top: (
4581                                 pageY -                                                                                                                         // The absolute mouse position
4582                                 this.offset.click.top -                                                                                                 // Click offset (relative to the element)
4583                                 this.offset.relative.top        -                                                                                       // Only for relative positioned nodes: Relative offset from element to offset parent
4584                                 this.offset.parent.top +                                                                                                // The offsetParent's offset without borders (offset + border)
4585                                 ( ( this.cssPosition === "fixed" ? -this.scrollParent.scrollTop() : ( scrollIsRootNode ? 0 : scroll.scrollTop() ) ))
4586                         ),
4587                         left: (
4588                                 pageX -                                                                                                                         // The absolute mouse position
4589                                 this.offset.click.left -                                                                                                // Click offset (relative to the element)
4590                                 this.offset.relative.left       -                                                                                       // Only for relative positioned nodes: Relative offset from element to offset parent
4591                                 this.offset.parent.left +                                                                                               // The offsetParent's offset without borders (offset + border)
4592                                 ( ( this.cssPosition === "fixed" ? -this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 : scroll.scrollLeft() ))
4593                         )
4594                 };
4595
4596         },
4597
4598         _rearrange: function(event, i, a, hardRefresh) {
4599
4600                 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));
4601
4602                 //Various things done here to improve the performance:
4603                 // 1. we create a setTimeout, that calls refreshPositions
4604                 // 2. on the instance, we have a counter variable, that get's higher after every append
4605                 // 3. on the local scope, we copy the counter variable, and check in the timeout, if it's still the same
4606                 // 4. this lets only the last addition to the timeout stack through
4607                 this.counter = this.counter ? ++this.counter : 1;
4608                 var counter = this.counter;
4609
4610                 this._delay(function() {
4611                         if(counter === this.counter) {
4612                                 this.refreshPositions(!hardRefresh); //Precompute after each DOM insertion, NOT on mousemove
4613                         }
4614                 });
4615
4616         },
4617
4618         _clear: function(event, noPropagation) {
4619
4620                 this.reverting = false;
4621                 // We delay all events that have to be triggered to after the point where the placeholder has been removed and
4622                 // everything else normalized again
4623                 var i,
4624                         delayedTriggers = [];
4625
4626                 // We first have to update the dom position of the actual currentItem
4627                 // Note: don't do it if the current item is already removed (by a user), or it gets reappended (see #4088)
4628                 if(!this._noFinalSort && this.currentItem.parent().length) {
4629                         this.placeholder.before(this.currentItem);
4630                 }
4631                 this._noFinalSort = null;
4632
4633                 if(this.helper[0] === this.currentItem[0]) {
4634                         for(i in this._storedCSS) {
4635                                 if(this._storedCSS[i] === "auto" || this._storedCSS[i] === "static") {
4636                                         this._storedCSS[i] = "";
4637                                 }
4638                         }
4639                         this.currentItem.css(this._storedCSS).removeClass("ui-sortable-helper");
4640                 } else {
4641                         this.currentItem.show();
4642                 }
4643
4644                 if(this.fromOutside && !noPropagation) {
4645                         delayedTriggers.push(function(event) { this._trigger("receive", event, this._uiHash(this.fromOutside)); });
4646                 }
4647                 if((this.fromOutside || this.domPosition.prev !== this.currentItem.prev().not(".ui-sortable-helper")[0] || this.domPosition.parent !== this.currentItem.parent()[0]) && !noPropagation) {
4648                         delayedTriggers.push(function(event) { this._trigger("update", event, this._uiHash()); }); //Trigger update callback if the DOM position has changed
4649                 }
4650
4651                 // Check if the items Container has Changed and trigger appropriate
4652                 // events.
4653                 if (this !== this.currentContainer) {
4654                         if(!noPropagation) {
4655                                 delayedTriggers.push(function(event) { this._trigger("remove", event, this._uiHash()); });
4656                                 delayedTriggers.push((function(c) { return function(event) { c._trigger("receive", event, this._uiHash(this)); };  }).call(this, this.currentContainer));
4657                                 delayedTriggers.push((function(c) { return function(event) { c._trigger("update", event, this._uiHash(this));  }; }).call(this, this.currentContainer));
4658                         }
4659                 }
4660
4661
4662                 //Post events to containers
4663                 for (i = this.containers.length - 1; i >= 0; i--){
4664                         if(!noPropagation) {
4665                                 delayedTriggers.push((function(c) { return function(event) { c._trigger("deactivate", event, this._uiHash(this)); };  }).call(this, this.containers[i]));
4666                         }
4667                         if(this.containers[i].containerCache.over) {
4668                                 delayedTriggers.push((function(c) { return function(event) { c._trigger("out", event, this._uiHash(this)); };  }).call(this, this.containers[i]));
4669                                 this.containers[i].containerCache.over = 0;
4670                         }
4671                 }
4672
4673                 //Do what was originally in plugins
4674                 if ( this.storedCursor ) {
4675                         this.document.find( "body" ).css( "cursor", this.storedCursor );
4676                         this.storedStylesheet.remove();
4677                 }
4678                 if(this._storedOpacity) {
4679                         this.helper.css("opacity", this._storedOpacity);
4680                 }
4681                 if(this._storedZIndex) {
4682                         this.helper.css("zIndex", this._storedZIndex === "auto" ? "" : this._storedZIndex);
4683                 }
4684
4685                 this.dragging = false;
4686                 if(this.cancelHelperRemoval) {
4687                         if(!noPropagation) {
4688                                 this._trigger("beforeStop", event, this._uiHash());
4689                                 for (i=0; i < delayedTriggers.length; i++) {
4690                                         delayedTriggers[i].call(this, event);
4691                                 } //Trigger all delayed events
4692                                 this._trigger("stop", event, this._uiHash());
4693                         }
4694
4695                         this.fromOutside = false;
4696                         return false;
4697                 }
4698
4699                 if(!noPropagation) {
4700                         this._trigger("beforeStop", event, this._uiHash());
4701                 }
4702
4703                 //$(this.placeholder[0]).remove(); would have been the jQuery way - unfortunately, it unbinds ALL events from the original node!
4704                 this.placeholder[0].parentNode.removeChild(this.placeholder[0]);
4705
4706                 if(this.helper[0] !== this.currentItem[0]) {
4707                         this.helper.remove();
4708                 }
4709                 this.helper = null;
4710
4711                 if(!noPropagation) {
4712                         for (i=0; i < delayedTriggers.length; i++) {
4713                                 delayedTriggers[i].call(this, event);
4714                         } //Trigger all delayed events
4715                         this._trigger("stop", event, this._uiHash());
4716                 }
4717
4718                 this.fromOutside = false;
4719                 return true;
4720
4721         },
4722
4723         _trigger: function() {
4724                 if ($.Widget.prototype._trigger.apply(this, arguments) === false) {
4725                         this.cancel();
4726                 }
4727         },
4728
4729         _uiHash: function(_inst) {
4730                 var inst = _inst || this;
4731                 return {
4732                         helper: inst.helper,
4733                         placeholder: inst.placeholder || $([]),
4734                         position: inst.position,
4735                         originalPosition: inst.originalPosition,
4736                         offset: inst.positionAbs,
4737                         item: inst.currentItem,
4738                         sender: _inst ? _inst.element : null
4739                 };
4740         }
4741
4742 });
4743
4744 })(jQuery);
4745
4746 (function($, undefined) {
4747
4748 var dataSpace = "ui-effects-";
4749
4750 $.effects = {
4751         effect: {}
4752 };
4753
4754 /*!
4755  * jQuery Color Animations v2.1.2
4756  * https://github.com/jquery/jquery-color
4757  *
4758  * Copyright 2013 jQuery Foundation and other contributors
4759  * Released under the MIT license.
4760  * http://jquery.org/license
4761  *
4762  * Date: Wed Jan 16 08:47:09 2013 -0600
4763  */
4764 (function( jQuery, undefined ) {
4765
4766         var stepHooks = "backgroundColor borderBottomColor borderLeftColor borderRightColor borderTopColor color columnRuleColor outlineColor textDecorationColor textEmphasisColor",
4767
4768         // plusequals test for += 100 -= 100
4769         rplusequals = /^([\-+])=\s*(\d+\.?\d*)/,
4770         // a set of RE's that can match strings and generate color tuples.
4771         stringParsers = [{
4772                         re: /rgba?\(\s*(\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(\d{1,3})\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/,
4773                         parse: function( execResult ) {
4774                                 return [
4775                                         execResult[ 1 ],
4776                                         execResult[ 2 ],
4777                                         execResult[ 3 ],
4778                                         execResult[ 4 ]
4779                                 ];
4780                         }
4781                 }, {
4782                         re: /rgba?\(\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/,
4783                         parse: function( execResult ) {
4784                                 return [
4785                                         execResult[ 1 ] * 2.55,
4786                                         execResult[ 2 ] * 2.55,
4787                                         execResult[ 3 ] * 2.55,
4788                                         execResult[ 4 ]
4789                                 ];
4790                         }
4791                 }, {
4792                         // this regex ignores A-F because it's compared against an already lowercased string
4793                         re: /#([a-f0-9]{2})([a-f0-9]{2})([a-f0-9]{2})/,
4794                         parse: function( execResult ) {
4795                                 return [
4796                                         parseInt( execResult[ 1 ], 16 ),
4797                                         parseInt( execResult[ 2 ], 16 ),
4798                                         parseInt( execResult[ 3 ], 16 )
4799                                 ];
4800                         }
4801                 }, {
4802                         // this regex ignores A-F because it's compared against an already lowercased string
4803                         re: /#([a-f0-9])([a-f0-9])([a-f0-9])/,
4804                         parse: function( execResult ) {
4805                                 return [
4806                                         parseInt( execResult[ 1 ] + execResult[ 1 ], 16 ),
4807                                         parseInt( execResult[ 2 ] + execResult[ 2 ], 16 ),
4808                                         parseInt( execResult[ 3 ] + execResult[ 3 ], 16 )
4809                                 ];
4810                         }
4811                 }, {
4812                         re: /hsla?\(\s*(\d+(?:\.\d+)?)\s*,\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/,
4813                         space: "hsla",
4814                         parse: function( execResult ) {
4815                                 return [
4816                                         execResult[ 1 ],
4817                                         execResult[ 2 ] / 100,
4818                                         execResult[ 3 ] / 100,
4819                                         execResult[ 4 ]
4820                                 ];
4821                         }
4822                 }],
4823
4824         // jQuery.Color( )
4825         color = jQuery.Color = function( color, green, blue, alpha ) {
4826                 return new jQuery.Color.fn.parse( color, green, blue, alpha );
4827         },
4828         spaces = {
4829                 rgba: {
4830                         props: {
4831                                 red: {
4832                                         idx: 0,
4833                                         type: "byte"
4834                                 },
4835                                 green: {
4836                                         idx: 1,
4837                                         type: "byte"
4838                                 },
4839                                 blue: {
4840                                         idx: 2,
4841                                         type: "byte"
4842                                 }
4843                         }
4844                 },
4845
4846                 hsla: {
4847                         props: {
4848                                 hue: {
4849                                         idx: 0,
4850                                         type: "degrees"
4851                                 },
4852                                 saturation: {
4853                                         idx: 1,
4854                                         type: "percent"
4855                                 },
4856                                 lightness: {
4857                                         idx: 2,
4858                                         type: "percent"
4859                                 }
4860                         }
4861                 }
4862         },
4863         propTypes = {
4864                 "byte": {
4865                         floor: true,
4866                         max: 255
4867                 },
4868                 "percent": {
4869                         max: 1
4870                 },
4871                 "degrees": {
4872                         mod: 360,
4873                         floor: true
4874                 }
4875         },
4876         support = color.support = {},
4877
4878         // element for support tests
4879         supportElem = jQuery( "<p>" )[ 0 ],
4880
4881         // colors = jQuery.Color.names
4882         colors,
4883
4884         // local aliases of functions called often
4885         each = jQuery.each;
4886
4887 // determine rgba support immediately
4888 supportElem.style.cssText = "background-color:rgba(1,1,1,.5)";
4889 support.rgba = supportElem.style.backgroundColor.indexOf( "rgba" ) > -1;
4890
4891 // define cache name and alpha properties
4892 // for rgba and hsla spaces
4893 each( spaces, function( spaceName, space ) {
4894         space.cache = "_" + spaceName;
4895         space.props.alpha = {
4896                 idx: 3,
4897                 type: "percent",
4898                 def: 1
4899         };
4900 });
4901
4902 function clamp( value, prop, allowEmpty ) {
4903         var type = propTypes[ prop.type ] || {};
4904
4905         if ( value == null ) {
4906                 return (allowEmpty || !prop.def) ? null : prop.def;
4907         }
4908
4909         // ~~ is an short way of doing floor for positive numbers
4910         value = type.floor ? ~~value : parseFloat( value );
4911
4912         // IE will pass in empty strings as value for alpha,
4913         // which will hit this case
4914         if ( isNaN( value ) ) {
4915                 return prop.def;
4916         }
4917
4918         if ( type.mod ) {
4919                 // we add mod before modding to make sure that negatives values
4920                 // get converted properly: -10 -> 350
4921                 return (value + type.mod) % type.mod;
4922         }
4923
4924         // for now all property types without mod have min and max
4925         return 0 > value ? 0 : type.max < value ? type.max : value;
4926 }
4927
4928 function stringParse( string ) {
4929         var inst = color(),
4930                 rgba = inst._rgba = [];
4931
4932         string = string.toLowerCase();
4933
4934         each( stringParsers, function( i, parser ) {
4935                 var parsed,
4936                         match = parser.re.exec( string ),
4937                         values = match && parser.parse( match ),
4938                         spaceName = parser.space || "rgba";
4939
4940                 if ( values ) {
4941                         parsed = inst[ spaceName ]( values );
4942
4943                         // if this was an rgba parse the assignment might happen twice
4944                         // oh well....
4945                         inst[ spaces[ spaceName ].cache ] = parsed[ spaces[ spaceName ].cache ];
4946                         rgba = inst._rgba = parsed._rgba;
4947
4948                         // exit each( stringParsers ) here because we matched
4949                         return false;
4950                 }
4951         });
4952
4953         // Found a stringParser that handled it
4954         if ( rgba.length ) {
4955
4956                 // if this came from a parsed string, force "transparent" when alpha is 0
4957                 // chrome, (and maybe others) return "transparent" as rgba(0,0,0,0)
4958                 if ( rgba.join() === "0,0,0,0" ) {
4959                         jQuery.extend( rgba, colors.transparent );
4960                 }
4961                 return inst;
4962         }
4963
4964         // named colors
4965         return colors[ string ];
4966 }
4967
4968 color.fn = jQuery.extend( color.prototype, {
4969         parse: function( red, green, blue, alpha ) {
4970                 if ( red === undefined ) {
4971                         this._rgba = [ null, null, null, null ];
4972                         return this;
4973                 }
4974                 if ( red.jquery || red.nodeType ) {
4975                         red = jQuery( red ).css( green );
4976                         green = undefined;
4977                 }
4978
4979                 var inst = this,
4980                         type = jQuery.type( red ),
4981                         rgba = this._rgba = [];
4982
4983                 // more than 1 argument specified - assume ( red, green, blue, alpha )
4984                 if ( green !== undefined ) {
4985                         red = [ red, green, blue, alpha ];
4986                         type = "array";
4987                 }
4988
4989                 if ( type === "string" ) {
4990                         return this.parse( stringParse( red ) || colors._default );
4991                 }
4992
4993                 if ( type === "array" ) {
4994                         each( spaces.rgba.props, function( key, prop ) {
4995                                 rgba[ prop.idx ] = clamp( red[ prop.idx ], prop );
4996                         });
4997                         return this;
4998                 }
4999
5000                 if ( type === "object" ) {
5001                         if ( red instanceof color ) {
5002                                 each( spaces, function( spaceName, space ) {
5003                                         if ( red[ space.cache ] ) {
5004                                                 inst[ space.cache ] = red[ space.cache ].slice();
5005                                         }
5006                                 });
5007                         } else {
5008                                 each( spaces, function( spaceName, space ) {
5009                                         var cache = space.cache;
5010                                         each( space.props, function( key, prop ) {
5011
5012                                                 // if the cache doesn't exist, and we know how to convert
5013                                                 if ( !inst[ cache ] && space.to ) {
5014
5015                                                         // if the value was null, we don't need to copy it
5016                                                         // if the key was alpha, we don't need to copy it either
5017                                                         if ( key === "alpha" || red[ key ] == null ) {
5018                                                                 return;
5019                                                         }
5020                                                         inst[ cache ] = space.to( inst._rgba );
5021                                                 }
5022
5023                                                 // this is the only case where we allow nulls for ALL properties.
5024                                                 // call clamp with alwaysAllowEmpty
5025                                                 inst[ cache ][ prop.idx ] = clamp( red[ key ], prop, true );
5026                                         });
5027
5028                                         // everything defined but alpha?
5029                                         if ( inst[ cache ] && jQuery.inArray( null, inst[ cache ].slice( 0, 3 ) ) < 0 ) {
5030                                                 // use the default of 1
5031                                                 inst[ cache ][ 3 ] = 1;
5032                                                 if ( space.from ) {
5033                                                         inst._rgba = space.from( inst[ cache ] );
5034                                                 }
5035                                         }
5036                                 });
5037                         }
5038                         return this;
5039                 }
5040         },
5041         is: function( compare ) {
5042                 var is = color( compare ),
5043                         same = true,
5044                         inst = this;
5045
5046                 each( spaces, function( _, space ) {
5047                         var localCache,
5048                                 isCache = is[ space.cache ];
5049                         if (isCache) {
5050                                 localCache = inst[ space.cache ] || space.to && space.to( inst._rgba ) || [];
5051                                 each( space.props, function( _, prop ) {
5052                                         if ( isCache[ prop.idx ] != null ) {
5053                                                 same = ( isCache[ prop.idx ] === localCache[ prop.idx ] );
5054                                                 return same;
5055                                         }
5056                                 });
5057                         }
5058                         return same;
5059                 });
5060                 return same;
5061         },
5062         _space: function() {
5063                 var used = [],
5064                         inst = this;
5065                 each( spaces, function( spaceName, space ) {
5066                         if ( inst[ space.cache ] ) {
5067                                 used.push( spaceName );
5068                         }
5069                 });
5070                 return used.pop();
5071         },
5072         transition: function( other, distance ) {
5073                 var end = color( other ),
5074                         spaceName = end._space(),
5075                         space = spaces[ spaceName ],
5076                         startColor = this.alpha() === 0 ? color( "transparent" ) : this,
5077                         start = startColor[ space.cache ] || space.to( startColor._rgba ),
5078                         result = start.slice();
5079
5080                 end = end[ space.cache ];
5081                 each( space.props, function( key, prop ) {
5082                         var index = prop.idx,
5083                                 startValue = start[ index ],
5084                                 endValue = end[ index ],
5085                                 type = propTypes[ prop.type ] || {};
5086
5087                         // if null, don't override start value
5088                         if ( endValue === null ) {
5089                                 return;
5090                         }
5091                         // if null - use end
5092                         if ( startValue === null ) {
5093                                 result[ index ] = endValue;
5094                         } else {
5095                                 if ( type.mod ) {
5096                                         if ( endValue - startValue > type.mod / 2 ) {
5097                                                 startValue += type.mod;
5098                                         } else if ( startValue - endValue > type.mod / 2 ) {
5099                                                 startValue -= type.mod;
5100                                         }
5101                                 }
5102                                 result[ index ] = clamp( ( endValue - startValue ) * distance + startValue, prop );
5103                         }
5104                 });
5105                 return this[ spaceName ]( result );
5106         },
5107         blend: function( opaque ) {
5108                 // if we are already opaque - return ourself
5109                 if ( this._rgba[ 3 ] === 1 ) {
5110                         return this;
5111                 }
5112
5113                 var rgb = this._rgba.slice(),
5114                         a = rgb.pop(),
5115                         blend = color( opaque )._rgba;
5116
5117                 return color( jQuery.map( rgb, function( v, i ) {
5118                         return ( 1 - a ) * blend[ i ] + a * v;
5119                 }));
5120         },
5121         toRgbaString: function() {
5122                 var prefix = "rgba(",
5123                         rgba = jQuery.map( this._rgba, function( v, i ) {
5124                                 return v == null ? ( i > 2 ? 1 : 0 ) : v;
5125                         });
5126
5127                 if ( rgba[ 3 ] === 1 ) {
5128                         rgba.pop();
5129                         prefix = "rgb(";
5130                 }
5131
5132                 return prefix + rgba.join() + ")";
5133         },
5134         toHslaString: function() {
5135                 var prefix = "hsla(",
5136                         hsla = jQuery.map( this.hsla(), function( v, i ) {
5137                                 if ( v == null ) {
5138                                         v = i > 2 ? 1 : 0;
5139                                 }
5140
5141                                 // catch 1 and 2
5142                                 if ( i && i < 3 ) {
5143                                         v = Math.round( v * 100 ) + "%";
5144                                 }
5145                                 return v;
5146                         });
5147
5148                 if ( hsla[ 3 ] === 1 ) {
5149                         hsla.pop();
5150                         prefix = "hsl(";
5151                 }
5152                 return prefix + hsla.join() + ")";
5153         },
5154         toHexString: function( includeAlpha ) {
5155                 var rgba = this._rgba.slice(),
5156                         alpha = rgba.pop();
5157
5158                 if ( includeAlpha ) {
5159                         rgba.push( ~~( alpha * 255 ) );
5160                 }
5161
5162                 return "#" + jQuery.map( rgba, function( v ) {
5163
5164                         // default to 0 when nulls exist
5165                         v = ( v || 0 ).toString( 16 );
5166                         return v.length === 1 ? "0" + v : v;
5167                 }).join("");
5168         },
5169         toString: function() {
5170                 return this._rgba[ 3 ] === 0 ? "transparent" : this.toRgbaString();
5171         }
5172 });
5173 color.fn.parse.prototype = color.fn;
5174
5175 // hsla conversions adapted from:
5176 // https://code.google.com/p/maashaack/source/browse/packages/graphics/trunk/src/graphics/colors/HUE2RGB.as?r=5021
5177
5178 function hue2rgb( p, q, h ) {
5179         h = ( h + 1 ) % 1;
5180         if ( h * 6 < 1 ) {
5181                 return p + (q - p) * h * 6;
5182         }
5183         if ( h * 2 < 1) {
5184                 return q;
5185         }
5186         if ( h * 3 < 2 ) {
5187                 return p + (q - p) * ((2/3) - h) * 6;
5188         }
5189         return p;
5190 }
5191
5192 spaces.hsla.to = function ( rgba ) {
5193         if ( rgba[ 0 ] == null || rgba[ 1 ] == null || rgba[ 2 ] == null ) {
5194                 return [ null, null, null, rgba[ 3 ] ];
5195         }
5196         var r = rgba[ 0 ] / 255,
5197                 g = rgba[ 1 ] / 255,
5198                 b = rgba[ 2 ] / 255,
5199                 a = rgba[ 3 ],
5200                 max = Math.max( r, g, b ),
5201                 min = Math.min( r, g, b ),
5202                 diff = max - min,
5203                 add = max + min,
5204                 l = add * 0.5,
5205                 h, s;
5206
5207         if ( min === max ) {
5208                 h = 0;
5209         } else if ( r === max ) {
5210                 h = ( 60 * ( g - b ) / diff ) + 360;
5211         } else if ( g === max ) {
5212                 h = ( 60 * ( b - r ) / diff ) + 120;
5213         } else {
5214                 h = ( 60 * ( r - g ) / diff ) + 240;
5215         }
5216
5217         // chroma (diff) == 0 means greyscale which, by definition, saturation = 0%
5218         // otherwise, saturation is based on the ratio of chroma (diff) to lightness (add)
5219         if ( diff === 0 ) {
5220                 s = 0;
5221         } else if ( l <= 0.5 ) {
5222                 s = diff / add;
5223         } else {
5224                 s = diff / ( 2 - add );
5225         }
5226         return [ Math.round(h) % 360, s, l, a == null ? 1 : a ];
5227 };
5228
5229 spaces.hsla.from = function ( hsla ) {
5230         if ( hsla[ 0 ] == null || hsla[ 1 ] == null || hsla[ 2 ] == null ) {
5231                 return [ null, null, null, hsla[ 3 ] ];
5232         }
5233         var h = hsla[ 0 ] / 360,
5234                 s = hsla[ 1 ],
5235                 l = hsla[ 2 ],
5236                 a = hsla[ 3 ],
5237                 q = l <= 0.5 ? l * ( 1 + s ) : l + s - l * s,
5238                 p = 2 * l - q;
5239
5240         return [
5241                 Math.round( hue2rgb( p, q, h + ( 1 / 3 ) ) * 255 ),
5242                 Math.round( hue2rgb( p, q, h ) * 255 ),
5243                 Math.round( hue2rgb( p, q, h - ( 1 / 3 ) ) * 255 ),
5244                 a
5245         ];
5246 };
5247
5248
5249 each( spaces, function( spaceName, space ) {
5250         var props = space.props,
5251                 cache = space.cache,
5252                 to = space.to,
5253                 from = space.from;
5254
5255         // makes rgba() and hsla()
5256         color.fn[ spaceName ] = function( value ) {
5257
5258                 // generate a cache for this space if it doesn't exist
5259                 if ( to && !this[ cache ] ) {
5260                         this[ cache ] = to( this._rgba );
5261                 }
5262                 if ( value === undefined ) {
5263                         return this[ cache ].slice();
5264                 }
5265
5266                 var ret,
5267                         type = jQuery.type( value ),
5268                         arr = ( type === "array" || type === "object" ) ? value : arguments,
5269                         local = this[ cache ].slice();
5270
5271                 each( props, function( key, prop ) {
5272                         var val = arr[ type === "object" ? key : prop.idx ];
5273                         if ( val == null ) {
5274                                 val = local[ prop.idx ];
5275                         }
5276                         local[ prop.idx ] = clamp( val, prop );
5277                 });
5278
5279                 if ( from ) {
5280                         ret = color( from( local ) );
5281                         ret[ cache ] = local;
5282                         return ret;
5283                 } else {
5284                         return color( local );
5285                 }
5286         };
5287
5288         // makes red() green() blue() alpha() hue() saturation() lightness()
5289         each( props, function( key, prop ) {
5290                 // alpha is included in more than one space
5291                 if ( color.fn[ key ] ) {
5292                         return;
5293                 }
5294                 color.fn[ key ] = function( value ) {
5295                         var vtype = jQuery.type( value ),
5296                                 fn = ( key === "alpha" ? ( this._hsla ? "hsla" : "rgba" ) : spaceName ),
5297                                 local = this[ fn ](),
5298                                 cur = local[ prop.idx ],
5299                                 match;
5300
5301                         if ( vtype === "undefined" ) {
5302                                 return cur;
5303                         }
5304
5305                         if ( vtype === "function" ) {
5306                                 value = value.call( this, cur );
5307                                 vtype = jQuery.type( value );
5308                         }
5309                         if ( value == null && prop.empty ) {
5310                                 return this;
5311                         }
5312                         if ( vtype === "string" ) {
5313                                 match = rplusequals.exec( value );
5314                                 if ( match ) {
5315                                         value = cur + parseFloat( match[ 2 ] ) * ( match[ 1 ] === "+" ? 1 : -1 );
5316                                 }
5317                         }
5318                         local[ prop.idx ] = value;
5319                         return this[ fn ]( local );
5320                 };
5321         });
5322 });
5323
5324 // add cssHook and .fx.step function for each named hook.
5325 // accept a space separated string of properties
5326 color.hook = function( hook ) {
5327         var hooks = hook.split( " " );
5328         each( hooks, function( i, hook ) {
5329                 jQuery.cssHooks[ hook ] = {
5330                         set: function( elem, value ) {
5331                                 var parsed, curElem,
5332                                         backgroundColor = "";
5333
5334                                 if ( value !== "transparent" && ( jQuery.type( value ) !== "string" || ( parsed = stringParse( value ) ) ) ) {
5335                                         value = color( parsed || value );
5336                                         if ( !support.rgba && value._rgba[ 3 ] !== 1 ) {
5337                                                 curElem = hook === "backgroundColor" ? elem.parentNode : elem;
5338                                                 while (
5339                                                         (backgroundColor === "" || backgroundColor === "transparent") &&
5340                                                         curElem && curElem.style
5341                                                 ) {
5342                                                         try {
5343                                                                 backgroundColor = jQuery.css( curElem, "backgroundColor" );
5344                                                                 curElem = curElem.parentNode;
5345                                                         } catch ( e ) {
5346                                                         }
5347                                                 }
5348
5349                                                 value = value.blend( backgroundColor && backgroundColor !== "transparent" ?
5350                                                         backgroundColor :
5351                                                         "_default" );
5352                                         }
5353
5354                                         value = value.toRgbaString();
5355                                 }
5356                                 try {
5357                                         elem.style[ hook ] = value;
5358                                 } catch( e ) {
5359                                         // wrapped to prevent IE from throwing errors on "invalid" values like 'auto' or 'inherit'
5360                                 }
5361                         }
5362                 };
5363                 jQuery.fx.step[ hook ] = function( fx ) {
5364                         if ( !fx.colorInit ) {
5365                                 fx.start = color( fx.elem, hook );
5366                                 fx.end = color( fx.end );
5367                                 fx.colorInit = true;
5368                         }
5369                         jQuery.cssHooks[ hook ].set( fx.elem, fx.start.transition( fx.end, fx.pos ) );
5370                 };
5371         });
5372
5373 };
5374
5375 color.hook( stepHooks );
5376
5377 jQuery.cssHooks.borderColor = {
5378         expand: function( value ) {
5379                 var expanded = {};
5380
5381                 each( [ "Top", "Right", "Bottom", "Left" ], function( i, part ) {
5382                         expanded[ "border" + part + "Color" ] = value;
5383                 });
5384                 return expanded;
5385         }
5386 };
5387
5388 // Basic color names only.
5389 // Usage of any of the other color names requires adding yourself or including
5390 // jquery.color.svg-names.js.
5391 colors = jQuery.Color.names = {
5392         // 4.1. Basic color keywords
5393         aqua: "#00ffff",
5394         black: "#000000",
5395         blue: "#0000ff",
5396         fuchsia: "#ff00ff",
5397         gray: "#808080",
5398         green: "#008000",
5399         lime: "#00ff00",
5400         maroon: "#800000",
5401         navy: "#000080",
5402         olive: "#808000",
5403         purple: "#800080",
5404         red: "#ff0000",
5405         silver: "#c0c0c0",
5406         teal: "#008080",
5407         white: "#ffffff",
5408         yellow: "#ffff00",
5409
5410         // 4.2.3. "transparent" color keyword
5411         transparent: [ null, null, null, 0 ],
5412
5413         _default: "#ffffff"
5414 };
5415
5416 })( jQuery );
5417
5418
5419 /******************************************************************************/
5420 /****************************** CLASS ANIMATIONS ******************************/
5421 /******************************************************************************/
5422 (function() {
5423
5424 var classAnimationActions = [ "add", "remove", "toggle" ],
5425         shorthandStyles = {
5426                 border: 1,
5427                 borderBottom: 1,
5428                 borderColor: 1,
5429                 borderLeft: 1,
5430                 borderRight: 1,
5431                 borderTop: 1,
5432                 borderWidth: 1,
5433                 margin: 1,
5434                 padding: 1
5435         };
5436
5437 $.each([ "borderLeftStyle", "borderRightStyle", "borderBottomStyle", "borderTopStyle" ], function( _, prop ) {
5438         $.fx.step[ prop ] = function( fx ) {
5439                 if ( fx.end !== "none" && !fx.setAttr || fx.pos === 1 && !fx.setAttr ) {
5440                         jQuery.style( fx.elem, prop, fx.end );
5441                         fx.setAttr = true;
5442                 }
5443         };
5444 });
5445
5446 function getElementStyles( elem ) {
5447         var key, len,
5448                 style = elem.ownerDocument.defaultView ?
5449                         elem.ownerDocument.defaultView.getComputedStyle( elem, null ) :
5450                         elem.currentStyle,
5451                 styles = {};
5452
5453         if ( style && style.length && style[ 0 ] && style[ style[ 0 ] ] ) {
5454                 len = style.length;
5455                 while ( len-- ) {
5456                         key = style[ len ];
5457                         if ( typeof style[ key ] === "string" ) {
5458                                 styles[ $.camelCase( key ) ] = style[ key ];
5459                         }
5460                 }
5461         // support: Opera, IE <9
5462         } else {
5463                 for ( key in style ) {
5464                         if ( typeof style[ key ] === "string" ) {
5465                                 styles[ key ] = style[ key ];
5466                         }
5467                 }
5468         }
5469
5470         return styles;
5471 }
5472
5473
5474 function styleDifference( oldStyle, newStyle ) {
5475         var diff = {},
5476                 name, value;
5477
5478         for ( name in newStyle ) {
5479                 value = newStyle[ name ];
5480                 if ( oldStyle[ name ] !== value ) {
5481                         if ( !shorthandStyles[ name ] ) {
5482                                 if ( $.fx.step[ name ] || !isNaN( parseFloat( value ) ) ) {
5483                                         diff[ name ] = value;
5484                                 }
5485                         }
5486                 }
5487         }
5488
5489         return diff;
5490 }
5491
5492 // support: jQuery <1.8
5493 if ( !$.fn.addBack ) {
5494         $.fn.addBack = function( selector ) {
5495                 return this.add( selector == null ?
5496                         this.prevObject : this.prevObject.filter( selector )
5497                 );
5498         };
5499 }
5500
5501 $.effects.animateClass = function( value, duration, easing, callback ) {
5502         var o = $.speed( duration, easing, callback );
5503
5504         return this.queue( function() {
5505                 var animated = $( this ),
5506                         baseClass = animated.attr( "class" ) || "",
5507                         applyClassChange,
5508                         allAnimations = o.children ? animated.find( "*" ).addBack() : animated;
5509
5510                 // map the animated objects to store the original styles.
5511                 allAnimations = allAnimations.map(function() {
5512                         var el = $( this );
5513                         return {
5514                                 el: el,
5515                                 start: getElementStyles( this )
5516                         };
5517                 });
5518
5519                 // apply class change
5520                 applyClassChange = function() {
5521                         $.each( classAnimationActions, function(i, action) {
5522                                 if ( value[ action ] ) {
5523                                         animated[ action + "Class" ]( value[ action ] );
5524                                 }
5525                         });
5526                 };
5527                 applyClassChange();
5528
5529                 // map all animated objects again - calculate new styles and diff
5530                 allAnimations = allAnimations.map(function() {
5531                         this.end = getElementStyles( this.el[ 0 ] );
5532                         this.diff = styleDifference( this.start, this.end );
5533                         return this;
5534                 });
5535
5536                 // apply original class
5537                 animated.attr( "class", baseClass );
5538
5539                 // map all animated objects again - this time collecting a promise
5540                 allAnimations = allAnimations.map(function() {
5541                         var styleInfo = this,
5542                                 dfd = $.Deferred(),
5543                                 opts = $.extend({}, o, {
5544                                         queue: false,
5545                                         complete: function() {
5546                                                 dfd.resolve( styleInfo );
5547                                         }
5548                                 });
5549
5550                         this.el.animate( this.diff, opts );
5551                         return dfd.promise();
5552                 });
5553
5554                 // once all animations have completed:
5555                 $.when.apply( $, allAnimations.get() ).done(function() {
5556
5557                         // set the final class
5558                         applyClassChange();
5559
5560                         // for each animated element,
5561                         // clear all css properties that were animated
5562                         $.each( arguments, function() {
5563                                 var el = this.el;
5564                                 $.each( this.diff, function(key) {
5565                                         el.css( key, "" );
5566                                 });
5567                         });
5568
5569                         // this is guarnteed to be there if you use jQuery.speed()
5570                         // it also handles dequeuing the next anim...
5571                         o.complete.call( animated[ 0 ] );
5572                 });
5573         });
5574 };
5575
5576 $.fn.extend({
5577         addClass: (function( orig ) {
5578                 return function( classNames, speed, easing, callback ) {
5579                         return speed ?
5580                                 $.effects.animateClass.call( this,
5581                                         { add: classNames }, speed, easing, callback ) :
5582                                 orig.apply( this, arguments );
5583                 };
5584         })( $.fn.addClass ),
5585
5586         removeClass: (function( orig ) {
5587                 return function( classNames, speed, easing, callback ) {
5588                         return arguments.length > 1 ?
5589                                 $.effects.animateClass.call( this,
5590                                         { remove: classNames }, speed, easing, callback ) :
5591                                 orig.apply( this, arguments );
5592                 };
5593         })( $.fn.removeClass ),
5594
5595         toggleClass: (function( orig ) {
5596                 return function( classNames, force, speed, easing, callback ) {
5597                         if ( typeof force === "boolean" || force === undefined ) {
5598                                 if ( !speed ) {
5599                                         // without speed parameter
5600                                         return orig.apply( this, arguments );
5601                                 } else {
5602                                         return $.effects.animateClass.call( this,
5603                                                 (force ? { add: classNames } : { remove: classNames }),
5604                                                 speed, easing, callback );
5605                                 }
5606                         } else {
5607                                 // without force parameter
5608                                 return $.effects.animateClass.call( this,
5609                                         { toggle: classNames }, force, speed, easing );
5610                         }
5611                 };
5612         })( $.fn.toggleClass ),
5613
5614         switchClass: function( remove, add, speed, easing, callback) {
5615                 return $.effects.animateClass.call( this, {
5616                         add: add,
5617                         remove: remove
5618                 }, speed, easing, callback );
5619         }
5620 });
5621
5622 })();
5623
5624 /******************************************************************************/
5625 /*********************************** EFFECTS **********************************/
5626 /******************************************************************************/
5627
5628 (function() {
5629
5630 $.extend( $.effects, {
5631         version: "1.10.2",
5632
5633         // Saves a set of properties in a data storage
5634         save: function( element, set ) {
5635                 for( var i=0; i < set.length; i++ ) {
5636                         if ( set[ i ] !== null ) {
5637                                 element.data( dataSpace + set[ i ], element[ 0 ].style[ set[ i ] ] );
5638                         }
5639                 }
5640         },
5641
5642         // Restores a set of previously saved properties from a data storage
5643         restore: function( element, set ) {
5644                 var val, i;
5645                 for( i=0; i < set.length; i++ ) {
5646                         if ( set[ i ] !== null ) {
5647                                 val = element.data( dataSpace + set[ i ] );
5648                                 // support: jQuery 1.6.2
5649                                 // http://bugs.jquery.com/ticket/9917
5650                                 // jQuery 1.6.2 incorrectly returns undefined for any falsy value.
5651                                 // We can't differentiate between "" and 0 here, so we just assume
5652                                 // empty string since it's likely to be a more common value...
5653                                 if ( val === undefined ) {
5654                                         val = "";
5655                                 }
5656                                 element.css( set[ i ], val );
5657                         }
5658                 }
5659         },
5660
5661         setMode: function( el, mode ) {
5662                 if (mode === "toggle") {
5663                         mode = el.is( ":hidden" ) ? "show" : "hide";
5664                 }
5665                 return mode;
5666         },
5667
5668         // Translates a [top,left] array into a baseline value
5669         // this should be a little more flexible in the future to handle a string & hash
5670         getBaseline: function( origin, original ) {
5671                 var y, x;
5672                 switch ( origin[ 0 ] ) {
5673                         case "top": y = 0; break;
5674                         case "middle": y = 0.5; break;
5675                         case "bottom": y = 1; break;
5676                         default: y = origin[ 0 ] / original.height;
5677                 }
5678                 switch ( origin[ 1 ] ) {
5679                         case "left": x = 0; break;
5680                         case "center": x = 0.5; break;
5681                         case "right": x = 1; break;
5682                         default: x = origin[ 1 ] / original.width;
5683                 }
5684                 return {
5685                         x: x,
5686                         y: y
5687                 };
5688         },
5689
5690         // Wraps the element around a wrapper that copies position properties
5691         createWrapper: function( element ) {
5692
5693                 // if the element is already wrapped, return it
5694                 if ( element.parent().is( ".ui-effects-wrapper" )) {
5695                         return element.parent();
5696                 }
5697
5698                 // wrap the element
5699                 var props = {
5700                                 width: element.outerWidth(true),
5701                                 height: element.outerHeight(true),
5702                                 "float": element.css( "float" )
5703                         },
5704                         wrapper = $( "<div></div>" )
5705                                 .addClass( "ui-effects-wrapper" )
5706                                 .css({
5707                                         fontSize: "100%",
5708                                         background: "transparent",
5709                                         border: "none",
5710                                         margin: 0,
5711                                         padding: 0
5712                                 }),
5713                         // Store the size in case width/height are defined in % - Fixes #5245
5714                         size = {
5715                                 width: element.width(),
5716                                 height: element.height()
5717                         },
5718                         active = document.activeElement;
5719
5720                 // support: Firefox
5721                 // Firefox incorrectly exposes anonymous content
5722                 // https://bugzilla.mozilla.org/show_bug.cgi?id=561664
5723                 try {
5724                         active.id;
5725                 } catch( e ) {
5726                         active = document.body;
5727                 }
5728
5729                 element.wrap( wrapper );
5730
5731                 // Fixes #7595 - Elements lose focus when wrapped.
5732                 if ( element[ 0 ] === active || $.contains( element[ 0 ], active ) ) {
5733                         $( active ).focus();
5734                 }
5735
5736                 wrapper = element.parent(); //Hotfix for jQuery 1.4 since some change in wrap() seems to actually lose the reference to the wrapped element
5737
5738                 // transfer positioning properties to the wrapper
5739                 if ( element.css( "position" ) === "static" ) {
5740                         wrapper.css({ position: "relative" });
5741                         element.css({ position: "relative" });
5742                 } else {
5743                         $.extend( props, {
5744                                 position: element.css( "position" ),
5745                                 zIndex: element.css( "z-index" )
5746                         });
5747                         $.each([ "top", "left", "bottom", "right" ], function(i, pos) {
5748                                 props[ pos ] = element.css( pos );
5749                                 if ( isNaN( parseInt( props[ pos ], 10 ) ) ) {
5750                                         props[ pos ] = "auto";
5751                                 }
5752                         });
5753                         element.css({
5754                                 position: "relative",
5755                                 top: 0,
5756                                 left: 0,
5757                                 right: "auto",
5758                                 bottom: "auto"
5759                         });
5760                 }
5761                 element.css(size);
5762
5763                 return wrapper.css( props ).show();
5764         },
5765
5766         removeWrapper: function( element ) {
5767                 var active = document.activeElement;
5768
5769                 if ( element.parent().is( ".ui-effects-wrapper" ) ) {
5770                         element.parent().replaceWith( element );
5771
5772                         // Fixes #7595 - Elements lose focus when wrapped.
5773                         if ( element[ 0 ] === active || $.contains( element[ 0 ], active ) ) {
5774                                 $( active ).focus();
5775                         }
5776                 }
5777
5778
5779                 return element;
5780         },
5781
5782         setTransition: function( element, list, factor, value ) {
5783                 value = value || {};
5784                 $.each( list, function( i, x ) {
5785                         var unit = element.cssUnit( x );
5786                         if ( unit[ 0 ] > 0 ) {
5787                                 value[ x ] = unit[ 0 ] * factor + unit[ 1 ];
5788                         }
5789                 });
5790                 return value;
5791         }
5792 });
5793
5794 // return an effect options object for the given parameters:
5795 function _normalizeArguments( effect, options, speed, callback ) {
5796
5797         // allow passing all options as the first parameter
5798         if ( $.isPlainObject( effect ) ) {
5799                 options = effect;
5800                 effect = effect.effect;
5801         }
5802
5803         // convert to an object
5804         effect = { effect: effect };
5805
5806         // catch (effect, null, ...)
5807         if ( options == null ) {
5808                 options = {};
5809         }
5810
5811         // catch (effect, callback)
5812         if ( $.isFunction( options ) ) {
5813                 callback = options;
5814                 speed = null;
5815                 options = {};
5816         }
5817
5818         // catch (effect, speed, ?)
5819         if ( typeof options === "number" || $.fx.speeds[ options ] ) {
5820                 callback = speed;
5821                 speed = options;
5822                 options = {};
5823         }
5824
5825         // catch (effect, options, callback)
5826         if ( $.isFunction( speed ) ) {
5827                 callback = speed;
5828                 speed = null;
5829         }
5830
5831         // add options to effect
5832         if ( options ) {
5833                 $.extend( effect, options );
5834         }
5835
5836         speed = speed || options.duration;
5837         effect.duration = $.fx.off ? 0 :
5838                 typeof speed === "number" ? speed :
5839                 speed in $.fx.speeds ? $.fx.speeds[ speed ] :
5840                 $.fx.speeds._default;
5841
5842         effect.complete = callback || options.complete;
5843
5844         return effect;
5845 }
5846
5847 function standardAnimationOption( option ) {
5848         // Valid standard speeds (nothing, number, named speed)
5849         if ( !option || typeof option === "number" || $.fx.speeds[ option ] ) {
5850                 return true;
5851         }
5852
5853         // Invalid strings - treat as "normal" speed
5854         if ( typeof option === "string" && !$.effects.effect[ option ] ) {
5855                 return true;
5856         }
5857
5858         // Complete callback
5859         if ( $.isFunction( option ) ) {
5860                 return true;
5861         }
5862
5863         // Options hash (but not naming an effect)
5864         if ( typeof option === "object" && !option.effect ) {
5865                 return true;
5866         }
5867
5868         // Didn't match any standard API
5869         return false;
5870 }
5871
5872 $.fn.extend({
5873         effect: function( /* effect, options, speed, callback */ ) {
5874                 var args = _normalizeArguments.apply( this, arguments ),
5875                         mode = args.mode,
5876                         queue = args.queue,
5877                         effectMethod = $.effects.effect[ args.effect ];
5878
5879                 if ( $.fx.off || !effectMethod ) {
5880                         // delegate to the original method (e.g., .show()) if possible
5881                         if ( mode ) {
5882                                 return this[ mode ]( args.duration, args.complete );
5883                         } else {
5884                                 return this.each( function() {
5885                                         if ( args.complete ) {
5886                                                 args.complete.call( this );
5887                                         }
5888                                 });
5889                         }
5890                 }
5891
5892                 function run( next ) {
5893                         var elem = $( this ),
5894                                 complete = args.complete,
5895                                 mode = args.mode;
5896
5897                         function done() {
5898                                 if ( $.isFunction( complete ) ) {
5899                                         complete.call( elem[0] );
5900                                 }
5901                                 if ( $.isFunction( next ) ) {
5902                                         next();
5903                                 }
5904                         }
5905
5906                         // If the element already has the correct final state, delegate to
5907                         // the core methods so the internal tracking of "olddisplay" works.
5908                         if ( elem.is( ":hidden" ) ? mode === "hide" : mode === "show" ) {
5909                                 elem[ mode ]();
5910                                 done();
5911                         } else {
5912                                 effectMethod.call( elem[0], args, done );
5913                         }
5914                 }
5915
5916                 return queue === false ? this.each( run ) : this.queue( queue || "fx", run );
5917         },
5918
5919         show: (function( orig ) {
5920                 return function( option ) {
5921                         if ( standardAnimationOption( option ) ) {
5922                                 return orig.apply( this, arguments );
5923                         } else {
5924                                 var args = _normalizeArguments.apply( this, arguments );
5925                                 args.mode = "show";
5926                                 return this.effect.call( this, args );
5927                         }
5928                 };
5929         })( $.fn.show ),
5930
5931         hide: (function( orig ) {
5932                 return function( option ) {
5933                         if ( standardAnimationOption( option ) ) {
5934                                 return orig.apply( this, arguments );
5935                         } else {
5936                                 var args = _normalizeArguments.apply( this, arguments );
5937                                 args.mode = "hide";
5938                                 return this.effect.call( this, args );
5939                         }
5940                 };
5941         })( $.fn.hide ),
5942
5943         toggle: (function( orig ) {
5944                 return function( option ) {
5945                         if ( standardAnimationOption( option ) || typeof option === "boolean" ) {
5946                                 return orig.apply( this, arguments );
5947                         } else {
5948                                 var args = _normalizeArguments.apply( this, arguments );
5949                                 args.mode = "toggle";
5950                                 return this.effect.call( this, args );
5951                         }
5952                 };
5953         })( $.fn.toggle ),
5954
5955         // helper functions
5956         cssUnit: function(key) {
5957                 var style = this.css( key ),
5958                         val = [];
5959
5960                 $.each( [ "em", "px", "%", "pt" ], function( i, unit ) {
5961                         if ( style.indexOf( unit ) > 0 ) {
5962                                 val = [ parseFloat( style ), unit ];
5963                         }
5964                 });
5965                 return val;
5966         }
5967 });
5968
5969 })();
5970
5971 /******************************************************************************/
5972 /*********************************** EASING ***********************************/
5973 /******************************************************************************/
5974
5975 (function() {
5976
5977 // based on easing equations from Robert Penner (http://www.robertpenner.com/easing)
5978
5979 var baseEasings = {};
5980
5981 $.each( [ "Quad", "Cubic", "Quart", "Quint", "Expo" ], function( i, name ) {
5982         baseEasings[ name ] = function( p ) {
5983                 return Math.pow( p, i + 2 );
5984         };
5985 });
5986
5987 $.extend( baseEasings, {
5988         Sine: function ( p ) {
5989                 return 1 - Math.cos( p * Math.PI / 2 );
5990         },
5991         Circ: function ( p ) {
5992                 return 1 - Math.sqrt( 1 - p * p );
5993         },
5994         Elastic: function( p ) {
5995                 return p === 0 || p === 1 ? p :
5996                         -Math.pow( 2, 8 * (p - 1) ) * Math.sin( ( (p - 1) * 80 - 7.5 ) * Math.PI / 15 );
5997         },
5998         Back: function( p ) {
5999                 return p * p * ( 3 * p - 2 );
6000         },
6001         Bounce: function ( p ) {
6002                 var pow2,
6003                         bounce = 4;
6004
6005                 while ( p < ( ( pow2 = Math.pow( 2, --bounce ) ) - 1 ) / 11 ) {}
6006                 return 1 / Math.pow( 4, 3 - bounce ) - 7.5625 * Math.pow( ( pow2 * 3 - 2 ) / 22 - p, 2 );
6007         }
6008 });
6009
6010 $.each( baseEasings, function( name, easeIn ) {
6011         $.easing[ "easeIn" + name ] = easeIn;
6012         $.easing[ "easeOut" + name ] = function( p ) {
6013                 return 1 - easeIn( 1 - p );
6014         };
6015         $.easing[ "easeInOut" + name ] = function( p ) {
6016                 return p < 0.5 ?
6017                         easeIn( p * 2 ) / 2 :
6018                         1 - easeIn( p * -2 + 2 ) / 2;
6019         };
6020 });
6021
6022 })();
6023
6024 })(jQuery);
6025
6026 (function( $, undefined ) {
6027
6028 var uid = 0,
6029         hideProps = {},
6030         showProps = {};
6031
6032 hideProps.height = hideProps.paddingTop = hideProps.paddingBottom =
6033         hideProps.borderTopWidth = hideProps.borderBottomWidth = "hide";
6034 showProps.height = showProps.paddingTop = showProps.paddingBottom =
6035         showProps.borderTopWidth = showProps.borderBottomWidth = "show";
6036
6037 $.widget( "ui.accordion", {
6038         version: "1.10.2",
6039         options: {
6040                 active: 0,
6041                 animate: {},
6042                 collapsible: false,
6043                 event: "click",
6044                 header: "> li > :first-child,> :not(li):even",
6045                 heightStyle: "auto",
6046                 icons: {
6047                         activeHeader: "ui-icon-triangle-1-s",
6048                         header: "ui-icon-triangle-1-e"
6049                 },
6050
6051                 // callbacks
6052                 activate: null,
6053                 beforeActivate: null
6054         },
6055
6056         _create: function() {
6057                 var options = this.options;
6058                 this.prevShow = this.prevHide = $();
6059                 this.element.addClass( "ui-accordion ui-widget ui-helper-reset" )
6060                         // ARIA
6061                         .attr( "role", "tablist" );
6062
6063                 // don't allow collapsible: false and active: false / null
6064                 if ( !options.collapsible && (options.active === false || options.active == null) ) {
6065                         options.active = 0;
6066                 }
6067
6068                 this._processPanels();
6069                 // handle negative values
6070                 if ( options.active < 0 ) {
6071                         options.active += this.headers.length;
6072                 }
6073                 this._refresh();
6074         },
6075
6076         _getCreateEventData: function() {
6077                 return {
6078                         header: this.active,
6079                         panel: !this.active.length ? $() : this.active.next(),
6080                         content: !this.active.length ? $() : this.active.next()
6081                 };
6082         },
6083
6084         _createIcons: function() {
6085                 var icons = this.options.icons;
6086                 if ( icons ) {
6087                         $( "<span>" )
6088                                 .addClass( "ui-accordion-header-icon ui-icon " + icons.header )
6089                                 .prependTo( this.headers );
6090                         this.active.children( ".ui-accordion-header-icon" )
6091                                 .removeClass( icons.header )
6092                                 .addClass( icons.activeHeader );
6093                         this.headers.addClass( "ui-accordion-icons" );
6094                 }
6095         },
6096
6097         _destroyIcons: function() {
6098                 this.headers
6099                         .removeClass( "ui-accordion-icons" )
6100                         .children( ".ui-accordion-header-icon" )
6101                                 .remove();
6102         },
6103
6104         _destroy: function() {
6105                 var contents;
6106
6107                 // clean up main element
6108                 this.element
6109                         .removeClass( "ui-accordion ui-widget ui-helper-reset" )
6110                         .removeAttr( "role" );
6111
6112                 // clean up headers
6113                 this.headers
6114                         .removeClass( "ui-accordion-header ui-accordion-header-active ui-helper-reset ui-state-default ui-corner-all ui-state-active ui-state-disabled ui-corner-top" )
6115                         .removeAttr( "role" )
6116                         .removeAttr( "aria-selected" )
6117                         .removeAttr( "aria-controls" )
6118                         .removeAttr( "tabIndex" )
6119                         .each(function() {
6120                                 if ( /^ui-accordion/.test( this.id ) ) {
6121                                         this.removeAttribute( "id" );
6122                                 }
6123                         });
6124                 this._destroyIcons();
6125
6126                 // clean up content panels
6127                 contents = this.headers.next()
6128                         .css( "display", "" )
6129                         .removeAttr( "role" )
6130                         .removeAttr( "aria-expanded" )
6131                         .removeAttr( "aria-hidden" )
6132                         .removeAttr( "aria-labelledby" )
6133                         .removeClass( "ui-helper-reset ui-widget-content ui-corner-bottom ui-accordion-content ui-accordion-content-active ui-state-disabled" )
6134                         .each(function() {
6135                                 if ( /^ui-accordion/.test( this.id ) ) {
6136                                         this.removeAttribute( "id" );
6137                                 }
6138                         });
6139                 if ( this.options.heightStyle !== "content" ) {
6140                         contents.css( "height", "" );
6141                 }
6142         },
6143
6144         _setOption: function( key, value ) {
6145                 if ( key === "active" ) {
6146                         // _activate() will handle invalid values and update this.options
6147                         this._activate( value );
6148                         return;
6149                 }
6150
6151                 if ( key === "event" ) {
6152                         if ( this.options.event ) {
6153                                 this._off( this.headers, this.options.event );
6154                         }
6155                         this._setupEvents( value );
6156                 }
6157
6158                 this._super( key, value );
6159
6160                 // setting collapsible: false while collapsed; open first panel
6161                 if ( key === "collapsible" && !value && this.options.active === false ) {
6162                         this._activate( 0 );
6163                 }
6164
6165                 if ( key === "icons" ) {
6166                         this._destroyIcons();
6167                         if ( value ) {
6168                                 this._createIcons();
6169                         }
6170                 }
6171
6172                 // #5332 - opacity doesn't cascade to positioned elements in IE
6173                 // so we need to add the disabled class to the headers and panels
6174                 if ( key === "disabled" ) {
6175                         this.headers.add( this.headers.next() )
6176                                 .toggleClass( "ui-state-disabled", !!value );
6177                 }
6178         },
6179
6180         _keydown: function( event ) {
6181                 /*jshint maxcomplexity:15*/
6182                 if ( event.altKey || event.ctrlKey ) {
6183                         return;
6184                 }
6185
6186                 var keyCode = $.ui.keyCode,
6187                         length = this.headers.length,
6188                         currentIndex = this.headers.index( event.target ),
6189                         toFocus = false;
6190
6191                 switch ( event.keyCode ) {
6192                         case keyCode.RIGHT:
6193                         case keyCode.DOWN:
6194                                 toFocus = this.headers[ ( currentIndex + 1 ) % length ];
6195                                 break;
6196                         case keyCode.LEFT:
6197                         case keyCode.UP:
6198                                 toFocus = this.headers[ ( currentIndex - 1 + length ) % length ];
6199                                 break;
6200                         case keyCode.SPACE:
6201                         case keyCode.ENTER:
6202                                 this._eventHandler( event );
6203                                 break;
6204                         case keyCode.HOME:
6205                                 toFocus = this.headers[ 0 ];
6206                                 break;
6207                         case keyCode.END:
6208                                 toFocus = this.headers[ length - 1 ];
6209                                 break;
6210                 }
6211
6212                 if ( toFocus ) {
6213                         $( event.target ).attr( "tabIndex", -1 );
6214                         $( toFocus ).attr( "tabIndex", 0 );
6215                         toFocus.focus();
6216                         event.preventDefault();
6217                 }
6218         },
6219
6220         _panelKeyDown : function( event ) {
6221                 if ( event.keyCode === $.ui.keyCode.UP && event.ctrlKey ) {
6222                         $( event.currentTarget ).prev().focus();
6223                 }
6224         },
6225
6226         refresh: function() {
6227                 var options = this.options;
6228                 this._processPanels();
6229
6230                 // was collapsed or no panel
6231                 if ( ( options.active === false && options.collapsible === true ) || !this.headers.length ) {
6232                         options.active = false;
6233                         this.active = $();
6234                 // active false only when collapsible is true
6235                 } if ( options.active === false ) {
6236                         this._activate( 0 );
6237                 // was active, but active panel is gone
6238                 } else if ( this.active.length && !$.contains( this.element[ 0 ], this.active[ 0 ] ) ) {
6239                         // all remaining panel are disabled
6240                         if ( this.headers.length === this.headers.find(".ui-state-disabled").length ) {
6241                                 options.active = false;
6242                                 this.active = $();
6243                         // activate previous panel
6244                         } else {
6245                                 this._activate( Math.max( 0, options.active - 1 ) );
6246                         }
6247                 // was active, active panel still exists
6248                 } else {
6249                         // make sure active index is correct
6250                         options.active = this.headers.index( this.active );
6251                 }
6252
6253                 this._destroyIcons();
6254
6255                 this._refresh();
6256         },
6257
6258         _processPanels: function() {
6259                 this.headers = this.element.find( this.options.header )
6260                         .addClass( "ui-accordion-header ui-helper-reset ui-state-default ui-corner-all" );
6261
6262                 this.headers.next()
6263                         .addClass( "ui-accordion-content ui-helper-reset ui-widget-content ui-corner-bottom" )
6264                         .filter(":not(.ui-accordion-content-active)")
6265                         .hide();
6266         },
6267
6268         _refresh: function() {
6269                 var maxHeight,
6270                         options = this.options,
6271                         heightStyle = options.heightStyle,
6272                         parent = this.element.parent(),
6273                         accordionId = this.accordionId = "ui-accordion-" +
6274                                 (this.element.attr( "id" ) || ++uid);
6275
6276                 this.active = this._findActive( options.active )
6277                         .addClass( "ui-accordion-header-active ui-state-active ui-corner-top" )
6278                         .removeClass( "ui-corner-all" );
6279                 this.active.next()
6280                         .addClass( "ui-accordion-content-active" )
6281                         .show();
6282
6283                 this.headers
6284                         .attr( "role", "tab" )
6285                         .each(function( i ) {
6286                                 var header = $( this ),
6287                                         headerId = header.attr( "id" ),
6288                                         panel = header.next(),
6289                                         panelId = panel.attr( "id" );
6290                                 if ( !headerId ) {
6291                                         headerId = accordionId + "-header-" + i;
6292                                         header.attr( "id", headerId );
6293                                 }
6294                                 if ( !panelId ) {
6295                                         panelId = accordionId + "-panel-" + i;
6296                                         panel.attr( "id", panelId );
6297                                 }
6298                                 header.attr( "aria-controls", panelId );
6299                                 panel.attr( "aria-labelledby", headerId );
6300                         })
6301                         .next()
6302                                 .attr( "role", "tabpanel" );
6303
6304                 this.headers
6305                         .not( this.active )
6306                         .attr({
6307                                 "aria-selected": "false",
6308                                 tabIndex: -1
6309                         })
6310                         .next()
6311                                 .attr({
6312                                         "aria-expanded": "false",
6313                                         "aria-hidden": "true"
6314                                 })
6315                                 .hide();
6316
6317                 // make sure at least one header is in the tab order
6318                 if ( !this.active.length ) {
6319                         this.headers.eq( 0 ).attr( "tabIndex", 0 );
6320                 } else {
6321                         this.active.attr({
6322                                 "aria-selected": "true",
6323                                 tabIndex: 0
6324                         })
6325                         .next()
6326                                 .attr({
6327                                         "aria-expanded": "true",
6328                                         "aria-hidden": "false"
6329                                 });
6330                 }
6331
6332                 this._createIcons();
6333
6334                 this._setupEvents( options.event );
6335
6336                 if ( heightStyle === "fill" ) {
6337                         maxHeight = parent.height();
6338                         this.element.siblings( ":visible" ).each(function() {
6339                                 var elem = $( this ),
6340                                         position = elem.css( "position" );
6341
6342                                 if ( position === "absolute" || position === "fixed" ) {
6343                                         return;
6344                                 }
6345                                 maxHeight -= elem.outerHeight( true );
6346                         });
6347
6348                         this.headers.each(function() {
6349                                 maxHeight -= $( this ).outerHeight( true );
6350                         });
6351
6352                         this.headers.next()
6353                                 .each(function() {
6354                                         $( this ).height( Math.max( 0, maxHeight -
6355                                                 $( this ).innerHeight() + $( this ).height() ) );
6356                                 })
6357                                 .css( "overflow", "auto" );
6358                 } else if ( heightStyle === "auto" ) {
6359                         maxHeight = 0;
6360                         this.headers.next()
6361                                 .each(function() {
6362                                         maxHeight = Math.max( maxHeight, $( this ).css( "height", "" ).height() );
6363                                 })
6364                                 .height( maxHeight );
6365                 }
6366         },
6367
6368         _activate: function( index ) {
6369                 var active = this._findActive( index )[ 0 ];
6370
6371                 // trying to activate the already active panel
6372                 if ( active === this.active[ 0 ] ) {
6373                         return;
6374                 }
6375
6376                 // trying to collapse, simulate a click on the currently active header
6377                 active = active || this.active[ 0 ];
6378
6379                 this._eventHandler({
6380                         target: active,
6381                         currentTarget: active,
6382                         preventDefault: $.noop
6383                 });
6384         },
6385
6386         _findActive: function( selector ) {
6387                 return typeof selector === "number" ? this.headers.eq( selector ) : $();
6388         },
6389
6390         _setupEvents: function( event ) {
6391                 var events = {
6392                         keydown: "_keydown"
6393                 };
6394                 if ( event ) {
6395                         $.each( event.split(" "), function( index, eventName ) {
6396                                 events[ eventName ] = "_eventHandler";
6397                         });
6398                 }
6399
6400                 this._off( this.headers.add( this.headers.next() ) );
6401                 this._on( this.headers, events );
6402                 this._on( this.headers.next(), { keydown: "_panelKeyDown" });
6403                 this._hoverable( this.headers );
6404                 this._focusable( this.headers );
6405         },
6406
6407         _eventHandler: function( event ) {
6408                 var options = this.options,
6409                         active = this.active,
6410                         clicked = $( event.currentTarget ),
6411                         clickedIsActive = clicked[ 0 ] === active[ 0 ],
6412                         collapsing = clickedIsActive && options.collapsible,
6413                         toShow = collapsing ? $() : clicked.next(),
6414                         toHide = active.next(),
6415                         eventData = {
6416                                 oldHeader: active,
6417                                 oldPanel: toHide,
6418                                 newHeader: collapsing ? $() : clicked,
6419                                 newPanel: toShow
6420                         };
6421
6422                 event.preventDefault();
6423
6424                 if (
6425                                 // click on active header, but not collapsible
6426                                 ( clickedIsActive && !options.collapsible ) ||
6427                                 // allow canceling activation
6428                                 ( this._trigger( "beforeActivate", event, eventData ) === false ) ) {
6429                         return;
6430                 }
6431
6432                 options.active = collapsing ? false : this.headers.index( clicked );
6433
6434                 // when the call to ._toggle() comes after the class changes
6435                 // it causes a very odd bug in IE 8 (see #6720)
6436                 this.active = clickedIsActive ? $() : clicked;
6437                 this._toggle( eventData );
6438
6439                 // switch classes
6440                 // corner classes on the previously active header stay after the animation
6441                 active.removeClass( "ui-accordion-header-active ui-state-active" );
6442                 if ( options.icons ) {
6443                         active.children( ".ui-accordion-header-icon" )
6444                                 .removeClass( options.icons.activeHeader )
6445                                 .addClass( options.icons.header );
6446                 }
6447
6448                 if ( !clickedIsActive ) {
6449                         clicked
6450                                 .removeClass( "ui-corner-all" )
6451                                 .addClass( "ui-accordion-header-active ui-state-active ui-corner-top" );
6452                         if ( options.icons ) {
6453                                 clicked.children( ".ui-accordion-header-icon" )
6454                                         .removeClass( options.icons.header )
6455                                         .addClass( options.icons.activeHeader );
6456                         }
6457
6458                         clicked
6459                                 .next()
6460                                 .addClass( "ui-accordion-content-active" );
6461                 }
6462         },
6463
6464         _toggle: function( data ) {
6465                 var toShow = data.newPanel,
6466                         toHide = this.prevShow.length ? this.prevShow : data.oldPanel;
6467
6468                 // handle activating a panel during the animation for another activation
6469                 this.prevShow.add( this.prevHide ).stop( true, true );
6470                 this.prevShow = toShow;
6471                 this.prevHide = toHide;
6472
6473                 if ( this.options.animate ) {
6474                         this._animate( toShow, toHide, data );
6475                 } else {
6476                         toHide.hide();
6477                         toShow.show();
6478                         this._toggleComplete( data );
6479                 }
6480
6481                 toHide.attr({
6482                         "aria-expanded": "false",
6483                         "aria-hidden": "true"
6484                 });
6485                 toHide.prev().attr( "aria-selected", "false" );
6486                 // if we're switching panels, remove the old header from the tab order
6487                 // if we're opening from collapsed state, remove the previous header from the tab order
6488                 // if we're collapsing, then keep the collapsing header in the tab order
6489                 if ( toShow.length && toHide.length ) {
6490                         toHide.prev().attr( "tabIndex", -1 );
6491                 } else if ( toShow.length ) {
6492                         this.headers.filter(function() {
6493                                 return $( this ).attr( "tabIndex" ) === 0;
6494                         })
6495                         .attr( "tabIndex", -1 );
6496                 }
6497
6498                 toShow
6499                         .attr({
6500                                 "aria-expanded": "true",
6501                                 "aria-hidden": "false"
6502                         })
6503                         .prev()
6504                                 .attr({
6505                                         "aria-selected": "true",
6506                                         tabIndex: 0
6507                                 });
6508         },
6509
6510         _animate: function( toShow, toHide, data ) {
6511                 var total, easing, duration,
6512                         that = this,
6513                         adjust = 0,
6514                         down = toShow.length &&
6515                                 ( !toHide.length || ( toShow.index() < toHide.index() ) ),
6516                         animate = this.options.animate || {},
6517                         options = down && animate.down || animate,
6518                         complete = function() {
6519                                 that._toggleComplete( data );
6520                         };
6521
6522                 if ( typeof options === "number" ) {
6523                         duration = options;
6524                 }
6525                 if ( typeof options === "string" ) {
6526                         easing = options;
6527                 }
6528                 // fall back from options to animation in case of partial down settings
6529                 easing = easing || options.easing || animate.easing;
6530                 duration = duration || options.duration || animate.duration;
6531
6532                 if ( !toHide.length ) {
6533                         return toShow.animate( showProps, duration, easing, complete );
6534                 }
6535                 if ( !toShow.length ) {
6536                         return toHide.animate( hideProps, duration, easing, complete );
6537                 }
6538
6539                 total = toShow.show().outerHeight();
6540                 toHide.animate( hideProps, {
6541                         duration: duration,
6542                         easing: easing,
6543                         step: function( now, fx ) {
6544                                 fx.now = Math.round( now );
6545                         }
6546                 });
6547                 toShow
6548                         .hide()
6549                         .animate( showProps, {
6550                                 duration: duration,
6551                                 easing: easing,
6552                                 complete: complete,
6553                                 step: function( now, fx ) {
6554                                         fx.now = Math.round( now );
6555                                         if ( fx.prop !== "height" ) {
6556                                                 adjust += fx.now;
6557                                         } else if ( that.options.heightStyle !== "content" ) {
6558                                                 fx.now = Math.round( total - toHide.outerHeight() - adjust );
6559                                                 adjust = 0;
6560                                         }
6561                                 }
6562                         });
6563         },
6564
6565         _toggleComplete: function( data ) {
6566                 var toHide = data.oldPanel;
6567
6568                 toHide
6569                         .removeClass( "ui-accordion-content-active" )
6570                         .prev()
6571                                 .removeClass( "ui-corner-top" )
6572                                 .addClass( "ui-corner-all" );
6573
6574                 // Work around for rendering bug in IE (#5421)
6575                 if ( toHide.length ) {
6576                         toHide.parent()[0].className = toHide.parent()[0].className;
6577                 }
6578
6579                 this._trigger( "activate", null, data );
6580         }
6581 });
6582
6583 })( jQuery );
6584
6585 (function( $, undefined ) {
6586
6587 // used to prevent race conditions with remote data sources
6588 var requestIndex = 0;
6589
6590 $.widget( "ui.autocomplete", {
6591         version: "1.10.2",
6592         defaultElement: "<input>",
6593         options: {
6594                 appendTo: null,
6595                 autoFocus: false,
6596                 delay: 300,
6597                 minLength: 1,
6598                 position: {
6599                         my: "left top",
6600                         at: "left bottom",
6601                         collision: "none"
6602                 },
6603                 source: null,
6604
6605                 // callbacks
6606                 change: null,
6607                 close: null,
6608                 focus: null,
6609                 open: null,
6610                 response: null,
6611                 search: null,
6612                 select: null
6613         },
6614
6615         pending: 0,
6616
6617         _create: function() {
6618                 // Some browsers only repeat keydown events, not keypress events,
6619                 // so we use the suppressKeyPress flag to determine if we've already
6620                 // handled the keydown event. #7269
6621                 // Unfortunately the code for & in keypress is the same as the up arrow,
6622                 // so we use the suppressKeyPressRepeat flag to avoid handling keypress
6623                 // events when we know the keydown event was used to modify the
6624                 // search term. #7799
6625                 var suppressKeyPress, suppressKeyPressRepeat, suppressInput,
6626                         nodeName = this.element[0].nodeName.toLowerCase(),
6627                         isTextarea = nodeName === "textarea",
6628                         isInput = nodeName === "input";
6629
6630                 this.isMultiLine =
6631                         // Textareas are always multi-line
6632                         isTextarea ? true :
6633                         // Inputs are always single-line, even if inside a contentEditable element
6634                         // IE also treats inputs as contentEditable
6635                         isInput ? false :
6636                         // All other element types are determined by whether or not they're contentEditable
6637                         this.element.prop( "isContentEditable" );
6638
6639                 this.valueMethod = this.element[ isTextarea || isInput ? "val" : "text" ];
6640                 this.isNewMenu = true;
6641
6642                 this.element
6643                         .addClass( "ui-autocomplete-input" )
6644                         .attr( "autocomplete", "off" );
6645
6646                 this._on( this.element, {
6647                         keydown: function( event ) {
6648                                 /*jshint maxcomplexity:15*/
6649                                 if ( this.element.prop( "readOnly" ) ) {
6650                                         suppressKeyPress = true;
6651                                         suppressInput = true;
6652                                         suppressKeyPressRepeat = true;
6653                                         return;
6654                                 }
6655
6656                                 suppressKeyPress = false;
6657                                 suppressInput = false;
6658                                 suppressKeyPressRepeat = false;
6659                                 var keyCode = $.ui.keyCode;
6660                                 switch( event.keyCode ) {
6661                                 case keyCode.PAGE_UP:
6662                                         suppressKeyPress = true;
6663                                         this._move( "previousPage", event );
6664                                         break;
6665                                 case keyCode.PAGE_DOWN:
6666                                         suppressKeyPress = true;
6667                                         this._move( "nextPage", event );
6668                                         break;
6669                                 case keyCode.UP:
6670                                         suppressKeyPress = true;
6671                                         this._keyEvent( "previous", event );
6672                                         break;
6673                                 case keyCode.DOWN:
6674                                         suppressKeyPress = true;
6675                                         this._keyEvent( "next", event );
6676                                         break;
6677                                 case keyCode.ENTER:
6678                                 case keyCode.NUMPAD_ENTER:
6679                                         // when menu is open and has focus
6680                                         if ( this.menu.active ) {
6681                                                 // #6055 - Opera still allows the keypress to occur
6682                                                 // which causes forms to submit
6683                                                 suppressKeyPress = true;
6684                                                 event.preventDefault();
6685                                                 this.menu.select( event );
6686                                         }
6687                                         break;
6688                                 case keyCode.TAB:
6689                                         if ( this.menu.active ) {
6690                                                 this.menu.select( event );
6691                                         }
6692                                         break;
6693                                 case keyCode.ESCAPE:
6694                                         if ( this.menu.element.is( ":visible" ) ) {
6695                                                 this._value( this.term );
6696                                                 this.close( event );
6697                                                 // Different browsers have different default behavior for escape
6698                                                 // Single press can mean undo or clear
6699                                                 // Double press in IE means clear the whole form
6700                                                 event.preventDefault();
6701                                         }
6702                                         break;
6703                                 default:
6704                                         suppressKeyPressRepeat = true;
6705                                         // search timeout should be triggered before the input value is changed
6706                                         this._searchTimeout( event );
6707                                         break;
6708                                 }
6709                         },
6710                         keypress: function( event ) {
6711                                 if ( suppressKeyPress ) {
6712                                         suppressKeyPress = false;
6713                                         event.preventDefault();
6714                                         return;
6715                                 }
6716                                 if ( suppressKeyPressRepeat ) {
6717                                         return;
6718                                 }
6719
6720                                 // replicate some key handlers to allow them to repeat in Firefox and Opera
6721                                 var keyCode = $.ui.keyCode;
6722                                 switch( event.keyCode ) {
6723                                 case keyCode.PAGE_UP:
6724                                         this._move( "previousPage", event );
6725                                         break;
6726                                 case keyCode.PAGE_DOWN:
6727                                         this._move( "nextPage", event );
6728                                         break;
6729                                 case keyCode.UP:
6730                                         this._keyEvent( "previous", event );
6731                                         break;
6732                                 case keyCode.DOWN:
6733                                         this._keyEvent( "next", event );
6734                                         break;
6735                                 }
6736                         },
6737                         input: function( event ) {
6738                                 if ( suppressInput ) {
6739                                         suppressInput = false;
6740                                         event.preventDefault();
6741                                         return;
6742                                 }
6743                                 this._searchTimeout( event );
6744                         },
6745                         focus: function() {
6746                                 this.selectedItem = null;
6747                                 this.previous = this._value();
6748                         },
6749                         blur: function( event ) {
6750                                 if ( this.cancelBlur ) {
6751                                         delete this.cancelBlur;
6752                                         return;
6753                                 }
6754
6755                                 clearTimeout( this.searching );
6756                                 this.close( event );
6757                                 this._change( event );
6758                         }
6759                 });
6760
6761                 this._initSource();
6762                 this.menu = $( "<ul>" )
6763                         .addClass( "ui-autocomplete ui-front" )
6764                         .appendTo( this._appendTo() )
6765                         .menu({
6766                                 // custom key handling for now
6767                                 input: $(),
6768                                 // disable ARIA support, the live region takes care of that
6769                                 role: null
6770                         })
6771                         .hide()
6772                         .data( "ui-menu" );
6773
6774                 this._on( this.menu.element, {
6775                         mousedown: function( event ) {
6776                                 // prevent moving focus out of the text field
6777                                 event.preventDefault();
6778
6779                                 // IE doesn't prevent moving focus even with event.preventDefault()
6780                                 // so we set a flag to know when we should ignore the blur event
6781                                 this.cancelBlur = true;
6782                                 this._delay(function() {
6783                                         delete this.cancelBlur;
6784                                 });
6785
6786                                 // clicking on the scrollbar causes focus to shift to the body
6787                                 // but we can't detect a mouseup or a click immediately afterward
6788                                 // so we have to track the next mousedown and close the menu if
6789                                 // the user clicks somewhere outside of the autocomplete
6790                                 var menuElement = this.menu.element[ 0 ];
6791                                 if ( !$( event.target ).closest( ".ui-menu-item" ).length ) {
6792                                         this._delay(function() {
6793                                                 var that = this;
6794                                                 this.document.one( "mousedown", function( event ) {
6795                                                         if ( event.target !== that.element[ 0 ] &&
6796                                                                         event.target !== menuElement &&
6797                                                                         !$.contains( menuElement, event.target ) ) {
6798                                                                 that.close();
6799                                                         }
6800                                                 });
6801                                         });
6802                                 }
6803                         },
6804                         menufocus: function( event, ui ) {
6805                                 // support: Firefox
6806                                 // Prevent accidental activation of menu items in Firefox (#7024 #9118)
6807                                 if ( this.isNewMenu ) {
6808                                         this.isNewMenu = false;
6809                                         if ( event.originalEvent && /^mouse/.test( event.originalEvent.type ) ) {
6810                                                 this.menu.blur();
6811
6812                                                 this.document.one( "mousemove", function() {
6813                                                         $( event.target ).trigger( event.originalEvent );
6814                                                 });
6815
6816                                                 return;
6817                                         }
6818                                 }
6819
6820                                 var item = ui.item.data( "ui-autocomplete-item" );
6821                                 if ( false !== this._trigger( "focus", event, { item: item } ) ) {
6822                                         // use value to match what will end up in the input, if it was a key event
6823                                         if ( event.originalEvent && /^key/.test( event.originalEvent.type ) ) {
6824                                                 this._value( item.value );
6825                                         }
6826                                 } else {
6827                                         // Normally the input is populated with the item's value as the
6828                                         // menu is navigated, causing screen readers to notice a change and
6829                                         // announce the item. Since the focus event was canceled, this doesn't
6830                                         // happen, so we update the live region so that screen readers can
6831                                         // still notice the change and announce it.
6832                                         this.liveRegion.text( item.value );
6833                                 }
6834                         },
6835                         menuselect: function( event, ui ) {
6836                                 var item = ui.item.data( "ui-autocomplete-item" ),
6837                                         previous = this.previous;
6838
6839                                 // only trigger when focus was lost (click on menu)
6840                                 if ( this.element[0] !== this.document[0].activeElement ) {
6841                                         this.element.focus();
6842                                         this.previous = previous;
6843                                         // #6109 - IE triggers two focus events and the second
6844                                         // is asynchronous, so we need to reset the previous
6845                                         // term synchronously and asynchronously :-(
6846                                         this._delay(function() {
6847                                                 this.previous = previous;
6848                                                 this.selectedItem = item;
6849                                         });
6850                                 }
6851
6852                                 if ( false !== this._trigger( "select", event, { item: item } ) ) {
6853                                         this._value( item.value );
6854                                 }
6855                                 // reset the term after the select event
6856                                 // this allows custom select handling to work properly
6857                                 this.term = this._value();
6858
6859                                 this.close( event );
6860                                 this.selectedItem = item;
6861                         }
6862                 });
6863
6864                 this.liveRegion = $( "<span>", {
6865                                 role: "status",
6866                                 "aria-live": "polite"
6867                         })
6868                         .addClass( "ui-helper-hidden-accessible" )
6869                         .insertAfter( this.element );
6870
6871                 // turning off autocomplete prevents the browser from remembering the
6872                 // value when navigating through history, so we re-enable autocomplete
6873                 // if the page is unloaded before the widget is destroyed. #7790
6874                 this._on( this.window, {
6875                         beforeunload: function() {
6876                                 this.element.removeAttr( "autocomplete" );
6877                         }
6878                 });
6879         },
6880
6881         _destroy: function() {
6882                 clearTimeout( this.searching );
6883                 this.element
6884                         .removeClass( "ui-autocomplete-input" )
6885                         .removeAttr( "autocomplete" );
6886                 this.menu.element.remove();
6887                 this.liveRegion.remove();
6888         },
6889
6890         _setOption: function( key, value ) {
6891                 this._super( key, value );
6892                 if ( key === "source" ) {
6893                         this._initSource();
6894                 }
6895                 if ( key === "appendTo" ) {
6896                         this.menu.element.appendTo( this._appendTo() );
6897                 }
6898                 if ( key === "disabled" && value && this.xhr ) {
6899                         this.xhr.abort();
6900                 }
6901         },
6902
6903         _appendTo: function() {
6904                 var element = this.options.appendTo;
6905
6906                 if ( element ) {
6907                         element = element.jquery || element.nodeType ?
6908                                 $( element ) :
6909                                 this.document.find( element ).eq( 0 );
6910                 }
6911
6912                 if ( !element ) {
6913                         element = this.element.closest( ".ui-front" );
6914                 }
6915
6916                 if ( !element.length ) {
6917                         element = this.document[0].body;
6918                 }
6919
6920                 return element;
6921         },
6922
6923         _initSource: function() {
6924                 var array, url,
6925                         that = this;
6926                 if ( $.isArray(this.options.source) ) {
6927                         array = this.options.source;
6928                         this.source = function( request, response ) {
6929                                 response( $.ui.autocomplete.filter( array, request.term ) );
6930                         };
6931                 } else if ( typeof this.options.source === "string" ) {
6932                         url = this.options.source;
6933                         this.source = function( request, response ) {
6934                                 if ( that.xhr ) {
6935                                         that.xhr.abort();
6936                                 }
6937                                 that.xhr = $.ajax({
6938                                         url: url,
6939                                         data: request,
6940                                         dataType: "json",
6941                                         success: function( data ) {
6942                                                 response( data );
6943                                         },
6944                                         error: function() {
6945                                                 response( [] );
6946                                         }
6947                                 });
6948                         };
6949                 } else {
6950                         this.source = this.options.source;
6951                 }
6952         },
6953
6954         _searchTimeout: function( event ) {
6955                 clearTimeout( this.searching );
6956                 this.searching = this._delay(function() {
6957                         // only search if the value has changed
6958                         if ( this.term !== this._value() ) {
6959                                 this.selectedItem = null;
6960                                 this.search( null, event );
6961                         }
6962                 }, this.options.delay );
6963         },
6964
6965         search: function( value, event ) {
6966                 value = value != null ? value : this._value();
6967
6968                 // always save the actual value, not the one passed as an argument
6969                 this.term = this._value();
6970
6971                 if ( value.length < this.options.minLength ) {
6972                         return this.close( event );
6973                 }
6974
6975                 if ( this._trigger( "search", event ) === false ) {
6976                         return;
6977                 }
6978
6979                 return this._search( value );
6980         },
6981
6982         _search: function( value ) {
6983                 this.pending++;
6984                 this.element.addClass( "ui-autocomplete-loading" );
6985                 this.cancelSearch = false;
6986
6987                 this.source( { term: value }, this._response() );
6988         },
6989
6990         _response: function() {
6991                 var that = this,
6992                         index = ++requestIndex;
6993
6994                 return function( content ) {
6995                         if ( index === requestIndex ) {
6996                                 that.__response( content );
6997                         }
6998
6999                         that.pending--;
7000                         if ( !that.pending ) {
7001                                 that.element.removeClass( "ui-autocomplete-loading" );
7002                         }
7003                 };
7004         },
7005
7006         __response: function( content ) {
7007                 if ( content ) {
7008                         content = this._normalize( content );
7009                 }
7010                 this._trigger( "response", null, { content: content } );
7011                 if ( !this.options.disabled && content && content.length && !this.cancelSearch ) {
7012                         this._suggest( content );
7013                         this._trigger( "open" );
7014                 } else {
7015                         // use ._close() instead of .close() so we don't cancel future searches
7016                         this._close();
7017                 }
7018         },
7019
7020         close: function( event ) {
7021                 this.cancelSearch = true;
7022                 this._close( event );
7023         },
7024
7025         _close: function( event ) {
7026                 if ( this.menu.element.is( ":visible" ) ) {
7027                         this.menu.element.hide();
7028                         this.menu.blur();
7029                         this.isNewMenu = true;
7030                         this._trigger( "close", event );
7031                 }
7032         },
7033
7034         _change: function( event ) {
7035                 if ( this.previous !== this._value() ) {
7036                         this._trigger( "change", event, { item: this.selectedItem } );
7037                 }
7038         },
7039
7040         _normalize: function( items ) {
7041                 // assume all items have the right format when the first item is complete
7042                 if ( items.length && items[0].label && items[0].value ) {
7043                         return items;
7044                 }
7045                 return $.map( items, function( item ) {
7046                         if ( typeof item === "string" ) {
7047                                 return {
7048                                         label: item,
7049                                         value: item
7050                                 };
7051                         }
7052                         return $.extend({
7053                                 label: item.label || item.value,
7054                                 value: item.value || item.label
7055                         }, item );
7056                 });
7057         },
7058
7059         _suggest: function( items ) {
7060                 var ul = this.menu.element.empty();
7061                 this._renderMenu( ul, items );
7062                 this.isNewMenu = true;
7063                 this.menu.refresh();
7064
7065                 // size and position menu
7066                 ul.show();
7067                 this._resizeMenu();
7068                 ul.position( $.extend({
7069                         of: this.element
7070                 }, this.options.position ));
7071
7072                 if ( this.options.autoFocus ) {
7073                         this.menu.next();
7074                 }
7075         },
7076
7077         _resizeMenu: function() {
7078                 var ul = this.menu.element;
7079                 ul.outerWidth( Math.max(
7080                         // Firefox wraps long text (possibly a rounding bug)
7081                         // so we add 1px to avoid the wrapping (#7513)
7082                         ul.width( "" ).outerWidth() + 1,
7083                         this.element.outerWidth()
7084                 ) );
7085         },
7086
7087         _renderMenu: function( ul, items ) {
7088                 var that = this;
7089                 $.each( items, function( index, item ) {
7090                         that._renderItemData( ul, item );
7091                 });
7092         },
7093
7094         _renderItemData: function( ul, item ) {
7095                 return this._renderItem( ul, item ).data( "ui-autocomplete-item", item );
7096         },
7097
7098         _renderItem: function( ul, item ) {
7099                 return $( "<li>" )
7100                         .append( $( "<a>" ).text( item.label ) )
7101                         .appendTo( ul );
7102         },
7103
7104         _move: function( direction, event ) {
7105                 if ( !this.menu.element.is( ":visible" ) ) {
7106                         this.search( null, event );
7107                         return;
7108                 }
7109                 if ( this.menu.isFirstItem() && /^previous/.test( direction ) ||
7110                                 this.menu.isLastItem() && /^next/.test( direction ) ) {
7111                         this._value( this.term );
7112                         this.menu.blur();
7113                         return;
7114                 }
7115                 this.menu[ direction ]( event );
7116         },
7117
7118         widget: function() {
7119                 return this.menu.element;
7120         },
7121
7122         _value: function() {
7123                 return this.valueMethod.apply( this.element, arguments );
7124         },
7125
7126         _keyEvent: function( keyEvent, event ) {
7127                 if ( !this.isMultiLine || this.menu.element.is( ":visible" ) ) {
7128                         this._move( keyEvent, event );
7129
7130                         // prevents moving cursor to beginning/end of the text field in some browsers
7131                         event.preventDefault();
7132                 }
7133         }
7134 });
7135
7136 $.extend( $.ui.autocomplete, {
7137         escapeRegex: function( value ) {
7138                 return value.replace(/[\-\[\]{}()*+?.,\\\^$|#\s]/g, "\\$&");
7139         },
7140         filter: function(array, term) {
7141                 var matcher = new RegExp( $.ui.autocomplete.escapeRegex(term), "i" );
7142                 return $.grep( array, function(value) {
7143                         return matcher.test( value.label || value.value || value );
7144                 });
7145         }
7146 });
7147
7148
7149 // live region extension, adding a `messages` option
7150 // NOTE: This is an experimental API. We are still investigating
7151 // a full solution for string manipulation and internationalization.
7152 $.widget( "ui.autocomplete", $.ui.autocomplete, {
7153         options: {
7154                 messages: {
7155                         noResults: "No search results.",
7156                         results: function( amount ) {
7157                                 return amount + ( amount > 1 ? " results are" : " result is" ) +
7158                                         " available, use up and down arrow keys to navigate.";
7159                         }
7160                 }
7161         },
7162
7163         __response: function( content ) {
7164                 var message;
7165                 this._superApply( arguments );
7166                 if ( this.options.disabled || this.cancelSearch ) {
7167                         return;
7168                 }
7169                 if ( content && content.length ) {
7170                         message = this.options.messages.results( content.length );
7171                 } else {
7172                         message = this.options.messages.noResults;
7173                 }
7174                 this.liveRegion.text( message );
7175         }
7176 });
7177
7178 }( jQuery ));
7179
7180 (function( $, undefined ) {
7181
7182 var lastActive, startXPos, startYPos, clickDragged,
7183         baseClasses = "ui-button ui-widget ui-state-default ui-corner-all",
7184         stateClasses = "ui-state-hover ui-state-active ",
7185         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",
7186         formResetHandler = function() {
7187                 var buttons = $( this ).find( ":ui-button" );
7188                 setTimeout(function() {
7189                         buttons.button( "refresh" );
7190                 }, 1 );
7191         },
7192         radioGroup = function( radio ) {
7193                 var name = radio.name,
7194                         form = radio.form,
7195                         radios = $( [] );
7196                 if ( name ) {
7197                         name = name.replace( /'/g, "\\'" );
7198                         if ( form ) {
7199                                 radios = $( form ).find( "[name='" + name + "']" );
7200                         } else {
7201                                 radios = $( "[name='" + name + "']", radio.ownerDocument )
7202                                         .filter(function() {
7203                                                 return !this.form;
7204                                         });
7205                         }
7206                 }
7207                 return radios;
7208         };
7209
7210 $.widget( "ui.button", {
7211         version: "1.10.2",
7212         defaultElement: "<button>",
7213         options: {
7214                 disabled: null,
7215                 text: true,
7216                 label: null,
7217                 icons: {
7218                         primary: null,
7219                         secondary: null
7220                 }
7221         },
7222         _create: function() {
7223                 this.element.closest( "form" )
7224                         .unbind( "reset" + this.eventNamespace )
7225                         .bind( "reset" + this.eventNamespace, formResetHandler );
7226
7227                 if ( typeof this.options.disabled !== "boolean" ) {
7228                         this.options.disabled = !!this.element.prop( "disabled" );
7229                 } else {
7230                         this.element.prop( "disabled", this.options.disabled );
7231                 }
7232
7233                 this._determineButtonType();
7234                 this.hasTitle = !!this.buttonElement.attr( "title" );
7235
7236                 var that = this,
7237                         options = this.options,
7238                         toggleButton = this.type === "checkbox" || this.type === "radio",
7239                         activeClass = !toggleButton ? "ui-state-active" : "",
7240                         focusClass = "ui-state-focus";
7241
7242                 if ( options.label === null ) {
7243                         options.label = (this.type === "input" ? this.buttonElement.val() : this.buttonElement.html());
7244                 }
7245
7246                 this._hoverable( this.buttonElement );
7247
7248                 this.buttonElement
7249                         .addClass( baseClasses )
7250                         .attr( "role", "button" )
7251                         .bind( "mouseenter" + this.eventNamespace, function() {
7252                                 if ( options.disabled ) {
7253                                         return;
7254                                 }
7255                                 if ( this === lastActive ) {
7256                                         $( this ).addClass( "ui-state-active" );
7257                                 }
7258                         })
7259                         .bind( "mouseleave" + this.eventNamespace, function() {
7260                                 if ( options.disabled ) {
7261                                         return;
7262                                 }
7263                                 $( this ).removeClass( activeClass );
7264                         })
7265                         .bind( "click" + this.eventNamespace, function( event ) {
7266                                 if ( options.disabled ) {
7267                                         event.preventDefault();
7268                                         event.stopImmediatePropagation();
7269                                 }
7270                         });
7271
7272                 this.element
7273                         .bind( "focus" + this.eventNamespace, function() {
7274                                 // no need to check disabled, focus won't be triggered anyway
7275                                 that.buttonElement.addClass( focusClass );
7276                         })
7277                         .bind( "blur" + this.eventNamespace, function() {
7278                                 that.buttonElement.removeClass( focusClass );
7279                         });
7280
7281                 if ( toggleButton ) {
7282                         this.element.bind( "change" + this.eventNamespace, function() {
7283                                 if ( clickDragged ) {
7284                                         return;
7285                                 }
7286                                 that.refresh();
7287                         });
7288                         // if mouse moves between mousedown and mouseup (drag) set clickDragged flag
7289                         // prevents issue where button state changes but checkbox/radio checked state
7290                         // does not in Firefox (see ticket #6970)
7291                         this.buttonElement
7292                                 .bind( "mousedown" + this.eventNamespace, function( event ) {
7293                                         if ( options.disabled ) {
7294                                                 return;
7295                                         }
7296                                         clickDragged = false;
7297                                         startXPos = event.pageX;
7298                                         startYPos = event.pageY;
7299                                 })
7300                                 .bind( "mouseup" + this.eventNamespace, function( event ) {
7301                                         if ( options.disabled ) {
7302                                                 return;
7303                                         }
7304                                         if ( startXPos !== event.pageX || startYPos !== event.pageY ) {
7305                                                 clickDragged = true;
7306                                         }
7307                         });
7308                 }
7309
7310                 if ( this.type === "checkbox" ) {
7311                         this.buttonElement.bind( "click" + this.eventNamespace, function() {
7312                                 if ( options.disabled || clickDragged ) {
7313                                         return false;
7314                                 }
7315                         });
7316                 } else if ( this.type === "radio" ) {
7317                         this.buttonElement.bind( "click" + this.eventNamespace, function() {
7318                                 if ( options.disabled || clickDragged ) {
7319                                         return false;
7320                                 }
7321                                 $( this ).addClass( "ui-state-active" );
7322                                 that.buttonElement.attr( "aria-pressed", "true" );
7323
7324                                 var radio = that.element[ 0 ];
7325                                 radioGroup( radio )
7326                                         .not( radio )
7327                                         .map(function() {
7328                                                 return $( this ).button( "widget" )[ 0 ];
7329                                         })
7330                                         .removeClass( "ui-state-active" )
7331                                         .attr( "aria-pressed", "false" );
7332                         });
7333                 } else {
7334                         this.buttonElement
7335                                 .bind( "mousedown" + this.eventNamespace, function() {
7336                                         if ( options.disabled ) {
7337                                                 return false;
7338                                         }
7339                                         $( this ).addClass( "ui-state-active" );
7340                                         lastActive = this;
7341                                         that.document.one( "mouseup", function() {
7342                                                 lastActive = null;
7343                                         });
7344                                 })
7345                                 .bind( "mouseup" + this.eventNamespace, function() {
7346                                         if ( options.disabled ) {
7347                                                 return false;
7348                                         }
7349                                         $( this ).removeClass( "ui-state-active" );
7350                                 })
7351                                 .bind( "keydown" + this.eventNamespace, function(event) {
7352                                         if ( options.disabled ) {
7353                                                 return false;
7354                                         }
7355                                         if ( event.keyCode === $.ui.keyCode.SPACE || event.keyCode === $.ui.keyCode.ENTER ) {
7356                                                 $( this ).addClass( "ui-state-active" );
7357                                         }
7358                                 })
7359                                 // see #8559, we bind to blur here in case the button element loses
7360                                 // focus between keydown and keyup, it would be left in an "active" state
7361                                 .bind( "keyup" + this.eventNamespace + " blur" + this.eventNamespace, function() {
7362                                         $( this ).removeClass( "ui-state-active" );
7363                                 });
7364
7365                         if ( this.buttonElement.is("a") ) {
7366                                 this.buttonElement.keyup(function(event) {
7367                                         if ( event.keyCode === $.ui.keyCode.SPACE ) {
7368                                                 // TODO pass through original event correctly (just as 2nd argument doesn't work)
7369                                                 $( this ).click();
7370                                         }
7371                                 });
7372                         }
7373                 }
7374
7375                 // TODO: pull out $.Widget's handling for the disabled option into
7376                 // $.Widget.prototype._setOptionDisabled so it's easy to proxy and can
7377                 // be overridden by individual plugins
7378                 this._setOption( "disabled", options.disabled );
7379                 this._resetButton();
7380         },
7381
7382         _determineButtonType: function() {
7383                 var ancestor, labelSelector, checked;
7384
7385                 if ( this.element.is("[type=checkbox]") ) {
7386                         this.type = "checkbox";
7387                 } else if ( this.element.is("[type=radio]") ) {
7388                         this.type = "radio";
7389                 } else if ( this.element.is("input") ) {
7390                         this.type = "input";
7391                 } else {
7392                         this.type = "button";
7393                 }
7394
7395                 if ( this.type === "checkbox" || this.type === "radio" ) {
7396                         // we don't search against the document in case the element
7397                         // is disconnected from the DOM
7398                         ancestor = this.element.parents().last();
7399                         labelSelector = "label[for='" + this.element.attr("id") + "']";
7400                         this.buttonElement = ancestor.find( labelSelector );
7401                         if ( !this.buttonElement.length ) {
7402                                 ancestor = ancestor.length ? ancestor.siblings() : this.element.siblings();
7403                                 this.buttonElement = ancestor.filter( labelSelector );
7404                                 if ( !this.buttonElement.length ) {
7405                                         this.buttonElement = ancestor.find( labelSelector );
7406                                 }
7407                         }
7408                         this.element.addClass( "ui-helper-hidden-accessible" );
7409
7410                         checked = this.element.is( ":checked" );
7411                         if ( checked ) {
7412                                 this.buttonElement.addClass( "ui-state-active" );
7413                         }
7414                         this.buttonElement.prop( "aria-pressed", checked );
7415                 } else {
7416                         this.buttonElement = this.element;
7417                 }
7418         },
7419
7420         widget: function() {
7421                 return this.buttonElement;
7422         },
7423
7424         _destroy: function() {
7425                 this.element
7426                         .removeClass( "ui-helper-hidden-accessible" );
7427                 this.buttonElement
7428                         .removeClass( baseClasses + " " + stateClasses + " " + typeClasses )
7429                         .removeAttr( "role" )
7430                         .removeAttr( "aria-pressed" )
7431                         .html( this.buttonElement.find(".ui-button-text").html() );
7432
7433                 if ( !this.hasTitle ) {
7434                         this.buttonElement.removeAttr( "title" );
7435                 }
7436         },
7437
7438         _setOption: function( key, value ) {
7439                 this._super( key, value );
7440                 if ( key === "disabled" ) {
7441                         if ( value ) {
7442                                 this.element.prop( "disabled", true );
7443                         } else {
7444                                 this.element.prop( "disabled", false );
7445                         }
7446                         return;
7447                 }
7448                 this._resetButton();
7449         },
7450
7451         refresh: function() {
7452                 //See #8237 & #8828
7453                 var isDisabled = this.element.is( "input, button" ) ? this.element.is( ":disabled" ) : this.element.hasClass( "ui-button-disabled" );
7454
7455                 if ( isDisabled !== this.options.disabled ) {
7456                         this._setOption( "disabled", isDisabled );
7457                 }
7458                 if ( this.type === "radio" ) {
7459                         radioGroup( this.element[0] ).each(function() {
7460                                 if ( $( this ).is( ":checked" ) ) {
7461                                         $( this ).button( "widget" )
7462                                                 .addClass( "ui-state-active" )
7463                                                 .attr( "aria-pressed", "true" );
7464                                 } else {
7465                                         $( this ).button( "widget" )
7466                                                 .removeClass( "ui-state-active" )
7467                                                 .attr( "aria-pressed", "false" );
7468                                 }
7469                         });
7470                 } else if ( this.type === "checkbox" ) {
7471                         if ( this.element.is( ":checked" ) ) {
7472                                 this.buttonElement
7473                                         .addClass( "ui-state-active" )
7474                                         .attr( "aria-pressed", "true" );
7475                         } else {
7476                                 this.buttonElement
7477                                         .removeClass( "ui-state-active" )
7478                                         .attr( "aria-pressed", "false" );
7479                         }
7480                 }
7481         },
7482
7483         _resetButton: function() {
7484                 if ( this.type === "input" ) {
7485                         if ( this.options.label ) {
7486                                 this.element.val( this.options.label );
7487                         }
7488                         return;
7489                 }
7490                 var buttonElement = this.buttonElement.removeClass( typeClasses ),
7491                         buttonText = $( "<span></span>", this.document[0] )
7492                                 .addClass( "ui-button-text" )
7493                                 .html( this.options.label )
7494                                 .appendTo( buttonElement.empty() )
7495                                 .text(),
7496                         icons = this.options.icons,
7497                         multipleIcons = icons.primary && icons.secondary,
7498                         buttonClasses = [];
7499
7500                 if ( icons.primary || icons.secondary ) {
7501                         if ( this.options.text ) {
7502                                 buttonClasses.push( "ui-button-text-icon" + ( multipleIcons ? "s" : ( icons.primary ? "-primary" : "-secondary" ) ) );
7503                         }
7504
7505                         if ( icons.primary ) {
7506                                 buttonElement.prepend( "<span class='ui-button-icon-primary ui-icon " + icons.primary + "'></span>" );
7507                         }
7508
7509                         if ( icons.secondary ) {
7510                                 buttonElement.append( "<span class='ui-button-icon-secondary ui-icon " + icons.secondary + "'></span>" );
7511                         }
7512
7513                         if ( !this.options.text ) {
7514                                 buttonClasses.push( multipleIcons ? "ui-button-icons-only" : "ui-button-icon-only" );
7515
7516                                 if ( !this.hasTitle ) {
7517                                         buttonElement.attr( "title", $.trim( buttonText ) );
7518                                 }
7519                         }
7520                 } else {
7521                         buttonClasses.push( "ui-button-text-only" );
7522                 }
7523                 buttonElement.addClass( buttonClasses.join( " " ) );
7524         }
7525 });
7526
7527 $.widget( "ui.buttonset", {
7528         version: "1.10.2",
7529         options: {
7530                 items: "button, input[type=button], input[type=submit], input[type=reset], input[type=checkbox], input[type=radio], a, :data(ui-button)"
7531         },
7532
7533         _create: function() {
7534                 this.element.addClass( "ui-buttonset" );
7535         },
7536
7537         _init: function() {
7538                 this.refresh();
7539         },
7540
7541         _setOption: function( key, value ) {
7542                 if ( key === "disabled" ) {
7543                         this.buttons.button( "option", key, value );
7544                 }
7545
7546                 this._super( key, value );
7547         },
7548
7549         refresh: function() {
7550                 var rtl = this.element.css( "direction" ) === "rtl";
7551
7552                 this.buttons = this.element.find( this.options.items )
7553                         .filter( ":ui-button" )
7554                                 .button( "refresh" )
7555                         .end()
7556                         .not( ":ui-button" )
7557                                 .button()
7558                         .end()
7559                         .map(function() {
7560                                 return $( this ).button( "widget" )[ 0 ];
7561                         })
7562                                 .removeClass( "ui-corner-all ui-corner-left ui-corner-right" )
7563                                 .filter( ":first" )
7564                                         .addClass( rtl ? "ui-corner-right" : "ui-corner-left" )
7565                                 .end()
7566                                 .filter( ":last" )
7567                                         .addClass( rtl ? "ui-corner-left" : "ui-corner-right" )
7568                                 .end()
7569                         .end();
7570         },
7571
7572         _destroy: function() {
7573                 this.element.removeClass( "ui-buttonset" );
7574                 this.buttons
7575                         .map(function() {
7576                                 return $( this ).button( "widget" )[ 0 ];
7577                         })
7578                                 .removeClass( "ui-corner-left ui-corner-right" )
7579                         .end()
7580                         .button( "destroy" );
7581         }
7582 });
7583
7584 }( jQuery ) );
7585
7586 (function( $, undefined ) {
7587
7588 $.extend($.ui, { datepicker: { version: "1.10.2" } });
7589
7590 var PROP_NAME = "datepicker",
7591         dpuuid = new Date().getTime(),
7592         instActive;
7593
7594 /* Date picker manager.
7595    Use the singleton instance of this class, $.datepicker, to interact with the date picker.
7596    Settings for (groups of) date pickers are maintained in an instance object,
7597    allowing multiple different settings on the same page. */
7598
7599 function Datepicker() {
7600         this._curInst = null; // The current instance in use
7601         this._keyEvent = false; // If the last event was a key event
7602         this._disabledInputs = []; // List of date picker inputs that have been disabled
7603         this._datepickerShowing = false; // True if the popup picker is showing , false if not
7604         this._inDialog = false; // True if showing within a "dialog", false if not
7605         this._mainDivId = "ui-datepicker-div"; // The ID of the main datepicker division
7606         this._inlineClass = "ui-datepicker-inline"; // The name of the inline marker class
7607         this._appendClass = "ui-datepicker-append"; // The name of the append marker class
7608         this._triggerClass = "ui-datepicker-trigger"; // The name of the trigger marker class
7609         this._dialogClass = "ui-datepicker-dialog"; // The name of the dialog marker class
7610         this._disableClass = "ui-datepicker-disabled"; // The name of the disabled covering marker class
7611         this._unselectableClass = "ui-datepicker-unselectable"; // The name of the unselectable cell marker class
7612         this._currentClass = "ui-datepicker-current-day"; // The name of the current day marker class
7613         this._dayOverClass = "ui-datepicker-days-cell-over"; // The name of the day hover marker class
7614         this.regional = []; // Available regional settings, indexed by language code
7615         this.regional[""] = { // Default regional settings
7616                 closeText: "Done", // Display text for close link
7617                 prevText: "Prev", // Display text for previous month link
7618                 nextText: "Next", // Display text for next month link
7619                 currentText: "Today", // Display text for current month link
7620                 monthNames: ["January","February","March","April","May","June",
7621                         "July","August","September","October","November","December"], // Names of months for drop-down and formatting
7622                 monthNamesShort: ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"], // For formatting
7623                 dayNames: ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"], // For formatting
7624                 dayNamesShort: ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"], // For formatting
7625                 dayNamesMin: ["Su","Mo","Tu","We","Th","Fr","Sa"], // Column headings for days starting at Sunday
7626                 weekHeader: "Wk", // Column header for week of the year
7627                 dateFormat: "mm/dd/yy", // See format options on parseDate
7628                 firstDay: 0, // The first day of the week, Sun = 0, Mon = 1, ...
7629                 isRTL: false, // True if right-to-left language, false if left-to-right
7630                 showMonthAfterYear: false, // True if the year select precedes month, false for month then year
7631                 yearSuffix: "" // Additional text to append to the year in the month headers
7632         };
7633         this._defaults = { // Global defaults for all the date picker instances
7634                 showOn: "focus", // "focus" for popup on focus,
7635                         // "button" for trigger button, or "both" for either
7636                 showAnim: "fadeIn", // Name of jQuery animation for popup
7637                 showOptions: {}, // Options for enhanced animations
7638                 defaultDate: null, // Used when field is blank: actual date,
7639                         // +/-number for offset from today, null for today
7640                 appendText: "", // Display text following the input box, e.g. showing the format
7641                 buttonText: "...", // Text for trigger button
7642                 buttonImage: "", // URL for trigger button image
7643                 buttonImageOnly: false, // True if the image appears alone, false if it appears on a button
7644                 hideIfNoPrevNext: false, // True to hide next/previous month links
7645                         // if not applicable, false to just disable them
7646                 navigationAsDateFormat: false, // True if date formatting applied to prev/today/next links
7647                 gotoCurrent: false, // True if today link goes back to current selection instead
7648                 changeMonth: false, // True if month can be selected directly, false if only prev/next
7649                 changeYear: false, // True if year can be selected directly, false if only prev/next
7650                 yearRange: "c-10:c+10", // Range of years to display in drop-down,
7651                         // either relative to today's year (-nn:+nn), relative to currently displayed year
7652                         // (c-nn:c+nn), absolute (nnnn:nnnn), or a combination of the above (nnnn:-n)
7653                 showOtherMonths: false, // True to show dates in other months, false to leave blank
7654                 selectOtherMonths: false, // True to allow selection of dates in other months, false for unselectable
7655                 showWeek: false, // True to show week of the year, false to not show it
7656                 calculateWeek: this.iso8601Week, // How to calculate the week of the year,
7657                         // takes a Date and returns the number of the week for it
7658                 shortYearCutoff: "+10", // Short year values < this are in the current century,
7659                         // > this are in the previous century,
7660                         // string value starting with "+" for current year + value
7661                 minDate: null, // The earliest selectable date, or null for no limit
7662                 maxDate: null, // The latest selectable date, or null for no limit
7663                 duration: "fast", // Duration of display/closure
7664                 beforeShowDay: null, // Function that takes a date and returns an array with
7665                         // [0] = true if selectable, false if not, [1] = custom CSS class name(s) or "",
7666                         // [2] = cell title (optional), e.g. $.datepicker.noWeekends
7667                 beforeShow: null, // Function that takes an input field and
7668                         // returns a set of custom settings for the date picker
7669                 onSelect: null, // Define a callback function when a date is selected
7670                 onChangeMonthYear: null, // Define a callback function when the month or year is changed
7671                 onClose: null, // Define a callback function when the datepicker is closed
7672                 numberOfMonths: 1, // Number of months to show at a time
7673                 showCurrentAtPos: 0, // The position in multipe months at which to show the current month (starting at 0)
7674                 stepMonths: 1, // Number of months to step back/forward
7675                 stepBigMonths: 12, // Number of months to step back/forward for the big links
7676                 altField: "", // Selector for an alternate field to store selected dates into
7677                 altFormat: "", // The date format to use for the alternate field
7678                 constrainInput: true, // The input is constrained by the current date format
7679                 showButtonPanel: false, // True to show button panel, false to not show it
7680                 autoSize: false, // True to size the input for the date format, false to leave as is
7681                 disabled: false // The initial disabled state
7682         };
7683         $.extend(this._defaults, this.regional[""]);
7684         this.dpDiv = bindHover($("<div id='" + this._mainDivId + "' class='ui-datepicker ui-widget ui-widget-content ui-helper-clearfix ui-corner-all'></div>"));
7685 }
7686
7687 $.extend(Datepicker.prototype, {
7688         /* Class name added to elements to indicate already configured with a date picker. */
7689         markerClassName: "hasDatepicker",
7690
7691         //Keep track of the maximum number of rows displayed (see #7043)
7692         maxRows: 4,
7693
7694         // TODO rename to "widget" when switching to widget factory
7695         _widgetDatepicker: function() {
7696                 return this.dpDiv;
7697         },
7698
7699         /* Override the default settings for all instances of the date picker.
7700          * @param  settings  object - the new settings to use as defaults (anonymous object)
7701          * @return the manager object
7702          */
7703         setDefaults: function(settings) {
7704                 extendRemove(this._defaults, settings || {});
7705                 return this;
7706         },
7707
7708         /* Attach the date picker to a jQuery selection.
7709          * @param  target       element - the target input field or division or span
7710          * @param  settings  object - the new settings to use for this date picker instance (anonymous)
7711          */
7712         _attachDatepicker: function(target, settings) {
7713                 var nodeName, inline, inst;
7714                 nodeName = target.nodeName.toLowerCase();
7715                 inline = (nodeName === "div" || nodeName === "span");
7716                 if (!target.id) {
7717                         this.uuid += 1;
7718                         target.id = "dp" + this.uuid;
7719                 }
7720                 inst = this._newInst($(target), inline);
7721                 inst.settings = $.extend({}, settings || {});
7722                 if (nodeName === "input") {
7723                         this._connectDatepicker(target, inst);
7724                 } else if (inline) {
7725                         this._inlineDatepicker(target, inst);
7726                 }
7727         },
7728
7729         /* Create a new instance object. */
7730         _newInst: function(target, inline) {
7731                 var id = target[0].id.replace(/([^A-Za-z0-9_\-])/g, "\\\\$1"); // escape jQuery meta chars
7732                 return {id: id, input: target, // associated target
7733                         selectedDay: 0, selectedMonth: 0, selectedYear: 0, // current selection
7734                         drawMonth: 0, drawYear: 0, // month being drawn
7735                         inline: inline, // is datepicker inline or not
7736                         dpDiv: (!inline ? this.dpDiv : // presentation div
7737                         bindHover($("<div class='" + this._inlineClass + " ui-datepicker ui-widget ui-widget-content ui-helper-clearfix ui-corner-all'></div>")))};
7738         },
7739
7740         /* Attach the date picker to an input field. */
7741         _connectDatepicker: function(target, inst) {
7742                 var input = $(target);
7743                 inst.append = $([]);
7744                 inst.trigger = $([]);
7745                 if (input.hasClass(this.markerClassName)) {
7746                         return;
7747                 }
7748                 this._attachments(input, inst);
7749                 input.addClass(this.markerClassName).keydown(this._doKeyDown).
7750                         keypress(this._doKeyPress).keyup(this._doKeyUp);
7751                 this._autoSize(inst);
7752                 $.data(target, PROP_NAME, inst);
7753                 //If disabled option is true, disable the datepicker once it has been attached to the input (see ticket #5665)
7754                 if( inst.settings.disabled ) {
7755                         this._disableDatepicker( target );
7756                 }
7757         },
7758
7759         /* Make attachments based on settings. */
7760         _attachments: function(input, inst) {
7761                 var showOn, buttonText, buttonImage,
7762                         appendText = this._get(inst, "appendText"),
7763                         isRTL = this._get(inst, "isRTL");
7764
7765                 if (inst.append) {
7766                         inst.append.remove();
7767                 }
7768                 if (appendText) {
7769                         inst.append = $("<span class='" + this._appendClass + "'>" + appendText + "</span>");
7770                         input[isRTL ? "before" : "after"](inst.append);
7771                 }
7772
7773                 input.unbind("focus", this._showDatepicker);
7774
7775                 if (inst.trigger) {
7776                         inst.trigger.remove();
7777                 }
7778
7779                 showOn = this._get(inst, "showOn");
7780                 if (showOn === "focus" || showOn === "both") { // pop-up date picker when in the marked field
7781                         input.focus(this._showDatepicker);
7782                 }
7783                 if (showOn === "button" || showOn === "both") { // pop-up date picker when button clicked
7784                         buttonText = this._get(inst, "buttonText");
7785                         buttonImage = this._get(inst, "buttonImage");
7786                         inst.trigger = $(this._get(inst, "buttonImageOnly") ?
7787                                 $("<img/>").addClass(this._triggerClass).
7788                                         attr({ src: buttonImage, alt: buttonText, title: buttonText }) :
7789                                 $("<button type='button'></button>").addClass(this._triggerClass).
7790                                         html(!buttonImage ? buttonText : $("<img/>").attr(
7791                                         { src:buttonImage, alt:buttonText, title:buttonText })));
7792                         input[isRTL ? "before" : "after"](inst.trigger);
7793                         inst.trigger.click(function() {
7794                                 if ($.datepicker._datepickerShowing && $.datepicker._lastInput === input[0]) {
7795                                         $.datepicker._hideDatepicker();
7796                                 } else if ($.datepicker._datepickerShowing && $.datepicker._lastInput !== input[0]) {
7797                                         $.datepicker._hideDatepicker();
7798                                         $.datepicker._showDatepicker(input[0]);
7799                                 } else {
7800                                         $.datepicker._showDatepicker(input[0]);
7801                                 }
7802                                 return false;
7803                         });
7804                 }
7805         },
7806
7807         /* Apply the maximum length for the date format. */
7808         _autoSize: function(inst) {
7809                 if (this._get(inst, "autoSize") && !inst.inline) {
7810                         var findMax, max, maxI, i,
7811                                 date = new Date(2009, 12 - 1, 20), // Ensure double digits
7812                                 dateFormat = this._get(inst, "dateFormat");
7813
7814                         if (dateFormat.match(/[DM]/)) {
7815                                 findMax = function(names) {
7816                                         max = 0;
7817                                         maxI = 0;
7818                                         for (i = 0; i < names.length; i++) {
7819                                                 if (names[i].length > max) {
7820                                                         max = names[i].length;
7821                                                         maxI = i;
7822                                                 }
7823                                         }
7824                                         return maxI;
7825                                 };
7826                                 date.setMonth(findMax(this._get(inst, (dateFormat.match(/MM/) ?
7827                                         "monthNames" : "monthNamesShort"))));
7828                                 date.setDate(findMax(this._get(inst, (dateFormat.match(/DD/) ?
7829                                         "dayNames" : "dayNamesShort"))) + 20 - date.getDay());
7830                         }
7831                         inst.input.attr("size", this._formatDate(inst, date).length);
7832                 }
7833         },
7834
7835         /* Attach an inline date picker to a div. */
7836         _inlineDatepicker: function(target, inst) {
7837                 var divSpan = $(target);
7838                 if (divSpan.hasClass(this.markerClassName)) {
7839                         return;
7840                 }
7841                 divSpan.addClass(this.markerClassName).append(inst.dpDiv);
7842                 $.data(target, PROP_NAME, inst);
7843                 this._setDate(inst, this._getDefaultDate(inst), true);
7844                 this._updateDatepicker(inst);
7845                 this._updateAlternate(inst);
7846                 //If disabled option is true, disable the datepicker before showing it (see ticket #5665)
7847                 if( inst.settings.disabled ) {
7848                         this._disableDatepicker( target );
7849                 }
7850                 // Set display:block in place of inst.dpDiv.show() which won't work on disconnected elements
7851                 // http://bugs.jqueryui.com/ticket/7552 - A Datepicker created on a detached div has zero height
7852                 inst.dpDiv.css( "display", "block" );
7853         },
7854
7855         /* Pop-up the date picker in a "dialog" box.
7856          * @param  input element - ignored
7857          * @param  date string or Date - the initial date to display
7858          * @param  onSelect  function - the function to call when a date is selected
7859          * @param  settings  object - update the dialog date picker instance's settings (anonymous object)
7860          * @param  pos int[2] - coordinates for the dialog's position within the screen or
7861          *                                      event - with x/y coordinates or
7862          *                                      leave empty for default (screen centre)
7863          * @return the manager object
7864          */
7865         _dialogDatepicker: function(input, date, onSelect, settings, pos) {
7866                 var id, browserWidth, browserHeight, scrollX, scrollY,
7867                         inst = this._dialogInst; // internal instance
7868
7869                 if (!inst) {
7870                         this.uuid += 1;
7871                         id = "dp" + this.uuid;
7872                         this._dialogInput = $("<input type='text' id='" + id +
7873                                 "' style='position: absolute; top: -100px; width: 0px;'/>");
7874                         this._dialogInput.keydown(this._doKeyDown);
7875                         $("body").append(this._dialogInput);
7876                         inst = this._dialogInst = this._newInst(this._dialogInput, false);
7877                         inst.settings = {};
7878                         $.data(this._dialogInput[0], PROP_NAME, inst);
7879                 }
7880                 extendRemove(inst.settings, settings || {});
7881                 date = (date && date.constructor === Date ? this._formatDate(inst, date) : date);
7882                 this._dialogInput.val(date);
7883
7884                 this._pos = (pos ? (pos.length ? pos : [pos.pageX, pos.pageY]) : null);
7885                 if (!this._pos) {
7886                         browserWidth = document.documentElement.clientWidth;
7887                         browserHeight = document.documentElement.clientHeight;
7888                         scrollX = document.documentElement.scrollLeft || document.body.scrollLeft;
7889                         scrollY = document.documentElement.scrollTop || document.body.scrollTop;
7890                         this._pos = // should use actual width/height below
7891                                 [(browserWidth / 2) - 100 + scrollX, (browserHeight / 2) - 150 + scrollY];
7892                 }
7893
7894                 // move input on screen for focus, but hidden behind dialog
7895                 this._dialogInput.css("left", (this._pos[0] + 20) + "px").css("top", this._pos[1] + "px");
7896                 inst.settings.onSelect = onSelect;
7897                 this._inDialog = true;
7898                 this.dpDiv.addClass(this._dialogClass);
7899                 this._showDatepicker(this._dialogInput[0]);
7900                 if ($.blockUI) {
7901                         $.blockUI(this.dpDiv);
7902                 }
7903                 $.data(this._dialogInput[0], PROP_NAME, inst);
7904                 return this;
7905         },
7906
7907         /* Detach a datepicker from its control.
7908          * @param  target       element - the target input field or division or span
7909          */
7910         _destroyDatepicker: function(target) {
7911                 var nodeName,
7912                         $target = $(target),
7913                         inst = $.data(target, PROP_NAME);
7914
7915                 if (!$target.hasClass(this.markerClassName)) {
7916                         return;
7917                 }
7918
7919                 nodeName = target.nodeName.toLowerCase();
7920                 $.removeData(target, PROP_NAME);
7921                 if (nodeName === "input") {
7922                         inst.append.remove();
7923                         inst.trigger.remove();
7924                         $target.removeClass(this.markerClassName).
7925                                 unbind("focus", this._showDatepicker).
7926                                 unbind("keydown", this._doKeyDown).
7927                                 unbind("keypress", this._doKeyPress).
7928                                 unbind("keyup", this._doKeyUp);
7929                 } else if (nodeName === "div" || nodeName === "span") {
7930                         $target.removeClass(this.markerClassName).empty();
7931                 }
7932         },
7933
7934         /* Enable the date picker to a jQuery selection.
7935          * @param  target       element - the target input field or division or span
7936          */
7937         _enableDatepicker: function(target) {
7938                 var nodeName, inline,
7939                         $target = $(target),
7940                         inst = $.data(target, PROP_NAME);
7941
7942                 if (!$target.hasClass(this.markerClassName)) {
7943                         return;
7944                 }
7945
7946                 nodeName = target.nodeName.toLowerCase();
7947                 if (nodeName === "input") {
7948                         target.disabled = false;
7949                         inst.trigger.filter("button").
7950                                 each(function() { this.disabled = false; }).end().
7951                                 filter("img").css({opacity: "1.0", cursor: ""});
7952                 } else if (nodeName === "div" || nodeName === "span") {
7953                         inline = $target.children("." + this._inlineClass);
7954                         inline.children().removeClass("ui-state-disabled");
7955                         inline.find("select.ui-datepicker-month, select.ui-datepicker-year").
7956                                 prop("disabled", false);
7957                 }
7958                 this._disabledInputs = $.map(this._disabledInputs,
7959                         function(value) { return (value === target ? null : value); }); // delete entry
7960         },
7961
7962         /* Disable the date picker to a jQuery selection.
7963          * @param  target       element - the target input field or division or span
7964          */
7965         _disableDatepicker: function(target) {
7966                 var nodeName, inline,
7967                         $target = $(target),
7968                         inst = $.data(target, PROP_NAME);
7969
7970                 if (!$target.hasClass(this.markerClassName)) {
7971                         return;
7972                 }
7973
7974                 nodeName = target.nodeName.toLowerCase();
7975                 if (nodeName === "input") {
7976                         target.disabled = true;
7977                         inst.trigger.filter("button").
7978                                 each(function() { this.disabled = true; }).end().
7979                                 filter("img").css({opacity: "0.5", cursor: "default"});
7980                 } else if (nodeName === "div" || nodeName === "span") {
7981                         inline = $target.children("." + this._inlineClass);
7982                         inline.children().addClass("ui-state-disabled");
7983                         inline.find("select.ui-datepicker-month, select.ui-datepicker-year").
7984                                 prop("disabled", true);
7985                 }
7986                 this._disabledInputs = $.map(this._disabledInputs,
7987                         function(value) { return (value === target ? null : value); }); // delete entry
7988                 this._disabledInputs[this._disabledInputs.length] = target;
7989         },
7990
7991         /* Is the first field in a jQuery collection disabled as a datepicker?
7992          * @param  target       element - the target input field or division or span
7993          * @return boolean - true if disabled, false if enabled
7994          */
7995         _isDisabledDatepicker: function(target) {
7996                 if (!target) {
7997                         return false;
7998                 }
7999                 for (var i = 0; i < this._disabledInputs.length; i++) {
8000                         if (this._disabledInputs[i] === target) {
8001                                 return true;
8002                         }
8003                 }
8004                 return false;
8005         },
8006
8007         /* Retrieve the instance data for the target control.
8008          * @param  target  element - the target input field or division or span
8009          * @return  object - the associated instance data
8010          * @throws  error if a jQuery problem getting data
8011          */
8012         _getInst: function(target) {
8013                 try {
8014                         return $.data(target, PROP_NAME);
8015                 }
8016                 catch (err) {
8017                         throw "Missing instance data for this datepicker";
8018                 }
8019         },
8020
8021         /* Update or retrieve the settings for a date picker attached to an input field or division.
8022          * @param  target  element - the target input field or division or span
8023          * @param  name object - the new settings to update or
8024          *                              string - the name of the setting to change or retrieve,
8025          *                              when retrieving also "all" for all instance settings or
8026          *                              "defaults" for all global defaults
8027          * @param  value   any - the new value for the setting
8028          *                              (omit if above is an object or to retrieve a value)
8029          */
8030         _optionDatepicker: function(target, name, value) {
8031                 var settings, date, minDate, maxDate,
8032                         inst = this._getInst(target);
8033
8034                 if (arguments.length === 2 && typeof name === "string") {
8035                         return (name === "defaults" ? $.extend({}, $.datepicker._defaults) :
8036                                 (inst ? (name === "all" ? $.extend({}, inst.settings) :
8037                                 this._get(inst, name)) : null));
8038                 }
8039
8040                 settings = name || {};
8041                 if (typeof name === "string") {
8042                         settings = {};
8043                         settings[name] = value;
8044                 }
8045
8046                 if (inst) {
8047                         if (this._curInst === inst) {
8048                                 this._hideDatepicker();
8049                         }
8050
8051                         date = this._getDateDatepicker(target, true);
8052                         minDate = this._getMinMaxDate(inst, "min");
8053                         maxDate = this._getMinMaxDate(inst, "max");
8054                         extendRemove(inst.settings, settings);
8055                         // reformat the old minDate/maxDate values if dateFormat changes and a new minDate/maxDate isn't provided
8056                         if (minDate !== null && settings.dateFormat !== undefined && settings.minDate === undefined) {
8057                                 inst.settings.minDate = this._formatDate(inst, minDate);
8058                         }
8059                         if (maxDate !== null && settings.dateFormat !== undefined && settings.maxDate === undefined) {
8060                                 inst.settings.maxDate = this._formatDate(inst, maxDate);
8061                         }
8062                         if ( "disabled" in settings ) {
8063                                 if ( settings.disabled ) {
8064                                         this._disableDatepicker(target);
8065                                 } else {
8066                                         this._enableDatepicker(target);
8067                                 }
8068                         }
8069                         this._attachments($(target), inst);
8070                         this._autoSize(inst);
8071                         this._setDate(inst, date);
8072                         this._updateAlternate(inst);
8073                         this._updateDatepicker(inst);
8074                 }
8075         },
8076
8077         // change method deprecated
8078         _changeDatepicker: function(target, name, value) {
8079                 this._optionDatepicker(target, name, value);
8080         },
8081
8082         /* Redraw the date picker attached to an input field or division.
8083          * @param  target  element - the target input field or division or span
8084          */
8085         _refreshDatepicker: function(target) {
8086                 var inst = this._getInst(target);
8087                 if (inst) {
8088                         this._updateDatepicker(inst);
8089                 }
8090         },
8091
8092         /* Set the dates for a jQuery selection.
8093          * @param  target element - the target input field or division or span
8094          * @param  date Date - the new date
8095          */
8096         _setDateDatepicker: function(target, date) {
8097                 var inst = this._getInst(target);
8098                 if (inst) {
8099                         this._setDate(inst, date);
8100                         this._updateDatepicker(inst);
8101                         this._updateAlternate(inst);
8102                 }
8103         },
8104
8105         /* Get the date(s) for the first entry in a jQuery selection.
8106          * @param  target element - the target input field or division or span
8107          * @param  noDefault boolean - true if no default date is to be used
8108          * @return Date - the current date
8109          */
8110         _getDateDatepicker: function(target, noDefault) {
8111                 var inst = this._getInst(target);
8112                 if (inst && !inst.inline) {
8113                         this._setDateFromField(inst, noDefault);
8114                 }
8115                 return (inst ? this._getDate(inst) : null);
8116         },
8117
8118         /* Handle keystrokes. */
8119         _doKeyDown: function(event) {
8120                 var onSelect, dateStr, sel,
8121                         inst = $.datepicker._getInst(event.target),
8122                         handled = true,
8123                         isRTL = inst.dpDiv.is(".ui-datepicker-rtl");
8124
8125                 inst._keyEvent = true;
8126                 if ($.datepicker._datepickerShowing) {
8127                         switch (event.keyCode) {
8128                                 case 9: $.datepicker._hideDatepicker();
8129                                                 handled = false;
8130                                                 break; // hide on tab out
8131                                 case 13: sel = $("td." + $.datepicker._dayOverClass + ":not(." +
8132                                                                         $.datepicker._currentClass + ")", inst.dpDiv);
8133                                                 if (sel[0]) {
8134                                                         $.datepicker._selectDay(event.target, inst.selectedMonth, inst.selectedYear, sel[0]);
8135                                                 }
8136
8137                                                 onSelect = $.datepicker._get(inst, "onSelect");
8138                                                 if (onSelect) {
8139                                                         dateStr = $.datepicker._formatDate(inst);
8140
8141                                                         // trigger custom callback
8142                                                         onSelect.apply((inst.input ? inst.input[0] : null), [dateStr, inst]);
8143                                                 } else {
8144                                                         $.datepicker._hideDatepicker();
8145                                                 }
8146
8147                                                 return false; // don't submit the form
8148                                 case 27: $.datepicker._hideDatepicker();
8149                                                 break; // hide on escape
8150                                 case 33: $.datepicker._adjustDate(event.target, (event.ctrlKey ?
8151                                                         -$.datepicker._get(inst, "stepBigMonths") :
8152                                                         -$.datepicker._get(inst, "stepMonths")), "M");
8153                                                 break; // previous month/year on page up/+ ctrl
8154                                 case 34: $.datepicker._adjustDate(event.target, (event.ctrlKey ?
8155                                                         +$.datepicker._get(inst, "stepBigMonths") :
8156                                                         +$.datepicker._get(inst, "stepMonths")), "M");
8157                                                 break; // next month/year on page down/+ ctrl
8158                                 case 35: if (event.ctrlKey || event.metaKey) {
8159                                                         $.datepicker._clearDate(event.target);
8160                                                 }
8161                                                 handled = event.ctrlKey || event.metaKey;
8162                                                 break; // clear on ctrl or command +end
8163                                 case 36: if (event.ctrlKey || event.metaKey) {
8164                                                         $.datepicker._gotoToday(event.target);
8165                                                 }
8166                                                 handled = event.ctrlKey || event.metaKey;
8167                                                 break; // current on ctrl or command +home
8168                                 case 37: if (event.ctrlKey || event.metaKey) {
8169                                                         $.datepicker._adjustDate(event.target, (isRTL ? +1 : -1), "D");
8170                                                 }
8171                                                 handled = event.ctrlKey || event.metaKey;
8172                                                 // -1 day on ctrl or command +left
8173                                                 if (event.originalEvent.altKey) {
8174                                                         $.datepicker._adjustDate(event.target, (event.ctrlKey ?
8175                                                                 -$.datepicker._get(inst, "stepBigMonths") :
8176                                                                 -$.datepicker._get(inst, "stepMonths")), "M");
8177                                                 }
8178                                                 // next month/year on alt +left on Mac
8179                                                 break;
8180                                 case 38: if (event.ctrlKey || event.metaKey) {
8181                                                         $.datepicker._adjustDate(event.target, -7, "D");
8182                                                 }
8183                                                 handled = event.ctrlKey || event.metaKey;
8184                                                 break; // -1 week on ctrl or command +up
8185                                 case 39: if (event.ctrlKey || event.metaKey) {
8186                                                         $.datepicker._adjustDate(event.target, (isRTL ? -1 : +1), "D");
8187                                                 }
8188                                                 handled = event.ctrlKey || event.metaKey;
8189                                                 // +1 day on ctrl or command +right
8190                                                 if (event.originalEvent.altKey) {
8191                                                         $.datepicker._adjustDate(event.target, (event.ctrlKey ?
8192                                                                 +$.datepicker._get(inst, "stepBigMonths") :
8193                                                                 +$.datepicker._get(inst, "stepMonths")), "M");
8194                                                 }
8195                                                 // next month/year on alt +right
8196                                                 break;
8197                                 case 40: if (event.ctrlKey || event.metaKey) {
8198                                                         $.datepicker._adjustDate(event.target, +7, "D");
8199                                                 }
8200                                                 handled = event.ctrlKey || event.metaKey;
8201                                                 break; // +1 week on ctrl or command +down
8202                                 default: handled = false;
8203                         }
8204                 } else if (event.keyCode === 36 && event.ctrlKey) { // display the date picker on ctrl+home
8205                         $.datepicker._showDatepicker(this);
8206                 } else {
8207                         handled = false;
8208                 }
8209
8210                 if (handled) {
8211                         event.preventDefault();
8212                         event.stopPropagation();
8213                 }
8214         },
8215
8216         /* Filter entered characters - based on date format. */
8217         _doKeyPress: function(event) {
8218                 var chars, chr,
8219                         inst = $.datepicker._getInst(event.target);
8220
8221                 if ($.datepicker._get(inst, "constrainInput")) {
8222                         chars = $.datepicker._possibleChars($.datepicker._get(inst, "dateFormat"));
8223                         chr = String.fromCharCode(event.charCode == null ? event.keyCode : event.charCode);
8224                         return event.ctrlKey || event.metaKey || (chr < " " || !chars || chars.indexOf(chr) > -1);
8225                 }
8226         },
8227
8228         /* Synchronise manual entry and field/alternate field. */
8229         _doKeyUp: function(event) {
8230                 var date,
8231                         inst = $.datepicker._getInst(event.target);
8232
8233                 if (inst.input.val() !== inst.lastVal) {
8234                         try {
8235                                 date = $.datepicker.parseDate($.datepicker._get(inst, "dateFormat"),
8236                                         (inst.input ? inst.input.val() : null),
8237                                         $.datepicker._getFormatConfig(inst));
8238
8239                                 if (date) { // only if valid
8240                                         $.datepicker._setDateFromField(inst);
8241                                         $.datepicker._updateAlternate(inst);
8242                                         $.datepicker._updateDatepicker(inst);
8243                                 }
8244                         }
8245                         catch (err) {
8246                         }
8247                 }
8248                 return true;
8249         },
8250
8251         /* Pop-up the date picker for a given input field.
8252          * If false returned from beforeShow event handler do not show.
8253          * @param  input  element - the input field attached to the date picker or
8254          *                                      event - if triggered by focus
8255          */
8256         _showDatepicker: function(input) {
8257                 input = input.target || input;
8258                 if (input.nodeName.toLowerCase() !== "input") { // find from button/image trigger
8259                         input = $("input", input.parentNode)[0];
8260                 }
8261
8262                 if ($.datepicker._isDisabledDatepicker(input) || $.datepicker._lastInput === input) { // already here
8263                         return;
8264                 }
8265
8266                 var inst, beforeShow, beforeShowSettings, isFixed,
8267                         offset, showAnim, duration;
8268
8269                 inst = $.datepicker._getInst(input);
8270                 if ($.datepicker._curInst && $.datepicker._curInst !== inst) {
8271                         $.datepicker._curInst.dpDiv.stop(true, true);
8272                         if ( inst && $.datepicker._datepickerShowing ) {
8273                                 $.datepicker._hideDatepicker( $.datepicker._curInst.input[0] );
8274                         }
8275                 }
8276
8277                 beforeShow = $.datepicker._get(inst, "beforeShow");
8278                 beforeShowSettings = beforeShow ? beforeShow.apply(input, [input, inst]) : {};
8279                 if(beforeShowSettings === false){
8280                         return;
8281                 }
8282                 extendRemove(inst.settings, beforeShowSettings);
8283
8284                 inst.lastVal = null;
8285                 $.datepicker._lastInput = input;
8286                 $.datepicker._setDateFromField(inst);
8287
8288                 if ($.datepicker._inDialog) { // hide cursor
8289                         input.value = "";
8290                 }
8291                 if (!$.datepicker._pos) { // position below input
8292                         $.datepicker._pos = $.datepicker._findPos(input);
8293                         $.datepicker._pos[1] += input.offsetHeight; // add the height
8294                 }
8295
8296                 isFixed = false;
8297                 $(input).parents().each(function() {
8298                         isFixed |= $(this).css("position") === "fixed";
8299                         return !isFixed;
8300                 });
8301
8302                 offset = {left: $.datepicker._pos[0], top: $.datepicker._pos[1]};
8303                 $.datepicker._pos = null;
8304                 //to avoid flashes on Firefox
8305                 inst.dpDiv.empty();
8306                 // determine sizing offscreen
8307                 inst.dpDiv.css({position: "absolute", display: "block", top: "-1000px"});
8308                 $.datepicker._updateDatepicker(inst);
8309                 // fix width for dynamic number of date pickers
8310                 // and adjust position before showing
8311                 offset = $.datepicker._checkOffset(inst, offset, isFixed);
8312                 inst.dpDiv.css({position: ($.datepicker._inDialog && $.blockUI ?
8313                         "static" : (isFixed ? "fixed" : "absolute")), display: "none",
8314                         left: offset.left + "px", top: offset.top + "px"});
8315
8316                 if (!inst.inline) {
8317                         showAnim = $.datepicker._get(inst, "showAnim");
8318                         duration = $.datepicker._get(inst, "duration");
8319                         inst.dpDiv.zIndex($(input).zIndex()+1);
8320                         $.datepicker._datepickerShowing = true;
8321
8322                         if ( $.effects && $.effects.effect[ showAnim ] ) {
8323                                 inst.dpDiv.show(showAnim, $.datepicker._get(inst, "showOptions"), duration);
8324                         } else {
8325                                 inst.dpDiv[showAnim || "show"](showAnim ? duration : null);
8326                         }
8327
8328                         if (inst.input.is(":visible") && !inst.input.is(":disabled")) {
8329                                 inst.input.focus();
8330                         }
8331                         $.datepicker._curInst = inst;
8332                 }
8333         },
8334
8335         /* Generate the date picker content. */
8336         _updateDatepicker: function(inst) {
8337                 this.maxRows = 4; //Reset the max number of rows being displayed (see #7043)
8338                 instActive = inst; // for delegate hover events
8339                 inst.dpDiv.empty().append(this._generateHTML(inst));
8340                 this._attachHandlers(inst);
8341                 inst.dpDiv.find("." + this._dayOverClass + " a").mouseover();
8342
8343                 var origyearshtml,
8344                         numMonths = this._getNumberOfMonths(inst),
8345                         cols = numMonths[1],
8346                         width = 17;
8347
8348                 inst.dpDiv.removeClass("ui-datepicker-multi-2 ui-datepicker-multi-3 ui-datepicker-multi-4").width("");
8349                 if (cols > 1) {
8350                         inst.dpDiv.addClass("ui-datepicker-multi-" + cols).css("width", (width * cols) + "em");
8351                 }
8352                 inst.dpDiv[(numMonths[0] !== 1 || numMonths[1] !== 1 ? "add" : "remove") +
8353                         "Class"]("ui-datepicker-multi");
8354                 inst.dpDiv[(this._get(inst, "isRTL") ? "add" : "remove") +
8355                         "Class"]("ui-datepicker-rtl");
8356
8357                 // #6694 - don't focus the input if it's already focused
8358                 // this breaks the change event in IE
8359                 if (inst === $.datepicker._curInst && $.datepicker._datepickerShowing && inst.input &&
8360                         inst.input.is(":visible") && !inst.input.is(":disabled") && inst.input[0] !== document.activeElement) {
8361                         inst.input.focus();
8362                 }
8363
8364                 // deffered render of the years select (to avoid flashes on Firefox)
8365                 if( inst.yearshtml ){
8366                         origyearshtml = inst.yearshtml;
8367                         setTimeout(function(){
8368                                 //assure that inst.yearshtml didn't change.
8369                                 if( origyearshtml === inst.yearshtml && inst.yearshtml ){
8370                                         inst.dpDiv.find("select.ui-datepicker-year:first").replaceWith(inst.yearshtml);
8371                                 }
8372                                 origyearshtml = inst.yearshtml = null;
8373                         }, 0);
8374                 }
8375         },
8376
8377         /* Retrieve the size of left and top borders for an element.
8378          * @param  elem  (jQuery object) the element of interest
8379          * @return  (number[2]) the left and top borders
8380          */
8381         _getBorders: function(elem) {
8382                 var convert = function(value) {
8383                         return {thin: 1, medium: 2, thick: 3}[value] || value;
8384                 };
8385                 return [parseFloat(convert(elem.css("border-left-width"))),
8386                         parseFloat(convert(elem.css("border-top-width")))];
8387         },
8388
8389         /* Check positioning to remain on screen. */
8390         _checkOffset: function(inst, offset, isFixed) {
8391                 var dpWidth = inst.dpDiv.outerWidth(),
8392                         dpHeight = inst.dpDiv.outerHeight(),
8393                         inputWidth = inst.input ? inst.input.outerWidth() : 0,
8394                         inputHeight = inst.input ? inst.input.outerHeight() : 0,
8395                         viewWidth = document.documentElement.clientWidth + (isFixed ? 0 : $(document).scrollLeft()),
8396                         viewHeight = document.documentElement.clientHeight + (isFixed ? 0 : $(document).scrollTop());
8397
8398                 offset.left -= (this._get(inst, "isRTL") ? (dpWidth - inputWidth) : 0);
8399                 offset.left -= (isFixed && offset.left === inst.input.offset().left) ? $(document).scrollLeft() : 0;
8400                 offset.top -= (isFixed && offset.top === (inst.input.offset().top + inputHeight)) ? $(document).scrollTop() : 0;
8401
8402                 // now check if datepicker is showing outside window viewport - move to a better place if so.
8403                 offset.left -= Math.min(offset.left, (offset.left + dpWidth > viewWidth && viewWidth > dpWidth) ?
8404                         Math.abs(offset.left + dpWidth - viewWidth) : 0);
8405                 offset.top -= Math.min(offset.top, (offset.top + dpHeight > viewHeight && viewHeight > dpHeight) ?
8406                         Math.abs(dpHeight + inputHeight) : 0);
8407
8408                 return offset;
8409         },
8410
8411         /* Find an object's position on the screen. */
8412         _findPos: function(obj) {
8413                 var position,
8414                         inst = this._getInst(obj),
8415                         isRTL = this._get(inst, "isRTL");
8416
8417                 while (obj && (obj.type === "hidden" || obj.nodeType !== 1 || $.expr.filters.hidden(obj))) {
8418                         obj = obj[isRTL ? "previousSibling" : "nextSibling"];
8419                 }
8420
8421                 position = $(obj).offset();
8422                 return [position.left, position.top];
8423         },
8424
8425         /* Hide the date picker from view.
8426          * @param  input  element - the input field attached to the date picker
8427          */
8428         _hideDatepicker: function(input) {
8429                 var showAnim, duration, postProcess, onClose,
8430                         inst = this._curInst;
8431
8432                 if (!inst || (input && inst !== $.data(input, PROP_NAME))) {
8433                         return;
8434                 }
8435
8436                 if (this._datepickerShowing) {
8437                         showAnim = this._get(inst, "showAnim");
8438                         duration = this._get(inst, "duration");
8439                         postProcess = function() {
8440                                 $.datepicker._tidyDialog(inst);
8441                         };
8442
8443                         // DEPRECATED: after BC for 1.8.x $.effects[ showAnim ] is not needed
8444                         if ( $.effects && ( $.effects.effect[ showAnim ] || $.effects[ showAnim ] ) ) {
8445                                 inst.dpDiv.hide(showAnim, $.datepicker._get(inst, "showOptions"), duration, postProcess);
8446                         } else {
8447                                 inst.dpDiv[(showAnim === "slideDown" ? "slideUp" :
8448                                         (showAnim === "fadeIn" ? "fadeOut" : "hide"))]((showAnim ? duration : null), postProcess);
8449                         }
8450
8451                         if (!showAnim) {
8452                                 postProcess();
8453                         }
8454                         this._datepickerShowing = false;
8455
8456                         onClose = this._get(inst, "onClose");
8457                         if (onClose) {
8458                                 onClose.apply((inst.input ? inst.input[0] : null), [(inst.input ? inst.input.val() : ""), inst]);
8459                         }
8460
8461                         this._lastInput = null;
8462                         if (this._inDialog) {
8463                                 this._dialogInput.css({ position: "absolute", left: "0", top: "-100px" });
8464                                 if ($.blockUI) {
8465                                         $.unblockUI();
8466                                         $("body").append(this.dpDiv);
8467                                 }
8468                         }
8469                         this._inDialog = false;
8470                 }
8471         },
8472
8473         /* Tidy up after a dialog display. */
8474         _tidyDialog: function(inst) {
8475                 inst.dpDiv.removeClass(this._dialogClass).unbind(".ui-datepicker-calendar");
8476         },
8477
8478         /* Close date picker if clicked elsewhere. */
8479         _checkExternalClick: function(event) {
8480                 if (!$.datepicker._curInst) {
8481                         return;
8482                 }
8483
8484                 var $target = $(event.target),
8485                         inst = $.datepicker._getInst($target[0]);
8486
8487                 if ( ( ( $target[0].id !== $.datepicker._mainDivId &&
8488                                 $target.parents("#" + $.datepicker._mainDivId).length === 0 &&
8489                                 !$target.hasClass($.datepicker.markerClassName) &&
8490                                 !$target.closest("." + $.datepicker._triggerClass).length &&
8491                                 $.datepicker._datepickerShowing && !($.datepicker._inDialog && $.blockUI) ) ) ||
8492                         ( $target.hasClass($.datepicker.markerClassName) && $.datepicker._curInst !== inst ) ) {
8493                                 $.datepicker._hideDatepicker();
8494                 }
8495         },
8496
8497         /* Adjust one of the date sub-fields. */
8498         _adjustDate: function(id, offset, period) {
8499                 var target = $(id),
8500                         inst = this._getInst(target[0]);
8501
8502                 if (this._isDisabledDatepicker(target[0])) {
8503                         return;
8504                 }
8505                 this._adjustInstDate(inst, offset +
8506                         (period === "M" ? this._get(inst, "showCurrentAtPos") : 0), // undo positioning
8507                         period);
8508                 this._updateDatepicker(inst);
8509         },
8510
8511         /* Action for current link. */
8512         _gotoToday: function(id) {
8513                 var date,
8514                         target = $(id),
8515                         inst = this._getInst(target[0]);
8516
8517                 if (this._get(inst, "gotoCurrent") && inst.currentDay) {
8518                         inst.selectedDay = inst.currentDay;
8519                         inst.drawMonth = inst.selectedMonth = inst.currentMonth;
8520                         inst.drawYear = inst.selectedYear = inst.currentYear;
8521                 } else {
8522                         date = new Date();
8523                         inst.selectedDay = date.getDate();
8524                         inst.drawMonth = inst.selectedMonth = date.getMonth();
8525                         inst.drawYear = inst.selectedYear = date.getFullYear();
8526                 }
8527                 this._notifyChange(inst);
8528                 this._adjustDate(target);
8529         },
8530
8531         /* Action for selecting a new month/year. */
8532         _selectMonthYear: function(id, select, period) {
8533                 var target = $(id),
8534                         inst = this._getInst(target[0]);
8535
8536                 inst["selected" + (period === "M" ? "Month" : "Year")] =
8537                 inst["draw" + (period === "M" ? "Month" : "Year")] =
8538                         parseInt(select.options[select.selectedIndex].value,10);
8539
8540                 this._notifyChange(inst);
8541                 this._adjustDate(target);
8542         },
8543
8544         /* Action for selecting a day. */
8545         _selectDay: function(id, month, year, td) {
8546                 var inst,
8547                         target = $(id);
8548
8549                 if ($(td).hasClass(this._unselectableClass) || this._isDisabledDatepicker(target[0])) {
8550                         return;
8551                 }
8552
8553                 inst = this._getInst(target[0]);
8554                 inst.selectedDay = inst.currentDay = $("a", td).html();
8555                 inst.selectedMonth = inst.currentMonth = month;
8556                 inst.selectedYear = inst.currentYear = year;
8557                 this._selectDate(id, this._formatDate(inst,
8558                         inst.currentDay, inst.currentMonth, inst.currentYear));
8559         },
8560
8561         /* Erase the input field and hide the date picker. */
8562         _clearDate: function(id) {
8563                 var target = $(id);
8564                 this._selectDate(target, "");
8565         },
8566
8567         /* Update the input field with the selected date. */
8568         _selectDate: function(id, dateStr) {
8569                 var onSelect,
8570                         target = $(id),
8571                         inst = this._getInst(target[0]);
8572
8573                 dateStr = (dateStr != null ? dateStr : this._formatDate(inst));
8574                 if (inst.input) {
8575                         inst.input.val(dateStr);
8576                 }
8577                 this._updateAlternate(inst);
8578
8579                 onSelect = this._get(inst, "onSelect");
8580                 if (onSelect) {
8581                         onSelect.apply((inst.input ? inst.input[0] : null), [dateStr, inst]);  // trigger custom callback
8582                 } else if (inst.input) {
8583                         inst.input.trigger("change"); // fire the change event
8584                 }
8585
8586                 if (inst.inline){
8587                         this._updateDatepicker(inst);
8588                 } else {
8589                         this._hideDatepicker();
8590                         this._lastInput = inst.input[0];
8591                         if (typeof(inst.input[0]) !== "object") {
8592                                 inst.input.focus(); // restore focus
8593                         }
8594                         this._lastInput = null;
8595                 }
8596         },
8597
8598         /* Update any alternate field to synchronise with the main field. */
8599         _updateAlternate: function(inst) {
8600                 var altFormat, date, dateStr,
8601                         altField = this._get(inst, "altField");
8602
8603                 if (altField) { // update alternate field too
8604                         altFormat = this._get(inst, "altFormat") || this._get(inst, "dateFormat");
8605                         date = this._getDate(inst);
8606                         dateStr = this.formatDate(altFormat, date, this._getFormatConfig(inst));
8607                         $(altField).each(function() { $(this).val(dateStr); });
8608                 }
8609         },
8610
8611         /* Set as beforeShowDay function to prevent selection of weekends.
8612          * @param  date  Date - the date to customise
8613          * @return [boolean, string] - is this date selectable?, what is its CSS class?
8614          */
8615         noWeekends: function(date) {
8616                 var day = date.getDay();
8617                 return [(day > 0 && day < 6), ""];
8618         },
8619
8620         /* Set as calculateWeek to determine the week of the year based on the ISO 8601 definition.
8621          * @param  date  Date - the date to get the week for
8622          * @return  number - the number of the week within the year that contains this date
8623          */
8624         iso8601Week: function(date) {
8625                 var time,
8626                         checkDate = new Date(date.getTime());
8627
8628                 // Find Thursday of this week starting on Monday
8629                 checkDate.setDate(checkDate.getDate() + 4 - (checkDate.getDay() || 7));
8630
8631                 time = checkDate.getTime();
8632                 checkDate.setMonth(0); // Compare with Jan 1
8633                 checkDate.setDate(1);
8634                 return Math.floor(Math.round((time - checkDate) / 86400000) / 7) + 1;
8635         },
8636
8637         /* Parse a string value into a date object.
8638          * See formatDate below for the possible formats.
8639          *
8640          * @param  format string - the expected format of the date
8641          * @param  value string - the date in the above format
8642          * @param  settings Object - attributes include:
8643          *                                      shortYearCutoff  number - the cutoff year for determining the century (optional)
8644          *                                      dayNamesShort   string[7] - abbreviated names of the days from Sunday (optional)
8645          *                                      dayNames                string[7] - names of the days from Sunday (optional)
8646          *                                      monthNamesShort string[12] - abbreviated names of the months (optional)
8647          *                                      monthNames              string[12] - names of the months (optional)
8648          * @return  Date - the extracted date value or null if value is blank
8649          */
8650         parseDate: function (format, value, settings) {
8651                 if (format == null || value == null) {
8652                         throw "Invalid arguments";
8653                 }
8654
8655                 value = (typeof value === "object" ? value.toString() : value + "");
8656                 if (value === "") {
8657                         return null;
8658                 }
8659
8660                 var iFormat, dim, extra,
8661                         iValue = 0,
8662                         shortYearCutoffTemp = (settings ? settings.shortYearCutoff : null) || this._defaults.shortYearCutoff,
8663                         shortYearCutoff = (typeof shortYearCutoffTemp !== "string" ? shortYearCutoffTemp :
8664                                 new Date().getFullYear() % 100 + parseInt(shortYearCutoffTemp, 10)),
8665                         dayNamesShort = (settings ? settings.dayNamesShort : null) || this._defaults.dayNamesShort,
8666                         dayNames = (settings ? settings.dayNames : null) || this._defaults.dayNames,
8667                         monthNamesShort = (settings ? settings.monthNamesShort : null) || this._defaults.monthNamesShort,
8668                         monthNames = (settings ? settings.monthNames : null) || this._defaults.monthNames,
8669                         year = -1,
8670                         month = -1,
8671                         day = -1,
8672                         doy = -1,
8673                         literal = false,
8674                         date,
8675                         // Check whether a format character is doubled
8676                         lookAhead = function(match) {
8677                                 var matches = (iFormat + 1 < format.length && format.charAt(iFormat + 1) === match);
8678                                 if (matches) {
8679                                         iFormat++;
8680                                 }
8681                                 return matches;
8682                         },
8683                         // Extract a number from the string value
8684                         getNumber = function(match) {
8685                                 var isDoubled = lookAhead(match),
8686                                         size = (match === "@" ? 14 : (match === "!" ? 20 :
8687                                         (match === "y" && isDoubled ? 4 : (match === "o" ? 3 : 2)))),
8688                                         digits = new RegExp("^\\d{1," + size + "}"),
8689                                         num = value.substring(iValue).match(digits);
8690                                 if (!num) {
8691                                         throw "Missing number at position " + iValue;
8692                                 }
8693                                 iValue += num[0].length;
8694                                 return parseInt(num[0], 10);
8695                         },
8696                         // Extract a name from the string value and convert to an index
8697                         getName = function(match, shortNames, longNames) {
8698                                 var index = -1,
8699                                         names = $.map(lookAhead(match) ? longNames : shortNames, function (v, k) {
8700                                                 return [ [k, v] ];
8701                                         }).sort(function (a, b) {
8702                                                 return -(a[1].length - b[1].length);
8703                                         });
8704
8705                                 $.each(names, function (i, pair) {
8706                                         var name = pair[1];
8707                                         if (value.substr(iValue, name.length).toLowerCase() === name.toLowerCase()) {
8708                                                 index = pair[0];
8709                                                 iValue += name.length;
8710                                                 return false;
8711                                         }
8712                                 });
8713                                 if (index !== -1) {
8714                                         return index + 1;
8715                                 } else {
8716                                         throw "Unknown name at position " + iValue;
8717                                 }
8718                         },
8719                         // Confirm that a literal character matches the string value
8720                         checkLiteral = function() {
8721                                 if (value.charAt(iValue) !== format.charAt(iFormat)) {
8722                                         throw "Unexpected literal at position " + iValue;
8723                                 }
8724                                 iValue++;
8725                         };
8726
8727                 for (iFormat = 0; iFormat < format.length; iFormat++) {
8728                         if (literal) {
8729                                 if (format.charAt(iFormat) === "'" && !lookAhead("'")) {
8730                                         literal = false;
8731                                 } else {
8732                                         checkLiteral();
8733                                 }
8734                         } else {
8735                                 switch (format.charAt(iFormat)) {
8736                                         case "d":
8737                                                 day = getNumber("d");
8738                                                 break;
8739                                         case "D":
8740                                                 getName("D", dayNamesShort, dayNames);
8741                                                 break;
8742                                         case "o":
8743                                                 doy = getNumber("o");
8744                                                 break;
8745                                         case "m":
8746                                                 month = getNumber("m");
8747                                                 break;
8748                                         case "M":
8749                                                 month = getName("M", monthNamesShort, monthNames);
8750                                                 break;
8751                                         case "y":
8752                                                 year = getNumber("y");
8753                                                 break;
8754                                         case "@":
8755                                                 date = new Date(getNumber("@"));
8756                                                 year = date.getFullYear();
8757                                                 month = date.getMonth() + 1;
8758                                                 day = date.getDate();
8759                                                 break;
8760                                         case "!":
8761                                                 date = new Date((getNumber("!") - this._ticksTo1970) / 10000);
8762                                                 year = date.getFullYear();
8763                                                 month = date.getMonth() + 1;
8764                                                 day = date.getDate();
8765                                                 break;
8766                                         case "'":
8767                                                 if (lookAhead("'")){
8768                                                         checkLiteral();
8769                                                 } else {
8770                                                         literal = true;
8771                                                 }
8772                                                 break;
8773                                         default:
8774                                                 checkLiteral();
8775                                 }
8776                         }
8777                 }
8778
8779                 if (iValue < value.length){
8780                         extra = value.substr(iValue);
8781                         if (!/^\s+/.test(extra)) {
8782                                 throw "Extra/unparsed characters found in date: " + extra;
8783                         }
8784                 }
8785
8786                 if (year === -1) {
8787                         year = new Date().getFullYear();
8788                 } else if (year < 100) {
8789                         year += new Date().getFullYear() - new Date().getFullYear() % 100 +
8790                                 (year <= shortYearCutoff ? 0 : -100);
8791                 }
8792
8793                 if (doy > -1) {
8794                         month = 1;
8795                         day = doy;
8796                         do {
8797                                 dim = this._getDaysInMonth(year, month - 1);
8798                                 if (day <= dim) {
8799                                         break;
8800                                 }
8801                                 month++;
8802                                 day -= dim;
8803                         } while (true);
8804                 }
8805
8806                 date = this._daylightSavingAdjust(new Date(year, month - 1, day));
8807                 if (date.getFullYear() !== year || date.getMonth() + 1 !== month || date.getDate() !== day) {
8808                         throw "Invalid date"; // E.g. 31/02/00
8809                 }
8810                 return date;
8811         },
8812
8813         /* Standard date formats. */
8814         ATOM: "yy-mm-dd", // RFC 3339 (ISO 8601)
8815         COOKIE: "D, dd M yy",
8816         ISO_8601: "yy-mm-dd",
8817         RFC_822: "D, d M y",
8818         RFC_850: "DD, dd-M-y",
8819         RFC_1036: "D, d M y",
8820         RFC_1123: "D, d M yy",
8821         RFC_2822: "D, d M yy",
8822         RSS: "D, d M y", // RFC 822
8823         TICKS: "!",
8824         TIMESTAMP: "@",
8825         W3C: "yy-mm-dd", // ISO 8601
8826
8827         _ticksTo1970: (((1970 - 1) * 365 + Math.floor(1970 / 4) - Math.floor(1970 / 100) +
8828                 Math.floor(1970 / 400)) * 24 * 60 * 60 * 10000000),
8829
8830         /* Format a date object into a string value.
8831          * The format can be combinations of the following:
8832          * d  - day of month (no leading zero)
8833          * dd - day of month (two digit)
8834          * o  - day of year (no leading zeros)
8835          * oo - day of year (three digit)
8836          * D  - day name short
8837          * DD - day name long
8838          * m  - month of year (no leading zero)
8839          * mm - month of year (two digit)
8840          * M  - month name short
8841          * MM - month name long
8842          * y  - year (two digit)
8843          * yy - year (four digit)
8844          * @ - Unix timestamp (ms since 01/01/1970)
8845          * ! - Windows ticks (100ns since 01/01/0001)
8846          * "..." - literal text
8847          * '' - single quote
8848          *
8849          * @param  format string - the desired format of the date
8850          * @param  date Date - the date value to format
8851          * @param  settings Object - attributes include:
8852          *                                      dayNamesShort   string[7] - abbreviated names of the days from Sunday (optional)
8853          *                                      dayNames                string[7] - names of the days from Sunday (optional)
8854          *                                      monthNamesShort string[12] - abbreviated names of the months (optional)
8855          *                                      monthNames              string[12] - names of the months (optional)
8856          * @return  string - the date in the above format
8857          */
8858         formatDate: function (format, date, settings) {
8859                 if (!date) {
8860                         return "";
8861                 }
8862
8863                 var iFormat,
8864                         dayNamesShort = (settings ? settings.dayNamesShort : null) || this._defaults.dayNamesShort,
8865                         dayNames = (settings ? settings.dayNames : null) || this._defaults.dayNames,
8866                         monthNamesShort = (settings ? settings.monthNamesShort : null) || this._defaults.monthNamesShort,
8867                         monthNames = (settings ? settings.monthNames : null) || this._defaults.monthNames,
8868                         // Check whether a format character is doubled
8869                         lookAhead = function(match) {
8870                                 var matches = (iFormat + 1 < format.length && format.charAt(iFormat + 1) === match);
8871                                 if (matches) {
8872                                         iFormat++;
8873                                 }
8874                                 return matches;
8875                         },
8876                         // Format a number, with leading zero if necessary
8877                         formatNumber = function(match, value, len) {
8878                                 var num = "" + value;
8879                                 if (lookAhead(match)) {
8880                                         while (num.length < len) {
8881                                                 num = "0" + num;
8882                                         }
8883                                 }
8884                                 return num;
8885                         },
8886                         // Format a name, short or long as requested
8887                         formatName = function(match, value, shortNames, longNames) {
8888                                 return (lookAhead(match) ? longNames[value] : shortNames[value]);
8889                         },
8890                         output = "",
8891                         literal = false;
8892
8893                 if (date) {
8894                         for (iFormat = 0; iFormat < format.length; iFormat++) {
8895                                 if (literal) {
8896                                         if (format.charAt(iFormat) === "'" && !lookAhead("'")) {
8897                                                 literal = false;
8898                                         } else {
8899                                                 output += format.charAt(iFormat);
8900                                         }
8901                                 } else {
8902                                         switch (format.charAt(iFormat)) {
8903                                                 case "d":
8904                                                         output += formatNumber("d", date.getDate(), 2);
8905                                                         break;
8906                                                 case "D":
8907                                                         output += formatName("D", date.getDay(), dayNamesShort, dayNames);
8908                                                         break;
8909                                                 case "o":
8910                                                         output += formatNumber("o",
8911                                                                 Math.round((new Date(date.getFullYear(), date.getMonth(), date.getDate()).getTime() - new Date(date.getFullYear(), 0, 0).getTime()) / 86400000), 3);
8912                                                         break;
8913                                                 case "m":
8914                                                         output += formatNumber("m", date.getMonth() + 1, 2);
8915                                                         break;
8916                                                 case "M":
8917                                                         output += formatName("M", date.getMonth(), monthNamesShort, monthNames);
8918                                                         break;
8919                                                 case "y":
8920                                                         output += (lookAhead("y") ? date.getFullYear() :
8921                                                                 (date.getYear() % 100 < 10 ? "0" : "") + date.getYear() % 100);
8922                                                         break;
8923                                                 case "@":
8924                                                         output += date.getTime();
8925                                                         break;
8926                                                 case "!":
8927                                                         output += date.getTime() * 10000 + this._ticksTo1970;
8928                                                         break;
8929                                                 case "'":
8930                                                         if (lookAhead("'")) {
8931                                                                 output += "'";
8932                                                         } else {
8933                                                                 literal = true;
8934                                                         }
8935                                                         break;
8936                                                 default:
8937                                                         output += format.charAt(iFormat);
8938                                         }
8939                                 }
8940                         }
8941                 }
8942                 return output;
8943         },
8944
8945         /* Extract all possible characters from the date format. */
8946         _possibleChars: function (format) {
8947                 var iFormat,
8948                         chars = "",
8949                         literal = false,
8950                         // Check whether a format character is doubled
8951                         lookAhead = function(match) {
8952                                 var matches = (iFormat + 1 < format.length && format.charAt(iFormat + 1) === match);
8953                                 if (matches) {
8954                                         iFormat++;
8955                                 }
8956                                 return matches;
8957                         };
8958
8959                 for (iFormat = 0; iFormat < format.length; iFormat++) {
8960                         if (literal) {
8961                                 if (format.charAt(iFormat) === "'" && !lookAhead("'")) {
8962                                         literal = false;
8963                                 } else {
8964                                         chars += format.charAt(iFormat);
8965                                 }
8966                         } else {
8967                                 switch (format.charAt(iFormat)) {
8968                                         case "d": case "m": case "y": case "@":
8969                                                 chars += "0123456789";
8970                                                 break;
8971                                         case "D": case "M":
8972                                                 return null; // Accept anything
8973                                         case "'":
8974                                                 if (lookAhead("'")) {
8975                                                         chars += "'";
8976                                                 } else {
8977                                                         literal = true;
8978                                                 }
8979                                                 break;
8980                                         default:
8981                                                 chars += format.charAt(iFormat);
8982                                 }
8983                         }
8984                 }
8985                 return chars;
8986         },
8987
8988         /* Get a setting value, defaulting if necessary. */
8989         _get: function(inst, name) {
8990                 return inst.settings[name] !== undefined ?
8991                         inst.settings[name] : this._defaults[name];
8992         },
8993
8994         /* Parse existing date and initialise date picker. */
8995         _setDateFromField: function(inst, noDefault) {
8996                 if (inst.input.val() === inst.lastVal) {
8997                         return;
8998                 }
8999
9000                 var dateFormat = this._get(inst, "dateFormat"),
9001                         dates = inst.lastVal = inst.input ? inst.input.val() : null,
9002                         defaultDate = this._getDefaultDate(inst),
9003                         date = defaultDate,
9004                         settings = this._getFormatConfig(inst);
9005
9006                 try {
9007                         date = this.parseDate(dateFormat, dates, settings) || defaultDate;
9008                 } catch (event) {
9009                         dates = (noDefault ? "" : dates);
9010                 }
9011                 inst.selectedDay = date.getDate();
9012                 inst.drawMonth = inst.selectedMonth = date.getMonth();
9013                 inst.drawYear = inst.selectedYear = date.getFullYear();
9014                 inst.currentDay = (dates ? date.getDate() : 0);
9015                 inst.currentMonth = (dates ? date.getMonth() : 0);
9016                 inst.currentYear = (dates ? date.getFullYear() : 0);
9017                 this._adjustInstDate(inst);
9018         },
9019
9020         /* Retrieve the default date shown on opening. */
9021         _getDefaultDate: function(inst) {
9022                 return this._restrictMinMax(inst,
9023                         this._determineDate(inst, this._get(inst, "defaultDate"), new Date()));
9024         },
9025
9026         /* A date may be specified as an exact value or a relative one. */
9027         _determineDate: function(inst, date, defaultDate) {
9028                 var offsetNumeric = function(offset) {
9029                                 var date = new Date();
9030                                 date.setDate(date.getDate() + offset);
9031                                 return date;
9032                         },
9033                         offsetString = function(offset) {
9034                                 try {
9035                                         return $.datepicker.parseDate($.datepicker._get(inst, "dateFormat"),
9036                                                 offset, $.datepicker._getFormatConfig(inst));
9037                                 }
9038                                 catch (e) {
9039                                         // Ignore
9040                                 }
9041
9042                                 var date = (offset.toLowerCase().match(/^c/) ?
9043                                         $.datepicker._getDate(inst) : null) || new Date(),
9044                                         year = date.getFullYear(),
9045                                         month = date.getMonth(),
9046                                         day = date.getDate(),
9047                                         pattern = /([+\-]?[0-9]+)\s*(d|D|w|W|m|M|y|Y)?/g,
9048                                         matches = pattern.exec(offset);
9049
9050                                 while (matches) {
9051                                         switch (matches[2] || "d") {
9052                                                 case "d" : case "D" :
9053                                                         day += parseInt(matches[1],10); break;
9054                                                 case "w" : case "W" :
9055                                                         day += parseInt(matches[1],10) * 7; break;
9056                                                 case "m" : case "M" :
9057                                                         month += parseInt(matches[1],10);
9058                                                         day = Math.min(day, $.datepicker._getDaysInMonth(year, month));
9059                                                         break;
9060                                                 case "y": case "Y" :
9061                                                         year += parseInt(matches[1],10);
9062                                                         day = Math.min(day, $.datepicker._getDaysInMonth(year, month));
9063                                                         break;
9064                                         }
9065                                         matches = pattern.exec(offset);
9066                                 }
9067                                 return new Date(year, month, day);
9068                         },
9069                         newDate = (date == null || date === "" ? defaultDate : (typeof date === "string" ? offsetString(date) :
9070                                 (typeof date === "number" ? (isNaN(date) ? defaultDate : offsetNumeric(date)) : new Date(date.getTime()))));
9071
9072                 newDate = (newDate && newDate.toString() === "Invalid Date" ? defaultDate : newDate);
9073                 if (newDate) {
9074                         newDate.setHours(0);
9075                         newDate.setMinutes(0);
9076                         newDate.setSeconds(0);
9077                         newDate.setMilliseconds(0);
9078                 }
9079                 return this._daylightSavingAdjust(newDate);
9080         },
9081
9082         /* Handle switch to/from daylight saving.
9083          * Hours may be non-zero on daylight saving cut-over:
9084          * > 12 when midnight changeover, but then cannot generate
9085          * midnight datetime, so jump to 1AM, otherwise reset.
9086          * @param  date  (Date) the date to check
9087          * @return  (Date) the corrected date
9088          */
9089         _daylightSavingAdjust: function(date) {
9090                 if (!date) {
9091                         return null;
9092                 }
9093                 date.setHours(date.getHours() > 12 ? date.getHours() + 2 : 0);
9094                 return date;
9095         },
9096
9097         /* Set the date(s) directly. */
9098         _setDate: function(inst, date, noChange) {
9099                 var clear = !date,
9100                         origMonth = inst.selectedMonth,
9101                         origYear = inst.selectedYear,
9102                         newDate = this._restrictMinMax(inst, this._determineDate(inst, date, new Date()));
9103
9104                 inst.selectedDay = inst.currentDay = newDate.getDate();
9105                 inst.drawMonth = inst.selectedMonth = inst.currentMonth = newDate.getMonth();
9106                 inst.drawYear = inst.selectedYear = inst.currentYear = newDate.getFullYear();
9107                 if ((origMonth !== inst.selectedMonth || origYear !== inst.selectedYear) && !noChange) {
9108                         this._notifyChange(inst);
9109                 }
9110                 this._adjustInstDate(inst);
9111                 if (inst.input) {
9112                         inst.input.val(clear ? "" : this._formatDate(inst));
9113                 }
9114         },
9115
9116         /* Retrieve the date(s) directly. */
9117         _getDate: function(inst) {
9118                 var startDate = (!inst.currentYear || (inst.input && inst.input.val() === "") ? null :
9119                         this._daylightSavingAdjust(new Date(
9120                         inst.currentYear, inst.currentMonth, inst.currentDay)));
9121                         return startDate;
9122         },
9123
9124         /* Attach the onxxx handlers.  These are declared statically so
9125          * they work with static code transformers like Caja.
9126          */
9127         _attachHandlers: function(inst) {
9128                 var stepMonths = this._get(inst, "stepMonths"),
9129                         id = "#" + inst.id.replace( /\\\\/g, "\\" );
9130                 inst.dpDiv.find("[data-handler]").map(function () {
9131                         var handler = {
9132                                 prev: function () {
9133                                         window["DP_jQuery_" + dpuuid].datepicker._adjustDate(id, -stepMonths, "M");
9134                                 },
9135                                 next: function () {
9136                                         window["DP_jQuery_" + dpuuid].datepicker._adjustDate(id, +stepMonths, "M");
9137                                 },
9138                                 hide: function () {
9139                                         window["DP_jQuery_" + dpuuid].datepicker._hideDatepicker();
9140                                 },
9141                                 today: function () {
9142                                         window["DP_jQuery_" + dpuuid].datepicker._gotoToday(id);
9143                                 },
9144                                 selectDay: function () {
9145                                         window["DP_jQuery_" + dpuuid].datepicker._selectDay(id, +this.getAttribute("data-month"), +this.getAttribute("data-year"), this);
9146                                         return false;
9147                                 },
9148                                 selectMonth: function () {
9149                                         window["DP_jQuery_" + dpuuid].datepicker._selectMonthYear(id, this, "M");
9150                                         return false;
9151                                 },
9152                                 selectYear: function () {
9153                                         window["DP_jQuery_" + dpuuid].datepicker._selectMonthYear(id, this, "Y");
9154                                         return false;
9155                                 }
9156                         };
9157                         $(this).bind(this.getAttribute("data-event"), handler[this.getAttribute("data-handler")]);
9158                 });
9159         },
9160
9161         /* Generate the HTML for the current state of the date picker. */
9162         _generateHTML: function(inst) {
9163                 var maxDraw, prevText, prev, nextText, next, currentText, gotoDate,
9164                         controls, buttonPanel, firstDay, showWeek, dayNames, dayNamesMin,
9165                         monthNames, monthNamesShort, beforeShowDay, showOtherMonths,
9166                         selectOtherMonths, defaultDate, html, dow, row, group, col, selectedDate,
9167                         cornerClass, calender, thead, day, daysInMonth, leadDays, curRows, numRows,
9168                         printDate, dRow, tbody, daySettings, otherMonth, unselectable,
9169                         tempDate = new Date(),
9170                         today = this._daylightSavingAdjust(
9171                                 new Date(tempDate.getFullYear(), tempDate.getMonth(), tempDate.getDate())), // clear time
9172                         isRTL = this._get(inst, "isRTL"),
9173                         showButtonPanel = this._get(inst, "showButtonPanel"),
9174                         hideIfNoPrevNext = this._get(inst, "hideIfNoPrevNext"),
9175                         navigationAsDateFormat = this._get(inst, "navigationAsDateFormat"),
9176                         numMonths = this._getNumberOfMonths(inst),
9177                         showCurrentAtPos = this._get(inst, "showCurrentAtPos"),
9178                         stepMonths = this._get(inst, "stepMonths"),
9179                         isMultiMonth = (numMonths[0] !== 1 || numMonths[1] !== 1),
9180                         currentDate = this._daylightSavingAdjust((!inst.currentDay ? new Date(9999, 9, 9) :
9181                                 new Date(inst.currentYear, inst.currentMonth, inst.currentDay))),
9182                         minDate = this._getMinMaxDate(inst, "min"),
9183                         maxDate = this._getMinMaxDate(inst, "max"),
9184                         drawMonth = inst.drawMonth - showCurrentAtPos,
9185                         drawYear = inst.drawYear;
9186
9187                 if (drawMonth < 0) {
9188                         drawMonth += 12;
9189                         drawYear--;
9190                 }
9191                 if (maxDate) {
9192                         maxDraw = this._daylightSavingAdjust(new Date(maxDate.getFullYear(),
9193                                 maxDate.getMonth() - (numMonths[0] * numMonths[1]) + 1, maxDate.getDate()));
9194                         maxDraw = (minDate && maxDraw < minDate ? minDate : maxDraw);
9195                         while (this._daylightSavingAdjust(new Date(drawYear, drawMonth, 1)) > maxDraw) {
9196                                 drawMonth--;
9197                                 if (drawMonth < 0) {
9198                                         drawMonth = 11;
9199                                         drawYear--;
9200                                 }
9201                         }
9202                 }
9203                 inst.drawMonth = drawMonth;
9204                 inst.drawYear = drawYear;
9205
9206                 prevText = this._get(inst, "prevText");
9207                 prevText = (!navigationAsDateFormat ? prevText : this.formatDate(prevText,
9208                         this._daylightSavingAdjust(new Date(drawYear, drawMonth - stepMonths, 1)),
9209                         this._getFormatConfig(inst)));
9210
9211                 prev = (this._canAdjustMonth(inst, -1, drawYear, drawMonth) ?
9212                         "<a class='ui-datepicker-prev ui-corner-all' data-handler='prev' data-event='click'" +
9213                         " title='" + prevText + "'><span class='ui-icon ui-icon-circle-triangle-" + ( isRTL ? "e" : "w") + "'>" + prevText + "</span></a>" :
9214                         (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>"));
9215
9216                 nextText = this._get(inst, "nextText");
9217                 nextText = (!navigationAsDateFormat ? nextText : this.formatDate(nextText,
9218                         this._daylightSavingAdjust(new Date(drawYear, drawMonth + stepMonths, 1)),
9219                         this._getFormatConfig(inst)));
9220
9221                 next = (this._canAdjustMonth(inst, +1, drawYear, drawMonth) ?
9222                         "<a class='ui-datepicker-next ui-corner-all' data-handler='next' data-event='click'" +
9223                         " title='" + nextText + "'><span class='ui-icon ui-icon-circle-triangle-" + ( isRTL ? "w" : "e") + "'>" + nextText + "</span></a>" :
9224                         (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>"));
9225
9226                 currentText = this._get(inst, "currentText");
9227                 gotoDate = (this._get(inst, "gotoCurrent") && inst.currentDay ? currentDate : today);
9228                 currentText = (!navigationAsDateFormat ? currentText :
9229                         this.formatDate(currentText, gotoDate, this._getFormatConfig(inst)));
9230
9231                 controls = (!inst.inline ? "<button type='button' class='ui-datepicker-close ui-state-default ui-priority-primary ui-corner-all' data-handler='hide' data-event='click'>" +
9232                         this._get(inst, "closeText") + "</button>" : "");
9233
9234                 buttonPanel = (showButtonPanel) ? "<div class='ui-datepicker-buttonpane ui-widget-content'>" + (isRTL ? controls : "") +
9235                         (this._isInRange(inst, gotoDate) ? "<button type='button' class='ui-datepicker-current ui-state-default ui-priority-secondary ui-corner-all' data-handler='today' data-event='click'" +
9236                         ">" + currentText + "</button>" : "") + (isRTL ? "" : controls) + "</div>" : "";
9237
9238                 firstDay = parseInt(this._get(inst, "firstDay"),10);
9239                 firstDay = (isNaN(firstDay) ? 0 : firstDay);
9240
9241                 showWeek = this._get(inst, "showWeek");
9242                 dayNames = this._get(inst, "dayNames");
9243                 dayNamesMin = this._get(inst, "dayNamesMin");
9244                 monthNames = this._get(inst, "monthNames");
9245                 monthNamesShort = this._get(inst, "monthNamesShort");
9246                 beforeShowDay = this._get(inst, "beforeShowDay");
9247                 showOtherMonths = this._get(inst, "showOtherMonths");
9248                 selectOtherMonths = this._get(inst, "selectOtherMonths");
9249                 defaultDate = this._getDefaultDate(inst);
9250                 html = "";
9251                 dow;
9252                 for (row = 0; row < numMonths[0]; row++) {
9253                         group = "";
9254                         this.maxRows = 4;
9255                         for (col = 0; col < numMonths[1]; col++) {
9256                                 selectedDate = this._daylightSavingAdjust(new Date(drawYear, drawMonth, inst.selectedDay));
9257                                 cornerClass = " ui-corner-all";
9258                                 calender = "";
9259                                 if (isMultiMonth) {
9260                                         calender += "<div class='ui-datepicker-group";
9261                                         if (numMonths[1] > 1) {
9262                                                 switch (col) {
9263                                                         case 0: calender += " ui-datepicker-group-first";
9264                                                                 cornerClass = " ui-corner-" + (isRTL ? "right" : "left"); break;
9265                                                         case numMonths[1]-1: calender += " ui-datepicker-group-last";
9266                                                                 cornerClass = " ui-corner-" + (isRTL ? "left" : "right"); break;
9267                                                         default: calender += " ui-datepicker-group-middle"; cornerClass = ""; break;
9268                                                 }
9269                                         }
9270                                         calender += "'>";
9271                                 }
9272                                 calender += "<div class='ui-datepicker-header ui-widget-header ui-helper-clearfix" + cornerClass + "'>" +
9273                                         (/all|left/.test(cornerClass) && row === 0 ? (isRTL ? next : prev) : "") +
9274                                         (/all|right/.test(cornerClass) && row === 0 ? (isRTL ? prev : next) : "") +
9275                                         this._generateMonthYearHeader(inst, drawMonth, drawYear, minDate, maxDate,
9276                                         row > 0 || col > 0, monthNames, monthNamesShort) + // draw month headers
9277                                         "</div><table class='ui-datepicker-calendar'><thead>" +
9278                                         "<tr>";
9279                                 thead = (showWeek ? "<th class='ui-datepicker-week-col'>" + this._get(inst, "weekHeader") + "</th>" : "");
9280                                 for (dow = 0; dow < 7; dow++) { // days of the week
9281                                         day = (dow + firstDay) % 7;
9282                                         thead += "<th" + ((dow + firstDay + 6) % 7 >= 5 ? " class='ui-datepicker-week-end'" : "") + ">" +
9283                                                 "<span title='" + dayNames[day] + "'>" + dayNamesMin[day] + "</span></th>";
9284                                 }
9285                                 calender += thead + "</tr></thead><tbody>";
9286                                 daysInMonth = this._getDaysInMonth(drawYear, drawMonth);
9287                                 if (drawYear === inst.selectedYear && drawMonth === inst.selectedMonth) {
9288                                         inst.selectedDay = Math.min(inst.selectedDay, daysInMonth);
9289                                 }
9290                                 leadDays = (this._getFirstDayOfMonth(drawYear, drawMonth) - firstDay + 7) % 7;
9291                                 curRows = Math.ceil((leadDays + daysInMonth) / 7); // calculate the number of rows to generate
9292                                 numRows = (isMultiMonth ? this.maxRows > curRows ? this.maxRows : curRows : curRows); //If multiple months, use the higher number of rows (see #7043)
9293                                 this.maxRows = numRows;
9294                                 printDate = this._daylightSavingAdjust(new Date(drawYear, drawMonth, 1 - leadDays));
9295                                 for (dRow = 0; dRow < numRows; dRow++) { // create date picker rows
9296                                         calender += "<tr>";
9297                                         tbody = (!showWeek ? "" : "<td class='ui-datepicker-week-col'>" +
9298                                                 this._get(inst, "calculateWeek")(printDate) + "</td>");
9299                                         for (dow = 0; dow < 7; dow++) { // create date picker days
9300                                                 daySettings = (beforeShowDay ?
9301                                                         beforeShowDay.apply((inst.input ? inst.input[0] : null), [printDate]) : [true, ""]);
9302                                                 otherMonth = (printDate.getMonth() !== drawMonth);
9303                                                 unselectable = (otherMonth && !selectOtherMonths) || !daySettings[0] ||
9304                                                         (minDate && printDate < minDate) || (maxDate && printDate > maxDate);
9305                                                 tbody += "<td class='" +
9306                                                         ((dow + firstDay + 6) % 7 >= 5 ? " ui-datepicker-week-end" : "") + // highlight weekends
9307                                                         (otherMonth ? " ui-datepicker-other-month" : "") + // highlight days from other months
9308                                                         ((printDate.getTime() === selectedDate.getTime() && drawMonth === inst.selectedMonth && inst._keyEvent) || // user pressed key
9309                                                         (defaultDate.getTime() === printDate.getTime() && defaultDate.getTime() === selectedDate.getTime()) ?
9310                                                         // or defaultDate is current printedDate and defaultDate is selectedDate
9311                                                         " " + this._dayOverClass : "") + // highlight selected day
9312                                                         (unselectable ? " " + this._unselectableClass + " ui-state-disabled": "") +  // highlight unselectable days
9313                                                         (otherMonth && !showOtherMonths ? "" : " " + daySettings[1] + // highlight custom dates
9314                                                         (printDate.getTime() === currentDate.getTime() ? " " + this._currentClass : "") + // highlight selected day
9315                                                         (printDate.getTime() === today.getTime() ? " ui-datepicker-today" : "")) + "'" + // highlight today (if different)
9316                                                         ((!otherMonth || showOtherMonths) && daySettings[2] ? " title='" + daySettings[2].replace(/'/g, "&#39;") + "'" : "") + // cell title
9317                                                         (unselectable ? "" : " data-handler='selectDay' data-event='click' data-month='" + printDate.getMonth() + "' data-year='" + printDate.getFullYear() + "'") + ">" + // actions
9318                                                         (otherMonth && !showOtherMonths ? "&#xa0;" : // display for other months
9319                                                         (unselectable ? "<span class='ui-state-default'>" + printDate.getDate() + "</span>" : "<a class='ui-state-default" +
9320                                                         (printDate.getTime() === today.getTime() ? " ui-state-highlight" : "") +
9321                                                         (printDate.getTime() === currentDate.getTime() ? " ui-state-active" : "") + // highlight selected day
9322                                                         (otherMonth ? " ui-priority-secondary" : "") + // distinguish dates from other months
9323                                                         "' href='#'>" + printDate.getDate() + "</a>")) + "</td>"; // display selectable date
9324                                                 printDate.setDate(printDate.getDate() + 1);
9325                                                 printDate = this._daylightSavingAdjust(printDate);
9326                                         }
9327                                         calender += tbody + "</tr>";
9328                                 }
9329                                 drawMonth++;
9330                                 if (drawMonth > 11) {
9331                                         drawMonth = 0;
9332                                         drawYear++;
9333                                 }
9334                                 calender += "</tbody></table>" + (isMultiMonth ? "</div>" +
9335                                                         ((numMonths[0] > 0 && col === numMonths[1]-1) ? "<div class='ui-datepicker-row-break'></div>" : "") : "");
9336                                 group += calender;
9337                         }
9338                         html += group;
9339                 }
9340                 html += buttonPanel;
9341                 inst._keyEvent = false;
9342                 return html;
9343         },
9344
9345         /* Generate the month and year header. */
9346         _generateMonthYearHeader: function(inst, drawMonth, drawYear, minDate, maxDate,
9347                         secondary, monthNames, monthNamesShort) {
9348
9349                 var inMinYear, inMaxYear, month, years, thisYear, determineYear, year, endYear,
9350                         changeMonth = this._get(inst, "changeMonth"),
9351                         changeYear = this._get(inst, "changeYear"),
9352                         showMonthAfterYear = this._get(inst, "showMonthAfterYear"),
9353                         html = "<div class='ui-datepicker-title'>",
9354                         monthHtml = "";
9355
9356                 // month selection
9357                 if (secondary || !changeMonth) {
9358                         monthHtml += "<span class='ui-datepicker-month'>" + monthNames[drawMonth] + "</span>";
9359                 } else {
9360                         inMinYear = (minDate && minDate.getFullYear() === drawYear);
9361                         inMaxYear = (maxDate && maxDate.getFullYear() === drawYear);
9362                         monthHtml += "<select class='ui-datepicker-month' data-handler='selectMonth' data-event='change'>";
9363                         for ( month = 0; month < 12; month++) {
9364                                 if ((!inMinYear || month >= minDate.getMonth()) && (!inMaxYear || month <= maxDate.getMonth())) {
9365                                         monthHtml += "<option value='" + month + "'" +
9366                                                 (month === drawMonth ? " selected='selected'" : "") +
9367                                                 ">" + monthNamesShort[month] + "</option>";
9368                                 }
9369                         }
9370                         monthHtml += "</select>";
9371                 }
9372
9373                 if (!showMonthAfterYear) {
9374                         html += monthHtml + (secondary || !(changeMonth && changeYear) ? "&#xa0;" : "");
9375                 }
9376
9377                 // year selection
9378                 if ( !inst.yearshtml ) {
9379                         inst.yearshtml = "";
9380                         if (secondary || !changeYear) {
9381                                 html += "<span class='ui-datepicker-year'>" + drawYear + "</span>";
9382                         } else {
9383                                 // determine range of years to display
9384                                 years = this._get(inst, "yearRange").split(":");
9385                                 thisYear = new Date().getFullYear();
9386                                 determineYear = function(value) {
9387                                         var year = (value.match(/c[+\-].*/) ? drawYear + parseInt(value.substring(1), 10) :
9388                                                 (value.match(/[+\-].*/) ? thisYear + parseInt(value, 10) :
9389                                                 parseInt(value, 10)));
9390                                         return (isNaN(year) ? thisYear : year);
9391                                 };
9392                                 year = determineYear(years[0]);
9393                                 endYear = Math.max(year, determineYear(years[1] || ""));
9394                                 year = (minDate ? Math.max(year, minDate.getFullYear()) : year);
9395                                 endYear = (maxDate ? Math.min(endYear, maxDate.getFullYear()) : endYear);
9396                                 inst.yearshtml += "<select class='ui-datepicker-year' data-handler='selectYear' data-event='change'>";
9397                                 for (; year <= endYear; year++) {
9398                                         inst.yearshtml += "<option value='" + year + "'" +
9399                                                 (year === drawYear ? " selected='selected'" : "") +
9400                                                 ">" + year + "</option>";
9401                                 }
9402                                 inst.yearshtml += "</select>";
9403
9404                                 html += inst.yearshtml;
9405                                 inst.yearshtml = null;
9406                         }
9407                 }
9408
9409                 html += this._get(inst, "yearSuffix");
9410                 if (showMonthAfterYear) {
9411                         html += (secondary || !(changeMonth && changeYear) ? "&#xa0;" : "") + monthHtml;
9412                 }
9413                 html += "</div>"; // Close datepicker_header
9414                 return html;
9415         },
9416
9417         /* Adjust one of the date sub-fields. */
9418         _adjustInstDate: function(inst, offset, period) {
9419                 var year = inst.drawYear + (period === "Y" ? offset : 0),
9420                         month = inst.drawMonth + (period === "M" ? offset : 0),
9421                         day = Math.min(inst.selectedDay, this._getDaysInMonth(year, month)) + (period === "D" ? offset : 0),
9422                         date = this._restrictMinMax(inst, this._daylightSavingAdjust(new Date(year, month, day)));
9423
9424                 inst.selectedDay = date.getDate();
9425                 inst.drawMonth = inst.selectedMonth = date.getMonth();
9426                 inst.drawYear = inst.selectedYear = date.getFullYear();
9427                 if (period === "M" || period === "Y") {
9428                         this._notifyChange(inst);
9429                 }
9430         },
9431
9432         /* Ensure a date is within any min/max bounds. */
9433         _restrictMinMax: function(inst, date) {
9434                 var minDate = this._getMinMaxDate(inst, "min"),
9435                         maxDate = this._getMinMaxDate(inst, "max"),
9436                         newDate = (minDate && date < minDate ? minDate : date);
9437                 return (maxDate && newDate > maxDate ? maxDate : newDate);
9438         },
9439
9440         /* Notify change of month/year. */
9441         _notifyChange: function(inst) {
9442                 var onChange = this._get(inst, "onChangeMonthYear");
9443                 if (onChange) {
9444                         onChange.apply((inst.input ? inst.input[0] : null),
9445                                 [inst.selectedYear, inst.selectedMonth + 1, inst]);
9446                 }
9447         },
9448
9449         /* Determine the number of months to show. */
9450         _getNumberOfMonths: function(inst) {
9451                 var numMonths = this._get(inst, "numberOfMonths");
9452                 return (numMonths == null ? [1, 1] : (typeof numMonths === "number" ? [1, numMonths] : numMonths));
9453         },
9454
9455         /* Determine the current maximum date - ensure no time components are set. */
9456         _getMinMaxDate: function(inst, minMax) {
9457                 return this._determineDate(inst, this._get(inst, minMax + "Date"), null);
9458         },
9459
9460         /* Find the number of days in a given month. */
9461         _getDaysInMonth: function(year, month) {
9462                 return 32 - this._daylightSavingAdjust(new Date(year, month, 32)).getDate();
9463         },
9464
9465         /* Find the day of the week of the first of a month. */
9466         _getFirstDayOfMonth: function(year, month) {
9467                 return new Date(year, month, 1).getDay();
9468         },
9469
9470         /* Determines if we should allow a "next/prev" month display change. */
9471         _canAdjustMonth: function(inst, offset, curYear, curMonth) {
9472                 var numMonths = this._getNumberOfMonths(inst),
9473                         date = this._daylightSavingAdjust(new Date(curYear,
9474                         curMonth + (offset < 0 ? offset : numMonths[0] * numMonths[1]), 1));
9475
9476                 if (offset < 0) {
9477                         date.setDate(this._getDaysInMonth(date.getFullYear(), date.getMonth()));
9478                 }
9479                 return this._isInRange(inst, date);
9480         },
9481
9482         /* Is the given date in the accepted range? */
9483         _isInRange: function(inst, date) {
9484                 var yearSplit, currentYear,
9485                         minDate = this._getMinMaxDate(inst, "min"),
9486                         maxDate = this._getMinMaxDate(inst, "max"),
9487                         minYear = null,
9488                         maxYear = null,
9489                         years = this._get(inst, "yearRange");
9490                         if (years){
9491                                 yearSplit = years.split(":");
9492                                 currentYear = new Date().getFullYear();
9493                                 minYear = parseInt(yearSplit[0], 10);
9494                                 maxYear = parseInt(yearSplit[1], 10);
9495                                 if ( yearSplit[0].match(/[+\-].*/) ) {
9496                                         minYear += currentYear;
9497                                 }
9498                                 if ( yearSplit[1].match(/[+\-].*/) ) {
9499                                         maxYear += currentYear;
9500                                 }
9501                         }
9502
9503                 return ((!minDate || date.getTime() >= minDate.getTime()) &&
9504                         (!maxDate || date.getTime() <= maxDate.getTime()) &&
9505                         (!minYear || date.getFullYear() >= minYear) &&
9506                         (!maxYear || date.getFullYear() <= maxYear));
9507         },
9508
9509         /* Provide the configuration settings for formatting/parsing. */
9510         _getFormatConfig: function(inst) {
9511                 var shortYearCutoff = this._get(inst, "shortYearCutoff");
9512                 shortYearCutoff = (typeof shortYearCutoff !== "string" ? shortYearCutoff :
9513                         new Date().getFullYear() % 100 + parseInt(shortYearCutoff, 10));
9514                 return {shortYearCutoff: shortYearCutoff,
9515                         dayNamesShort: this._get(inst, "dayNamesShort"), dayNames: this._get(inst, "dayNames"),
9516                         monthNamesShort: this._get(inst, "monthNamesShort"), monthNames: this._get(inst, "monthNames")};
9517         },
9518
9519         /* Format the given date for display. */
9520         _formatDate: function(inst, day, month, year) {
9521                 if (!day) {
9522                         inst.currentDay = inst.selectedDay;
9523                         inst.currentMonth = inst.selectedMonth;
9524                         inst.currentYear = inst.selectedYear;
9525                 }
9526                 var date = (day ? (typeof day === "object" ? day :
9527                         this._daylightSavingAdjust(new Date(year, month, day))) :
9528                         this._daylightSavingAdjust(new Date(inst.currentYear, inst.currentMonth, inst.currentDay)));
9529                 return this.formatDate(this._get(inst, "dateFormat"), date, this._getFormatConfig(inst));
9530         }
9531 });
9532
9533 /*
9534  * Bind hover events for datepicker elements.
9535  * Done via delegate so the binding only occurs once in the lifetime of the parent div.
9536  * Global instActive, set by _updateDatepicker allows the handlers to find their way back to the active picker.
9537  */
9538 function bindHover(dpDiv) {
9539         var selector = "button, .ui-datepicker-prev, .ui-datepicker-next, .ui-datepicker-calendar td a";
9540         return dpDiv.delegate(selector, "mouseout", function() {
9541                         $(this).removeClass("ui-state-hover");
9542                         if (this.className.indexOf("ui-datepicker-prev") !== -1) {
9543                                 $(this).removeClass("ui-datepicker-prev-hover");
9544                         }
9545                         if (this.className.indexOf("ui-datepicker-next") !== -1) {
9546                                 $(this).removeClass("ui-datepicker-next-hover");
9547                         }
9548                 })
9549                 .delegate(selector, "mouseover", function(){
9550                         if (!$.datepicker._isDisabledDatepicker( instActive.inline ? dpDiv.parent()[0] : instActive.input[0])) {
9551                                 $(this).parents(".ui-datepicker-calendar").find("a").removeClass("ui-state-hover");
9552                                 $(this).addClass("ui-state-hover");
9553                                 if (this.className.indexOf("ui-datepicker-prev") !== -1) {
9554                                         $(this).addClass("ui-datepicker-prev-hover");
9555                                 }
9556                                 if (this.className.indexOf("ui-datepicker-next") !== -1) {
9557                                         $(this).addClass("ui-datepicker-next-hover");
9558                                 }
9559                         }
9560                 });
9561 }
9562
9563 /* jQuery extend now ignores nulls! */
9564 function extendRemove(target, props) {
9565         $.extend(target, props);
9566         for (var name in props) {
9567                 if (props[name] == null) {
9568                         target[name] = props[name];
9569                 }
9570         }
9571         return target;
9572 }
9573
9574 /* Invoke the datepicker functionality.
9575    @param  options  string - a command, optionally followed by additional parameters or
9576                                         Object - settings for attaching new datepicker functionality
9577    @return  jQuery object */
9578 $.fn.datepicker = function(options){
9579
9580         /* Verify an empty collection wasn't passed - Fixes #6976 */
9581         if ( !this.length ) {
9582                 return this;
9583         }
9584
9585         /* Initialise the date picker. */
9586         if (!$.datepicker.initialized) {
9587                 $(document).mousedown($.datepicker._checkExternalClick);
9588                 $.datepicker.initialized = true;
9589         }
9590
9591         /* Append datepicker main container to body if not exist. */
9592         if ($("#"+$.datepicker._mainDivId).length === 0) {
9593                 $("body").append($.datepicker.dpDiv);
9594         }
9595
9596         var otherArgs = Array.prototype.slice.call(arguments, 1);
9597         if (typeof options === "string" && (options === "isDisabled" || options === "getDate" || options === "widget")) {
9598                 return $.datepicker["_" + options + "Datepicker"].
9599                         apply($.datepicker, [this[0]].concat(otherArgs));
9600         }
9601         if (options === "option" && arguments.length === 2 && typeof arguments[1] === "string") {
9602                 return $.datepicker["_" + options + "Datepicker"].
9603                         apply($.datepicker, [this[0]].concat(otherArgs));
9604         }
9605         return this.each(function() {
9606                 typeof options === "string" ?
9607                         $.datepicker["_" + options + "Datepicker"].
9608                                 apply($.datepicker, [this].concat(otherArgs)) :
9609                         $.datepicker._attachDatepicker(this, options);
9610         });
9611 };
9612
9613 $.datepicker = new Datepicker(); // singleton instance
9614 $.datepicker.initialized = false;
9615 $.datepicker.uuid = new Date().getTime();
9616 $.datepicker.version = "1.10.2";
9617
9618 // Workaround for #4055
9619 // Add another global to avoid noConflict issues with inline event handlers
9620 window["DP_jQuery_" + dpuuid] = $;
9621
9622 })(jQuery);
9623
9624 (function( $, undefined ) {
9625
9626 var sizeRelatedOptions = {
9627                 buttons: true,
9628                 height: true,
9629                 maxHeight: true,
9630                 maxWidth: true,
9631                 minHeight: true,
9632                 minWidth: true,
9633                 width: true
9634         },
9635         resizableRelatedOptions = {
9636                 maxHeight: true,
9637                 maxWidth: true,
9638                 minHeight: true,
9639                 minWidth: true
9640         };
9641
9642 $.widget( "ui.dialog", {
9643         version: "1.10.2",
9644         options: {
9645                 appendTo: "body",
9646                 autoOpen: true,
9647                 buttons: [],
9648                 closeOnEscape: true,
9649                 closeText: "close",
9650                 dialogClass: "",
9651                 draggable: true,
9652                 hide: null,
9653                 height: "auto",
9654                 maxHeight: null,
9655                 maxWidth: null,
9656                 minHeight: 150,
9657                 minWidth: 150,
9658                 modal: false,
9659                 position: {
9660                         my: "center",
9661                         at: "center",
9662                         of: window,
9663                         collision: "fit",
9664                         // Ensure the titlebar is always visible
9665                         using: function( pos ) {
9666                                 var topOffset = $( this ).css( pos ).offset().top;
9667                                 if ( topOffset < 0 ) {
9668                                         $( this ).css( "top", pos.top - topOffset );
9669                                 }
9670                         }
9671                 },
9672                 resizable: true,
9673                 show: null,
9674                 title: null,
9675                 width: 300,
9676
9677                 // callbacks
9678                 beforeClose: null,
9679                 close: null,
9680                 drag: null,
9681                 dragStart: null,
9682                 dragStop: null,
9683                 focus: null,
9684                 open: null,
9685                 resize: null,
9686                 resizeStart: null,
9687                 resizeStop: null
9688         },
9689
9690         _create: function() {
9691                 this.originalCss = {
9692                         display: this.element[0].style.display,
9693                         width: this.element[0].style.width,
9694                         minHeight: this.element[0].style.minHeight,
9695                         maxHeight: this.element[0].style.maxHeight,
9696                         height: this.element[0].style.height
9697                 };
9698                 this.originalPosition = {
9699                         parent: this.element.parent(),
9700                         index: this.element.parent().children().index( this.element )
9701                 };
9702                 this.originalTitle = this.element.attr("title");
9703                 this.options.title = this.options.title || this.originalTitle;
9704
9705                 this._createWrapper();
9706
9707                 this.element
9708                         .show()
9709                         .removeAttr("title")
9710                         .addClass("ui-dialog-content ui-widget-content")
9711                         .appendTo( this.uiDialog );
9712
9713                 this._createTitlebar();
9714                 this._createButtonPane();
9715
9716                 if ( this.options.draggable && $.fn.draggable ) {
9717                         this._makeDraggable();
9718                 }
9719                 if ( this.options.resizable && $.fn.resizable ) {
9720                         this._makeResizable();
9721                 }
9722
9723                 this._isOpen = false;
9724         },
9725
9726         _init: function() {
9727                 if ( this.options.autoOpen ) {
9728                         this.open();
9729                 }
9730         },
9731
9732         _appendTo: function() {
9733                 var element = this.options.appendTo;
9734                 if ( element && (element.jquery || element.nodeType) ) {
9735                         return $( element );
9736                 }
9737                 return this.document.find( element || "body" ).eq( 0 );
9738         },
9739
9740         _destroy: function() {
9741                 var next,
9742                         originalPosition = this.originalPosition;
9743
9744                 this._destroyOverlay();
9745
9746                 this.element
9747                         .removeUniqueId()
9748                         .removeClass("ui-dialog-content ui-widget-content")
9749                         .css( this.originalCss )
9750                         // Without detaching first, the following becomes really slow
9751                         .detach();
9752
9753                 this.uiDialog.stop( true, true ).remove();
9754
9755                 if ( this.originalTitle ) {
9756                         this.element.attr( "title", this.originalTitle );
9757                 }
9758
9759                 next = originalPosition.parent.children().eq( originalPosition.index );
9760                 // Don't try to place the dialog next to itself (#8613)
9761                 if ( next.length && next[0] !== this.element[0] ) {
9762                         next.before( this.element );
9763                 } else {
9764                         originalPosition.parent.append( this.element );
9765                 }
9766         },
9767
9768         widget: function() {
9769                 return this.uiDialog;
9770         },
9771
9772         disable: $.noop,
9773         enable: $.noop,
9774
9775         close: function( event ) {
9776                 var that = this;
9777
9778                 if ( !this._isOpen || this._trigger( "beforeClose", event ) === false ) {
9779                         return;
9780                 }
9781
9782                 this._isOpen = false;
9783                 this._destroyOverlay();
9784
9785                 if ( !this.opener.filter(":focusable").focus().length ) {
9786                         // Hiding a focused element doesn't trigger blur in WebKit
9787                         // so in case we have nothing to focus on, explicitly blur the active element
9788                         // https://bugs.webkit.org/show_bug.cgi?id=47182
9789                         $( this.document[0].activeElement ).blur();
9790                 }
9791
9792                 this._hide( this.uiDialog, this.options.hide, function() {
9793                         that._trigger( "close", event );
9794                 });
9795         },
9796
9797         isOpen: function() {
9798                 return this._isOpen;
9799         },
9800
9801         moveToTop: function() {
9802                 this._moveToTop();
9803         },
9804
9805         _moveToTop: function( event, silent ) {
9806                 var moved = !!this.uiDialog.nextAll(":visible").insertBefore( this.uiDialog ).length;
9807                 if ( moved && !silent ) {
9808                         this._trigger( "focus", event );
9809                 }
9810                 return moved;
9811         },
9812
9813         open: function() {
9814                 var that = this;
9815                 if ( this._isOpen ) {
9816                         if ( this._moveToTop() ) {
9817                                 this._focusTabbable();
9818                         }
9819                         return;
9820                 }
9821
9822                 this._isOpen = true;
9823                 this.opener = $( this.document[0].activeElement );
9824
9825                 this._size();
9826                 this._position();
9827                 this._createOverlay();
9828                 this._moveToTop( null, true );
9829                 this._show( this.uiDialog, this.options.show, function() {
9830                         that._focusTabbable();
9831                         that._trigger("focus");
9832                 });
9833
9834                 this._trigger("open");
9835         },
9836
9837         _focusTabbable: function() {
9838                 // Set focus to the first match:
9839                 // 1. First element inside the dialog matching [autofocus]
9840                 // 2. Tabbable element inside the content element
9841                 // 3. Tabbable element inside the buttonpane
9842                 // 4. The close button
9843                 // 5. The dialog itself
9844                 var hasFocus = this.element.find("[autofocus]");
9845                 if ( !hasFocus.length ) {
9846                         hasFocus = this.element.find(":tabbable");
9847                 }
9848                 if ( !hasFocus.length ) {
9849                         hasFocus = this.uiDialogButtonPane.find(":tabbable");
9850                 }
9851                 if ( !hasFocus.length ) {
9852                         hasFocus = this.uiDialogTitlebarClose.filter(":tabbable");
9853                 }
9854                 if ( !hasFocus.length ) {
9855                         hasFocus = this.uiDialog;
9856                 }
9857                 hasFocus.eq( 0 ).focus();
9858         },
9859
9860         _keepFocus: function( event ) {
9861                 function checkFocus() {
9862                         var activeElement = this.document[0].activeElement,
9863                                 isActive = this.uiDialog[0] === activeElement ||
9864                                         $.contains( this.uiDialog[0], activeElement );
9865                         if ( !isActive ) {
9866                                 this._focusTabbable();
9867                         }
9868                 }
9869                 event.preventDefault();
9870                 checkFocus.call( this );
9871                 // support: IE
9872                 // IE <= 8 doesn't prevent moving focus even with event.preventDefault()
9873                 // so we check again later
9874                 this._delay( checkFocus );
9875         },
9876
9877         _createWrapper: function() {
9878                 this.uiDialog = $("<div>")
9879                         .addClass( "ui-dialog ui-widget ui-widget-content ui-corner-all ui-front " +
9880                                 this.options.dialogClass )
9881                         .hide()
9882                         .attr({
9883                                 // Setting tabIndex makes the div focusable
9884                                 tabIndex: -1,
9885                                 role: "dialog"
9886                         })
9887                         .appendTo( this._appendTo() );
9888
9889                 this._on( this.uiDialog, {
9890                         keydown: function( event ) {
9891                                 if ( this.options.closeOnEscape && !event.isDefaultPrevented() && event.keyCode &&
9892                                                 event.keyCode === $.ui.keyCode.ESCAPE ) {
9893                                         event.preventDefault();
9894                                         this.close( event );
9895                                         return;
9896                                 }
9897
9898                                 // prevent tabbing out of dialogs
9899                                 if ( event.keyCode !== $.ui.keyCode.TAB ) {
9900                                         return;
9901                                 }
9902                                 var tabbables = this.uiDialog.find(":tabbable"),
9903                                         first = tabbables.filter(":first"),
9904                                         last  = tabbables.filter(":last");
9905
9906                                 if ( ( event.target === last[0] || event.target === this.uiDialog[0] ) && !event.shiftKey ) {
9907                                         first.focus( 1 );
9908                                         event.preventDefault();
9909                                 } else if ( ( event.target === first[0] || event.target === this.uiDialog[0] ) && event.shiftKey ) {
9910                                         last.focus( 1 );
9911                                         event.preventDefault();
9912                                 }
9913                         },
9914                         mousedown: function( event ) {
9915                                 if ( this._moveToTop( event ) ) {
9916                                         this._focusTabbable();
9917                                 }
9918                         }
9919                 });
9920
9921                 // We assume that any existing aria-describedby attribute means
9922                 // that the dialog content is marked up properly
9923                 // otherwise we brute force the content as the description
9924                 if ( !this.element.find("[aria-describedby]").length ) {
9925                         this.uiDialog.attr({
9926                                 "aria-describedby": this.element.uniqueId().attr("id")
9927                         });
9928                 }
9929         },
9930
9931         _createTitlebar: function() {
9932                 var uiDialogTitle;
9933
9934                 this.uiDialogTitlebar = $("<div>")
9935                         .addClass("ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix")
9936                         .prependTo( this.uiDialog );
9937                 this._on( this.uiDialogTitlebar, {
9938                         mousedown: function( event ) {
9939                                 // Don't prevent click on close button (#8838)
9940                                 // Focusing a dialog that is partially scrolled out of view
9941                                 // causes the browser to scroll it into view, preventing the click event
9942                                 if ( !$( event.target ).closest(".ui-dialog-titlebar-close") ) {
9943                                         // Dialog isn't getting focus when dragging (#8063)
9944                                         this.uiDialog.focus();
9945                                 }
9946                         }
9947                 });
9948
9949                 this.uiDialogTitlebarClose = $("<button></button>")
9950                         .button({
9951                                 label: this.options.closeText,
9952                                 icons: {
9953                                         primary: "ui-icon-closethick"
9954                                 },
9955                                 text: false
9956                         })
9957                         .addClass("ui-dialog-titlebar-close")
9958                         .appendTo( this.uiDialogTitlebar );
9959                 this._on( this.uiDialogTitlebarClose, {
9960                         click: function( event ) {
9961                                 event.preventDefault();
9962                                 this.close( event );
9963                         }
9964                 });
9965
9966                 uiDialogTitle = $("<span>")
9967                         .uniqueId()
9968                         .addClass("ui-dialog-title")
9969                         .prependTo( this.uiDialogTitlebar );
9970                 this._title( uiDialogTitle );
9971
9972                 this.uiDialog.attr({
9973                         "aria-labelledby": uiDialogTitle.attr("id")
9974                 });
9975         },
9976
9977         _title: function( title ) {
9978                 if ( !this.options.title ) {
9979                         title.html("&#160;");
9980                 }
9981                 title.text( this.options.title );
9982         },
9983
9984         _createButtonPane: function() {
9985                 this.uiDialogButtonPane = $("<div>")
9986                         .addClass("ui-dialog-buttonpane ui-widget-content ui-helper-clearfix");
9987
9988                 this.uiButtonSet = $("<div>")
9989                         .addClass("ui-dialog-buttonset")
9990                         .appendTo( this.uiDialogButtonPane );
9991
9992                 this._createButtons();
9993         },
9994
9995         _createButtons: function() {
9996                 var that = this,
9997                         buttons = this.options.buttons;
9998
9999                 // if we already have a button pane, remove it
10000                 this.uiDialogButtonPane.remove();
10001                 this.uiButtonSet.empty();
10002
10003                 if ( $.isEmptyObject( buttons ) || ($.isArray( buttons ) && !buttons.length) ) {
10004                         this.uiDialog.removeClass("ui-dialog-buttons");
10005                         return;
10006                 }
10007
10008                 $.each( buttons, function( name, props ) {
10009                         var click, buttonOptions;
10010                         props = $.isFunction( props ) ?
10011                                 { click: props, text: name } :
10012                                 props;
10013                         // Default to a non-submitting button
10014                         props = $.extend( { type: "button" }, props );
10015                         // Change the context for the click callback to be the main element
10016                         click = props.click;
10017                         props.click = function() {
10018                                 click.apply( that.element[0], arguments );
10019                         };
10020                         buttonOptions = {
10021                                 icons: props.icons,
10022                                 text: props.showText
10023                         };
10024                         delete props.icons;
10025                         delete props.showText;
10026                         $( "<button></button>", props )
10027                                 .button( buttonOptions )
10028                                 .appendTo( that.uiButtonSet );
10029                 });
10030                 this.uiDialog.addClass("ui-dialog-buttons");
10031                 this.uiDialogButtonPane.appendTo( this.uiDialog );
10032         },
10033
10034         _makeDraggable: function() {
10035                 var that = this,
10036                         options = this.options;
10037
10038                 function filteredUi( ui ) {
10039                         return {
10040                                 position: ui.position,
10041                                 offset: ui.offset
10042                         };
10043                 }
10044
10045                 this.uiDialog.draggable({
10046                         cancel: ".ui-dialog-content, .ui-dialog-titlebar-close",
10047                         handle: ".ui-dialog-titlebar",
10048                         containment: "document",
10049                         start: function( event, ui ) {
10050                                 $( this ).addClass("ui-dialog-dragging");
10051                                 that._blockFrames();
10052                                 that._trigger( "dragStart", event, filteredUi( ui ) );
10053                         },
10054                         drag: function( event, ui ) {
10055                                 that._trigger( "drag", event, filteredUi( ui ) );
10056                         },
10057                         stop: function( event, ui ) {
10058                                 options.position = [
10059                                         ui.position.left - that.document.scrollLeft(),
10060                                         ui.position.top - that.document.scrollTop()
10061                                 ];
10062                                 $( this ).removeClass("ui-dialog-dragging");
10063                                 that._unblockFrames();
10064                                 that._trigger( "dragStop", event, filteredUi( ui ) );
10065                         }
10066                 });
10067         },
10068
10069         _makeResizable: function() {
10070                 var that = this,
10071                         options = this.options,
10072                         handles = options.resizable,
10073                         // .ui-resizable has position: relative defined in the stylesheet
10074                         // but dialogs have to use absolute or fixed positioning
10075                         position = this.uiDialog.css("position"),
10076                         resizeHandles = typeof handles === "string" ?
10077                                 handles :
10078                                 "n,e,s,w,se,sw,ne,nw";
10079
10080                 function filteredUi( ui ) {
10081                         return {
10082                                 originalPosition: ui.originalPosition,
10083                                 originalSize: ui.originalSize,
10084                                 position: ui.position,
10085                                 size: ui.size
10086                         };
10087                 }
10088
10089                 this.uiDialog.resizable({
10090                         cancel: ".ui-dialog-content",
10091                         containment: "document",
10092                         alsoResize: this.element,
10093                         maxWidth: options.maxWidth,
10094                         maxHeight: options.maxHeight,
10095                         minWidth: options.minWidth,
10096                         minHeight: this._minHeight(),
10097                         handles: resizeHandles,
10098                         start: function( event, ui ) {
10099                                 $( this ).addClass("ui-dialog-resizing");
10100                                 that._blockFrames();
10101                                 that._trigger( "resizeStart", event, filteredUi( ui ) );
10102                         },
10103                         resize: function( event, ui ) {
10104                                 that._trigger( "resize", event, filteredUi( ui ) );
10105                         },
10106                         stop: function( event, ui ) {
10107                                 options.height = $( this ).height();
10108                                 options.width = $( this ).width();
10109                                 $( this ).removeClass("ui-dialog-resizing");
10110                                 that._unblockFrames();
10111                                 that._trigger( "resizeStop", event, filteredUi( ui ) );
10112                         }
10113                 })
10114                 .css( "position", position );
10115         },
10116
10117         _minHeight: function() {
10118                 var options = this.options;
10119
10120                 return options.height === "auto" ?
10121                         options.minHeight :
10122                         Math.min( options.minHeight, options.height );
10123         },
10124
10125         _position: function() {
10126                 // Need to show the dialog to get the actual offset in the position plugin
10127                 var isVisible = this.uiDialog.is(":visible");
10128                 if ( !isVisible ) {
10129                         this.uiDialog.show();
10130                 }
10131                 this.uiDialog.position( this.options.position );
10132                 if ( !isVisible ) {
10133                         this.uiDialog.hide();
10134                 }
10135         },
10136
10137         _setOptions: function( options ) {
10138                 var that = this,
10139                         resize = false,
10140                         resizableOptions = {};
10141
10142                 $.each( options, function( key, value ) {
10143                         that._setOption( key, value );
10144
10145                         if ( key in sizeRelatedOptions ) {
10146                                 resize = true;
10147                         }
10148                         if ( key in resizableRelatedOptions ) {
10149                                 resizableOptions[ key ] = value;
10150                         }
10151                 });
10152
10153                 if ( resize ) {
10154                         this._size();
10155                         this._position();
10156                 }
10157                 if ( this.uiDialog.is(":data(ui-resizable)") ) {
10158                         this.uiDialog.resizable( "option", resizableOptions );
10159                 }
10160         },
10161
10162         _setOption: function( key, value ) {
10163                 /*jshint maxcomplexity:15*/
10164                 var isDraggable, isResizable,
10165                         uiDialog = this.uiDialog;
10166
10167                 if ( key === "dialogClass" ) {
10168                         uiDialog
10169                                 .removeClass( this.options.dialogClass )
10170                                 .addClass( value );
10171                 }
10172
10173                 if ( key === "disabled" ) {
10174                         return;
10175                 }
10176
10177                 this._super( key, value );
10178
10179                 if ( key === "appendTo" ) {
10180                         this.uiDialog.appendTo( this._appendTo() );
10181                 }
10182
10183                 if ( key === "buttons" ) {
10184                         this._createButtons();
10185                 }
10186
10187                 if ( key === "closeText" ) {
10188                         this.uiDialogTitlebarClose.button({
10189                                 // Ensure that we always pass a string
10190                                 label: "" + value
10191                         });
10192                 }
10193
10194                 if ( key === "draggable" ) {
10195                         isDraggable = uiDialog.is(":data(ui-draggable)");
10196                         if ( isDraggable && !value ) {
10197                                 uiDialog.draggable("destroy");
10198                         }
10199
10200                         if ( !isDraggable && value ) {
10201                                 this._makeDraggable();
10202                         }
10203                 }
10204
10205                 if ( key === "position" ) {
10206                         this._position();
10207                 }
10208
10209                 if ( key === "resizable" ) {
10210                         // currently resizable, becoming non-resizable
10211                         isResizable = uiDialog.is(":data(ui-resizable)");
10212                         if ( isResizable && !value ) {
10213                                 uiDialog.resizable("destroy");
10214                         }
10215
10216                         // currently resizable, changing handles
10217                         if ( isResizable && typeof value === "string" ) {
10218                                 uiDialog.resizable( "option", "handles", value );
10219                         }
10220
10221                         // currently non-resizable, becoming resizable
10222                         if ( !isResizable && value !== false ) {
10223                                 this._makeResizable();
10224                         }
10225                 }
10226
10227                 if ( key === "title" ) {
10228                         this._title( this.uiDialogTitlebar.find(".ui-dialog-title") );
10229                 }
10230         },
10231
10232         _size: function() {
10233                 // If the user has resized the dialog, the .ui-dialog and .ui-dialog-content
10234                 // divs will both have width and height set, so we need to reset them
10235                 var nonContentHeight, minContentHeight, maxContentHeight,
10236                         options = this.options;
10237
10238                 // Reset content sizing
10239                 this.element.show().css({
10240                         width: "auto",
10241                         minHeight: 0,
10242                         maxHeight: "none",
10243                         height: 0
10244                 });
10245
10246                 if ( options.minWidth > options.width ) {
10247                         options.width = options.minWidth;
10248                 }
10249
10250                 // reset wrapper sizing
10251                 // determine the height of all the non-content elements
10252                 nonContentHeight = this.uiDialog.css({
10253                                 height: "auto",
10254                                 width: options.width
10255                         })
10256                         .outerHeight();
10257                 minContentHeight = Math.max( 0, options.minHeight - nonContentHeight );
10258                 maxContentHeight = typeof options.maxHeight === "number" ?
10259                         Math.max( 0, options.maxHeight - nonContentHeight ) :
10260                         "none";
10261
10262                 if ( options.height === "auto" ) {
10263                         this.element.css({
10264                                 minHeight: minContentHeight,
10265                                 maxHeight: maxContentHeight,
10266                                 height: "auto"
10267                         });
10268                 } else {
10269                         this.element.height( Math.max( 0, options.height - nonContentHeight ) );
10270                 }
10271
10272                 if (this.uiDialog.is(":data(ui-resizable)") ) {
10273                         this.uiDialog.resizable( "option", "minHeight", this._minHeight() );
10274                 }
10275         },
10276
10277         _blockFrames: function() {
10278                 this.iframeBlocks = this.document.find( "iframe" ).map(function() {
10279                         var iframe = $( this );
10280
10281                         return $( "<div>" )
10282                                 .css({
10283                                         position: "absolute",
10284                                         width: iframe.outerWidth(),
10285                                         height: iframe.outerHeight()
10286                                 })
10287                                 .appendTo( iframe.parent() )
10288                                 .offset( iframe.offset() )[0];
10289                 });
10290         },
10291
10292         _unblockFrames: function() {
10293                 if ( this.iframeBlocks ) {
10294                         this.iframeBlocks.remove();
10295                         delete this.iframeBlocks;
10296                 }
10297         },
10298
10299         _allowInteraction: function( event ) {
10300                 if ( $( event.target ).closest(".ui-dialog").length ) {
10301                         return true;
10302                 }
10303
10304                 // TODO: Remove hack when datepicker implements
10305                 // the .ui-front logic (#8989)
10306                 return !!$( event.target ).closest(".ui-datepicker").length;
10307         },
10308
10309         _createOverlay: function() {
10310                 if ( !this.options.modal ) {
10311                         return;
10312                 }
10313
10314                 var that = this,
10315                         widgetFullName = this.widgetFullName;
10316                 if ( !$.ui.dialog.overlayInstances ) {
10317                         // Prevent use of anchors and inputs.
10318                         // We use a delay in case the overlay is created from an
10319                         // event that we're going to be cancelling. (#2804)
10320                         this._delay(function() {
10321                                 // Handle .dialog().dialog("close") (#4065)
10322                                 if ( $.ui.dialog.overlayInstances ) {
10323                                         this.document.bind( "focusin.dialog", function( event ) {
10324                                                 if ( !that._allowInteraction( event ) ) {
10325                                                         event.preventDefault();
10326                                                         $(".ui-dialog:visible:last .ui-dialog-content")
10327                                                                 .data( widgetFullName )._focusTabbable();
10328                                                 }
10329                                         });
10330                                 }
10331                         });
10332                 }
10333
10334                 this.overlay = $("<div>")
10335                         .addClass("ui-widget-overlay ui-front")
10336                         .appendTo( this._appendTo() );
10337                 this._on( this.overlay, {
10338                         mousedown: "_keepFocus"
10339                 });
10340                 $.ui.dialog.overlayInstances++;
10341         },
10342
10343         _destroyOverlay: function() {
10344                 if ( !this.options.modal ) {
10345                         return;
10346                 }
10347
10348                 if ( this.overlay ) {
10349                         $.ui.dialog.overlayInstances--;
10350
10351                         if ( !$.ui.dialog.overlayInstances ) {
10352                                 this.document.unbind( "focusin.dialog" );
10353                         }
10354                         this.overlay.remove();
10355                         this.overlay = null;
10356                 }
10357         }
10358 });
10359
10360 $.ui.dialog.overlayInstances = 0;
10361
10362 // DEPRECATED
10363 if ( $.uiBackCompat !== false ) {
10364         // position option with array notation
10365         // just override with old implementation
10366         $.widget( "ui.dialog", $.ui.dialog, {
10367                 _position: function() {
10368                         var position = this.options.position,
10369                                 myAt = [],
10370                                 offset = [ 0, 0 ],
10371                                 isVisible;
10372
10373                         if ( position ) {
10374                                 if ( typeof position === "string" || (typeof position === "object" && "0" in position ) ) {
10375                                         myAt = position.split ? position.split(" ") : [ position[0], position[1] ];
10376                                         if ( myAt.length === 1 ) {
10377                                                 myAt[1] = myAt[0];
10378                                         }
10379
10380                                         $.each( [ "left", "top" ], function( i, offsetPosition ) {
10381                                                 if ( +myAt[ i ] === myAt[ i ] ) {
10382                                                         offset[ i ] = myAt[ i ];
10383                                                         myAt[ i ] = offsetPosition;
10384                                                 }
10385                                         });
10386
10387                                         position = {
10388                                                 my: myAt[0] + (offset[0] < 0 ? offset[0] : "+" + offset[0]) + " " +
10389                                                         myAt[1] + (offset[1] < 0 ? offset[1] : "+" + offset[1]),
10390                                                 at: myAt.join(" ")
10391                                         };
10392                                 }
10393
10394                                 position = $.extend( {}, $.ui.dialog.prototype.options.position, position );
10395                         } else {
10396                                 position = $.ui.dialog.prototype.options.position;
10397                         }
10398
10399                         // need to show the dialog to get the actual offset in the position plugin
10400                         isVisible = this.uiDialog.is(":visible");
10401                         if ( !isVisible ) {
10402                                 this.uiDialog.show();
10403                         }
10404                         this.uiDialog.position( position );
10405                         if ( !isVisible ) {
10406                                 this.uiDialog.hide();
10407                         }
10408                 }
10409         });
10410 }
10411
10412 }( jQuery ) );
10413
10414 (function( $, undefined ) {
10415
10416 var rvertical = /up|down|vertical/,
10417         rpositivemotion = /up|left|vertical|horizontal/;
10418
10419 $.effects.effect.blind = function( o, done ) {
10420         // Create element
10421         var el = $( this ),
10422                 props = [ "position", "top", "bottom", "left", "right", "height", "width" ],
10423                 mode = $.effects.setMode( el, o.mode || "hide" ),
10424                 direction = o.direction || "up",
10425                 vertical = rvertical.test( direction ),
10426                 ref = vertical ? "height" : "width",
10427                 ref2 = vertical ? "top" : "left",
10428                 motion = rpositivemotion.test( direction ),
10429                 animation = {},
10430                 show = mode === "show",
10431                 wrapper, distance, margin;
10432
10433         // if already wrapped, the wrapper's properties are my property. #6245
10434         if ( el.parent().is( ".ui-effects-wrapper" ) ) {
10435                 $.effects.save( el.parent(), props );
10436         } else {
10437                 $.effects.save( el, props );
10438         }
10439         el.show();
10440         wrapper = $.effects.createWrapper( el ).css({
10441                 overflow: "hidden"
10442         });
10443
10444         distance = wrapper[ ref ]();
10445         margin = parseFloat( wrapper.css( ref2 ) ) || 0;
10446
10447         animation[ ref ] = show ? distance : 0;
10448         if ( !motion ) {
10449                 el
10450                         .css( vertical ? "bottom" : "right", 0 )
10451                         .css( vertical ? "top" : "left", "auto" )
10452                         .css({ position: "absolute" });
10453
10454                 animation[ ref2 ] = show ? margin : distance + margin;
10455         }
10456
10457         // start at 0 if we are showing
10458         if ( show ) {
10459                 wrapper.css( ref, 0 );
10460                 if ( ! motion ) {
10461                         wrapper.css( ref2, margin + distance );
10462                 }
10463         }
10464
10465         // Animate
10466         wrapper.animate( animation, {
10467                 duration: o.duration,
10468                 easing: o.easing,
10469                 queue: false,
10470                 complete: function() {
10471                         if ( mode === "hide" ) {
10472                                 el.hide();
10473                         }
10474                         $.effects.restore( el, props );
10475                         $.effects.removeWrapper( el );
10476                         done();
10477                 }
10478         });
10479
10480 };
10481
10482 })(jQuery);
10483
10484 (function( $, undefined ) {
10485
10486 $.effects.effect.bounce = function( o, done ) {
10487         var el = $( this ),
10488                 props = [ "position", "top", "bottom", "left", "right", "height", "width" ],
10489
10490                 // defaults:
10491                 mode = $.effects.setMode( el, o.mode || "effect" ),
10492                 hide = mode === "hide",
10493                 show = mode === "show",
10494                 direction = o.direction || "up",
10495                 distance = o.distance,
10496                 times = o.times || 5,
10497
10498                 // number of internal animations
10499                 anims = times * 2 + ( show || hide ? 1 : 0 ),
10500                 speed = o.duration / anims,
10501                 easing = o.easing,
10502
10503                 // utility:
10504                 ref = ( direction === "up" || direction === "down" ) ? "top" : "left",
10505                 motion = ( direction === "up" || direction === "left" ),
10506                 i,
10507                 upAnim,
10508                 downAnim,
10509
10510                 // we will need to re-assemble the queue to stack our animations in place
10511                 queue = el.queue(),
10512                 queuelen = queue.length;
10513
10514         // Avoid touching opacity to prevent clearType and PNG issues in IE
10515         if ( show || hide ) {
10516                 props.push( "opacity" );
10517         }
10518
10519         $.effects.save( el, props );
10520         el.show();
10521         $.effects.createWrapper( el ); // Create Wrapper
10522
10523         // default distance for the BIGGEST bounce is the outer Distance / 3
10524         if ( !distance ) {
10525                 distance = el[ ref === "top" ? "outerHeight" : "outerWidth" ]() / 3;
10526         }
10527
10528         if ( show ) {
10529                 downAnim = { opacity: 1 };
10530                 downAnim[ ref ] = 0;
10531
10532                 // if we are showing, force opacity 0 and set the initial position
10533                 // then do the "first" animation
10534                 el.css( "opacity", 0 )
10535                         .css( ref, motion ? -distance * 2 : distance * 2 )
10536                         .animate( downAnim, speed, easing );
10537         }
10538
10539         // start at the smallest distance if we are hiding
10540         if ( hide ) {
10541                 distance = distance / Math.pow( 2, times - 1 );
10542         }
10543
10544         downAnim = {};
10545         downAnim[ ref ] = 0;
10546         // Bounces up/down/left/right then back to 0 -- times * 2 animations happen here
10547         for ( i = 0; i < times; i++ ) {
10548                 upAnim = {};
10549                 upAnim[ ref ] = ( motion ? "-=" : "+=" ) + distance;
10550
10551                 el.animate( upAnim, speed, easing )
10552                         .animate( downAnim, speed, easing );
10553
10554                 distance = hide ? distance * 2 : distance / 2;
10555         }
10556
10557         // Last Bounce when Hiding
10558         if ( hide ) {
10559                 upAnim = { opacity: 0 };
10560                 upAnim[ ref ] = ( motion ? "-=" : "+=" ) + distance;
10561
10562                 el.animate( upAnim, speed, easing );
10563         }
10564
10565         el.queue(function() {
10566                 if ( hide ) {
10567                         el.hide();
10568                 }
10569                 $.effects.restore( el, props );
10570                 $.effects.removeWrapper( el );
10571                 done();
10572         });
10573
10574         // inject all the animations we just queued to be first in line (after "inprogress")
10575         if ( queuelen > 1) {
10576                 queue.splice.apply( queue,
10577                         [ 1, 0 ].concat( queue.splice( queuelen, anims + 1 ) ) );
10578         }
10579         el.dequeue();
10580
10581 };
10582
10583 })(jQuery);
10584
10585 (function( $, undefined ) {
10586
10587 $.effects.effect.clip = function( o, done ) {
10588         // Create element
10589         var el = $( this ),
10590                 props = [ "position", "top", "bottom", "left", "right", "height", "width" ],
10591                 mode = $.effects.setMode( el, o.mode || "hide" ),
10592                 show = mode === "show",
10593                 direction = o.direction || "vertical",
10594                 vert = direction === "vertical",
10595                 size = vert ? "height" : "width",
10596                 position = vert ? "top" : "left",
10597                 animation = {},
10598                 wrapper, animate, distance;
10599
10600         // Save & Show
10601         $.effects.save( el, props );
10602         el.show();
10603
10604         // Create Wrapper
10605         wrapper = $.effects.createWrapper( el ).css({
10606                 overflow: "hidden"
10607         });
10608         animate = ( el[0].tagName === "IMG" ) ? wrapper : el;
10609         distance = animate[ size ]();
10610
10611         // Shift
10612         if ( show ) {
10613                 animate.css( size, 0 );
10614                 animate.css( position, distance / 2 );
10615         }
10616
10617         // Create Animation Object:
10618         animation[ size ] = show ? distance : 0;
10619         animation[ position ] = show ? 0 : distance / 2;
10620
10621         // Animate
10622         animate.animate( animation, {
10623                 queue: false,
10624                 duration: o.duration,
10625                 easing: o.easing,
10626                 complete: function() {
10627                         if ( !show ) {
10628                                 el.hide();
10629                         }
10630                         $.effects.restore( el, props );
10631                         $.effects.removeWrapper( el );
10632                         done();
10633                 }
10634         });
10635
10636 };
10637
10638 })(jQuery);
10639
10640 (function( $, undefined ) {
10641
10642 $.effects.effect.drop = function( o, done ) {
10643
10644         var el = $( this ),
10645                 props = [ "position", "top", "bottom", "left", "right", "opacity", "height", "width" ],
10646                 mode = $.effects.setMode( el, o.mode || "hide" ),
10647                 show = mode === "show",
10648                 direction = o.direction || "left",
10649                 ref = ( direction === "up" || direction === "down" ) ? "top" : "left",
10650                 motion = ( direction === "up" || direction === "left" ) ? "pos" : "neg",
10651                 animation = {
10652                         opacity: show ? 1 : 0
10653                 },
10654                 distance;
10655
10656         // Adjust
10657         $.effects.save( el, props );
10658         el.show();
10659         $.effects.createWrapper( el );
10660
10661         distance = o.distance || el[ ref === "top" ? "outerHeight": "outerWidth" ]( true ) / 2;
10662
10663         if ( show ) {
10664                 el
10665                         .css( "opacity", 0 )
10666                         .css( ref, motion === "pos" ? -distance : distance );
10667         }
10668
10669         // Animation
10670         animation[ ref ] = ( show ?
10671                 ( motion === "pos" ? "+=" : "-=" ) :
10672                 ( motion === "pos" ? "-=" : "+=" ) ) +
10673                 distance;
10674
10675         // Animate
10676         el.animate( animation, {
10677                 queue: false,
10678                 duration: o.duration,
10679                 easing: o.easing,
10680                 complete: function() {
10681                         if ( mode === "hide" ) {
10682                                 el.hide();
10683                         }
10684                         $.effects.restore( el, props );
10685                         $.effects.removeWrapper( el );
10686                         done();
10687                 }
10688         });
10689 };
10690
10691 })(jQuery);
10692
10693 (function( $, undefined ) {
10694
10695 $.effects.effect.explode = function( o, done ) {
10696
10697         var rows = o.pieces ? Math.round( Math.sqrt( o.pieces ) ) : 3,
10698                 cells = rows,
10699                 el = $( this ),
10700                 mode = $.effects.setMode( el, o.mode || "hide" ),
10701                 show = mode === "show",
10702
10703                 // show and then visibility:hidden the element before calculating offset
10704                 offset = el.show().css( "visibility", "hidden" ).offset(),
10705
10706                 // width and height of a piece
10707                 width = Math.ceil( el.outerWidth() / cells ),
10708                 height = Math.ceil( el.outerHeight() / rows ),
10709                 pieces = [],
10710
10711                 // loop
10712                 i, j, left, top, mx, my;
10713
10714         // children animate complete:
10715         function childComplete() {
10716                 pieces.push( this );
10717                 if ( pieces.length === rows * cells ) {
10718                         animComplete();
10719                 }
10720         }
10721
10722         // clone the element for each row and cell.
10723         for( i = 0; i < rows ; i++ ) { // ===>
10724                 top = offset.top + i * height;
10725                 my = i - ( rows - 1 ) / 2 ;
10726
10727                 for( j = 0; j < cells ; j++ ) { // |||
10728                         left = offset.left + j * width;
10729                         mx = j - ( cells - 1 ) / 2 ;
10730
10731                         // Create a clone of the now hidden main element that will be absolute positioned
10732                         // within a wrapper div off the -left and -top equal to size of our pieces
10733                         el
10734                                 .clone()
10735                                 .appendTo( "body" )
10736                                 .wrap( "<div></div>" )
10737                                 .css({
10738                                         position: "absolute",
10739                                         visibility: "visible",
10740                                         left: -j * width,
10741                                         top: -i * height
10742                                 })
10743
10744                         // select the wrapper - make it overflow: hidden and absolute positioned based on
10745                         // where the original was located +left and +top equal to the size of pieces
10746                                 .parent()
10747                                 .addClass( "ui-effects-explode" )
10748                                 .css({
10749                                         position: "absolute",
10750                                         overflow: "hidden",
10751                                         width: width,
10752                                         height: height,
10753                                         left: left + ( show ? mx * width : 0 ),
10754                                         top: top + ( show ? my * height : 0 ),
10755                                         opacity: show ? 0 : 1
10756                                 }).animate({
10757                                         left: left + ( show ? 0 : mx * width ),
10758                                         top: top + ( show ? 0 : my * height ),
10759                                         opacity: show ? 1 : 0
10760                                 }, o.duration || 500, o.easing, childComplete );
10761                 }
10762         }
10763
10764         function animComplete() {
10765                 el.css({
10766                         visibility: "visible"
10767                 });
10768                 $( pieces ).remove();
10769                 if ( !show ) {
10770                         el.hide();
10771                 }
10772                 done();
10773         }
10774 };
10775
10776 })(jQuery);
10777
10778 (function( $, undefined ) {
10779
10780 $.effects.effect.fade = function( o, done ) {
10781         var el = $( this ),
10782                 mode = $.effects.setMode( el, o.mode || "toggle" );
10783
10784         el.animate({
10785                 opacity: mode
10786         }, {
10787                 queue: false,
10788                 duration: o.duration,
10789                 easing: o.easing,
10790                 complete: done
10791         });
10792 };
10793
10794 })( jQuery );
10795
10796 (function( $, undefined ) {
10797
10798 $.effects.effect.fold = function( o, done ) {
10799
10800         // Create element
10801         var el = $( this ),
10802                 props = [ "position", "top", "bottom", "left", "right", "height", "width" ],
10803                 mode = $.effects.setMode( el, o.mode || "hide" ),
10804                 show = mode === "show",
10805                 hide = mode === "hide",
10806                 size = o.size || 15,
10807                 percent = /([0-9]+)%/.exec( size ),
10808                 horizFirst = !!o.horizFirst,
10809                 widthFirst = show !== horizFirst,
10810                 ref = widthFirst ? [ "width", "height" ] : [ "height", "width" ],
10811                 duration = o.duration / 2,
10812                 wrapper, distance,
10813                 animation1 = {},
10814                 animation2 = {};
10815
10816         $.effects.save( el, props );
10817         el.show();
10818
10819         // Create Wrapper
10820         wrapper = $.effects.createWrapper( el ).css({
10821                 overflow: "hidden"
10822         });
10823         distance = widthFirst ?
10824                 [ wrapper.width(), wrapper.height() ] :
10825                 [ wrapper.height(), wrapper.width() ];
10826
10827         if ( percent ) {
10828                 size = parseInt( percent[ 1 ], 10 ) / 100 * distance[ hide ? 0 : 1 ];
10829         }
10830         if ( show ) {
10831                 wrapper.css( horizFirst ? {
10832                         height: 0,
10833                         width: size
10834                 } : {
10835                         height: size,
10836                         width: 0
10837                 });
10838         }
10839
10840         // Animation
10841         animation1[ ref[ 0 ] ] = show ? distance[ 0 ] : size;
10842         animation2[ ref[ 1 ] ] = show ? distance[ 1 ] : 0;
10843
10844         // Animate
10845         wrapper
10846                 .animate( animation1, duration, o.easing )
10847                 .animate( animation2, duration, o.easing, function() {
10848                         if ( hide ) {
10849                                 el.hide();
10850                         }
10851                         $.effects.restore( el, props );
10852                         $.effects.removeWrapper( el );
10853                         done();
10854                 });
10855
10856 };
10857
10858 })(jQuery);
10859
10860 (function( $, undefined ) {
10861
10862 $.effects.effect.highlight = function( o, done ) {
10863         var elem = $( this ),
10864                 props = [ "backgroundImage", "backgroundColor", "opacity" ],
10865                 mode = $.effects.setMode( elem, o.mode || "show" ),
10866                 animation = {
10867                         backgroundColor: elem.css( "backgroundColor" )
10868                 };
10869
10870         if (mode === "hide") {
10871                 animation.opacity = 0;
10872         }
10873
10874         $.effects.save( elem, props );
10875
10876         elem
10877                 .show()
10878                 .css({
10879                         backgroundImage: "none",
10880                         backgroundColor: o.color || "#ffff99"
10881                 })
10882                 .animate( animation, {
10883                         queue: false,
10884                         duration: o.duration,
10885                         easing: o.easing,
10886                         complete: function() {
10887                                 if ( mode === "hide" ) {
10888                                         elem.hide();
10889                                 }
10890                                 $.effects.restore( elem, props );
10891                                 done();
10892                         }
10893                 });
10894 };
10895
10896 })(jQuery);
10897
10898 (function( $, undefined ) {
10899
10900 $.effects.effect.pulsate = function( o, done ) {
10901         var elem = $( this ),
10902                 mode = $.effects.setMode( elem, o.mode || "show" ),
10903                 show = mode === "show",
10904                 hide = mode === "hide",
10905                 showhide = ( show || mode === "hide" ),
10906
10907                 // showing or hiding leaves of the "last" animation
10908                 anims = ( ( o.times || 5 ) * 2 ) + ( showhide ? 1 : 0 ),
10909                 duration = o.duration / anims,
10910                 animateTo = 0,
10911                 queue = elem.queue(),
10912                 queuelen = queue.length,
10913                 i;
10914
10915         if ( show || !elem.is(":visible")) {
10916                 elem.css( "opacity", 0 ).show();
10917                 animateTo = 1;
10918         }
10919
10920         // anims - 1 opacity "toggles"
10921         for ( i = 1; i < anims; i++ ) {
10922                 elem.animate({
10923                         opacity: animateTo
10924                 }, duration, o.easing );
10925                 animateTo = 1 - animateTo;
10926         }
10927
10928         elem.animate({
10929                 opacity: animateTo
10930         }, duration, o.easing);
10931
10932         elem.queue(function() {
10933                 if ( hide ) {
10934                         elem.hide();
10935                 }
10936                 done();
10937         });
10938
10939         // We just queued up "anims" animations, we need to put them next in the queue
10940         if ( queuelen > 1 ) {
10941                 queue.splice.apply( queue,
10942                         [ 1, 0 ].concat( queue.splice( queuelen, anims + 1 ) ) );
10943         }
10944         elem.dequeue();
10945 };
10946
10947 })(jQuery);
10948
10949 (function( $, undefined ) {
10950
10951 $.effects.effect.puff = function( o, done ) {
10952         var elem = $( this ),
10953                 mode = $.effects.setMode( elem, o.mode || "hide" ),
10954                 hide = mode === "hide",
10955                 percent = parseInt( o.percent, 10 ) || 150,
10956                 factor = percent / 100,
10957                 original = {
10958                         height: elem.height(),
10959                         width: elem.width(),
10960                         outerHeight: elem.outerHeight(),
10961                         outerWidth: elem.outerWidth()
10962                 };
10963
10964         $.extend( o, {
10965                 effect: "scale",
10966                 queue: false,
10967                 fade: true,
10968                 mode: mode,
10969                 complete: done,
10970                 percent: hide ? percent : 100,
10971                 from: hide ?
10972                         original :
10973                         {
10974                                 height: original.height * factor,
10975                                 width: original.width * factor,
10976                                 outerHeight: original.outerHeight * factor,
10977                                 outerWidth: original.outerWidth * factor
10978                         }
10979         });
10980
10981         elem.effect( o );
10982 };
10983
10984 $.effects.effect.scale = function( o, done ) {
10985
10986         // Create element
10987         var el = $( this ),
10988                 options = $.extend( true, {}, o ),
10989                 mode = $.effects.setMode( el, o.mode || "effect" ),
10990                 percent = parseInt( o.percent, 10 ) ||
10991                         ( parseInt( o.percent, 10 ) === 0 ? 0 : ( mode === "hide" ? 0 : 100 ) ),
10992                 direction = o.direction || "both",
10993                 origin = o.origin,
10994                 original = {
10995                         height: el.height(),
10996                         width: el.width(),
10997                         outerHeight: el.outerHeight(),
10998                         outerWidth: el.outerWidth()
10999                 },
11000                 factor = {
11001                         y: direction !== "horizontal" ? (percent / 100) : 1,
11002                         x: direction !== "vertical" ? (percent / 100) : 1
11003                 };
11004
11005         // We are going to pass this effect to the size effect:
11006         options.effect = "size";
11007         options.queue = false;
11008         options.complete = done;
11009
11010         // Set default origin and restore for show/hide
11011         if ( mode !== "effect" ) {
11012                 options.origin = origin || ["middle","center"];
11013                 options.restore = true;
11014         }
11015
11016         options.from = o.from || ( mode === "show" ? {
11017                 height: 0,
11018                 width: 0,
11019                 outerHeight: 0,
11020                 outerWidth: 0
11021         } : original );
11022         options.to = {
11023                 height: original.height * factor.y,
11024                 width: original.width * factor.x,
11025                 outerHeight: original.outerHeight * factor.y,
11026                 outerWidth: original.outerWidth * factor.x
11027         };
11028
11029         // Fade option to support puff
11030         if ( options.fade ) {
11031                 if ( mode === "show" ) {
11032                         options.from.opacity = 0;
11033                         options.to.opacity = 1;
11034                 }
11035                 if ( mode === "hide" ) {
11036                         options.from.opacity = 1;
11037                         options.to.opacity = 0;
11038                 }
11039         }
11040
11041         // Animate
11042         el.effect( options );
11043
11044 };
11045
11046 $.effects.effect.size = function( o, done ) {
11047
11048         // Create element
11049         var original, baseline, factor,
11050                 el = $( this ),
11051                 props0 = [ "position", "top", "bottom", "left", "right", "width", "height", "overflow", "opacity" ],
11052
11053                 // Always restore
11054                 props1 = [ "position", "top", "bottom", "left", "right", "overflow", "opacity" ],
11055
11056                 // Copy for children
11057                 props2 = [ "width", "height", "overflow" ],
11058                 cProps = [ "fontSize" ],
11059                 vProps = [ "borderTopWidth", "borderBottomWidth", "paddingTop", "paddingBottom" ],
11060                 hProps = [ "borderLeftWidth", "borderRightWidth", "paddingLeft", "paddingRight" ],
11061
11062                 // Set options
11063                 mode = $.effects.setMode( el, o.mode || "effect" ),
11064                 restore = o.restore || mode !== "effect",
11065                 scale = o.scale || "both",
11066                 origin = o.origin || [ "middle", "center" ],
11067                 position = el.css( "position" ),
11068                 props = restore ? props0 : props1,
11069                 zero = {
11070                         height: 0,
11071                         width: 0,
11072                         outerHeight: 0,
11073                         outerWidth: 0
11074                 };
11075
11076         if ( mode === "show" ) {
11077                 el.show();
11078         }
11079         original = {
11080                 height: el.height(),
11081                 width: el.width(),
11082                 outerHeight: el.outerHeight(),
11083                 outerWidth: el.outerWidth()
11084         };
11085
11086         if ( o.mode === "toggle" && mode === "show" ) {
11087                 el.from = o.to || zero;
11088                 el.to = o.from || original;
11089         } else {
11090                 el.from = o.from || ( mode === "show" ? zero : original );
11091                 el.to = o.to || ( mode === "hide" ? zero : original );
11092         }
11093
11094         // Set scaling factor
11095         factor = {
11096                 from: {
11097                         y: el.from.height / original.height,
11098                         x: el.from.width / original.width
11099                 },
11100                 to: {
11101                         y: el.to.height / original.height,
11102                         x: el.to.width / original.width
11103                 }
11104         };
11105
11106         // Scale the css box
11107         if ( scale === "box" || scale === "both" ) {
11108
11109                 // Vertical props scaling
11110                 if ( factor.from.y !== factor.to.y ) {
11111                         props = props.concat( vProps );
11112                         el.from = $.effects.setTransition( el, vProps, factor.from.y, el.from );
11113                         el.to = $.effects.setTransition( el, vProps, factor.to.y, el.to );
11114                 }
11115
11116                 // Horizontal props scaling
11117                 if ( factor.from.x !== factor.to.x ) {
11118                         props = props.concat( hProps );
11119                         el.from = $.effects.setTransition( el, hProps, factor.from.x, el.from );
11120                         el.to = $.effects.setTransition( el, hProps, factor.to.x, el.to );
11121                 }
11122         }
11123
11124         // Scale the content
11125         if ( scale === "content" || scale === "both" ) {
11126
11127                 // Vertical props scaling
11128                 if ( factor.from.y !== factor.to.y ) {
11129                         props = props.concat( cProps ).concat( props2 );
11130                         el.from = $.effects.setTransition( el, cProps, factor.from.y, el.from );
11131                         el.to = $.effects.setTransition( el, cProps, factor.to.y, el.to );
11132                 }
11133         }
11134
11135         $.effects.save( el, props );
11136         el.show();
11137         $.effects.createWrapper( el );
11138         el.css( "overflow", "hidden" ).css( el.from );
11139
11140         // Adjust
11141         if (origin) { // Calculate baseline shifts
11142                 baseline = $.effects.getBaseline( origin, original );
11143                 el.from.top = ( original.outerHeight - el.outerHeight() ) * baseline.y;
11144                 el.from.left = ( original.outerWidth - el.outerWidth() ) * baseline.x;
11145                 el.to.top = ( original.outerHeight - el.to.outerHeight ) * baseline.y;
11146                 el.to.left = ( original.outerWidth - el.to.outerWidth ) * baseline.x;
11147         }
11148         el.css( el.from ); // set top & left
11149
11150         // Animate
11151         if ( scale === "content" || scale === "both" ) { // Scale the children
11152
11153                 // Add margins/font-size
11154                 vProps = vProps.concat([ "marginTop", "marginBottom" ]).concat(cProps);
11155                 hProps = hProps.concat([ "marginLeft", "marginRight" ]);
11156                 props2 = props0.concat(vProps).concat(hProps);
11157
11158                 el.find( "*[width]" ).each( function(){
11159                         var child = $( this ),
11160                                 c_original = {
11161                                         height: child.height(),
11162                                         width: child.width(),
11163                                         outerHeight: child.outerHeight(),
11164                                         outerWidth: child.outerWidth()
11165                                 };
11166                         if (restore) {
11167                                 $.effects.save(child, props2);
11168                         }
11169
11170                         child.from = {
11171                                 height: c_original.height * factor.from.y,
11172                                 width: c_original.width * factor.from.x,
11173                                 outerHeight: c_original.outerHeight * factor.from.y,
11174                                 outerWidth: c_original.outerWidth * factor.from.x
11175                         };
11176                         child.to = {
11177                                 height: c_original.height * factor.to.y,
11178                                 width: c_original.width * factor.to.x,
11179                                 outerHeight: c_original.height * factor.to.y,
11180                                 outerWidth: c_original.width * factor.to.x
11181                         };
11182
11183                         // Vertical props scaling
11184                         if ( factor.from.y !== factor.to.y ) {
11185                                 child.from = $.effects.setTransition( child, vProps, factor.from.y, child.from );
11186                                 child.to = $.effects.setTransition( child, vProps, factor.to.y, child.to );
11187                         }
11188
11189                         // Horizontal props scaling
11190                         if ( factor.from.x !== factor.to.x ) {
11191                                 child.from = $.effects.setTransition( child, hProps, factor.from.x, child.from );
11192                                 child.to = $.effects.setTransition( child, hProps, factor.to.x, child.to );
11193                         }
11194
11195                         // Animate children
11196                         child.css( child.from );
11197                         child.animate( child.to, o.duration, o.easing, function() {
11198
11199                                 // Restore children
11200                                 if ( restore ) {
11201                                         $.effects.restore( child, props2 );
11202                                 }
11203                         });
11204                 });
11205         }
11206
11207         // Animate
11208         el.animate( el.to, {
11209                 queue: false,
11210                 duration: o.duration,
11211                 easing: o.easing,
11212                 complete: function() {
11213                         if ( el.to.opacity === 0 ) {
11214                                 el.css( "opacity", el.from.opacity );
11215                         }
11216                         if( mode === "hide" ) {
11217                                 el.hide();
11218                         }
11219                         $.effects.restore( el, props );
11220                         if ( !restore ) {
11221
11222                                 // we need to calculate our new positioning based on the scaling
11223                                 if ( position === "static" ) {
11224                                         el.css({
11225                                                 position: "relative",
11226                                                 top: el.to.top,
11227                                                 left: el.to.left
11228                                         });
11229                                 } else {
11230                                         $.each([ "top", "left" ], function( idx, pos ) {
11231                                                 el.css( pos, function( _, str ) {
11232                                                         var val = parseInt( str, 10 ),
11233                                                                 toRef = idx ? el.to.left : el.to.top;
11234
11235                                                         // if original was "auto", recalculate the new value from wrapper
11236                                                         if ( str === "auto" ) {
11237                                                                 return toRef + "px";
11238                                                         }
11239
11240                                                         return val + toRef + "px";
11241                                                 });
11242                                         });
11243                                 }
11244                         }
11245
11246                         $.effects.removeWrapper( el );
11247                         done();
11248                 }
11249         });
11250
11251 };
11252
11253 })(jQuery);
11254
11255 (function( $, undefined ) {
11256
11257 $.effects.effect.shake = function( o, done ) {
11258
11259         var el = $( this ),
11260                 props = [ "position", "top", "bottom", "left", "right", "height", "width" ],
11261                 mode = $.effects.setMode( el, o.mode || "effect" ),
11262                 direction = o.direction || "left",
11263                 distance = o.distance || 20,
11264                 times = o.times || 3,
11265                 anims = times * 2 + 1,
11266                 speed = Math.round(o.duration/anims),
11267                 ref = (direction === "up" || direction === "down") ? "top" : "left",
11268                 positiveMotion = (direction === "up" || direction === "left"),
11269                 animation = {},
11270                 animation1 = {},
11271                 animation2 = {},
11272                 i,
11273
11274                 // we will need to re-assemble the queue to stack our animations in place
11275                 queue = el.queue(),
11276                 queuelen = queue.length;
11277
11278         $.effects.save( el, props );
11279         el.show();
11280         $.effects.createWrapper( el );
11281
11282         // Animation
11283         animation[ ref ] = ( positiveMotion ? "-=" : "+=" ) + distance;
11284         animation1[ ref ] = ( positiveMotion ? "+=" : "-=" ) + distance * 2;
11285         animation2[ ref ] = ( positiveMotion ? "-=" : "+=" ) + distance * 2;
11286
11287         // Animate
11288         el.animate( animation, speed, o.easing );
11289
11290         // Shakes
11291         for ( i = 1; i < times; i++ ) {
11292                 el.animate( animation1, speed, o.easing ).animate( animation2, speed, o.easing );
11293         }
11294         el
11295                 .animate( animation1, speed, o.easing )
11296                 .animate( animation, speed / 2, o.easing )
11297                 .queue(function() {
11298                         if ( mode === "hide" ) {
11299                                 el.hide();
11300                         }
11301                         $.effects.restore( el, props );
11302                         $.effects.removeWrapper( el );
11303                         done();
11304                 });
11305
11306         // inject all the animations we just queued to be first in line (after "inprogress")
11307         if ( queuelen > 1) {
11308                 queue.splice.apply( queue,
11309                         [ 1, 0 ].concat( queue.splice( queuelen, anims + 1 ) ) );
11310         }
11311         el.dequeue();
11312
11313 };
11314
11315 })(jQuery);
11316
11317 (function( $, undefined ) {
11318
11319 $.effects.effect.slide = function( o, done ) {
11320
11321         // Create element
11322         var el = $( this ),
11323                 props = [ "position", "top", "bottom", "left", "right", "width", "height" ],
11324                 mode = $.effects.setMode( el, o.mode || "show" ),
11325                 show = mode === "show",
11326                 direction = o.direction || "left",
11327                 ref = (direction === "up" || direction === "down") ? "top" : "left",
11328                 positiveMotion = (direction === "up" || direction === "left"),
11329                 distance,
11330                 animation = {};
11331
11332         // Adjust
11333         $.effects.save( el, props );
11334         el.show();
11335         distance = o.distance || el[ ref === "top" ? "outerHeight" : "outerWidth" ]( true );
11336
11337         $.effects.createWrapper( el ).css({
11338                 overflow: "hidden"
11339         });
11340
11341         if ( show ) {
11342                 el.css( ref, positiveMotion ? (isNaN(distance) ? "-" + distance : -distance) : distance );
11343         }
11344
11345         // Animation
11346         animation[ ref ] = ( show ?
11347                 ( positiveMotion ? "+=" : "-=") :
11348                 ( positiveMotion ? "-=" : "+=")) +
11349                 distance;
11350
11351         // Animate
11352         el.animate( animation, {
11353                 queue: false,
11354                 duration: o.duration,
11355                 easing: o.easing,
11356                 complete: function() {
11357                         if ( mode === "hide" ) {
11358                                 el.hide();
11359                         }
11360                         $.effects.restore( el, props );
11361                         $.effects.removeWrapper( el );
11362                         done();
11363                 }
11364         });
11365 };
11366
11367 })(jQuery);
11368
11369 (function( $, undefined ) {
11370
11371 $.effects.effect.transfer = function( o, done ) {
11372         var elem = $( this ),
11373                 target = $( o.to ),
11374                 targetFixed = target.css( "position" ) === "fixed",
11375                 body = $("body"),
11376                 fixTop = targetFixed ? body.scrollTop() : 0,
11377                 fixLeft = targetFixed ? body.scrollLeft() : 0,
11378                 endPosition = target.offset(),
11379                 animation = {
11380                         top: endPosition.top - fixTop ,
11381                         left: endPosition.left - fixLeft ,
11382                         height: target.innerHeight(),
11383                         width: target.innerWidth()
11384                 },
11385                 startPosition = elem.offset(),
11386                 transfer = $( "<div class='ui-effects-transfer'></div>" )
11387                         .appendTo( document.body )
11388                         .addClass( o.className )
11389                         .css({
11390                                 top: startPosition.top - fixTop ,
11391                                 left: startPosition.left - fixLeft ,
11392                                 height: elem.innerHeight(),
11393                                 width: elem.innerWidth(),
11394                                 position: targetFixed ? "fixed" : "absolute"
11395                         })
11396                         .animate( animation, o.duration, o.easing, function() {
11397                                 transfer.remove();
11398                                 done();
11399                         });
11400 };
11401
11402 })(jQuery);
11403
11404 (function( $, undefined ) {
11405
11406 $.widget( "ui.menu", {
11407         version: "1.10.2",
11408         defaultElement: "<ul>",
11409         delay: 300,
11410         options: {
11411                 icons: {
11412                         submenu: "ui-icon-carat-1-e"
11413                 },
11414                 menus: "ul",
11415                 position: {
11416                         my: "left top",
11417                         at: "right top"
11418                 },
11419                 role: "menu",
11420
11421                 // callbacks
11422                 blur: null,
11423                 focus: null,
11424                 select: null
11425         },
11426
11427         _create: function() {
11428                 this.activeMenu = this.element;
11429                 // flag used to prevent firing of the click handler
11430                 // as the event bubbles up through nested menus
11431                 this.mouseHandled = false;
11432                 this.element
11433                         .uniqueId()
11434                         .addClass( "ui-menu ui-widget ui-widget-content ui-corner-all" )
11435                         .toggleClass( "ui-menu-icons", !!this.element.find( ".ui-icon" ).length )
11436                         .attr({
11437                                 role: this.options.role,
11438                                 tabIndex: 0
11439                         })
11440                         // need to catch all clicks on disabled menu
11441                         // not possible through _on
11442                         .bind( "click" + this.eventNamespace, $.proxy(function( event ) {
11443                                 if ( this.options.disabled ) {
11444                                         event.preventDefault();
11445                                 }
11446                         }, this ));
11447
11448                 if ( this.options.disabled ) {
11449                         this.element
11450                                 .addClass( "ui-state-disabled" )
11451                                 .attr( "aria-disabled", "true" );
11452                 }
11453
11454                 this._on({
11455                         // Prevent focus from sticking to links inside menu after clicking
11456                         // them (focus should always stay on UL during navigation).
11457                         "mousedown .ui-menu-item > a": function( event ) {
11458                                 event.preventDefault();
11459                         },
11460                         "click .ui-state-disabled > a": function( event ) {
11461                                 event.preventDefault();
11462                         },
11463                         "click .ui-menu-item:has(a)": function( event ) {
11464                                 var target = $( event.target ).closest( ".ui-menu-item" );
11465                                 if ( !this.mouseHandled && target.not( ".ui-state-disabled" ).length ) {
11466                                         this.mouseHandled = true;
11467
11468                                         this.select( event );
11469                                         // Open submenu on click
11470                                         if ( target.has( ".ui-menu" ).length ) {
11471                                                 this.expand( event );
11472                                         } else if ( !this.element.is( ":focus" ) ) {
11473                                                 // Redirect focus to the menu
11474                                                 this.element.trigger( "focus", [ true ] );
11475
11476                                                 // If the active item is on the top level, let it stay active.
11477                                                 // Otherwise, blur the active item since it is no longer visible.
11478                                                 if ( this.active && this.active.parents( ".ui-menu" ).length === 1 ) {
11479                                                         clearTimeout( this.timer );
11480                                                 }
11481                                         }
11482                                 }
11483                         },
11484                         "mouseenter .ui-menu-item": function( event ) {
11485                                 var target = $( event.currentTarget );
11486                                 // Remove ui-state-active class from siblings of the newly focused menu item
11487                                 // to avoid a jump caused by adjacent elements both having a class with a border
11488                                 target.siblings().children( ".ui-state-active" ).removeClass( "ui-state-active" );
11489                                 this.focus( event, target );
11490                         },
11491                         mouseleave: "collapseAll",
11492                         "mouseleave .ui-menu": "collapseAll",
11493                         focus: function( event, keepActiveItem ) {
11494                                 // If there's already an active item, keep it active
11495                                 // If not, activate the first item
11496                                 var item = this.active || this.element.children( ".ui-menu-item" ).eq( 0 );
11497
11498                                 if ( !keepActiveItem ) {
11499                                         this.focus( event, item );
11500                                 }
11501                         },
11502                         blur: function( event ) {
11503                                 this._delay(function() {
11504                                         if ( !$.contains( this.element[0], this.document[0].activeElement ) ) {
11505                                                 this.collapseAll( event );
11506                                         }
11507                                 });
11508                         },
11509                         keydown: "_keydown"
11510                 });
11511
11512                 this.refresh();
11513
11514                 // Clicks outside of a menu collapse any open menus
11515                 this._on( this.document, {
11516                         click: function( event ) {
11517                                 if ( !$( event.target ).closest( ".ui-menu" ).length ) {
11518                                         this.collapseAll( event );
11519                                 }
11520
11521                                 // Reset the mouseHandled flag
11522                                 this.mouseHandled = false;
11523                         }
11524                 });
11525         },
11526
11527         _destroy: function() {
11528                 // Destroy (sub)menus
11529                 this.element
11530                         .removeAttr( "aria-activedescendant" )
11531                         .find( ".ui-menu" ).addBack()
11532                                 .removeClass( "ui-menu ui-widget ui-widget-content ui-corner-all ui-menu-icons" )
11533                                 .removeAttr( "role" )
11534                                 .removeAttr( "tabIndex" )
11535                                 .removeAttr( "aria-labelledby" )
11536                                 .removeAttr( "aria-expanded" )
11537                                 .removeAttr( "aria-hidden" )
11538                                 .removeAttr( "aria-disabled" )
11539                                 .removeUniqueId()
11540                                 .show();
11541
11542                 // Destroy menu items
11543                 this.element.find( ".ui-menu-item" )
11544                         .removeClass( "ui-menu-item" )
11545                         .removeAttr( "role" )
11546                         .removeAttr( "aria-disabled" )
11547                         .children( "a" )
11548                                 .removeUniqueId()
11549                                 .removeClass( "ui-corner-all ui-state-hover" )
11550                                 .removeAttr( "tabIndex" )
11551                                 .removeAttr( "role" )
11552                                 .removeAttr( "aria-haspopup" )
11553                                 .children().each( function() {
11554                                         var elem = $( this );
11555                                         if ( elem.data( "ui-menu-submenu-carat" ) ) {
11556                                                 elem.remove();
11557                                         }
11558                                 });
11559
11560                 // Destroy menu dividers
11561                 this.element.find( ".ui-menu-divider" ).removeClass( "ui-menu-divider ui-widget-content" );
11562         },
11563
11564         _keydown: function( event ) {
11565                 /*jshint maxcomplexity:20*/
11566                 var match, prev, character, skip, regex,
11567                         preventDefault = true;
11568
11569                 function escape( value ) {
11570                         return value.replace( /[\-\[\]{}()*+?.,\\\^$|#\s]/g, "\\$&" );
11571                 }
11572
11573                 switch ( event.keyCode ) {
11574                 case $.ui.keyCode.PAGE_UP:
11575                         this.previousPage( event );
11576                         break;
11577                 case $.ui.keyCode.PAGE_DOWN:
11578                         this.nextPage( event );
11579                         break;
11580                 case $.ui.keyCode.HOME:
11581                         this._move( "first", "first", event );
11582                         break;
11583                 case $.ui.keyCode.END:
11584                         this._move( "last", "last", event );
11585                         break;
11586                 case $.ui.keyCode.UP:
11587                         this.previous( event );
11588                         break;
11589                 case $.ui.keyCode.DOWN:
11590                         this.next( event );
11591                         break;
11592                 case $.ui.keyCode.LEFT:
11593                         this.collapse( event );
11594                         break;
11595                 case $.ui.keyCode.RIGHT:
11596                         if ( this.active && !this.active.is( ".ui-state-disabled" ) ) {
11597                                 this.expand( event );
11598                         }
11599                         break;
11600                 case $.ui.keyCode.ENTER:
11601                 case $.ui.keyCode.SPACE:
11602                         this._activate( event );
11603                         break;
11604                 case $.ui.keyCode.ESCAPE:
11605                         this.collapse( event );
11606                         break;
11607                 default:
11608                         preventDefault = false;
11609                         prev = this.previousFilter || "";
11610                         character = String.fromCharCode( event.keyCode );
11611                         skip = false;
11612
11613                         clearTimeout( this.filterTimer );
11614
11615                         if ( character === prev ) {
11616                                 skip = true;
11617                         } else {
11618                                 character = prev + character;
11619                         }
11620
11621                         regex = new RegExp( "^" + escape( character ), "i" );
11622                         match = this.activeMenu.children( ".ui-menu-item" ).filter(function() {
11623                                 return regex.test( $( this ).children( "a" ).text() );
11624                         });
11625                         match = skip && match.index( this.active.next() ) !== -1 ?
11626                                 this.active.nextAll( ".ui-menu-item" ) :
11627                                 match;
11628
11629                         // If no matches on the current filter, reset to the last character pressed
11630                         // to move down the menu to the first item that starts with that character
11631                         if ( !match.length ) {
11632                                 character = String.fromCharCode( event.keyCode );
11633                                 regex = new RegExp( "^" + escape( character ), "i" );
11634                                 match = this.activeMenu.children( ".ui-menu-item" ).filter(function() {
11635                                         return regex.test( $( this ).children( "a" ).text() );
11636                                 });
11637                         }
11638
11639                         if ( match.length ) {
11640                                 this.focus( event, match );
11641                                 if ( match.length > 1 ) {
11642                                         this.previousFilter = character;
11643                                         this.filterTimer = this._delay(function() {
11644                                                 delete this.previousFilter;
11645                                         }, 1000 );
11646                                 } else {
11647                                         delete this.previousFilter;
11648                                 }
11649                         } else {
11650                                 delete this.previousFilter;
11651                         }
11652                 }
11653
11654                 if ( preventDefault ) {
11655                         event.preventDefault();
11656                 }
11657         },
11658
11659         _activate: function( event ) {
11660                 if ( !this.active.is( ".ui-state-disabled" ) ) {
11661                         if ( this.active.children( "a[aria-haspopup='true']" ).length ) {
11662                                 this.expand( event );
11663                         } else {
11664                                 this.select( event );
11665                         }
11666                 }
11667         },
11668
11669         refresh: function() {
11670                 var menus,
11671                         icon = this.options.icons.submenu,
11672                         submenus = this.element.find( this.options.menus );
11673
11674                 // Initialize nested menus
11675                 submenus.filter( ":not(.ui-menu)" )
11676                         .addClass( "ui-menu ui-widget ui-widget-content ui-corner-all" )
11677                         .hide()
11678                         .attr({
11679                                 role: this.options.role,
11680                                 "aria-hidden": "true",
11681                                 "aria-expanded": "false"
11682                         })
11683                         .each(function() {
11684                                 var menu = $( this ),
11685                                         item = menu.prev( "a" ),
11686                                         submenuCarat = $( "<span>" )
11687                                                 .addClass( "ui-menu-icon ui-icon " + icon )
11688                                                 .data( "ui-menu-submenu-carat", true );
11689
11690                                 item
11691                                         .attr( "aria-haspopup", "true" )
11692                                         .prepend( submenuCarat );
11693                                 menu.attr( "aria-labelledby", item.attr( "id" ) );
11694                         });
11695
11696                 menus = submenus.add( this.element );
11697
11698                 // Don't refresh list items that are already adapted
11699                 menus.children( ":not(.ui-menu-item):has(a)" )
11700                         .addClass( "ui-menu-item" )
11701                         .attr( "role", "presentation" )
11702                         .children( "a" )
11703                                 .uniqueId()
11704                                 .addClass( "ui-corner-all" )
11705                                 .attr({
11706                                         tabIndex: -1,
11707                                         role: this._itemRole()
11708                                 });
11709
11710                 // Initialize unlinked menu-items containing spaces and/or dashes only as dividers
11711                 menus.children( ":not(.ui-menu-item)" ).each(function() {
11712                         var item = $( this );
11713                         // hyphen, em dash, en dash
11714                         if ( !/[^\-\u2014\u2013\s]/.test( item.text() ) ) {
11715                                 item.addClass( "ui-widget-content ui-menu-divider" );
11716                         }
11717                 });
11718
11719                 // Add aria-disabled attribute to any disabled menu item
11720                 menus.children( ".ui-state-disabled" ).attr( "aria-disabled", "true" );
11721
11722                 // If the active item has been removed, blur the menu
11723                 if ( this.active && !$.contains( this.element[ 0 ], this.active[ 0 ] ) ) {
11724                         this.blur();
11725                 }
11726         },
11727
11728         _itemRole: function() {
11729                 return {
11730                         menu: "menuitem",
11731                         listbox: "option"
11732                 }[ this.options.role ];
11733         },
11734
11735         _setOption: function( key, value ) {
11736                 if ( key === "icons" ) {
11737                         this.element.find( ".ui-menu-icon" )
11738                                 .removeClass( this.options.icons.submenu )
11739                                 .addClass( value.submenu );
11740                 }
11741                 this._super( key, value );
11742         },
11743
11744         focus: function( event, item ) {
11745                 var nested, focused;
11746                 this.blur( event, event && event.type === "focus" );
11747
11748                 this._scrollIntoView( item );
11749
11750                 this.active = item.first();
11751                 focused = this.active.children( "a" ).addClass( "ui-state-focus" );
11752                 // Only update aria-activedescendant if there's a role
11753                 // otherwise we assume focus is managed elsewhere
11754                 if ( this.options.role ) {
11755                         this.element.attr( "aria-activedescendant", focused.attr( "id" ) );
11756                 }
11757
11758                 // Highlight active parent menu item, if any
11759                 this.active
11760                         .parent()
11761                         .closest( ".ui-menu-item" )
11762                         .children( "a:first" )
11763                         .addClass( "ui-state-active" );
11764
11765                 if ( event && event.type === "keydown" ) {
11766                         this._close();
11767                 } else {
11768                         this.timer = this._delay(function() {
11769                                 this._close();
11770                         }, this.delay );
11771                 }
11772
11773                 nested = item.children( ".ui-menu" );
11774                 if ( nested.length && ( /^mouse/.test( event.type ) ) ) {
11775                         this._startOpening(nested);
11776                 }
11777                 this.activeMenu = item.parent();
11778
11779                 this._trigger( "focus", event, { item: item } );
11780         },
11781
11782         _scrollIntoView: function( item ) {
11783                 var borderTop, paddingTop, offset, scroll, elementHeight, itemHeight;
11784                 if ( this._hasScroll() ) {
11785                         borderTop = parseFloat( $.css( this.activeMenu[0], "borderTopWidth" ) ) || 0;
11786                         paddingTop = parseFloat( $.css( this.activeMenu[0], "paddingTop" ) ) || 0;
11787                         offset = item.offset().top - this.activeMenu.offset().top - borderTop - paddingTop;
11788                         scroll = this.activeMenu.scrollTop();
11789                         elementHeight = this.activeMenu.height();
11790                         itemHeight = item.height();
11791
11792                         if ( offset < 0 ) {
11793                                 this.activeMenu.scrollTop( scroll + offset );
11794                         } else if ( offset + itemHeight > elementHeight ) {
11795                                 this.activeMenu.scrollTop( scroll + offset - elementHeight + itemHeight );
11796                         }
11797                 }
11798         },
11799
11800         blur: function( event, fromFocus ) {
11801                 if ( !fromFocus ) {
11802                         clearTimeout( this.timer );
11803                 }
11804
11805                 if ( !this.active ) {
11806                         return;
11807                 }
11808
11809                 this.active.children( "a" ).removeClass( "ui-state-focus" );
11810                 this.active = null;
11811
11812                 this._trigger( "blur", event, { item: this.active } );
11813         },
11814
11815         _startOpening: function( submenu ) {
11816                 clearTimeout( this.timer );
11817
11818                 // Don't open if already open fixes a Firefox bug that caused a .5 pixel
11819                 // shift in the submenu position when mousing over the carat icon
11820                 if ( submenu.attr( "aria-hidden" ) !== "true" ) {
11821                         return;
11822                 }
11823
11824                 this.timer = this._delay(function() {
11825                         this._close();
11826                         this._open( submenu );
11827                 }, this.delay );
11828         },
11829
11830         _open: function( submenu ) {
11831                 var position = $.extend({
11832                         of: this.active
11833                 }, this.options.position );
11834
11835                 clearTimeout( this.timer );
11836                 this.element.find( ".ui-menu" ).not( submenu.parents( ".ui-menu" ) )
11837                         .hide()
11838                         .attr( "aria-hidden", "true" );
11839
11840                 submenu
11841                         .show()
11842                         .removeAttr( "aria-hidden" )
11843                         .attr( "aria-expanded", "true" )
11844                         .position( position );
11845         },
11846
11847         collapseAll: function( event, all ) {
11848                 clearTimeout( this.timer );
11849                 this.timer = this._delay(function() {
11850                         // If we were passed an event, look for the submenu that contains the event
11851                         var currentMenu = all ? this.element :
11852                                 $( event && event.target ).closest( this.element.find( ".ui-menu" ) );
11853
11854                         // If we found no valid submenu ancestor, use the main menu to close all sub menus anyway
11855                         if ( !currentMenu.length ) {
11856                                 currentMenu = this.element;
11857                         }
11858
11859                         this._close( currentMenu );
11860
11861                         this.blur( event );
11862                         this.activeMenu = currentMenu;
11863                 }, this.delay );
11864         },
11865
11866         // With no arguments, closes the currently active menu - if nothing is active
11867         // it closes all menus.  If passed an argument, it will search for menus BELOW
11868         _close: function( startMenu ) {
11869                 if ( !startMenu ) {
11870                         startMenu = this.active ? this.active.parent() : this.element;
11871                 }
11872
11873                 startMenu
11874                         .find( ".ui-menu" )
11875                                 .hide()
11876                                 .attr( "aria-hidden", "true" )
11877                                 .attr( "aria-expanded", "false" )
11878                         .end()
11879                         .find( "a.ui-state-active" )
11880                                 .removeClass( "ui-state-active" );
11881         },
11882
11883         collapse: function( event ) {
11884                 var newItem = this.active &&
11885                         this.active.parent().closest( ".ui-menu-item", this.element );
11886                 if ( newItem && newItem.length ) {
11887                         this._close();
11888                         this.focus( event, newItem );
11889                 }
11890         },
11891
11892         expand: function( event ) {
11893                 var newItem = this.active &&
11894                         this.active
11895                                 .children( ".ui-menu " )
11896                                 .children( ".ui-menu-item" )
11897                                 .first();
11898
11899                 if ( newItem && newItem.length ) {
11900                         this._open( newItem.parent() );
11901
11902                         // Delay so Firefox will not hide activedescendant change in expanding submenu from AT
11903                         this._delay(function() {
11904                                 this.focus( event, newItem );
11905                         });
11906                 }
11907         },
11908
11909         next: function( event ) {
11910                 this._move( "next", "first", event );
11911         },
11912
11913         previous: function( event ) {
11914                 this._move( "prev", "last", event );
11915         },
11916
11917         isFirstItem: function() {
11918                 return this.active && !this.active.prevAll( ".ui-menu-item" ).length;
11919         },
11920
11921         isLastItem: function() {
11922                 return this.active && !this.active.nextAll( ".ui-menu-item" ).length;
11923         },
11924
11925         _move: function( direction, filter, event ) {
11926                 var next;
11927                 if ( this.active ) {
11928                         if ( direction === "first" || direction === "last" ) {
11929                                 next = this.active
11930                                         [ direction === "first" ? "prevAll" : "nextAll" ]( ".ui-menu-item" )
11931                                         .eq( -1 );
11932                         } else {
11933                                 next = this.active
11934                                         [ direction + "All" ]( ".ui-menu-item" )
11935                                         .eq( 0 );
11936                         }
11937                 }
11938                 if ( !next || !next.length || !this.active ) {
11939                         next = this.activeMenu.children( ".ui-menu-item" )[ filter ]();
11940                 }
11941
11942                 this.focus( event, next );
11943         },
11944
11945         nextPage: function( event ) {
11946                 var item, base, height;
11947
11948                 if ( !this.active ) {
11949                         this.next( event );
11950                         return;
11951                 }
11952                 if ( this.isLastItem() ) {
11953                         return;
11954                 }
11955                 if ( this._hasScroll() ) {
11956                         base = this.active.offset().top;
11957                         height = this.element.height();
11958                         this.active.nextAll( ".ui-menu-item" ).each(function() {
11959                                 item = $( this );
11960                                 return item.offset().top - base - height < 0;
11961                         });
11962
11963                         this.focus( event, item );
11964                 } else {
11965                         this.focus( event, this.activeMenu.children( ".ui-menu-item" )
11966                                 [ !this.active ? "first" : "last" ]() );
11967                 }
11968         },
11969
11970         previousPage: function( event ) {
11971                 var item, base, height;
11972                 if ( !this.active ) {
11973                         this.next( event );
11974                         return;
11975                 }
11976                 if ( this.isFirstItem() ) {
11977                         return;
11978                 }
11979                 if ( this._hasScroll() ) {
11980                         base = this.active.offset().top;
11981                         height = this.element.height();
11982                         this.active.prevAll( ".ui-menu-item" ).each(function() {
11983                                 item = $( this );
11984                                 return item.offset().top - base + height > 0;
11985                         });
11986
11987                         this.focus( event, item );
11988                 } else {
11989                         this.focus( event, this.activeMenu.children( ".ui-menu-item" ).first() );
11990                 }
11991         },
11992
11993         _hasScroll: function() {
11994                 return this.element.outerHeight() < this.element.prop( "scrollHeight" );
11995         },
11996
11997         select: function( event ) {
11998                 // TODO: It should never be possible to not have an active item at this
11999                 // point, but the tests don't trigger mouseenter before click.
12000                 this.active = this.active || $( event.target ).closest( ".ui-menu-item" );
12001                 var ui = { item: this.active };
12002                 if ( !this.active.has( ".ui-menu" ).length ) {
12003                         this.collapseAll( event, true );
12004                 }
12005                 this._trigger( "select", event, ui );
12006         }
12007 });
12008
12009 }( jQuery ));
12010
12011 (function( $, undefined ) {
12012
12013 $.ui = $.ui || {};
12014
12015 var cachedScrollbarWidth,
12016         max = Math.max,
12017         abs = Math.abs,
12018         round = Math.round,
12019         rhorizontal = /left|center|right/,
12020         rvertical = /top|center|bottom/,
12021         roffset = /[\+\-]\d+(\.[\d]+)?%?/,
12022         rposition = /^\w+/,
12023         rpercent = /%$/,
12024         _position = $.fn.position;
12025
12026 function getOffsets( offsets, width, height ) {
12027         return [
12028                 parseFloat( offsets[ 0 ] ) * ( rpercent.test( offsets[ 0 ] ) ? width / 100 : 1 ),
12029                 parseFloat( offsets[ 1 ] ) * ( rpercent.test( offsets[ 1 ] ) ? height / 100 : 1 )
12030         ];
12031 }
12032
12033 function parseCss( element, property ) {
12034         return parseInt( $.css( element, property ), 10 ) || 0;
12035 }
12036
12037 function getDimensions( elem ) {
12038         var raw = elem[0];
12039         if ( raw.nodeType === 9 ) {
12040                 return {
12041                         width: elem.width(),
12042                         height: elem.height(),
12043                         offset: { top: 0, left: 0 }
12044                 };
12045         }
12046         if ( $.isWindow( raw ) ) {
12047                 return {
12048                         width: elem.width(),
12049                         height: elem.height(),
12050                         offset: { top: elem.scrollTop(), left: elem.scrollLeft() }
12051                 };
12052         }
12053         if ( raw.preventDefault ) {
12054                 return {
12055                         width: 0,
12056                         height: 0,
12057                         offset: { top: raw.pageY, left: raw.pageX }
12058                 };
12059         }
12060         return {
12061                 width: elem.outerWidth(),
12062                 height: elem.outerHeight(),
12063                 offset: elem.offset()
12064         };
12065 }
12066
12067 $.position = {
12068         scrollbarWidth: function() {
12069                 if ( cachedScrollbarWidth !== undefined ) {
12070                         return cachedScrollbarWidth;
12071                 }
12072                 var w1, w2,
12073                         div = $( "<div style='display:block;width:50px;height:50px;overflow:hidden;'><div style='height:100px;width:auto;'></div></div>" ),
12074                         innerDiv = div.children()[0];
12075
12076                 $( "body" ).append( div );
12077                 w1 = innerDiv.offsetWidth;
12078                 div.css( "overflow", "scroll" );
12079
12080                 w2 = innerDiv.offsetWidth;
12081
12082                 if ( w1 === w2 ) {
12083                         w2 = div[0].clientWidth;
12084                 }
12085
12086                 div.remove();
12087
12088                 return (cachedScrollbarWidth = w1 - w2);
12089         },
12090         getScrollInfo: function( within ) {
12091                 var overflowX = within.isWindow ? "" : within.element.css( "overflow-x" ),
12092                         overflowY = within.isWindow ? "" : within.element.css( "overflow-y" ),
12093                         hasOverflowX = overflowX === "scroll" ||
12094                                 ( overflowX === "auto" && within.width < within.element[0].scrollWidth ),
12095                         hasOverflowY = overflowY === "scroll" ||
12096                                 ( overflowY === "auto" && within.height < within.element[0].scrollHeight );
12097                 return {
12098                         width: hasOverflowY ? $.position.scrollbarWidth() : 0,
12099                         height: hasOverflowX ? $.position.scrollbarWidth() : 0
12100                 };
12101         },
12102         getWithinInfo: function( element ) {
12103                 var withinElement = $( element || window ),
12104                         isWindow = $.isWindow( withinElement[0] );
12105                 return {
12106                         element: withinElement,
12107                         isWindow: isWindow,
12108                         offset: withinElement.offset() || { left: 0, top: 0 },
12109                         scrollLeft: withinElement.scrollLeft(),
12110                         scrollTop: withinElement.scrollTop(),
12111                         width: isWindow ? withinElement.width() : withinElement.outerWidth(),
12112                         height: isWindow ? withinElement.height() : withinElement.outerHeight()
12113                 };
12114         }
12115 };
12116
12117 $.fn.position = function( options ) {
12118         if ( !options || !options.of ) {
12119                 return _position.apply( this, arguments );
12120         }
12121
12122         // make a copy, we don't want to modify arguments
12123         options = $.extend( {}, options );
12124
12125         var atOffset, targetWidth, targetHeight, targetOffset, basePosition, dimensions,
12126                 target = $( options.of ),
12127                 within = $.position.getWithinInfo( options.within ),
12128                 scrollInfo = $.position.getScrollInfo( within ),
12129                 collision = ( options.collision || "flip" ).split( " " ),
12130                 offsets = {};
12131
12132         dimensions = getDimensions( target );
12133         if ( target[0].preventDefault ) {
12134                 // force left top to allow flipping
12135                 options.at = "left top";
12136         }
12137         targetWidth = dimensions.width;
12138         targetHeight = dimensions.height;
12139         targetOffset = dimensions.offset;
12140         // clone to reuse original targetOffset later
12141         basePosition = $.extend( {}, targetOffset );
12142
12143         // force my and at to have valid horizontal and vertical positions
12144         // if a value is missing or invalid, it will be converted to center
12145         $.each( [ "my", "at" ], function() {
12146                 var pos = ( options[ this ] || "" ).split( " " ),
12147                         horizontalOffset,
12148                         verticalOffset;
12149
12150                 if ( pos.length === 1) {
12151                         pos = rhorizontal.test( pos[ 0 ] ) ?
12152                                 pos.concat( [ "center" ] ) :
12153                                 rvertical.test( pos[ 0 ] ) ?
12154                                         [ "center" ].concat( pos ) :
12155                                         [ "center", "center" ];
12156                 }
12157                 pos[ 0 ] = rhorizontal.test( pos[ 0 ] ) ? pos[ 0 ] : "center";
12158                 pos[ 1 ] = rvertical.test( pos[ 1 ] ) ? pos[ 1 ] : "center";
12159
12160                 // calculate offsets
12161                 horizontalOffset = roffset.exec( pos[ 0 ] );
12162                 verticalOffset = roffset.exec( pos[ 1 ] );
12163                 offsets[ this ] = [
12164                         horizontalOffset ? horizontalOffset[ 0 ] : 0,
12165                         verticalOffset ? verticalOffset[ 0 ] : 0
12166                 ];
12167
12168                 // reduce to just the positions without the offsets
12169                 options[ this ] = [
12170                         rposition.exec( pos[ 0 ] )[ 0 ],
12171                         rposition.exec( pos[ 1 ] )[ 0 ]
12172                 ];
12173         });
12174
12175         // normalize collision option
12176         if ( collision.length === 1 ) {
12177                 collision[ 1 ] = collision[ 0 ];
12178         }
12179
12180         if ( options.at[ 0 ] === "right" ) {
12181                 basePosition.left += targetWidth;
12182         } else if ( options.at[ 0 ] === "center" ) {
12183                 basePosition.left += targetWidth / 2;
12184         }
12185
12186         if ( options.at[ 1 ] === "bottom" ) {
12187                 basePosition.top += targetHeight;
12188         } else if ( options.at[ 1 ] === "center" ) {
12189                 basePosition.top += targetHeight / 2;
12190         }
12191
12192         atOffset = getOffsets( offsets.at, targetWidth, targetHeight );
12193         basePosition.left += atOffset[ 0 ];
12194         basePosition.top += atOffset[ 1 ];
12195
12196         return this.each(function() {
12197                 var collisionPosition, using,
12198                         elem = $( this ),
12199                         elemWidth = elem.outerWidth(),
12200                         elemHeight = elem.outerHeight(),
12201                         marginLeft = parseCss( this, "marginLeft" ),
12202                         marginTop = parseCss( this, "marginTop" ),
12203                         collisionWidth = elemWidth + marginLeft + parseCss( this, "marginRight" ) + scrollInfo.width,
12204                         collisionHeight = elemHeight + marginTop + parseCss( this, "marginBottom" ) + scrollInfo.height,
12205                         position = $.extend( {}, basePosition ),
12206                         myOffset = getOffsets( offsets.my, elem.outerWidth(), elem.outerHeight() );
12207
12208                 if ( options.my[ 0 ] === "right" ) {
12209                         position.left -= elemWidth;
12210                 } else if ( options.my[ 0 ] === "center" ) {
12211                         position.left -= elemWidth / 2;
12212                 }
12213
12214                 if ( options.my[ 1 ] === "bottom" ) {
12215                         position.top -= elemHeight;
12216                 } else if ( options.my[ 1 ] === "center" ) {
12217                         position.top -= elemHeight / 2;
12218                 }
12219
12220                 position.left += myOffset[ 0 ];
12221                 position.top += myOffset[ 1 ];
12222
12223                 // if the browser doesn't support fractions, then round for consistent results
12224                 if ( !$.support.offsetFractions ) {
12225                         position.left = round( position.left );
12226                         position.top = round( position.top );
12227                 }
12228
12229                 collisionPosition = {
12230                         marginLeft: marginLeft,
12231                         marginTop: marginTop
12232                 };
12233
12234                 $.each( [ "left", "top" ], function( i, dir ) {
12235                         if ( $.ui.position[ collision[ i ] ] ) {
12236                                 $.ui.position[ collision[ i ] ][ dir ]( position, {
12237                                         targetWidth: targetWidth,
12238                                         targetHeight: targetHeight,
12239                                         elemWidth: elemWidth,
12240                                         elemHeight: elemHeight,
12241                                         collisionPosition: collisionPosition,
12242                                         collisionWidth: collisionWidth,
12243                                         collisionHeight: collisionHeight,
12244                                         offset: [ atOffset[ 0 ] + myOffset[ 0 ], atOffset [ 1 ] + myOffset[ 1 ] ],
12245                                         my: options.my,
12246                                         at: options.at,
12247                                         within: within,
12248                                         elem : elem
12249                                 });
12250                         }
12251                 });
12252
12253                 if ( options.using ) {
12254                         // adds feedback as second argument to using callback, if present
12255                         using = function( props ) {
12256                                 var left = targetOffset.left - position.left,
12257                                         right = left + targetWidth - elemWidth,
12258                                         top = targetOffset.top - position.top,
12259                                         bottom = top + targetHeight - elemHeight,
12260                                         feedback = {
12261                                                 target: {
12262                                                         element: target,
12263                                                         left: targetOffset.left,
12264                                                         top: targetOffset.top,
12265                                                         width: targetWidth,
12266                                                         height: targetHeight
12267                                                 },
12268                                                 element: {
12269                                                         element: elem,
12270                                                         left: position.left,
12271                                                         top: position.top,
12272                                                         width: elemWidth,
12273                                                         height: elemHeight
12274                                                 },
12275                                                 horizontal: right < 0 ? "left" : left > 0 ? "right" : "center",
12276                                                 vertical: bottom < 0 ? "top" : top > 0 ? "bottom" : "middle"
12277                                         };
12278                                 if ( targetWidth < elemWidth && abs( left + right ) < targetWidth ) {
12279                                         feedback.horizontal = "center";
12280                                 }
12281                                 if ( targetHeight < elemHeight && abs( top + bottom ) < targetHeight ) {
12282                                         feedback.vertical = "middle";
12283                                 }
12284                                 if ( max( abs( left ), abs( right ) ) > max( abs( top ), abs( bottom ) ) ) {
12285                                         feedback.important = "horizontal";
12286                                 } else {
12287                                         feedback.important = "vertical";
12288                                 }
12289                                 options.using.call( this, props, feedback );
12290                         };
12291                 }
12292
12293                 elem.offset( $.extend( position, { using: using } ) );
12294         });
12295 };
12296
12297 $.ui.position = {
12298         fit: {
12299                 left: function( position, data ) {
12300                         var within = data.within,
12301                                 withinOffset = within.isWindow ? within.scrollLeft : within.offset.left,
12302                                 outerWidth = within.width,
12303                                 collisionPosLeft = position.left - data.collisionPosition.marginLeft,
12304                                 overLeft = withinOffset - collisionPosLeft,
12305                                 overRight = collisionPosLeft + data.collisionWidth - outerWidth - withinOffset,
12306                                 newOverRight;
12307
12308                         // element is wider than within
12309                         if ( data.collisionWidth > outerWidth ) {
12310                                 // element is initially over the left side of within
12311                                 if ( overLeft > 0 && overRight <= 0 ) {
12312                                         newOverRight = position.left + overLeft + data.collisionWidth - outerWidth - withinOffset;
12313                                         position.left += overLeft - newOverRight;
12314                                 // element is initially over right side of within
12315                                 } else if ( overRight > 0 && overLeft <= 0 ) {
12316                                         position.left = withinOffset;
12317                                 // element is initially over both left and right sides of within
12318                                 } else {
12319                                         if ( overLeft > overRight ) {
12320                                                 position.left = withinOffset + outerWidth - data.collisionWidth;
12321                                         } else {
12322                                                 position.left = withinOffset;
12323                                         }
12324                                 }
12325                         // too far left -> align with left edge
12326                         } else if ( overLeft > 0 ) {
12327                                 position.left += overLeft;
12328                         // too far right -> align with right edge
12329                         } else if ( overRight > 0 ) {
12330                                 position.left -= overRight;
12331                         // adjust based on position and margin
12332                         } else {
12333                                 position.left = max( position.left - collisionPosLeft, position.left );
12334                         }
12335                 },
12336                 top: function( position, data ) {
12337                         var within = data.within,
12338                                 withinOffset = within.isWindow ? within.scrollTop : within.offset.top,
12339                                 outerHeight = data.within.height,
12340                                 collisionPosTop = position.top - data.collisionPosition.marginTop,
12341                                 overTop = withinOffset - collisionPosTop,
12342                                 overBottom = collisionPosTop + data.collisionHeight - outerHeight - withinOffset,
12343                                 newOverBottom;
12344
12345                         // element is taller than within
12346                         if ( data.collisionHeight > outerHeight ) {
12347                                 // element is initially over the top of within
12348                                 if ( overTop > 0 && overBottom <= 0 ) {
12349                                         newOverBottom = position.top + overTop + data.collisionHeight - outerHeight - withinOffset;
12350                                         position.top += overTop - newOverBottom;
12351                                 // element is initially over bottom of within
12352                                 } else if ( overBottom > 0 && overTop <= 0 ) {
12353                                         position.top = withinOffset;
12354                                 // element is initially over both top and bottom of within
12355                                 } else {
12356                                         if ( overTop > overBottom ) {
12357                                                 position.top = withinOffset + outerHeight - data.collisionHeight;
12358                                         } else {
12359                                                 position.top = withinOffset;
12360                                         }
12361                                 }
12362                         // too far up -> align with top
12363                         } else if ( overTop > 0 ) {
12364                                 position.top += overTop;
12365                         // too far down -> align with bottom edge
12366                         } else if ( overBottom > 0 ) {
12367                                 position.top -= overBottom;
12368                         // adjust based on position and margin
12369                         } else {
12370                                 position.top = max( position.top - collisionPosTop, position.top );
12371                         }
12372                 }
12373         },
12374         flip: {
12375                 left: function( position, data ) {
12376                         var within = data.within,
12377                                 withinOffset = within.offset.left + within.scrollLeft,
12378                                 outerWidth = within.width,
12379                                 offsetLeft = within.isWindow ? within.scrollLeft : within.offset.left,
12380                                 collisionPosLeft = position.left - data.collisionPosition.marginLeft,
12381                                 overLeft = collisionPosLeft - offsetLeft,
12382                                 overRight = collisionPosLeft + data.collisionWidth - outerWidth - offsetLeft,
12383                                 myOffset = data.my[ 0 ] === "left" ?
12384                                         -data.elemWidth :
12385                                         data.my[ 0 ] === "right" ?
12386                                                 data.elemWidth :
12387                                                 0,
12388                                 atOffset = data.at[ 0 ] === "left" ?
12389                                         data.targetWidth :
12390                                         data.at[ 0 ] === "right" ?
12391                                                 -data.targetWidth :
12392                                                 0,
12393                                 offset = -2 * data.offset[ 0 ],
12394                                 newOverRight,
12395                                 newOverLeft;
12396
12397                         if ( overLeft < 0 ) {
12398                                 newOverRight = position.left + myOffset + atOffset + offset + data.collisionWidth - outerWidth - withinOffset;
12399                                 if ( newOverRight < 0 || newOverRight < abs( overLeft ) ) {
12400                                         position.left += myOffset + atOffset + offset;
12401                                 }
12402                         }
12403                         else if ( overRight > 0 ) {
12404                                 newOverLeft = position.left - data.collisionPosition.marginLeft + myOffset + atOffset + offset - offsetLeft;
12405                                 if ( newOverLeft > 0 || abs( newOverLeft ) < overRight ) {
12406                                         position.left += myOffset + atOffset + offset;
12407                                 }
12408                         }
12409                 },
12410                 top: function( position, data ) {
12411                         var within = data.within,
12412                                 withinOffset = within.offset.top + within.scrollTop,
12413                                 outerHeight = within.height,
12414                                 offsetTop = within.isWindow ? within.scrollTop : within.offset.top,
12415                                 collisionPosTop = position.top - data.collisionPosition.marginTop,
12416                                 overTop = collisionPosTop - offsetTop,
12417                                 overBottom = collisionPosTop + data.collisionHeight - outerHeight - offsetTop,
12418                                 top = data.my[ 1 ] === "top",
12419                                 myOffset = top ?
12420                                         -data.elemHeight :
12421                                         data.my[ 1 ] === "bottom" ?
12422                                                 data.elemHeight :
12423                                                 0,
12424                                 atOffset = data.at[ 1 ] === "top" ?
12425                                         data.targetHeight :
12426                                         data.at[ 1 ] === "bottom" ?
12427                                                 -data.targetHeight :
12428                                                 0,
12429                                 offset = -2 * data.offset[ 1 ],
12430                                 newOverTop,
12431                                 newOverBottom;
12432                         if ( overTop < 0 ) {
12433                                 newOverBottom = position.top + myOffset + atOffset + offset + data.collisionHeight - outerHeight - withinOffset;
12434                                 if ( ( position.top + myOffset + atOffset + offset) > overTop && ( newOverBottom < 0 || newOverBottom < abs( overTop ) ) ) {
12435                                         position.top += myOffset + atOffset + offset;
12436                                 }
12437                         }
12438                         else if ( overBottom > 0 ) {
12439                                 newOverTop = position.top -  data.collisionPosition.marginTop + myOffset + atOffset + offset - offsetTop;
12440                                 if ( ( position.top + myOffset + atOffset + offset) > overBottom && ( newOverTop > 0 || abs( newOverTop ) < overBottom ) ) {
12441                                         position.top += myOffset + atOffset + offset;
12442                                 }
12443                         }
12444                 }
12445         },
12446         flipfit: {
12447                 left: function() {
12448                         $.ui.position.flip.left.apply( this, arguments );
12449                         $.ui.position.fit.left.apply( this, arguments );
12450                 },
12451                 top: function() {
12452                         $.ui.position.flip.top.apply( this, arguments );
12453                         $.ui.position.fit.top.apply( this, arguments );
12454                 }
12455         }
12456 };
12457
12458 // fraction support test
12459 (function () {
12460         var testElement, testElementParent, testElementStyle, offsetLeft, i,
12461                 body = document.getElementsByTagName( "body" )[ 0 ],
12462                 div = document.createElement( "div" );
12463
12464         //Create a "fake body" for testing based on method used in jQuery.support
12465         testElement = document.createElement( body ? "div" : "body" );
12466         testElementStyle = {
12467                 visibility: "hidden",
12468                 width: 0,
12469                 height: 0,
12470                 border: 0,
12471                 margin: 0,
12472                 background: "none"
12473         };
12474         if ( body ) {
12475                 $.extend( testElementStyle, {
12476                         position: "absolute",
12477                         left: "-1000px",
12478                         top: "-1000px"
12479                 });
12480         }
12481         for ( i in testElementStyle ) {
12482                 testElement.style[ i ] = testElementStyle[ i ];
12483         }
12484         testElement.appendChild( div );
12485         testElementParent = body || document.documentElement;
12486         testElementParent.insertBefore( testElement, testElementParent.firstChild );
12487
12488         div.style.cssText = "position: absolute; left: 10.7432222px;";
12489
12490         offsetLeft = $( div ).offset().left;
12491         $.support.offsetFractions = offsetLeft > 10 && offsetLeft < 11;
12492
12493         testElement.innerHTML = "";
12494         testElementParent.removeChild( testElement );
12495 })();
12496
12497 }( jQuery ) );
12498
12499 (function( $, undefined ) {
12500
12501 $.widget( "ui.progressbar", {
12502         version: "1.10.2",
12503         options: {
12504                 max: 100,
12505                 value: 0,
12506
12507                 change: null,
12508                 complete: null
12509         },
12510
12511         min: 0,
12512
12513         _create: function() {
12514                 // Constrain initial value
12515                 this.oldValue = this.options.value = this._constrainedValue();
12516
12517                 this.element
12518                         .addClass( "ui-progressbar ui-widget ui-widget-content ui-corner-all" )
12519                         .attr({
12520                                 // Only set static values, aria-valuenow and aria-valuemax are
12521                                 // set inside _refreshValue()
12522                                 role: "progressbar",
12523                                 "aria-valuemin": this.min
12524                         });
12525
12526                 this.valueDiv = $( "<div class='ui-progressbar-value ui-widget-header ui-corner-left'></div>" )
12527                         .appendTo( this.element );
12528
12529                 this._refreshValue();
12530         },
12531
12532         _destroy: function() {
12533                 this.element
12534                         .removeClass( "ui-progressbar ui-widget ui-widget-content ui-corner-all" )
12535                         .removeAttr( "role" )
12536                         .removeAttr( "aria-valuemin" )
12537                         .removeAttr( "aria-valuemax" )
12538                         .removeAttr( "aria-valuenow" );
12539
12540                 this.valueDiv.remove();
12541         },
12542
12543         value: function( newValue ) {
12544                 if ( newValue === undefined ) {
12545                         return this.options.value;
12546                 }
12547
12548                 this.options.value = this._constrainedValue( newValue );
12549                 this._refreshValue();
12550         },
12551
12552         _constrainedValue: function( newValue ) {
12553                 if ( newValue === undefined ) {
12554                         newValue = this.options.value;
12555                 }
12556
12557                 this.indeterminate = newValue === false;
12558
12559                 // sanitize value
12560                 if ( typeof newValue !== "number" ) {
12561                         newValue = 0;
12562                 }
12563
12564                 return this.indeterminate ? false :
12565                         Math.min( this.options.max, Math.max( this.min, newValue ) );
12566         },
12567
12568         _setOptions: function( options ) {
12569                 // Ensure "value" option is set after other values (like max)
12570                 var value = options.value;
12571                 delete options.value;
12572
12573                 this._super( options );
12574
12575                 this.options.value = this._constrainedValue( value );
12576                 this._refreshValue();
12577         },
12578
12579         _setOption: function( key, value ) {
12580                 if ( key === "max" ) {
12581                         // Don't allow a max less than min
12582                         value = Math.max( this.min, value );
12583                 }
12584
12585                 this._super( key, value );
12586         },
12587
12588         _percentage: function() {
12589                 return this.indeterminate ? 100 : 100 * ( this.options.value - this.min ) / ( this.options.max - this.min );
12590         },
12591
12592         _refreshValue: function() {
12593                 var value = this.options.value,
12594                         percentage = this._percentage();
12595
12596                 this.valueDiv
12597                         .toggle( this.indeterminate || value > this.min )
12598                         .toggleClass( "ui-corner-right", value === this.options.max )
12599                         .width( percentage.toFixed(0) + "%" );
12600
12601                 this.element.toggleClass( "ui-progressbar-indeterminate", this.indeterminate );
12602
12603                 if ( this.indeterminate ) {
12604                         this.element.removeAttr( "aria-valuenow" );
12605                         if ( !this.overlayDiv ) {
12606                                 this.overlayDiv = $( "<div class='ui-progressbar-overlay'></div>" ).appendTo( this.valueDiv );
12607                         }
12608                 } else {
12609                         this.element.attr({
12610                                 "aria-valuemax": this.options.max,
12611                                 "aria-valuenow": value
12612                         });
12613                         if ( this.overlayDiv ) {
12614                                 this.overlayDiv.remove();
12615                                 this.overlayDiv = null;
12616                         }
12617                 }
12618
12619                 if ( this.oldValue !== value ) {
12620                         this.oldValue = value;
12621                         this._trigger( "change" );
12622                 }
12623                 if ( value === this.options.max ) {
12624                         this._trigger( "complete" );
12625                 }
12626         }
12627 });
12628
12629 })( jQuery );
12630
12631 (function( $, undefined ) {
12632
12633 // number of pages in a slider
12634 // (how many times can you page up/down to go through the whole range)
12635 var numPages = 5;
12636
12637 $.widget( "ui.slider", $.ui.mouse, {
12638         version: "1.10.2",
12639         widgetEventPrefix: "slide",
12640
12641         options: {
12642                 animate: false,
12643                 distance: 0,
12644                 max: 100,
12645                 min: 0,
12646                 orientation: "horizontal",
12647                 range: false,
12648                 step: 1,
12649                 value: 0,
12650                 values: null,
12651
12652                 // callbacks
12653                 change: null,
12654                 slide: null,
12655                 start: null,
12656                 stop: null
12657         },
12658
12659         _create: function() {
12660                 this._keySliding = false;
12661                 this._mouseSliding = false;
12662                 this._animateOff = true;
12663                 this._handleIndex = null;
12664                 this._detectOrientation();
12665                 this._mouseInit();
12666
12667                 this.element
12668                         .addClass( "ui-slider" +
12669                                 " ui-slider-" + this.orientation +
12670                                 " ui-widget" +
12671                                 " ui-widget-content" +
12672                                 " ui-corner-all");
12673
12674                 this._refresh();
12675                 this._setOption( "disabled", this.options.disabled );
12676
12677                 this._animateOff = false;
12678         },
12679
12680         _refresh: function() {
12681                 this._createRange();
12682                 this._createHandles();
12683                 this._setupEvents();
12684                 this._refreshValue();
12685         },
12686
12687         _createHandles: function() {
12688                 var i, handleCount,
12689                         options = this.options,
12690                         existingHandles = this.element.find( ".ui-slider-handle" ).addClass( "ui-state-default ui-corner-all" ),
12691                         handle = "<a class='ui-slider-handle ui-state-default ui-corner-all' href='#'></a>",
12692                         handles = [];
12693
12694                 handleCount = ( options.values && options.values.length ) || 1;
12695
12696                 if ( existingHandles.length > handleCount ) {
12697                         existingHandles.slice( handleCount ).remove();
12698                         existingHandles = existingHandles.slice( 0, handleCount );
12699                 }
12700
12701                 for ( i = existingHandles.length; i < handleCount; i++ ) {
12702                         handles.push( handle );
12703                 }
12704
12705                 this.handles = existingHandles.add( $( handles.join( "" ) ).appendTo( this.element ) );
12706
12707                 this.handle = this.handles.eq( 0 );
12708
12709                 this.handles.each(function( i ) {
12710                         $( this ).data( "ui-slider-handle-index", i );
12711                 });
12712         },
12713
12714         _createRange: function() {
12715                 var options = this.options,
12716                         classes = "";
12717
12718                 if ( options.range ) {
12719                         if ( options.range === true ) {
12720                                 if ( !options.values ) {
12721                                         options.values = [ this._valueMin(), this._valueMin() ];
12722                                 } else if ( options.values.length && options.values.length !== 2 ) {
12723                                         options.values = [ options.values[0], options.values[0] ];
12724                                 } else if ( $.isArray( options.values ) ) {
12725                                         options.values = options.values.slice(0);
12726                                 }
12727                         }
12728
12729                         if ( !this.range || !this.range.length ) {
12730                                 this.range = $( "<div></div>" )
12731                                         .appendTo( this.element );
12732
12733                                 classes = "ui-slider-range" +
12734                                 // note: this isn't the most fittingly semantic framework class for this element,
12735                                 // but worked best visually with a variety of themes
12736                                 " ui-widget-header ui-corner-all";
12737                         } else {
12738                                 this.range.removeClass( "ui-slider-range-min ui-slider-range-max" )
12739                                         // Handle range switching from true to min/max
12740                                         .css({
12741                                                 "left": "",
12742                                                 "bottom": ""
12743                                         });
12744                         }
12745
12746                         this.range.addClass( classes +
12747                                 ( ( options.range === "min" || options.range === "max" ) ? " ui-slider-range-" + options.range : "" ) );
12748                 } else {
12749                         this.range = $([]);
12750                 }
12751         },
12752
12753         _setupEvents: function() {
12754                 var elements = this.handles.add( this.range ).filter( "a" );
12755                 this._off( elements );
12756                 this._on( elements, this._handleEvents );
12757                 this._hoverable( elements );
12758                 this._focusable( elements );
12759         },
12760
12761         _destroy: function() {
12762                 this.handles.remove();
12763                 this.range.remove();
12764
12765                 this.element
12766                         .removeClass( "ui-slider" +
12767                                 " ui-slider-horizontal" +
12768                                 " ui-slider-vertical" +
12769                                 " ui-widget" +
12770                                 " ui-widget-content" +
12771                                 " ui-corner-all" );
12772
12773                 this._mouseDestroy();
12774         },
12775
12776         _mouseCapture: function( event ) {
12777                 var position, normValue, distance, closestHandle, index, allowed, offset, mouseOverHandle,
12778                         that = this,
12779                         o = this.options;
12780
12781                 if ( o.disabled ) {
12782                         return false;
12783                 }
12784
12785                 this.elementSize = {
12786                         width: this.element.outerWidth(),
12787                         height: this.element.outerHeight()
12788                 };
12789                 this.elementOffset = this.element.offset();
12790
12791                 position = { x: event.pageX, y: event.pageY };
12792                 normValue = this._normValueFromMouse( position );
12793                 distance = this._valueMax() - this._valueMin() + 1;
12794                 this.handles.each(function( i ) {
12795                         var thisDistance = Math.abs( normValue - that.values(i) );
12796                         if (( distance > thisDistance ) ||
12797                                 ( distance === thisDistance &&
12798                                         (i === that._lastChangedValue || that.values(i) === o.min ))) {
12799                                 distance = thisDistance;
12800                                 closestHandle = $( this );
12801                                 index = i;
12802                         }
12803                 });
12804
12805                 allowed = this._start( event, index );
12806                 if ( allowed === false ) {
12807                         return false;
12808                 }
12809                 this._mouseSliding = true;
12810
12811                 this._handleIndex = index;
12812
12813                 closestHandle
12814                         .addClass( "ui-state-active" )
12815                         .focus();
12816
12817                 offset = closestHandle.offset();
12818                 mouseOverHandle = !$( event.target ).parents().addBack().is( ".ui-slider-handle" );
12819                 this._clickOffset = mouseOverHandle ? { left: 0, top: 0 } : {
12820                         left: event.pageX - offset.left - ( closestHandle.width() / 2 ),
12821                         top: event.pageY - offset.top -
12822                                 ( closestHandle.height() / 2 ) -
12823                                 ( parseInt( closestHandle.css("borderTopWidth"), 10 ) || 0 ) -
12824                                 ( parseInt( closestHandle.css("borderBottomWidth"), 10 ) || 0) +
12825                                 ( parseInt( closestHandle.css("marginTop"), 10 ) || 0)
12826                 };
12827
12828                 if ( !this.handles.hasClass( "ui-state-hover" ) ) {
12829                         this._slide( event, index, normValue );
12830                 }
12831                 this._animateOff = true;
12832                 return true;
12833         },
12834
12835         _mouseStart: function() {
12836                 return true;
12837         },
12838
12839         _mouseDrag: function( event ) {
12840                 var position = { x: event.pageX, y: event.pageY },
12841                         normValue = this._normValueFromMouse( position );
12842
12843                 this._slide( event, this._handleIndex, normValue );
12844
12845                 return false;
12846         },
12847
12848         _mouseStop: function( event ) {
12849                 this.handles.removeClass( "ui-state-active" );
12850                 this._mouseSliding = false;
12851
12852                 this._stop( event, this._handleIndex );
12853                 this._change( event, this._handleIndex );
12854
12855                 this._handleIndex = null;
12856                 this._clickOffset = null;
12857                 this._animateOff = false;
12858
12859                 return false;
12860         },
12861
12862         _detectOrientation: function() {
12863                 this.orientation = ( this.options.orientation === "vertical" ) ? "vertical" : "horizontal";
12864         },
12865
12866         _normValueFromMouse: function( position ) {
12867                 var pixelTotal,
12868                         pixelMouse,
12869                         percentMouse,
12870                         valueTotal,
12871                         valueMouse;
12872
12873                 if ( this.orientation === "horizontal" ) {
12874                         pixelTotal = this.elementSize.width;
12875                         pixelMouse = position.x - this.elementOffset.left - ( this._clickOffset ? this._clickOffset.left : 0 );
12876                 } else {
12877                         pixelTotal = this.elementSize.height;
12878                         pixelMouse = position.y - this.elementOffset.top - ( this._clickOffset ? this._clickOffset.top : 0 );
12879                 }
12880
12881                 percentMouse = ( pixelMouse / pixelTotal );
12882                 if ( percentMouse > 1 ) {
12883                         percentMouse = 1;
12884                 }
12885                 if ( percentMouse < 0 ) {
12886                         percentMouse = 0;
12887                 }
12888                 if ( this.orientation === "vertical" ) {
12889                         percentMouse = 1 - percentMouse;
12890                 }
12891
12892                 valueTotal = this._valueMax() - this._valueMin();
12893                 valueMouse = this._valueMin() + percentMouse * valueTotal;
12894
12895                 return this._trimAlignValue( valueMouse );
12896         },
12897
12898         _start: function( event, index ) {
12899                 var uiHash = {
12900                         handle: this.handles[ index ],
12901                         value: this.value()
12902                 };
12903                 if ( this.options.values && this.options.values.length ) {
12904                         uiHash.value = this.values( index );
12905                         uiHash.values = this.values();
12906                 }
12907                 return this._trigger( "start", event, uiHash );
12908         },
12909
12910         _slide: function( event, index, newVal ) {
12911                 var otherVal,
12912                         newValues,
12913                         allowed;
12914
12915                 if ( this.options.values && this.options.values.length ) {
12916                         otherVal = this.values( index ? 0 : 1 );
12917
12918                         if ( ( this.options.values.length === 2 && this.options.range === true ) &&
12919                                         ( ( index === 0 && newVal > otherVal) || ( index === 1 && newVal < otherVal ) )
12920                                 ) {
12921                                 newVal = otherVal;
12922                         }
12923
12924                         if ( newVal !== this.values( index ) ) {
12925                                 newValues = this.values();
12926                                 newValues[ index ] = newVal;
12927                                 // A slide can be canceled by returning false from the slide callback
12928                                 allowed = this._trigger( "slide", event, {
12929                                         handle: this.handles[ index ],
12930                                         value: newVal,
12931                                         values: newValues
12932                                 } );
12933                                 otherVal = this.values( index ? 0 : 1 );
12934                                 if ( allowed !== false ) {
12935                                         this.values( index, newVal, true );
12936                                 }
12937                         }
12938                 } else {
12939                         if ( newVal !== this.value() ) {
12940                                 // A slide can be canceled by returning false from the slide callback
12941                                 allowed = this._trigger( "slide", event, {
12942                                         handle: this.handles[ index ],
12943                                         value: newVal
12944                                 } );
12945                                 if ( allowed !== false ) {
12946                                         this.value( newVal );
12947                                 }
12948                         }
12949                 }
12950         },
12951
12952         _stop: function( event, index ) {
12953                 var uiHash = {
12954                         handle: this.handles[ index ],
12955                         value: this.value()
12956                 };
12957                 if ( this.options.values && this.options.values.length ) {
12958                         uiHash.value = this.values( index );
12959                         uiHash.values = this.values();
12960                 }
12961
12962                 this._trigger( "stop", event, uiHash );
12963         },
12964
12965         _change: function( event, index ) {
12966                 if ( !this._keySliding && !this._mouseSliding ) {
12967                         var uiHash = {
12968                                 handle: this.handles[ index ],
12969                                 value: this.value()
12970                         };
12971                         if ( this.options.values && this.options.values.length ) {
12972                                 uiHash.value = this.values( index );
12973                                 uiHash.values = this.values();
12974                         }
12975
12976                         //store the last changed value index for reference when handles overlap
12977                         this._lastChangedValue = index;
12978
12979                         this._trigger( "change", event, uiHash );
12980                 }
12981         },
12982
12983         value: function( newValue ) {
12984                 if ( arguments.length ) {
12985                         this.options.value = this._trimAlignValue( newValue );
12986                         this._refreshValue();
12987                         this._change( null, 0 );
12988                         return;
12989                 }
12990
12991                 return this._value();
12992         },
12993
12994         values: function( index, newValue ) {
12995                 var vals,
12996                         newValues,
12997                         i;
12998
12999                 if ( arguments.length > 1 ) {
13000                         this.options.values[ index ] = this._trimAlignValue( newValue );
13001                         this._refreshValue();
13002                         this._change( null, index );
13003                         return;
13004                 }
13005
13006                 if ( arguments.length ) {
13007                         if ( $.isArray( arguments[ 0 ] ) ) {
13008                                 vals = this.options.values;
13009                                 newValues = arguments[ 0 ];
13010                                 for ( i = 0; i < vals.length; i += 1 ) {
13011                                         vals[ i ] = this._trimAlignValue( newValues[ i ] );
13012                                         this._change( null, i );
13013                                 }
13014                                 this._refreshValue();
13015                         } else {
13016                                 if ( this.options.values && this.options.values.length ) {
13017                                         return this._values( index );
13018                                 } else {
13019                                         return this.value();
13020                                 }
13021                         }
13022                 } else {
13023                         return this._values();
13024                 }
13025         },
13026
13027         _setOption: function( key, value ) {
13028                 var i,
13029                         valsLength = 0;
13030
13031                 if ( key === "range" && this.options.range === true ) {
13032                         if ( value === "min" ) {
13033                                 this.options.value = this._values( 0 );
13034                                 this.options.values = null;
13035                         } else if ( value === "max" ) {
13036                                 this.options.value = this._values( this.options.values.length-1 );
13037                                 this.options.values = null;
13038                         }
13039                 }
13040
13041                 if ( $.isArray( this.options.values ) ) {
13042                         valsLength = this.options.values.length;
13043                 }
13044
13045                 $.Widget.prototype._setOption.apply( this, arguments );
13046
13047                 switch ( key ) {
13048                         case "orientation":
13049                                 this._detectOrientation();
13050                                 this.element
13051                                         .removeClass( "ui-slider-horizontal ui-slider-vertical" )
13052                                         .addClass( "ui-slider-" + this.orientation );
13053                                 this._refreshValue();
13054                                 break;
13055                         case "value":
13056                                 this._animateOff = true;
13057                                 this._refreshValue();
13058                                 this._change( null, 0 );
13059                                 this._animateOff = false;
13060                                 break;
13061                         case "values":
13062                                 this._animateOff = true;
13063                                 this._refreshValue();
13064                                 for ( i = 0; i < valsLength; i += 1 ) {
13065                                         this._change( null, i );
13066                                 }
13067                                 this._animateOff = false;
13068                                 break;
13069                         case "min":
13070                         case "max":
13071                                 this._animateOff = true;
13072                                 this._refreshValue();
13073                                 this._animateOff = false;
13074                                 break;
13075                         case "range":
13076                                 this._animateOff = true;
13077                                 this._refresh();
13078                                 this._animateOff = false;
13079                                 break;
13080                 }
13081         },
13082
13083         //internal value getter
13084         // _value() returns value trimmed by min and max, aligned by step
13085         _value: function() {
13086                 var val = this.options.value;
13087                 val = this._trimAlignValue( val );
13088
13089                 return val;
13090         },
13091
13092         //internal values getter
13093         // _values() returns array of values trimmed by min and max, aligned by step
13094         // _values( index ) returns single value trimmed by min and max, aligned by step
13095         _values: function( index ) {
13096                 var val,
13097                         vals,
13098                         i;
13099
13100                 if ( arguments.length ) {
13101                         val = this.options.values[ index ];
13102                         val = this._trimAlignValue( val );
13103
13104                         return val;
13105                 } else if ( this.options.values && this.options.values.length ) {
13106                         // .slice() creates a copy of the array
13107                         // this copy gets trimmed by min and max and then returned
13108                         vals = this.options.values.slice();
13109                         for ( i = 0; i < vals.length; i+= 1) {
13110                                 vals[ i ] = this._trimAlignValue( vals[ i ] );
13111                         }
13112
13113                         return vals;
13114                 } else {
13115                         return [];
13116                 }
13117         },
13118
13119         // returns the step-aligned value that val is closest to, between (inclusive) min and max
13120         _trimAlignValue: function( val ) {
13121                 if ( val <= this._valueMin() ) {
13122                         return this._valueMin();
13123                 }
13124                 if ( val >= this._valueMax() ) {
13125                         return this._valueMax();
13126                 }
13127                 var step = ( this.options.step > 0 ) ? this.options.step : 1,
13128                         valModStep = (val - this._valueMin()) % step,
13129                         alignValue = val - valModStep;
13130
13131                 if ( Math.abs(valModStep) * 2 >= step ) {
13132                         alignValue += ( valModStep > 0 ) ? step : ( -step );
13133                 }
13134
13135                 // Since JavaScript has problems with large floats, round
13136                 // the final value to 5 digits after the decimal point (see #4124)
13137                 return parseFloat( alignValue.toFixed(5) );
13138         },
13139
13140         _valueMin: function() {
13141                 return this.options.min;
13142         },
13143
13144         _valueMax: function() {
13145                 return this.options.max;
13146         },
13147
13148         _refreshValue: function() {
13149                 var lastValPercent, valPercent, value, valueMin, valueMax,
13150                         oRange = this.options.range,
13151                         o = this.options,
13152                         that = this,
13153                         animate = ( !this._animateOff ) ? o.animate : false,
13154                         _set = {};
13155
13156                 if ( this.options.values && this.options.values.length ) {
13157                         this.handles.each(function( i ) {
13158                                 valPercent = ( that.values(i) - that._valueMin() ) / ( that._valueMax() - that._valueMin() ) * 100;
13159                                 _set[ that.orientation === "horizontal" ? "left" : "bottom" ] = valPercent + "%";
13160                                 $( this ).stop( 1, 1 )[ animate ? "animate" : "css" ]( _set, o.animate );
13161                                 if ( that.options.range === true ) {
13162                                         if ( that.orientation === "horizontal" ) {
13163                                                 if ( i === 0 ) {
13164                                                         that.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { left: valPercent + "%" }, o.animate );
13165                                                 }
13166                                                 if ( i === 1 ) {
13167                                                         that.range[ animate ? "animate" : "css" ]( { width: ( valPercent - lastValPercent ) + "%" }, { queue: false, duration: o.animate } );
13168                                                 }
13169                                         } else {
13170                                                 if ( i === 0 ) {
13171                                                         that.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { bottom: ( valPercent ) + "%" }, o.animate );
13172                                                 }
13173                                                 if ( i === 1 ) {
13174                                                         that.range[ animate ? "animate" : "css" ]( { height: ( valPercent - lastValPercent ) + "%" }, { queue: false, duration: o.animate } );
13175                                                 }
13176                                         }
13177                                 }
13178                                 lastValPercent = valPercent;
13179                         });
13180                 } else {
13181                         value = this.value();
13182                         valueMin = this._valueMin();
13183                         valueMax = this._valueMax();
13184                         valPercent = ( valueMax !== valueMin ) ?
13185                                         ( value - valueMin ) / ( valueMax - valueMin ) * 100 :
13186                                         0;
13187                         _set[ this.orientation === "horizontal" ? "left" : "bottom" ] = valPercent + "%";
13188                         this.handle.stop( 1, 1 )[ animate ? "animate" : "css" ]( _set, o.animate );
13189
13190                         if ( oRange === "min" && this.orientation === "horizontal" ) {
13191                                 this.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { width: valPercent + "%" }, o.animate );
13192                         }
13193                         if ( oRange === "max" && this.orientation === "horizontal" ) {
13194                                 this.range[ animate ? "animate" : "css" ]( { width: ( 100 - valPercent ) + "%" }, { queue: false, duration: o.animate } );
13195                         }
13196                         if ( oRange === "min" && this.orientation === "vertical" ) {
13197                                 this.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { height: valPercent + "%" }, o.animate );
13198                         }
13199                         if ( oRange === "max" && this.orientation === "vertical" ) {
13200                                 this.range[ animate ? "animate" : "css" ]( { height: ( 100 - valPercent ) + "%" }, { queue: false, duration: o.animate } );
13201                         }
13202                 }
13203         },
13204
13205         _handleEvents: {
13206                 keydown: function( event ) {
13207                         /*jshint maxcomplexity:25*/
13208                         var allowed, curVal, newVal, step,
13209                                 index = $( event.target ).data( "ui-slider-handle-index" );
13210
13211                         switch ( event.keyCode ) {
13212                                 case $.ui.keyCode.HOME:
13213                                 case $.ui.keyCode.END:
13214                                 case $.ui.keyCode.PAGE_UP:
13215                                 case $.ui.keyCode.PAGE_DOWN:
13216                                 case $.ui.keyCode.UP:
13217                                 case $.ui.keyCode.RIGHT:
13218                                 case $.ui.keyCode.DOWN:
13219                                 case $.ui.keyCode.LEFT:
13220                                         event.preventDefault();
13221                                         if ( !this._keySliding ) {
13222                                                 this._keySliding = true;
13223                                                 $( event.target ).addClass( "ui-state-active" );
13224                                                 allowed = this._start( event, index );
13225                                                 if ( allowed === false ) {
13226                                                         return;
13227                                                 }
13228                                         }
13229                                         break;
13230                         }
13231
13232                         step = this.options.step;
13233                         if ( this.options.values && this.options.values.length ) {
13234                                 curVal = newVal = this.values( index );
13235                         } else {
13236                                 curVal = newVal = this.value();
13237                         }
13238
13239                         switch ( event.keyCode ) {
13240                                 case $.ui.keyCode.HOME:
13241                                         newVal = this._valueMin();
13242                                         break;
13243                                 case $.ui.keyCode.END:
13244                                         newVal = this._valueMax();
13245                                         break;
13246                                 case $.ui.keyCode.PAGE_UP:
13247                                         newVal = this._trimAlignValue( curVal + ( (this._valueMax() - this._valueMin()) / numPages ) );
13248                                         break;
13249                                 case $.ui.keyCode.PAGE_DOWN:
13250                                         newVal = this._trimAlignValue( curVal - ( (this._valueMax() - this._valueMin()) / numPages ) );
13251                                         break;
13252                                 case $.ui.keyCode.UP:
13253                                 case $.ui.keyCode.RIGHT:
13254                                         if ( curVal === this._valueMax() ) {
13255                                                 return;
13256                                         }
13257                                         newVal = this._trimAlignValue( curVal + step );
13258                                         break;
13259                                 case $.ui.keyCode.DOWN:
13260                                 case $.ui.keyCode.LEFT:
13261                                         if ( curVal === this._valueMin() ) {
13262                                                 return;
13263                                         }
13264                                         newVal = this._trimAlignValue( curVal - step );
13265                                         break;
13266                         }
13267
13268                         this._slide( event, index, newVal );
13269                 },
13270                 click: function( event ) {
13271                         event.preventDefault();
13272                 },
13273                 keyup: function( event ) {
13274                         var index = $( event.target ).data( "ui-slider-handle-index" );
13275
13276                         if ( this._keySliding ) {
13277                                 this._keySliding = false;
13278                                 this._stop( event, index );
13279                                 this._change( event, index );
13280                                 $( event.target ).removeClass( "ui-state-active" );
13281                         }
13282                 }
13283         }
13284
13285 });
13286
13287 }(jQuery));
13288
13289 (function( $ ) {
13290
13291 function modifier( fn ) {
13292         return function() {
13293                 var previous = this.element.val();
13294                 fn.apply( this, arguments );
13295                 this._refresh();
13296                 if ( previous !== this.element.val() ) {
13297                         this._trigger( "change" );
13298                 }
13299         };
13300 }
13301
13302 $.widget( "ui.spinner", {
13303         version: "1.10.2",
13304         defaultElement: "<input>",
13305         widgetEventPrefix: "spin",
13306         options: {
13307                 culture: null,
13308                 icons: {
13309                         down: "ui-icon-triangle-1-s",
13310                         up: "ui-icon-triangle-1-n"
13311                 },
13312                 incremental: true,
13313                 max: null,
13314                 min: null,
13315                 numberFormat: null,
13316                 page: 10,
13317                 step: 1,
13318
13319                 change: null,
13320                 spin: null,
13321                 start: null,
13322                 stop: null
13323         },
13324
13325         _create: function() {
13326                 // handle string values that need to be parsed
13327                 this._setOption( "max", this.options.max );
13328                 this._setOption( "min", this.options.min );
13329                 this._setOption( "step", this.options.step );
13330
13331                 // format the value, but don't constrain
13332                 this._value( this.element.val(), true );
13333
13334                 this._draw();
13335                 this._on( this._events );
13336                 this._refresh();
13337
13338                 // turning off autocomplete prevents the browser from remembering the
13339                 // value when navigating through history, so we re-enable autocomplete
13340                 // if the page is unloaded before the widget is destroyed. #7790
13341                 this._on( this.window, {
13342                         beforeunload: function() {
13343                                 this.element.removeAttr( "autocomplete" );
13344                         }
13345                 });
13346         },
13347
13348         _getCreateOptions: function() {
13349                 var options = {},
13350                         element = this.element;
13351
13352                 $.each( [ "min", "max", "step" ], function( i, option ) {
13353                         var value = element.attr( option );
13354                         if ( value !== undefined && value.length ) {
13355                                 options[ option ] = value;
13356                         }
13357                 });
13358
13359                 return options;
13360         },
13361
13362         _events: {
13363                 keydown: function( event ) {
13364                         if ( this._start( event ) && this._keydown( event ) ) {
13365                                 event.preventDefault();
13366                         }
13367                 },
13368                 keyup: "_stop",
13369                 focus: function() {
13370                         this.previous = this.element.val();
13371                 },
13372                 blur: function( event ) {
13373                         if ( this.cancelBlur ) {
13374                                 delete this.cancelBlur;
13375                                 return;
13376                         }
13377
13378                         this._stop();
13379                         this._refresh();
13380                         if ( this.previous !== this.element.val() ) {
13381                                 this._trigger( "change", event );
13382                         }
13383                 },
13384                 mousewheel: function( event, delta ) {
13385                         if ( !delta ) {
13386                                 return;
13387                         }
13388                         if ( !this.spinning && !this._start( event ) ) {
13389                                 return false;
13390                         }
13391
13392                         this._spin( (delta > 0 ? 1 : -1) * this.options.step, event );
13393                         clearTimeout( this.mousewheelTimer );
13394                         this.mousewheelTimer = this._delay(function() {
13395                                 if ( this.spinning ) {
13396                                         this._stop( event );
13397                                 }
13398                         }, 100 );
13399                         event.preventDefault();
13400                 },
13401                 "mousedown .ui-spinner-button": function( event ) {
13402                         var previous;
13403
13404                         // We never want the buttons to have focus; whenever the user is
13405                         // interacting with the spinner, the focus should be on the input.
13406                         // If the input is focused then this.previous is properly set from
13407                         // when the input first received focus. If the input is not focused
13408                         // then we need to set this.previous based on the value before spinning.
13409                         previous = this.element[0] === this.document[0].activeElement ?
13410                                 this.previous : this.element.val();
13411                         function checkFocus() {
13412                                 var isActive = this.element[0] === this.document[0].activeElement;
13413                                 if ( !isActive ) {
13414                                         this.element.focus();
13415                                         this.previous = previous;
13416                                         // support: IE
13417                                         // IE sets focus asynchronously, so we need to check if focus
13418                                         // moved off of the input because the user clicked on the button.
13419                                         this._delay(function() {
13420                                                 this.previous = previous;
13421                                         });
13422                                 }
13423                         }
13424
13425                         // ensure focus is on (or stays on) the text field
13426                         event.preventDefault();
13427                         checkFocus.call( this );
13428
13429                         // support: IE
13430                         // IE doesn't prevent moving focus even with event.preventDefault()
13431                         // so we set a flag to know when we should ignore the blur event
13432                         // and check (again) if focus moved off of the input.
13433                         this.cancelBlur = true;
13434                         this._delay(function() {
13435                                 delete this.cancelBlur;
13436                                 checkFocus.call( this );
13437                         });
13438
13439                         if ( this._start( event ) === false ) {
13440                                 return;
13441                         }
13442
13443                         this._repeat( null, $( event.currentTarget ).hasClass( "ui-spinner-up" ) ? 1 : -1, event );
13444                 },
13445                 "mouseup .ui-spinner-button": "_stop",
13446                 "mouseenter .ui-spinner-button": function( event ) {
13447                         // button will add ui-state-active if mouse was down while mouseleave and kept down
13448                         if ( !$( event.currentTarget ).hasClass( "ui-state-active" ) ) {
13449                                 return;
13450                         }
13451
13452                         if ( this._start( event ) === false ) {
13453                                 return false;
13454                         }
13455                         this._repeat( null, $( event.currentTarget ).hasClass( "ui-spinner-up" ) ? 1 : -1, event );
13456                 },
13457                 // TODO: do we really want to consider this a stop?
13458                 // shouldn't we just stop the repeater and wait until mouseup before
13459                 // we trigger the stop event?
13460                 "mouseleave .ui-spinner-button": "_stop"
13461         },
13462
13463         _draw: function() {
13464                 var uiSpinner = this.uiSpinner = this.element
13465                         .addClass( "ui-spinner-input" )
13466                         .attr( "autocomplete", "off" )
13467                         .wrap( this._uiSpinnerHtml() )
13468                         .parent()
13469                                 // add buttons
13470                                 .append( this._buttonHtml() );
13471
13472                 this.element.attr( "role", "spinbutton" );
13473
13474                 // button bindings
13475                 this.buttons = uiSpinner.find( ".ui-spinner-button" )
13476                         .attr( "tabIndex", -1 )
13477                         .button()
13478                         .removeClass( "ui-corner-all" );
13479
13480                 // IE 6 doesn't understand height: 50% for the buttons
13481                 // unless the wrapper has an explicit height
13482                 if ( this.buttons.height() > Math.ceil( uiSpinner.height() * 0.5 ) &&
13483                                 uiSpinner.height() > 0 ) {
13484                         uiSpinner.height( uiSpinner.height() );
13485                 }
13486
13487                 // disable spinner if element was already disabled
13488                 if ( this.options.disabled ) {
13489                         this.disable();
13490                 }
13491         },
13492
13493         _keydown: function( event ) {
13494                 var options = this.options,
13495                         keyCode = $.ui.keyCode;
13496
13497                 switch ( event.keyCode ) {
13498                 case keyCode.UP:
13499                         this._repeat( null, 1, event );
13500                         return true;
13501                 case keyCode.DOWN:
13502                         this._repeat( null, -1, event );
13503                         return true;
13504                 case keyCode.PAGE_UP:
13505                         this._repeat( null, options.page, event );
13506                         return true;
13507                 case keyCode.PAGE_DOWN:
13508                         this._repeat( null, -options.page, event );
13509                         return true;
13510                 }
13511
13512                 return false;
13513         },
13514
13515         _uiSpinnerHtml: function() {
13516                 return "<span class='ui-spinner ui-widget ui-widget-content ui-corner-all'></span>";
13517         },
13518
13519         _buttonHtml: function() {
13520                 return "" +
13521                         "<a class='ui-spinner-button ui-spinner-up ui-corner-tr'>" +
13522                                 "<span class='ui-icon " + this.options.icons.up + "'>&#9650;</span>" +
13523                         "</a>" +
13524                         "<a class='ui-spinner-button ui-spinner-down ui-corner-br'>" +
13525                                 "<span class='ui-icon " + this.options.icons.down + "'>&#9660;</span>" +
13526                         "</a>";
13527         },
13528
13529         _start: function( event ) {
13530                 if ( !this.spinning && this._trigger( "start", event ) === false ) {
13531                         return false;
13532                 }
13533
13534                 if ( !this.counter ) {
13535                         this.counter = 1;
13536                 }
13537                 this.spinning = true;
13538                 return true;
13539         },
13540
13541         _repeat: function( i, steps, event ) {
13542                 i = i || 500;
13543
13544                 clearTimeout( this.timer );
13545                 this.timer = this._delay(function() {
13546                         this._repeat( 40, steps, event );
13547                 }, i );
13548
13549                 this._spin( steps * this.options.step, event );
13550         },
13551
13552         _spin: function( step, event ) {
13553                 var value = this.value() || 0;
13554
13555                 if ( !this.counter ) {
13556                         this.counter = 1;
13557                 }
13558
13559                 value = this._adjustValue( value + step * this._increment( this.counter ) );
13560
13561                 if ( !this.spinning || this._trigger( "spin", event, { value: value } ) !== false) {
13562                         this._value( value );
13563                         this.counter++;
13564                 }
13565         },
13566
13567         _increment: function( i ) {
13568                 var incremental = this.options.incremental;
13569
13570                 if ( incremental ) {
13571                         return $.isFunction( incremental ) ?
13572                                 incremental( i ) :
13573                                 Math.floor( i*i*i/50000 - i*i/500 + 17*i/200 + 1 );
13574                 }
13575
13576                 return 1;
13577         },
13578
13579         _precision: function() {
13580                 var precision = this._precisionOf( this.options.step );
13581                 if ( this.options.min !== null ) {
13582                         precision = Math.max( precision, this._precisionOf( this.options.min ) );
13583                 }
13584                 return precision;
13585         },
13586
13587         _precisionOf: function( num ) {
13588                 var str = num.toString(),
13589                         decimal = str.indexOf( "." );
13590                 return decimal === -1 ? 0 : str.length - decimal - 1;
13591         },
13592
13593         _adjustValue: function( value ) {
13594                 var base, aboveMin,
13595                         options = this.options;
13596
13597                 // make sure we're at a valid step
13598                 // - find out where we are relative to the base (min or 0)
13599                 base = options.min !== null ? options.min : 0;
13600                 aboveMin = value - base;
13601                 // - round to the nearest step
13602                 aboveMin = Math.round(aboveMin / options.step) * options.step;
13603                 // - rounding is based on 0, so adjust back to our base
13604                 value = base + aboveMin;
13605
13606                 // fix precision from bad JS floating point math
13607                 value = parseFloat( value.toFixed( this._precision() ) );
13608
13609                 // clamp the value
13610                 if ( options.max !== null && value > options.max) {
13611                         return options.max;
13612                 }
13613                 if ( options.min !== null && value < options.min ) {
13614                         return options.min;
13615                 }
13616
13617                 return value;
13618         },
13619
13620         _stop: function( event ) {
13621                 if ( !this.spinning ) {
13622                         return;
13623                 }
13624
13625                 clearTimeout( this.timer );
13626                 clearTimeout( this.mousewheelTimer );
13627                 this.counter = 0;
13628                 this.spinning = false;
13629                 this._trigger( "stop", event );
13630         },
13631
13632         _setOption: function( key, value ) {
13633                 if ( key === "culture" || key === "numberFormat" ) {
13634                         var prevValue = this._parse( this.element.val() );
13635                         this.options[ key ] = value;
13636                         this.element.val( this._format( prevValue ) );
13637                         return;
13638                 }
13639
13640                 if ( key === "max" || key === "min" || key === "step" ) {
13641                         if ( typeof value === "string" ) {
13642                                 value = this._parse( value );
13643                         }
13644                 }
13645                 if ( key === "icons" ) {
13646                         this.buttons.first().find( ".ui-icon" )
13647                                 .removeClass( this.options.icons.up )
13648                                 .addClass( value.up );
13649                         this.buttons.last().find( ".ui-icon" )
13650                                 .removeClass( this.options.icons.down )
13651                                 .addClass( value.down );
13652                 }
13653
13654                 this._super( key, value );
13655
13656                 if ( key === "disabled" ) {
13657                         if ( value ) {
13658                                 this.element.prop( "disabled", true );
13659                                 this.buttons.button( "disable" );
13660                         } else {
13661                                 this.element.prop( "disabled", false );
13662                                 this.buttons.button( "enable" );
13663                         }
13664                 }
13665         },
13666
13667         _setOptions: modifier(function( options ) {
13668                 this._super( options );
13669                 this._value( this.element.val() );
13670         }),
13671
13672         _parse: function( val ) {
13673                 if ( typeof val === "string" && val !== "" ) {
13674                         val = window.Globalize && this.options.numberFormat ?
13675                                 Globalize.parseFloat( val, 10, this.options.culture ) : +val;
13676                 }
13677                 return val === "" || isNaN( val ) ? null : val;
13678         },
13679
13680         _format: function( value ) {
13681                 if ( value === "" ) {
13682                         return "";
13683                 }
13684                 return window.Globalize && this.options.numberFormat ?
13685                         Globalize.format( value, this.options.numberFormat, this.options.culture ) :
13686                         value;
13687         },
13688
13689         _refresh: function() {
13690                 this.element.attr({
13691                         "aria-valuemin": this.options.min,
13692                         "aria-valuemax": this.options.max,
13693                         // TODO: what should we do with values that can't be parsed?
13694                         "aria-valuenow": this._parse( this.element.val() )
13695                 });
13696         },
13697
13698         // update the value without triggering change
13699         _value: function( value, allowAny ) {
13700                 var parsed;
13701                 if ( value !== "" ) {
13702                         parsed = this._parse( value );
13703                         if ( parsed !== null ) {
13704                                 if ( !allowAny ) {
13705                                         parsed = this._adjustValue( parsed );
13706                                 }
13707                                 value = this._format( parsed );
13708                         }
13709                 }
13710                 this.element.val( value );
13711                 this._refresh();
13712         },
13713
13714         _destroy: function() {
13715                 this.element
13716                         .removeClass( "ui-spinner-input" )
13717                         .prop( "disabled", false )
13718                         .removeAttr( "autocomplete" )
13719                         .removeAttr( "role" )
13720                         .removeAttr( "aria-valuemin" )
13721                         .removeAttr( "aria-valuemax" )
13722                         .removeAttr( "aria-valuenow" );
13723                 this.uiSpinner.replaceWith( this.element );
13724         },
13725
13726         stepUp: modifier(function( steps ) {
13727                 this._stepUp( steps );
13728         }),
13729         _stepUp: function( steps ) {
13730                 if ( this._start() ) {
13731                         this._spin( (steps || 1) * this.options.step );
13732                         this._stop();
13733                 }
13734         },
13735
13736         stepDown: modifier(function( steps ) {
13737                 this._stepDown( steps );
13738         }),
13739         _stepDown: function( steps ) {
13740                 if ( this._start() ) {
13741                         this._spin( (steps || 1) * -this.options.step );
13742                         this._stop();
13743                 }
13744         },
13745
13746         pageUp: modifier(function( pages ) {
13747                 this._stepUp( (pages || 1) * this.options.page );
13748         }),
13749
13750         pageDown: modifier(function( pages ) {
13751                 this._stepDown( (pages || 1) * this.options.page );
13752         }),
13753
13754         value: function( newVal ) {
13755                 if ( !arguments.length ) {
13756                         return this._parse( this.element.val() );
13757                 }
13758                 modifier( this._value ).call( this, newVal );
13759         },
13760
13761         widget: function() {
13762                 return this.uiSpinner;
13763         }
13764 });
13765
13766 }( jQuery ) );
13767
13768 (function( $, undefined ) {
13769
13770 var tabId = 0,
13771         rhash = /#.*$/;
13772
13773 function getNextTabId() {
13774         return ++tabId;
13775 }
13776
13777 function isLocal( anchor ) {
13778         return anchor.hash.length > 1 &&
13779                 decodeURIComponent( anchor.href.replace( rhash, "" ) ) ===
13780                         decodeURIComponent( location.href.replace( rhash, "" ) );
13781 }
13782
13783 $.widget( "ui.tabs", {
13784         version: "1.10.2",
13785         delay: 300,
13786         options: {
13787                 active: null,
13788                 collapsible: false,
13789                 event: "click",
13790                 heightStyle: "content",
13791                 hide: null,
13792                 show: null,
13793
13794                 // callbacks
13795                 activate: null,
13796                 beforeActivate: null,
13797                 beforeLoad: null,
13798                 load: null
13799         },
13800
13801         _create: function() {
13802                 var that = this,
13803                         options = this.options;
13804
13805                 this.running = false;
13806
13807                 this.element
13808                         .addClass( "ui-tabs ui-widget ui-widget-content ui-corner-all" )
13809                         .toggleClass( "ui-tabs-collapsible", options.collapsible )
13810                         // Prevent users from focusing disabled tabs via click
13811                         .delegate( ".ui-tabs-nav > li", "mousedown" + this.eventNamespace, function( event ) {
13812                                 if ( $( this ).is( ".ui-state-disabled" ) ) {
13813                                         event.preventDefault();
13814                                 }
13815                         })
13816                         // support: IE <9
13817                         // Preventing the default action in mousedown doesn't prevent IE
13818                         // from focusing the element, so if the anchor gets focused, blur.
13819                         // We don't have to worry about focusing the previously focused
13820                         // element since clicking on a non-focusable element should focus
13821                         // the body anyway.
13822                         .delegate( ".ui-tabs-anchor", "focus" + this.eventNamespace, function() {
13823                                 if ( $( this ).closest( "li" ).is( ".ui-state-disabled" ) ) {
13824                                         this.blur();
13825                                 }
13826                         });
13827
13828                 this._processTabs();
13829                 options.active = this._initialActive();
13830
13831                 // Take disabling tabs via class attribute from HTML
13832                 // into account and update option properly.
13833                 if ( $.isArray( options.disabled ) ) {
13834                         options.disabled = $.unique( options.disabled.concat(
13835                                 $.map( this.tabs.filter( ".ui-state-disabled" ), function( li ) {
13836                                         return that.tabs.index( li );
13837                                 })
13838                         ) ).sort();
13839                 }
13840
13841                 // check for length avoids error when initializing empty list
13842                 if ( this.options.active !== false && this.anchors.length ) {
13843                         this.active = this._findActive( options.active );
13844                 } else {
13845                         this.active = $();
13846                 }
13847
13848                 this._refresh();
13849
13850                 if ( this.active.length ) {
13851                         this.load( options.active );
13852                 }
13853         },
13854
13855         _initialActive: function() {
13856                 var active = this.options.active,
13857                         collapsible = this.options.collapsible,
13858                         locationHash = location.hash.substring( 1 );
13859
13860                 if ( active === null ) {
13861                         // check the fragment identifier in the URL
13862                         if ( locationHash ) {
13863                                 this.tabs.each(function( i, tab ) {
13864                                         if ( $( tab ).attr( "aria-controls" ) === locationHash ) {
13865                                                 active = i;
13866                                                 return false;
13867                                         }
13868                                 });
13869                         }
13870
13871                         // check for a tab marked active via a class
13872                         if ( active === null ) {
13873                                 active = this.tabs.index( this.tabs.filter( ".ui-tabs-active" ) );
13874                         }
13875
13876                         // no active tab, set to false
13877                         if ( active === null || active === -1 ) {
13878                                 active = this.tabs.length ? 0 : false;
13879                         }
13880                 }
13881
13882                 // handle numbers: negative, out of range
13883                 if ( active !== false ) {
13884                         active = this.tabs.index( this.tabs.eq( active ) );
13885                         if ( active === -1 ) {
13886                                 active = collapsible ? false : 0;
13887                         }
13888                 }
13889
13890                 // don't allow collapsible: false and active: false
13891                 if ( !collapsible && active === false && this.anchors.length ) {
13892                         active = 0;
13893                 }
13894
13895                 return active;
13896         },
13897
13898         _getCreateEventData: function() {
13899                 return {
13900                         tab: this.active,
13901                         panel: !this.active.length ? $() : this._getPanelForTab( this.active )
13902                 };
13903         },
13904
13905         _tabKeydown: function( event ) {
13906                 /*jshint maxcomplexity:15*/
13907                 var focusedTab = $( this.document[0].activeElement ).closest( "li" ),
13908                         selectedIndex = this.tabs.index( focusedTab ),
13909                         goingForward = true;
13910
13911                 if ( this._handlePageNav( event ) ) {
13912                         return;
13913                 }
13914
13915                 switch ( event.keyCode ) {
13916                         case $.ui.keyCode.RIGHT:
13917                         case $.ui.keyCode.DOWN:
13918                                 selectedIndex++;
13919                                 break;
13920                         case $.ui.keyCode.UP:
13921                         case $.ui.keyCode.LEFT:
13922                                 goingForward = false;
13923                                 selectedIndex--;
13924                                 break;
13925                         case $.ui.keyCode.END:
13926                                 selectedIndex = this.anchors.length - 1;
13927                                 break;
13928                         case $.ui.keyCode.HOME:
13929                                 selectedIndex = 0;
13930                                 break;
13931                         case $.ui.keyCode.SPACE:
13932                                 // Activate only, no collapsing
13933                                 event.preventDefault();
13934                                 clearTimeout( this.activating );
13935                                 this._activate( selectedIndex );
13936                                 return;
13937                         case $.ui.keyCode.ENTER:
13938                                 // Toggle (cancel delayed activation, allow collapsing)
13939                                 event.preventDefault();
13940                                 clearTimeout( this.activating );
13941                                 // Determine if we should collapse or activate
13942                                 this._activate( selectedIndex === this.options.active ? false : selectedIndex );
13943                                 return;
13944                         default:
13945                                 return;
13946                 }
13947
13948                 // Focus the appropriate tab, based on which key was pressed
13949                 event.preventDefault();
13950                 clearTimeout( this.activating );
13951                 selectedIndex = this._focusNextTab( selectedIndex, goingForward );
13952
13953                 // Navigating with control key will prevent automatic activation
13954                 if ( !event.ctrlKey ) {
13955                         // Update aria-selected immediately so that AT think the tab is already selected.
13956                         // Otherwise AT may confuse the user by stating that they need to activate the tab,
13957                         // but the tab will already be activated by the time the announcement finishes.
13958                         focusedTab.attr( "aria-selected", "false" );
13959                         this.tabs.eq( selectedIndex ).attr( "aria-selected", "true" );
13960
13961                         this.activating = this._delay(function() {
13962                                 this.option( "active", selectedIndex );
13963                         }, this.delay );
13964                 }
13965         },
13966
13967         _panelKeydown: function( event ) {
13968                 if ( this._handlePageNav( event ) ) {
13969                         return;
13970                 }
13971
13972                 // Ctrl+up moves focus to the current tab
13973                 if ( event.ctrlKey && event.keyCode === $.ui.keyCode.UP ) {
13974                         event.preventDefault();
13975                         this.active.focus();
13976                 }
13977         },
13978
13979         // Alt+page up/down moves focus to the previous/next tab (and activates)
13980         _handlePageNav: function( event ) {
13981                 if ( event.altKey && event.keyCode === $.ui.keyCode.PAGE_UP ) {
13982                         this._activate( this._focusNextTab( this.options.active - 1, false ) );
13983                         return true;
13984                 }
13985                 if ( event.altKey && event.keyCode === $.ui.keyCode.PAGE_DOWN ) {
13986                         this._activate( this._focusNextTab( this.options.active + 1, true ) );
13987                         return true;
13988                 }
13989         },
13990
13991         _findNextTab: function( index, goingForward ) {
13992                 var lastTabIndex = this.tabs.length - 1;
13993
13994                 function constrain() {
13995                         if ( index > lastTabIndex ) {
13996                                 index = 0;
13997                         }
13998                         if ( index < 0 ) {
13999                                 index = lastTabIndex;
14000                         }
14001                         return index;
14002                 }
14003
14004                 while ( $.inArray( constrain(), this.options.disabled ) !== -1 ) {
14005                         index = goingForward ? index + 1 : index - 1;
14006                 }
14007
14008                 return index;
14009         },
14010
14011         _focusNextTab: function( index, goingForward ) {
14012                 index = this._findNextTab( index, goingForward );
14013                 this.tabs.eq( index ).focus();
14014                 return index;
14015         },
14016
14017         _setOption: function( key, value ) {
14018                 if ( key === "active" ) {
14019                         // _activate() will handle invalid values and update this.options
14020                         this._activate( value );
14021                         return;
14022                 }
14023
14024                 if ( key === "disabled" ) {
14025                         // don't use the widget factory's disabled handling
14026                         this._setupDisabled( value );
14027                         return;
14028                 }
14029
14030                 this._super( key, value);
14031
14032                 if ( key === "collapsible" ) {
14033                         this.element.toggleClass( "ui-tabs-collapsible", value );
14034                         // Setting collapsible: false while collapsed; open first panel
14035                         if ( !value && this.options.active === false ) {
14036                                 this._activate( 0 );
14037                         }
14038                 }
14039
14040                 if ( key === "event" ) {
14041                         this._setupEvents( value );
14042                 }
14043
14044                 if ( key === "heightStyle" ) {
14045                         this._setupHeightStyle( value );
14046                 }
14047         },
14048
14049         _tabId: function( tab ) {
14050                 return tab.attr( "aria-controls" ) || "ui-tabs-" + getNextTabId();
14051         },
14052
14053         _sanitizeSelector: function( hash ) {
14054                 return hash ? hash.replace( /[!"$%&'()*+,.\/:;<=>?@\[\]\^`{|}~]/g, "\\$&" ) : "";
14055         },
14056
14057         refresh: function() {
14058                 var options = this.options,
14059                         lis = this.tablist.children( ":has(a[href])" );
14060
14061                 // get disabled tabs from class attribute from HTML
14062                 // this will get converted to a boolean if needed in _refresh()
14063                 options.disabled = $.map( lis.filter( ".ui-state-disabled" ), function( tab ) {
14064                         return lis.index( tab );
14065                 });
14066
14067                 this._processTabs();
14068
14069                 // was collapsed or no tabs
14070                 if ( options.active === false || !this.anchors.length ) {
14071                         options.active = false;
14072                         this.active = $();
14073                 // was active, but active tab is gone
14074                 } else if ( this.active.length && !$.contains( this.tablist[ 0 ], this.active[ 0 ] ) ) {
14075                         // all remaining tabs are disabled
14076                         if ( this.tabs.length === options.disabled.length ) {
14077                                 options.active = false;
14078                                 this.active = $();
14079                         // activate previous tab
14080                         } else {
14081                                 this._activate( this._findNextTab( Math.max( 0, options.active - 1 ), false ) );
14082                         }
14083                 // was active, active tab still exists
14084                 } else {
14085                         // make sure active index is correct
14086                         options.active = this.tabs.index( this.active );
14087                 }
14088
14089                 this._refresh();
14090         },
14091
14092         _refresh: function() {
14093                 this._setupDisabled( this.options.disabled );
14094                 this._setupEvents( this.options.event );
14095                 this._setupHeightStyle( this.options.heightStyle );
14096
14097                 this.tabs.not( this.active ).attr({
14098                         "aria-selected": "false",
14099                         tabIndex: -1
14100                 });
14101                 this.panels.not( this._getPanelForTab( this.active ) )
14102                         .hide()
14103                         .attr({
14104                                 "aria-expanded": "false",
14105                                 "aria-hidden": "true"
14106                         });
14107
14108                 // Make sure one tab is in the tab order
14109                 if ( !this.active.length ) {
14110                         this.tabs.eq( 0 ).attr( "tabIndex", 0 );
14111                 } else {
14112                         this.active
14113                                 .addClass( "ui-tabs-active ui-state-active" )
14114                                 .attr({
14115                                         "aria-selected": "true",
14116                                         tabIndex: 0
14117                                 });
14118                         this._getPanelForTab( this.active )
14119                                 .show()
14120                                 .attr({
14121                                         "aria-expanded": "true",
14122                                         "aria-hidden": "false"
14123                                 });
14124                 }
14125         },
14126
14127         _processTabs: function() {
14128                 var that = this;
14129
14130                 this.tablist = this._getList()
14131                         .addClass( "ui-tabs-nav ui-helper-reset ui-helper-clearfix ui-widget-header ui-corner-all" )
14132                         .attr( "role", "tablist" );
14133
14134                 this.tabs = this.tablist.find( "> li:has(a[href])" )
14135                         .addClass( "ui-state-default ui-corner-top" )
14136                         .attr({
14137                                 role: "tab",
14138                                 tabIndex: -1
14139                         });
14140
14141                 this.anchors = this.tabs.map(function() {
14142                                 return $( "a", this )[ 0 ];
14143                         })
14144                         .addClass( "ui-tabs-anchor" )
14145                         .attr({
14146                                 role: "presentation",
14147                                 tabIndex: -1
14148                         });
14149
14150                 this.panels = $();
14151
14152                 this.anchors.each(function( i, anchor ) {
14153                         var selector, panel, panelId,
14154                                 anchorId = $( anchor ).uniqueId().attr( "id" ),
14155                                 tab = $( anchor ).closest( "li" ),
14156                                 originalAriaControls = tab.attr( "aria-controls" );
14157
14158                         // inline tab
14159                         if ( isLocal( anchor ) ) {
14160                                 selector = anchor.hash;
14161                                 panel = that.element.find( that._sanitizeSelector( selector ) );
14162                         // remote tab
14163                         } else {
14164                                 panelId = that._tabId( tab );
14165                                 selector = "#" + panelId;
14166                                 panel = that.element.find( selector );
14167                                 if ( !panel.length ) {
14168                                         panel = that._createPanel( panelId );
14169                                         panel.insertAfter( that.panels[ i - 1 ] || that.tablist );
14170                                 }
14171                                 panel.attr( "aria-live", "polite" );
14172                         }
14173
14174                         if ( panel.length) {
14175                                 that.panels = that.panels.add( panel );
14176                         }
14177                         if ( originalAriaControls ) {
14178                                 tab.data( "ui-tabs-aria-controls", originalAriaControls );
14179                         }
14180                         tab.attr({
14181                                 "aria-controls": selector.substring( 1 ),
14182                                 "aria-labelledby": anchorId
14183                         });
14184                         panel.attr( "aria-labelledby", anchorId );
14185                 });
14186
14187                 this.panels
14188                         .addClass( "ui-tabs-panel ui-widget-content ui-corner-bottom" )
14189                         .attr( "role", "tabpanel" );
14190         },
14191
14192         // allow overriding how to find the list for rare usage scenarios (#7715)
14193         _getList: function() {
14194                 return this.element.find( "ol,ul" ).eq( 0 );
14195         },
14196
14197         _createPanel: function( id ) {
14198                 return $( "<div>" )
14199                         .attr( "id", id )
14200                         .addClass( "ui-tabs-panel ui-widget-content ui-corner-bottom" )
14201                         .data( "ui-tabs-destroy", true );
14202         },
14203
14204         _setupDisabled: function( disabled ) {
14205                 if ( $.isArray( disabled ) ) {
14206                         if ( !disabled.length ) {
14207                                 disabled = false;
14208                         } else if ( disabled.length === this.anchors.length ) {
14209                                 disabled = true;
14210                         }
14211                 }
14212
14213                 // disable tabs
14214                 for ( var i = 0, li; ( li = this.tabs[ i ] ); i++ ) {
14215                         if ( disabled === true || $.inArray( i, disabled ) !== -1 ) {
14216                                 $( li )
14217                                         .addClass( "ui-state-disabled" )
14218                                         .attr( "aria-disabled", "true" );
14219                         } else {
14220                                 $( li )
14221                                         .removeClass( "ui-state-disabled" )
14222                                         .removeAttr( "aria-disabled" );
14223                         }
14224                 }
14225
14226                 this.options.disabled = disabled;
14227         },
14228
14229         _setupEvents: function( event ) {
14230                 var events = {
14231                         click: function( event ) {
14232                                 event.preventDefault();
14233                         }
14234                 };
14235                 if ( event ) {
14236                         $.each( event.split(" "), function( index, eventName ) {
14237                                 events[ eventName ] = "_eventHandler";
14238                         });
14239                 }
14240
14241                 this._off( this.anchors.add( this.tabs ).add( this.panels ) );
14242                 this._on( this.anchors, events );
14243                 this._on( this.tabs, { keydown: "_tabKeydown" } );
14244                 this._on( this.panels, { keydown: "_panelKeydown" } );
14245
14246                 this._focusable( this.tabs );
14247                 this._hoverable( this.tabs );
14248         },
14249
14250         _setupHeightStyle: function( heightStyle ) {
14251                 var maxHeight,
14252                         parent = this.element.parent();
14253
14254                 if ( heightStyle === "fill" ) {
14255                         maxHeight = parent.height();
14256                         maxHeight -= this.element.outerHeight() - this.element.height();
14257
14258                         this.element.siblings( ":visible" ).each(function() {
14259                                 var elem = $( this ),
14260                                         position = elem.css( "position" );
14261
14262                                 if ( position === "absolute" || position === "fixed" ) {
14263                                         return;
14264                                 }
14265                                 maxHeight -= elem.outerHeight( true );
14266                         });
14267
14268                         this.element.children().not( this.panels ).each(function() {
14269                                 maxHeight -= $( this ).outerHeight( true );
14270                         });
14271
14272                         this.panels.each(function() {
14273                                 $( this ).height( Math.max( 0, maxHeight -
14274                                         $( this ).innerHeight() + $( this ).height() ) );
14275                         })
14276                         .css( "overflow", "auto" );
14277                 } else if ( heightStyle === "auto" ) {
14278                         maxHeight = 0;
14279                         this.panels.each(function() {
14280                                 maxHeight = Math.max( maxHeight, $( this ).height( "" ).height() );
14281                         }).height( maxHeight );
14282                 }
14283         },
14284
14285         _eventHandler: function( event ) {
14286                 var options = this.options,
14287                         active = this.active,
14288                         anchor = $( event.currentTarget ),
14289                         tab = anchor.closest( "li" ),
14290                         clickedIsActive = tab[ 0 ] === active[ 0 ],
14291                         collapsing = clickedIsActive && options.collapsible,
14292                         toShow = collapsing ? $() : this._getPanelForTab( tab ),
14293                         toHide = !active.length ? $() : this._getPanelForTab( active ),
14294                         eventData = {
14295                                 oldTab: active,
14296                                 oldPanel: toHide,
14297                                 newTab: collapsing ? $() : tab,
14298                                 newPanel: toShow
14299                         };
14300
14301                 event.preventDefault();
14302
14303                 if ( tab.hasClass( "ui-state-disabled" ) ||
14304                                 // tab is already loading
14305                                 tab.hasClass( "ui-tabs-loading" ) ||
14306                                 // can't switch durning an animation
14307                                 this.running ||
14308                                 // click on active header, but not collapsible
14309                                 ( clickedIsActive && !options.collapsible ) ||
14310                                 // allow canceling activation
14311                                 ( this._trigger( "beforeActivate", event, eventData ) === false ) ) {
14312                         return;
14313                 }
14314
14315                 options.active = collapsing ? false : this.tabs.index( tab );
14316
14317                 this.active = clickedIsActive ? $() : tab;
14318                 if ( this.xhr ) {
14319                         this.xhr.abort();
14320                 }
14321
14322                 if ( !toHide.length && !toShow.length ) {
14323                         $.error( "jQuery UI Tabs: Mismatching fragment identifier." );
14324                 }
14325
14326                 if ( toShow.length ) {
14327                         this.load( this.tabs.index( tab ), event );
14328                 }
14329                 this._toggle( event, eventData );
14330         },
14331
14332         // handles show/hide for selecting tabs
14333         _toggle: function( event, eventData ) {
14334                 var that = this,
14335                         toShow = eventData.newPanel,
14336                         toHide = eventData.oldPanel;
14337
14338                 this.running = true;
14339
14340                 function complete() {
14341                         that.running = false;
14342                         that._trigger( "activate", event, eventData );
14343                 }
14344
14345                 function show() {
14346                         eventData.newTab.closest( "li" ).addClass( "ui-tabs-active ui-state-active" );
14347
14348                         if ( toShow.length && that.options.show ) {
14349                                 that._show( toShow, that.options.show, complete );
14350                         } else {
14351                                 toShow.show();
14352                                 complete();
14353                         }
14354                 }
14355
14356                 // start out by hiding, then showing, then completing
14357                 if ( toHide.length && this.options.hide ) {
14358                         this._hide( toHide, this.options.hide, function() {
14359                                 eventData.oldTab.closest( "li" ).removeClass( "ui-tabs-active ui-state-active" );
14360                                 show();
14361                         });
14362                 } else {
14363                         eventData.oldTab.closest( "li" ).removeClass( "ui-tabs-active ui-state-active" );
14364                         toHide.hide();
14365                         show();
14366                 }
14367
14368                 toHide.attr({
14369                         "aria-expanded": "false",
14370                         "aria-hidden": "true"
14371                 });
14372                 eventData.oldTab.attr( "aria-selected", "false" );
14373                 // If we're switching tabs, remove the old tab from the tab order.
14374                 // If we're opening from collapsed state, remove the previous tab from the tab order.
14375                 // If we're collapsing, then keep the collapsing tab in the tab order.
14376                 if ( toShow.length && toHide.length ) {
14377                         eventData.oldTab.attr( "tabIndex", -1 );
14378                 } else if ( toShow.length ) {
14379                         this.tabs.filter(function() {
14380                                 return $( this ).attr( "tabIndex" ) === 0;
14381                         })
14382                         .attr( "tabIndex", -1 );
14383                 }
14384
14385                 toShow.attr({
14386                         "aria-expanded": "true",
14387                         "aria-hidden": "false"
14388                 });
14389                 eventData.newTab.attr({
14390                         "aria-selected": "true",
14391                         tabIndex: 0
14392                 });
14393         },
14394
14395         _activate: function( index ) {
14396                 var anchor,
14397                         active = this._findActive( index );
14398
14399                 // trying to activate the already active panel
14400                 if ( active[ 0 ] === this.active[ 0 ] ) {
14401                         return;
14402                 }
14403
14404                 // trying to collapse, simulate a click on the current active header
14405                 if ( !active.length ) {
14406                         active = this.active;
14407                 }
14408
14409                 anchor = active.find( ".ui-tabs-anchor" )[ 0 ];
14410                 this._eventHandler({
14411                         target: anchor,
14412                         currentTarget: anchor,
14413                         preventDefault: $.noop
14414                 });
14415         },
14416
14417         _findActive: function( index ) {
14418                 return index === false ? $() : this.tabs.eq( index );
14419         },
14420
14421         _getIndex: function( index ) {
14422                 // meta-function to give users option to provide a href string instead of a numerical index.
14423                 if ( typeof index === "string" ) {
14424                         index = this.anchors.index( this.anchors.filter( "[href$='" + index + "']" ) );
14425                 }
14426
14427                 return index;
14428         },
14429
14430         _destroy: function() {
14431                 if ( this.xhr ) {
14432                         this.xhr.abort();
14433                 }
14434
14435                 this.element.removeClass( "ui-tabs ui-widget ui-widget-content ui-corner-all ui-tabs-collapsible" );
14436
14437                 this.tablist
14438                         .removeClass( "ui-tabs-nav ui-helper-reset ui-helper-clearfix ui-widget-header ui-corner-all" )
14439                         .removeAttr( "role" );
14440
14441                 this.anchors
14442                         .removeClass( "ui-tabs-anchor" )
14443                         .removeAttr( "role" )
14444                         .removeAttr( "tabIndex" )
14445                         .removeUniqueId();
14446
14447                 this.tabs.add( this.panels ).each(function() {
14448                         if ( $.data( this, "ui-tabs-destroy" ) ) {
14449                                 $( this ).remove();
14450                         } else {
14451                                 $( this )
14452                                         .removeClass( "ui-state-default ui-state-active ui-state-disabled " +
14453                                                 "ui-corner-top ui-corner-bottom ui-widget-content ui-tabs-active ui-tabs-panel" )
14454                                         .removeAttr( "tabIndex" )
14455                                         .removeAttr( "aria-live" )
14456                                         .removeAttr( "aria-busy" )
14457                                         .removeAttr( "aria-selected" )
14458                                         .removeAttr( "aria-labelledby" )
14459                                         .removeAttr( "aria-hidden" )
14460                                         .removeAttr( "aria-expanded" )
14461                                         .removeAttr( "role" );
14462                         }
14463                 });
14464
14465                 this.tabs.each(function() {
14466                         var li = $( this ),
14467                                 prev = li.data( "ui-tabs-aria-controls" );
14468                         if ( prev ) {
14469                                 li
14470                                         .attr( "aria-controls", prev )
14471                                         .removeData( "ui-tabs-aria-controls" );
14472                         } else {
14473                                 li.removeAttr( "aria-controls" );
14474                         }
14475                 });
14476
14477                 this.panels.show();
14478
14479                 if ( this.options.heightStyle !== "content" ) {
14480                         this.panels.css( "height", "" );
14481                 }
14482         },
14483
14484         enable: function( index ) {
14485                 var disabled = this.options.disabled;
14486                 if ( disabled === false ) {
14487                         return;
14488                 }
14489
14490                 if ( index === undefined ) {
14491                         disabled = false;
14492                 } else {
14493                         index = this._getIndex( index );
14494                         if ( $.isArray( disabled ) ) {
14495                                 disabled = $.map( disabled, function( num ) {
14496                                         return num !== index ? num : null;
14497                                 });
14498                         } else {
14499                                 disabled = $.map( this.tabs, function( li, num ) {
14500                                         return num !== index ? num : null;
14501                                 });
14502                         }
14503                 }
14504                 this._setupDisabled( disabled );
14505         },
14506
14507         disable: function( index ) {
14508                 var disabled = this.options.disabled;
14509                 if ( disabled === true ) {
14510                         return;
14511                 }
14512
14513                 if ( index === undefined ) {
14514                         disabled = true;
14515                 } else {
14516                         index = this._getIndex( index );
14517                         if ( $.inArray( index, disabled ) !== -1 ) {
14518                                 return;
14519                         }
14520                         if ( $.isArray( disabled ) ) {
14521                                 disabled = $.merge( [ index ], disabled ).sort();
14522                         } else {
14523                                 disabled = [ index ];
14524                         }
14525                 }
14526                 this._setupDisabled( disabled );
14527         },
14528
14529         load: function( index, event ) {
14530                 index = this._getIndex( index );
14531                 var that = this,
14532                         tab = this.tabs.eq( index ),
14533                         anchor = tab.find( ".ui-tabs-anchor" ),
14534                         panel = this._getPanelForTab( tab ),
14535                         eventData = {
14536                                 tab: tab,
14537                                 panel: panel
14538                         };
14539
14540                 // not remote
14541                 if ( isLocal( anchor[ 0 ] ) ) {
14542                         return;
14543                 }
14544
14545                 this.xhr = $.ajax( this._ajaxSettings( anchor, event, eventData ) );
14546
14547                 // support: jQuery <1.8
14548                 // jQuery <1.8 returns false if the request is canceled in beforeSend,
14549                 // but as of 1.8, $.ajax() always returns a jqXHR object.
14550                 if ( this.xhr && this.xhr.statusText !== "canceled" ) {
14551                         tab.addClass( "ui-tabs-loading" );
14552                         panel.attr( "aria-busy", "true" );
14553
14554                         this.xhr
14555                                 .success(function( response ) {
14556                                         // support: jQuery <1.8
14557                                         // http://bugs.jquery.com/ticket/11778
14558                                         setTimeout(function() {
14559                                                 panel.html( response );
14560                                                 that._trigger( "load", event, eventData );
14561                                         }, 1 );
14562                                 })
14563                                 .complete(function( jqXHR, status ) {
14564                                         // support: jQuery <1.8
14565                                         // http://bugs.jquery.com/ticket/11778
14566                                         setTimeout(function() {
14567                                                 if ( status === "abort" ) {
14568                                                         that.panels.stop( false, true );
14569                                                 }
14570
14571                                                 tab.removeClass( "ui-tabs-loading" );
14572                                                 panel.removeAttr( "aria-busy" );
14573
14574                                                 if ( jqXHR === that.xhr ) {
14575                                                         delete that.xhr;
14576                                                 }
14577                                         }, 1 );
14578                                 });
14579                 }
14580         },
14581
14582         _ajaxSettings: function( anchor, event, eventData ) {
14583                 var that = this;
14584                 return {
14585                         url: anchor.attr( "href" ),
14586                         beforeSend: function( jqXHR, settings ) {
14587                                 return that._trigger( "beforeLoad", event,
14588                                         $.extend( { jqXHR : jqXHR, ajaxSettings: settings }, eventData ) );
14589                         }
14590                 };
14591         },
14592
14593         _getPanelForTab: function( tab ) {
14594                 var id = $( tab ).attr( "aria-controls" );
14595                 return this.element.find( this._sanitizeSelector( "#" + id ) );
14596         }
14597 });
14598
14599 })( jQuery );
14600
14601 (function( $ ) {
14602
14603 var increments = 0;
14604
14605 function addDescribedBy( elem, id ) {
14606         var describedby = (elem.attr( "aria-describedby" ) || "").split( /\s+/ );
14607         describedby.push( id );
14608         elem
14609                 .data( "ui-tooltip-id", id )
14610                 .attr( "aria-describedby", $.trim( describedby.join( " " ) ) );
14611 }
14612
14613 function removeDescribedBy( elem ) {
14614         var id = elem.data( "ui-tooltip-id" ),
14615                 describedby = (elem.attr( "aria-describedby" ) || "").split( /\s+/ ),
14616                 index = $.inArray( id, describedby );
14617         if ( index !== -1 ) {
14618                 describedby.splice( index, 1 );
14619         }
14620
14621         elem.removeData( "ui-tooltip-id" );
14622         describedby = $.trim( describedby.join( " " ) );
14623         if ( describedby ) {
14624                 elem.attr( "aria-describedby", describedby );
14625         } else {
14626                 elem.removeAttr( "aria-describedby" );
14627         }
14628 }
14629
14630 $.widget( "ui.tooltip", {
14631         version: "1.10.2",
14632         options: {
14633                 content: function() {
14634                         // support: IE<9, Opera in jQuery <1.7
14635                         // .text() can't accept undefined, so coerce to a string
14636                         var title = $( this ).attr( "title" ) || "";
14637                         // Escape title, since we're going from an attribute to raw HTML
14638                         return $( "<a>" ).text( title ).html();
14639                 },
14640                 hide: true,
14641                 // Disabled elements have inconsistent behavior across browsers (#8661)
14642                 items: "[title]:not([disabled])",
14643                 position: {
14644                         my: "left top+15",
14645                         at: "left bottom",
14646                         collision: "flipfit flip"
14647                 },
14648                 show: true,
14649                 tooltipClass: null,
14650                 track: false,
14651
14652                 // callbacks
14653                 close: null,
14654                 open: null
14655         },
14656
14657         _create: function() {
14658                 this._on({
14659                         mouseover: "open",
14660                         focusin: "open"
14661                 });
14662
14663                 // IDs of generated tooltips, needed for destroy
14664                 this.tooltips = {};
14665                 // IDs of parent tooltips where we removed the title attribute
14666                 this.parents = {};
14667
14668                 if ( this.options.disabled ) {
14669                         this._disable();
14670                 }
14671         },
14672
14673         _setOption: function( key, value ) {
14674                 var that = this;
14675
14676                 if ( key === "disabled" ) {
14677                         this[ value ? "_disable" : "_enable" ]();
14678                         this.options[ key ] = value;
14679                         // disable element style changes
14680                         return;
14681                 }
14682
14683                 this._super( key, value );
14684
14685                 if ( key === "content" ) {
14686                         $.each( this.tooltips, function( id, element ) {
14687                                 that._updateContent( element );
14688                         });
14689                 }
14690         },
14691
14692         _disable: function() {
14693                 var that = this;
14694
14695                 // close open tooltips
14696                 $.each( this.tooltips, function( id, element ) {
14697                         var event = $.Event( "blur" );
14698                         event.target = event.currentTarget = element[0];
14699                         that.close( event, true );
14700                 });
14701
14702                 // remove title attributes to prevent native tooltips
14703                 this.element.find( this.options.items ).addBack().each(function() {
14704                         var element = $( this );
14705                         if ( element.is( "[title]" ) ) {
14706                                 element
14707                                         .data( "ui-tooltip-title", element.attr( "title" ) )
14708                                         .attr( "title", "" );
14709                         }
14710                 });
14711         },
14712
14713         _enable: function() {
14714                 // restore title attributes
14715                 this.element.find( this.options.items ).addBack().each(function() {
14716                         var element = $( this );
14717                         if ( element.data( "ui-tooltip-title" ) ) {
14718                                 element.attr( "title", element.data( "ui-tooltip-title" ) );
14719                         }
14720                 });
14721         },
14722
14723         open: function( event ) {
14724                 var that = this,
14725                         target = $( event ? event.target : this.element )
14726                                 // we need closest here due to mouseover bubbling,
14727                                 // but always pointing at the same event target
14728                                 .closest( this.options.items );
14729
14730                 // No element to show a tooltip for or the tooltip is already open
14731                 if ( !target.length || target.data( "ui-tooltip-id" ) ) {
14732                         return;
14733                 }
14734
14735                 if ( target.attr( "title" ) ) {
14736                         target.data( "ui-tooltip-title", target.attr( "title" ) );
14737                 }
14738
14739                 target.data( "ui-tooltip-open", true );
14740
14741                 // kill parent tooltips, custom or native, for hover
14742                 if ( event && event.type === "mouseover" ) {
14743                         target.parents().each(function() {
14744                                 var parent = $( this ),
14745                                         blurEvent;
14746                                 if ( parent.data( "ui-tooltip-open" ) ) {
14747                                         blurEvent = $.Event( "blur" );
14748                                         blurEvent.target = blurEvent.currentTarget = this;
14749                                         that.close( blurEvent, true );
14750                                 }
14751                                 if ( parent.attr( "title" ) ) {
14752                                         parent.uniqueId();
14753                                         that.parents[ this.id ] = {
14754                                                 element: this,
14755                                                 title: parent.attr( "title" )
14756                                         };
14757                                         parent.attr( "title", "" );
14758                                 }
14759                         });
14760                 }
14761
14762                 this._updateContent( target, event );
14763         },
14764
14765         _updateContent: function( target, event ) {
14766                 var content,
14767                         contentOption = this.options.content,
14768                         that = this,
14769                         eventType = event ? event.type : null;
14770
14771                 if ( typeof contentOption === "string" ) {
14772                         return this._open( event, target, contentOption );
14773                 }
14774
14775                 content = contentOption.call( target[0], function( response ) {
14776                         // ignore async response if tooltip was closed already
14777                         if ( !target.data( "ui-tooltip-open" ) ) {
14778                                 return;
14779                         }
14780                         // IE may instantly serve a cached response for ajax requests
14781                         // delay this call to _open so the other call to _open runs first
14782                         that._delay(function() {
14783                                 // jQuery creates a special event for focusin when it doesn't
14784                                 // exist natively. To improve performance, the native event
14785                                 // object is reused and the type is changed. Therefore, we can't
14786                                 // rely on the type being correct after the event finished
14787                                 // bubbling, so we set it back to the previous value. (#8740)
14788                                 if ( event ) {
14789                                         event.type = eventType;
14790                                 }
14791                                 this._open( event, target, response );
14792                         });
14793                 });
14794                 if ( content ) {
14795                         this._open( event, target, content );
14796                 }
14797         },
14798
14799         _open: function( event, target, content ) {
14800                 var tooltip, events, delayedShow,
14801                         positionOption = $.extend( {}, this.options.position );
14802
14803                 if ( !content ) {
14804                         return;
14805                 }
14806
14807                 // Content can be updated multiple times. If the tooltip already
14808                 // exists, then just update the content and bail.
14809                 tooltip = this._find( target );
14810                 if ( tooltip.length ) {
14811                         tooltip.find( ".ui-tooltip-content" ).html( content );
14812                         return;
14813                 }
14814
14815                 // if we have a title, clear it to prevent the native tooltip
14816                 // we have to check first to avoid defining a title if none exists
14817                 // (we don't want to cause an element to start matching [title])
14818                 //
14819                 // We use removeAttr only for key events, to allow IE to export the correct
14820                 // accessible attributes. For mouse events, set to empty string to avoid
14821                 // native tooltip showing up (happens only when removing inside mouseover).
14822                 if ( target.is( "[title]" ) ) {
14823                         if ( event && event.type === "mouseover" ) {
14824                                 target.attr( "title", "" );
14825                         } else {
14826                                 target.removeAttr( "title" );
14827                         }
14828                 }
14829
14830                 tooltip = this._tooltip( target );
14831                 addDescribedBy( target, tooltip.attr( "id" ) );
14832                 tooltip.find( ".ui-tooltip-content" ).html( content );
14833
14834                 function position( event ) {
14835                         positionOption.of = event;
14836                         if ( tooltip.is( ":hidden" ) ) {
14837                                 return;
14838                         }
14839                         tooltip.position( positionOption );
14840                 }
14841                 if ( this.options.track && event && /^mouse/.test( event.type ) ) {
14842                         this._on( this.document, {
14843                                 mousemove: position
14844                         });
14845                         // trigger once to override element-relative positioning
14846                         position( event );
14847                 } else {
14848                         tooltip.position( $.extend({
14849                                 of: target
14850                         }, this.options.position ) );
14851                 }
14852
14853                 tooltip.hide();
14854
14855                 this._show( tooltip, this.options.show );
14856                 // Handle tracking tooltips that are shown with a delay (#8644). As soon
14857                 // as the tooltip is visible, position the tooltip using the most recent
14858                 // event.
14859                 if ( this.options.show && this.options.show.delay ) {
14860                         delayedShow = this.delayedShow = setInterval(function() {
14861                                 if ( tooltip.is( ":visible" ) ) {
14862                                         position( positionOption.of );
14863                                         clearInterval( delayedShow );
14864                                 }
14865                         }, $.fx.interval );
14866                 }
14867
14868                 this._trigger( "open", event, { tooltip: tooltip } );
14869
14870                 events = {
14871                         keyup: function( event ) {
14872                                 if ( event.keyCode === $.ui.keyCode.ESCAPE ) {
14873                                         var fakeEvent = $.Event(event);
14874                                         fakeEvent.currentTarget = target[0];
14875                                         this.close( fakeEvent, true );
14876                                 }
14877                         },
14878                         remove: function() {
14879                                 this._removeTooltip( tooltip );
14880                         }
14881                 };
14882                 if ( !event || event.type === "mouseover" ) {
14883                         events.mouseleave = "close";
14884                 }
14885                 if ( !event || event.type === "focusin" ) {
14886                         events.focusout = "close";
14887                 }
14888                 this._on( true, target, events );
14889         },
14890
14891         close: function( event ) {
14892                 var that = this,
14893                         target = $( event ? event.currentTarget : this.element ),
14894                         tooltip = this._find( target );
14895
14896                 // disabling closes the tooltip, so we need to track when we're closing
14897                 // to avoid an infinite loop in case the tooltip becomes disabled on close
14898                 if ( this.closing ) {
14899                         return;
14900                 }
14901
14902                 // Clear the interval for delayed tracking tooltips
14903                 clearInterval( this.delayedShow );
14904
14905                 // only set title if we had one before (see comment in _open())
14906                 if ( target.data( "ui-tooltip-title" ) ) {
14907                         target.attr( "title", target.data( "ui-tooltip-title" ) );
14908                 }
14909
14910                 removeDescribedBy( target );
14911
14912                 tooltip.stop( true );
14913                 this._hide( tooltip, this.options.hide, function() {
14914                         that._removeTooltip( $( this ) );
14915                 });
14916
14917                 target.removeData( "ui-tooltip-open" );
14918                 this._off( target, "mouseleave focusout keyup" );
14919                 // Remove 'remove' binding only on delegated targets
14920                 if ( target[0] !== this.element[0] ) {
14921                         this._off( target, "remove" );
14922                 }
14923                 this._off( this.document, "mousemove" );
14924
14925                 if ( event && event.type === "mouseleave" ) {
14926                         $.each( this.parents, function( id, parent ) {
14927                                 $( parent.element ).attr( "title", parent.title );
14928                                 delete that.parents[ id ];
14929                         });
14930                 }
14931
14932                 this.closing = true;
14933                 this._trigger( "close", event, { tooltip: tooltip } );
14934                 this.closing = false;
14935         },
14936
14937         _tooltip: function( element ) {
14938                 var id = "ui-tooltip-" + increments++,
14939                         tooltip = $( "<div>" )
14940                                 .attr({
14941                                         id: id,
14942                                         role: "tooltip"
14943                                 })
14944                                 .addClass( "ui-tooltip ui-widget ui-corner-all ui-widget-content " +
14945                                         ( this.options.tooltipClass || "" ) );
14946                 $( "<div>" )
14947                         .addClass( "ui-tooltip-content" )
14948                         .appendTo( tooltip );
14949                 tooltip.appendTo( this.document[0].body );
14950                 this.tooltips[ id ] = element;
14951                 return tooltip;
14952         },
14953
14954         _find: function( target ) {
14955                 var id = target.data( "ui-tooltip-id" );
14956                 return id ? $( "#" + id ) : $();
14957         },
14958
14959         _removeTooltip: function( tooltip ) {
14960                 tooltip.remove();
14961                 delete this.tooltips[ tooltip.attr( "id" ) ];
14962         },
14963
14964         _destroy: function() {
14965                 var that = this;
14966
14967                 // close open tooltips
14968                 $.each( this.tooltips, function( id, element ) {
14969                         // Delegate to close method to handle common cleanup
14970                         var event = $.Event( "blur" );
14971                         event.target = event.currentTarget = element[0];
14972                         that.close( event, true );
14973
14974                         // Remove immediately; destroying an open tooltip doesn't use the
14975                         // hide animation
14976                         $( "#" + id ).remove();
14977
14978                         // Restore the title
14979                         if ( element.data( "ui-tooltip-title" ) ) {
14980                                 element.attr( "title", element.data( "ui-tooltip-title" ) );
14981                                 element.removeData( "ui-tooltip-title" );
14982                         }
14983                 });
14984         }
14985 });
14986
14987 }( jQuery ) );