luci2: fix CBI crash when deleting last remaining uci section in login management...
[project/luci2/ui.git] / luci2 / htdocs / luci2 / jquery-ui-1.10.3.js
1 /*! jQuery UI - v1.10.3 - 2013-05-03
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.3",
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 $.widget() extensions instead.
265         plugin: {
266                 add: function( module, option, set ) {
267                         var i,
268                                 proto = $.ui[ module ].prototype;
269                         for ( i in set ) {
270                                 proto.plugins[ i ] = proto.plugins[ i ] || [];
271                                 proto.plugins[ i ].push( [ option, set[ i ] ] );
272                         }
273                 },
274                 call: function( instance, name, args ) {
275                         var i,
276                                 set = instance.plugins[ name ];
277                         if ( !set || !instance.element[ 0 ].parentNode || instance.element[ 0 ].parentNode.nodeType === 11 ) {
278                                 return;
279                         }
280
281                         for ( i = 0; i < set.length; i++ ) {
282                                 if ( instance.options[ set[ i ][ 0 ] ] ) {
283                                         set[ i ][ 1 ].apply( instance.element, args );
284                                 }
285                         }
286                 }
287         },
288
289         // only used by resizable
290         hasScroll: function( el, a ) {
291
292                 //If overflow is hidden, the element might have extra content, but the user wants to hide it
293                 if ( $( el ).css( "overflow" ) === "hidden") {
294                         return false;
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.3",
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.3",
989         widgetEventPrefix: "drag",
990         options: {
991                 addClasses: true,
992                 appendTo: "parent",
993                 axis: false,
994                 connectToSortable: false,
995                 containment: false,
996                 cursor: "auto",
997                 cursorAt: false,
998                 grid: false,
999                 handle: false,
1000                 helper: "original",
1001                 iframeFix: false,
1002                 opacity: false,
1003                 refreshPositions: false,
1004                 revert: false,
1005                 revertDuration: 500,
1006                 scope: "default",
1007                 scroll: true,
1008                 scrollSensitivity: 20,
1009                 scrollSpeed: 20,
1010                 snap: false,
1011                 snapMode: "both",
1012                 snapTolerance: 20,
1013                 stack: false,
1014                 zIndex: false,
1015
1016                 // callbacks
1017                 drag: null,
1018                 start: null,
1019                 stop: null
1020         },
1021         _create: function() {
1022
1023                 if (this.options.helper === "original" && !(/^(?:r|a|f)/).test(this.element.css("position"))) {
1024                         this.element[0].style.position = "relative";
1025                 }
1026                 if (this.options.addClasses){
1027                         this.element.addClass("ui-draggable");
1028                 }
1029                 if (this.options.disabled){
1030                         this.element.addClass("ui-draggable-disabled");
1031                 }
1032
1033                 this._mouseInit();
1034
1035         },
1036
1037         _destroy: function() {
1038                 this.element.removeClass( "ui-draggable ui-draggable-dragging ui-draggable-disabled" );
1039                 this._mouseDestroy();
1040         },
1041
1042         _mouseCapture: function(event) {
1043
1044                 var o = this.options;
1045
1046                 // among others, prevent a drag on a resizable-handle
1047                 if (this.helper || o.disabled || $(event.target).closest(".ui-resizable-handle").length > 0) {
1048                         return false;
1049                 }
1050
1051                 //Quit if we're not on a valid handle
1052                 this.handle = this._getHandle(event);
1053                 if (!this.handle) {
1054                         return false;
1055                 }
1056
1057                 $(o.iframeFix === true ? "iframe" : o.iframeFix).each(function() {
1058                         $("<div class='ui-draggable-iframeFix' style='background: #fff;'></div>")
1059                         .css({
1060                                 width: this.offsetWidth+"px", height: this.offsetHeight+"px",
1061                                 position: "absolute", opacity: "0.001", zIndex: 1000
1062                         })
1063                         .css($(this).offset())
1064                         .appendTo("body");
1065                 });
1066
1067                 return true;
1068
1069         },
1070
1071         _mouseStart: function(event) {
1072
1073                 var o = this.options;
1074
1075                 //Create and append the visible helper
1076                 this.helper = this._createHelper(event);
1077
1078                 this.helper.addClass("ui-draggable-dragging");
1079
1080                 //Cache the helper size
1081                 this._cacheHelperProportions();
1082
1083                 //If ddmanager is used for droppables, set the global draggable
1084                 if($.ui.ddmanager) {
1085                         $.ui.ddmanager.current = this;
1086                 }
1087
1088                 /*
1089                  * - Position generation -
1090                  * This block generates everything position related - it's the core of draggables.
1091                  */
1092
1093                 //Cache the margins of the original element
1094                 this._cacheMargins();
1095
1096                 //Store the helper's css position
1097                 this.cssPosition = this.helper.css( "position" );
1098                 this.scrollParent = this.helper.scrollParent();
1099                 this.offsetParent = this.helper.offsetParent();
1100                 this.offsetParentCssPosition = this.offsetParent.css( "position" );
1101
1102                 //The element's absolute position on the page minus margins
1103                 this.offset = this.positionAbs = this.element.offset();
1104                 this.offset = {
1105                         top: this.offset.top - this.margins.top,
1106                         left: this.offset.left - this.margins.left
1107                 };
1108
1109                 //Reset scroll cache
1110                 this.offset.scroll = false;
1111
1112                 $.extend(this.offset, {
1113                         click: { //Where the click happened, relative to the element
1114                                 left: event.pageX - this.offset.left,
1115                                 top: event.pageY - this.offset.top
1116                         },
1117                         parent: this._getParentOffset(),
1118                         relative: this._getRelativeOffset() //This is a relative to absolute position minus the actual position calculation - only used for relative positioned helper
1119                 });
1120
1121                 //Generate the original position
1122                 this.originalPosition = this.position = this._generatePosition(event);
1123                 this.originalPageX = event.pageX;
1124                 this.originalPageY = event.pageY;
1125
1126                 //Adjust the mouse offset relative to the helper if "cursorAt" is supplied
1127                 (o.cursorAt && this._adjustOffsetFromHelper(o.cursorAt));
1128
1129                 //Set a containment if given in the options
1130                 this._setContainment();
1131
1132                 //Trigger event + callbacks
1133                 if(this._trigger("start", event) === false) {
1134                         this._clear();
1135                         return false;
1136                 }
1137
1138                 //Recache the helper size
1139                 this._cacheHelperProportions();
1140
1141                 //Prepare the droppable offsets
1142                 if ($.ui.ddmanager && !o.dropBehaviour) {
1143                         $.ui.ddmanager.prepareOffsets(this, event);
1144                 }
1145
1146
1147                 this._mouseDrag(event, true); //Execute the drag once - this causes the helper not to be visible before getting its correct position
1148
1149                 //If the ddmanager is used for droppables, inform the manager that dragging has started (see #5003)
1150                 if ( $.ui.ddmanager ) {
1151                         $.ui.ddmanager.dragStart(this, event);
1152                 }
1153
1154                 return true;
1155         },
1156
1157         _mouseDrag: function(event, noPropagation) {
1158                 // reset any necessary cached properties (see #5009)
1159                 if ( this.offsetParentCssPosition === "fixed" ) {
1160                         this.offset.parent = this._getParentOffset();
1161                 }
1162
1163                 //Compute the helpers position
1164                 this.position = this._generatePosition(event);
1165                 this.positionAbs = this._convertPositionTo("absolute");
1166
1167                 //Call plugins and callbacks and use the resulting position if something is returned
1168                 if (!noPropagation) {
1169                         var ui = this._uiHash();
1170                         if(this._trigger("drag", event, ui) === false) {
1171                                 this._mouseUp({});
1172                                 return false;
1173                         }
1174                         this.position = ui.position;
1175                 }
1176
1177                 if(!this.options.axis || this.options.axis !== "y") {
1178                         this.helper[0].style.left = this.position.left+"px";
1179                 }
1180                 if(!this.options.axis || this.options.axis !== "x") {
1181                         this.helper[0].style.top = this.position.top+"px";
1182                 }
1183                 if($.ui.ddmanager) {
1184                         $.ui.ddmanager.drag(this, event);
1185                 }
1186
1187                 return false;
1188         },
1189
1190         _mouseStop: function(event) {
1191
1192                 //If we are using droppables, inform the manager about the drop
1193                 var that = this,
1194                         dropped = false;
1195                 if ($.ui.ddmanager && !this.options.dropBehaviour) {
1196                         dropped = $.ui.ddmanager.drop(this, event);
1197                 }
1198
1199                 //if a drop comes from outside (a sortable)
1200                 if(this.dropped) {
1201                         dropped = this.dropped;
1202                         this.dropped = false;
1203                 }
1204
1205                 //if the original element is no longer in the DOM don't bother to continue (see #8269)
1206                 if ( this.options.helper === "original" && !$.contains( this.element[ 0 ].ownerDocument, this.element[ 0 ] ) ) {
1207                         return false;
1208                 }
1209
1210                 if((this.options.revert === "invalid" && !dropped) || (this.options.revert === "valid" && dropped) || this.options.revert === true || ($.isFunction(this.options.revert) && this.options.revert.call(this.element, dropped))) {
1211                         $(this.helper).animate(this.originalPosition, parseInt(this.options.revertDuration, 10), function() {
1212                                 if(that._trigger("stop", event) !== false) {
1213                                         that._clear();
1214                                 }
1215                         });
1216                 } else {
1217                         if(this._trigger("stop", event) !== false) {
1218                                 this._clear();
1219                         }
1220                 }
1221
1222                 return false;
1223         },
1224
1225         _mouseUp: function(event) {
1226                 //Remove frame helpers
1227                 $("div.ui-draggable-iframeFix").each(function() {
1228                         this.parentNode.removeChild(this);
1229                 });
1230
1231                 //If the ddmanager is used for droppables, inform the manager that dragging has stopped (see #5003)
1232                 if( $.ui.ddmanager ) {
1233                         $.ui.ddmanager.dragStop(this, event);
1234                 }
1235
1236                 return $.ui.mouse.prototype._mouseUp.call(this, event);
1237         },
1238
1239         cancel: function() {
1240
1241                 if(this.helper.is(".ui-draggable-dragging")) {
1242                         this._mouseUp({});
1243                 } else {
1244                         this._clear();
1245                 }
1246
1247                 return this;
1248
1249         },
1250
1251         _getHandle: function(event) {
1252                 return this.options.handle ?
1253                         !!$( event.target ).closest( this.element.find( this.options.handle ) ).length :
1254                         true;
1255         },
1256
1257         _createHelper: function(event) {
1258
1259                 var o = this.options,
1260                         helper = $.isFunction(o.helper) ? $(o.helper.apply(this.element[0], [event])) : (o.helper === "clone" ? this.element.clone().removeAttr("id") : this.element);
1261
1262                 if(!helper.parents("body").length) {
1263                         helper.appendTo((o.appendTo === "parent" ? this.element[0].parentNode : o.appendTo));
1264                 }
1265
1266                 if(helper[0] !== this.element[0] && !(/(fixed|absolute)/).test(helper.css("position"))) {
1267                         helper.css("position", "absolute");
1268                 }
1269
1270                 return helper;
1271
1272         },
1273
1274         _adjustOffsetFromHelper: function(obj) {
1275                 if (typeof obj === "string") {
1276                         obj = obj.split(" ");
1277                 }
1278                 if ($.isArray(obj)) {
1279                         obj = {left: +obj[0], top: +obj[1] || 0};
1280                 }
1281                 if ("left" in obj) {
1282                         this.offset.click.left = obj.left + this.margins.left;
1283                 }
1284                 if ("right" in obj) {
1285                         this.offset.click.left = this.helperProportions.width - obj.right + this.margins.left;
1286                 }
1287                 if ("top" in obj) {
1288                         this.offset.click.top = obj.top + this.margins.top;
1289                 }
1290                 if ("bottom" in obj) {
1291                         this.offset.click.top = this.helperProportions.height - obj.bottom + this.margins.top;
1292                 }
1293         },
1294
1295         _getParentOffset: function() {
1296
1297                 //Get the offsetParent and cache its position
1298                 var po = this.offsetParent.offset();
1299
1300                 // This is a special case where we need to modify a offset calculated on start, since the following happened:
1301                 // 1. The position of the helper is absolute, so it's position is calculated based on the next positioned parent
1302                 // 2. The actual offset parent is a child of the scroll parent, and the scroll parent isn't the document, which means that
1303                 //    the scroll is included in the initial calculation of the offset of the parent, and never recalculated upon drag
1304                 if(this.cssPosition === "absolute" && this.scrollParent[0] !== document && $.contains(this.scrollParent[0], this.offsetParent[0])) {
1305                         po.left += this.scrollParent.scrollLeft();
1306                         po.top += this.scrollParent.scrollTop();
1307                 }
1308
1309                 //This needs to be actually done for all browsers, since pageX/pageY includes this information
1310                 //Ugly IE fix
1311                 if((this.offsetParent[0] === document.body) ||
1312                         (this.offsetParent[0].tagName && this.offsetParent[0].tagName.toLowerCase() === "html" && $.ui.ie)) {
1313                         po = { top: 0, left: 0 };
1314                 }
1315
1316                 return {
1317                         top: po.top + (parseInt(this.offsetParent.css("borderTopWidth"),10) || 0),
1318                         left: po.left + (parseInt(this.offsetParent.css("borderLeftWidth"),10) || 0)
1319                 };
1320
1321         },
1322
1323         _getRelativeOffset: function() {
1324
1325                 if(this.cssPosition === "relative") {
1326                         var p = this.element.position();
1327                         return {
1328                                 top: p.top - (parseInt(this.helper.css("top"),10) || 0) + this.scrollParent.scrollTop(),
1329                                 left: p.left - (parseInt(this.helper.css("left"),10) || 0) + this.scrollParent.scrollLeft()
1330                         };
1331                 } else {
1332                         return { top: 0, left: 0 };
1333                 }
1334
1335         },
1336
1337         _cacheMargins: function() {
1338                 this.margins = {
1339                         left: (parseInt(this.element.css("marginLeft"),10) || 0),
1340                         top: (parseInt(this.element.css("marginTop"),10) || 0),
1341                         right: (parseInt(this.element.css("marginRight"),10) || 0),
1342                         bottom: (parseInt(this.element.css("marginBottom"),10) || 0)
1343                 };
1344         },
1345
1346         _cacheHelperProportions: function() {
1347                 this.helperProportions = {
1348                         width: this.helper.outerWidth(),
1349                         height: this.helper.outerHeight()
1350                 };
1351         },
1352
1353         _setContainment: function() {
1354
1355                 var over, c, ce,
1356                         o = this.options;
1357
1358                 if ( !o.containment ) {
1359                         this.containment = null;
1360                         return;
1361                 }
1362
1363                 if ( o.containment === "window" ) {
1364                         this.containment = [
1365                                 $( window ).scrollLeft() - this.offset.relative.left - this.offset.parent.left,
1366                                 $( window ).scrollTop() - this.offset.relative.top - this.offset.parent.top,
1367                                 $( window ).scrollLeft() + $( window ).width() - this.helperProportions.width - this.margins.left,
1368                                 $( window ).scrollTop() + ( $( window ).height() || document.body.parentNode.scrollHeight ) - this.helperProportions.height - this.margins.top
1369                         ];
1370                         return;
1371                 }
1372
1373                 if ( o.containment === "document") {
1374                         this.containment = [
1375                                 0,
1376                                 0,
1377                                 $( document ).width() - this.helperProportions.width - this.margins.left,
1378                                 ( $( document ).height() || document.body.parentNode.scrollHeight ) - this.helperProportions.height - this.margins.top
1379                         ];
1380                         return;
1381                 }
1382
1383                 if ( o.containment.constructor === Array ) {
1384                         this.containment = o.containment;
1385                         return;
1386                 }
1387
1388                 if ( o.containment === "parent" ) {
1389                         o.containment = this.helper[ 0 ].parentNode;
1390                 }
1391
1392                 c = $( o.containment );
1393                 ce = c[ 0 ];
1394
1395                 if( !ce ) {
1396                         return;
1397                 }
1398
1399                 over = c.css( "overflow" ) !== "hidden";
1400
1401                 this.containment = [
1402                         ( parseInt( c.css( "borderLeftWidth" ), 10 ) || 0 ) + ( parseInt( c.css( "paddingLeft" ), 10 ) || 0 ),
1403                         ( parseInt( c.css( "borderTopWidth" ), 10 ) || 0 ) + ( parseInt( c.css( "paddingTop" ), 10 ) || 0 ) ,
1404                         ( over ? Math.max( ce.scrollWidth, ce.offsetWidth ) : ce.offsetWidth ) - ( parseInt( c.css( "borderRightWidth" ), 10 ) || 0 ) - ( parseInt( c.css( "paddingRight" ), 10 ) || 0 ) - this.helperProportions.width - this.margins.left - this.margins.right,
1405                         ( over ? Math.max( ce.scrollHeight, ce.offsetHeight ) : ce.offsetHeight ) - ( parseInt( c.css( "borderBottomWidth" ), 10 ) || 0 ) - ( parseInt( c.css( "paddingBottom" ), 10 ) || 0 ) - this.helperProportions.height - this.margins.top  - this.margins.bottom
1406                 ];
1407                 this.relative_container = c;
1408         },
1409
1410         _convertPositionTo: function(d, pos) {
1411
1412                 if(!pos) {
1413                         pos = this.position;
1414                 }
1415
1416                 var mod = d === "absolute" ? 1 : -1,
1417                         scroll = this.cssPosition === "absolute" && !( this.scrollParent[ 0 ] !== document && $.contains( this.scrollParent[ 0 ], this.offsetParent[ 0 ] ) ) ? this.offsetParent : this.scrollParent;
1418
1419                 //Cache the scroll
1420                 if (!this.offset.scroll) {
1421                         this.offset.scroll = {top : scroll.scrollTop(), left : scroll.scrollLeft()};
1422                 }
1423
1424                 return {
1425                         top: (
1426                                 pos.top +                                                                                                                               // The absolute mouse position
1427                                 this.offset.relative.top * mod +                                                                                // Only for relative positioned nodes: Relative offset from element to offset parent
1428                                 this.offset.parent.top * mod -                                                                          // The offsetParent's offset without borders (offset + border)
1429                                 ( ( this.cssPosition === "fixed" ? -this.scrollParent.scrollTop() : this.offset.scroll.top ) * mod )
1430                         ),
1431                         left: (
1432                                 pos.left +                                                                                                                              // The absolute mouse position
1433                                 this.offset.relative.left * mod +                                                                               // Only for relative positioned nodes: Relative offset from element to offset parent
1434                                 this.offset.parent.left * mod   -                                                                               // The offsetParent's offset without borders (offset + border)
1435                                 ( ( this.cssPosition === "fixed" ? -this.scrollParent.scrollLeft() : this.offset.scroll.left ) * mod )
1436                         )
1437                 };
1438
1439         },
1440
1441         _generatePosition: function(event) {
1442
1443                 var containment, co, top, left,
1444                         o = this.options,
1445                         scroll = this.cssPosition === "absolute" && !( this.scrollParent[ 0 ] !== document && $.contains( this.scrollParent[ 0 ], this.offsetParent[ 0 ] ) ) ? this.offsetParent : this.scrollParent,
1446                         pageX = event.pageX,
1447                         pageY = event.pageY;
1448
1449                 //Cache the scroll
1450                 if (!this.offset.scroll) {
1451                         this.offset.scroll = {top : scroll.scrollTop(), left : scroll.scrollLeft()};
1452                 }
1453
1454                 /*
1455                  * - Position constraining -
1456                  * Constrain the position to a mix of grid, containment.
1457                  */
1458
1459                 // If we are not dragging yet, we won't check for options
1460                 if ( this.originalPosition ) {
1461                         if ( this.containment ) {
1462                                 if ( this.relative_container ){
1463                                         co = this.relative_container.offset();
1464                                         containment = [
1465                                                 this.containment[ 0 ] + co.left,
1466                                                 this.containment[ 1 ] + co.top,
1467                                                 this.containment[ 2 ] + co.left,
1468                                                 this.containment[ 3 ] + co.top
1469                                         ];
1470                                 }
1471                                 else {
1472                                         containment = this.containment;
1473                                 }
1474
1475                                 if(event.pageX - this.offset.click.left < containment[0]) {
1476                                         pageX = containment[0] + this.offset.click.left;
1477                                 }
1478                                 if(event.pageY - this.offset.click.top < containment[1]) {
1479                                         pageY = containment[1] + this.offset.click.top;
1480                                 }
1481                                 if(event.pageX - this.offset.click.left > containment[2]) {
1482                                         pageX = containment[2] + this.offset.click.left;
1483                                 }
1484                                 if(event.pageY - this.offset.click.top > containment[3]) {
1485                                         pageY = containment[3] + this.offset.click.top;
1486                                 }
1487                         }
1488
1489                         if(o.grid) {
1490                                 //Check for grid elements set to 0 to prevent divide by 0 error causing invalid argument errors in IE (see ticket #6950)
1491                                 top = o.grid[1] ? this.originalPageY + Math.round((pageY - this.originalPageY) / o.grid[1]) * o.grid[1] : this.originalPageY;
1492                                 pageY = containment ? ((top - this.offset.click.top >= containment[1] || top - this.offset.click.top > containment[3]) ? top : ((top - this.offset.click.top >= containment[1]) ? top - o.grid[1] : top + o.grid[1])) : top;
1493
1494                                 left = o.grid[0] ? this.originalPageX + Math.round((pageX - this.originalPageX) / o.grid[0]) * o.grid[0] : this.originalPageX;
1495                                 pageX = containment ? ((left - this.offset.click.left >= containment[0] || left - this.offset.click.left > containment[2]) ? left : ((left - this.offset.click.left >= containment[0]) ? left - o.grid[0] : left + o.grid[0])) : left;
1496                         }
1497
1498                 }
1499
1500                 return {
1501                         top: (
1502                                 pageY -                                                                                                                                 // The absolute mouse position
1503                                 this.offset.click.top   -                                                                                               // Click offset (relative to the element)
1504                                 this.offset.relative.top -                                                                                              // Only for relative positioned nodes: Relative offset from element to offset parent
1505                                 this.offset.parent.top +                                                                                                // The offsetParent's offset without borders (offset + border)
1506                                 ( this.cssPosition === "fixed" ? -this.scrollParent.scrollTop() : this.offset.scroll.top )
1507                         ),
1508                         left: (
1509                                 pageX -                                                                                                                                 // The absolute mouse position
1510                                 this.offset.click.left -                                                                                                // Click offset (relative to the element)
1511                                 this.offset.relative.left -                                                                                             // Only for relative positioned nodes: Relative offset from element to offset parent
1512                                 this.offset.parent.left +                                                                                               // The offsetParent's offset without borders (offset + border)
1513                                 ( this.cssPosition === "fixed" ? -this.scrollParent.scrollLeft() : this.offset.scroll.left )
1514                         )
1515                 };
1516
1517         },
1518
1519         _clear: function() {
1520                 this.helper.removeClass("ui-draggable-dragging");
1521                 if(this.helper[0] !== this.element[0] && !this.cancelHelperRemoval) {
1522                         this.helper.remove();
1523                 }
1524                 this.helper = null;
1525                 this.cancelHelperRemoval = false;
1526         },
1527
1528         // From now on bulk stuff - mainly helpers
1529
1530         _trigger: function(type, event, ui) {
1531                 ui = ui || this._uiHash();
1532                 $.ui.plugin.call(this, type, [event, ui]);
1533                 //The absolute position has to be recalculated after plugins
1534                 if(type === "drag") {
1535                         this.positionAbs = this._convertPositionTo("absolute");
1536                 }
1537                 return $.Widget.prototype._trigger.call(this, type, event, ui);
1538         },
1539
1540         plugins: {},
1541
1542         _uiHash: function() {
1543                 return {
1544                         helper: this.helper,
1545                         position: this.position,
1546                         originalPosition: this.originalPosition,
1547                         offset: this.positionAbs
1548                 };
1549         }
1550
1551 });
1552
1553 $.ui.plugin.add("draggable", "connectToSortable", {
1554         start: function(event, ui) {
1555
1556                 var inst = $(this).data("ui-draggable"), o = inst.options,
1557                         uiSortable = $.extend({}, ui, { item: inst.element });
1558                 inst.sortables = [];
1559                 $(o.connectToSortable).each(function() {
1560                         var sortable = $.data(this, "ui-sortable");
1561                         if (sortable && !sortable.options.disabled) {
1562                                 inst.sortables.push({
1563                                         instance: sortable,
1564                                         shouldRevert: sortable.options.revert
1565                                 });
1566                                 sortable.refreshPositions();    // Call the sortable's refreshPositions at drag start to refresh the containerCache since the sortable container cache is used in drag and needs to be up to date (this will ensure it's initialised as well as being kept in step with any changes that might have happened on the page).
1567                                 sortable._trigger("activate", event, uiSortable);
1568                         }
1569                 });
1570
1571         },
1572         stop: function(event, ui) {
1573
1574                 //If we are still over the sortable, we fake the stop event of the sortable, but also remove helper
1575                 var inst = $(this).data("ui-draggable"),
1576                         uiSortable = $.extend({}, ui, { item: inst.element });
1577
1578                 $.each(inst.sortables, function() {
1579                         if(this.instance.isOver) {
1580
1581                                 this.instance.isOver = 0;
1582
1583                                 inst.cancelHelperRemoval = true; //Don't remove the helper in the draggable instance
1584                                 this.instance.cancelHelperRemoval = false; //Remove it in the sortable instance (so sortable plugins like revert still work)
1585
1586                                 //The sortable revert is supported, and we have to set a temporary dropped variable on the draggable to support revert: "valid/invalid"
1587                                 if(this.shouldRevert) {
1588                                         this.instance.options.revert = this.shouldRevert;
1589                                 }
1590
1591                                 //Trigger the stop of the sortable
1592                                 this.instance._mouseStop(event);
1593
1594                                 this.instance.options.helper = this.instance.options._helper;
1595
1596                                 //If the helper has been the original item, restore properties in the sortable
1597                                 if(inst.options.helper === "original") {
1598                                         this.instance.currentItem.css({ top: "auto", left: "auto" });
1599                                 }
1600
1601                         } else {
1602                                 this.instance.cancelHelperRemoval = false; //Remove the helper in the sortable instance
1603                                 this.instance._trigger("deactivate", event, uiSortable);
1604                         }
1605
1606                 });
1607
1608         },
1609         drag: function(event, ui) {
1610
1611                 var inst = $(this).data("ui-draggable"), that = this;
1612
1613                 $.each(inst.sortables, function() {
1614
1615                         var innermostIntersecting = false,
1616                                 thisSortable = this;
1617
1618                         //Copy over some variables to allow calling the sortable's native _intersectsWith
1619                         this.instance.positionAbs = inst.positionAbs;
1620                         this.instance.helperProportions = inst.helperProportions;
1621                         this.instance.offset.click = inst.offset.click;
1622
1623                         if(this.instance._intersectsWith(this.instance.containerCache)) {
1624                                 innermostIntersecting = true;
1625                                 $.each(inst.sortables, function () {
1626                                         this.instance.positionAbs = inst.positionAbs;
1627                                         this.instance.helperProportions = inst.helperProportions;
1628                                         this.instance.offset.click = inst.offset.click;
1629                                         if (this !== thisSortable &&
1630                                                 this.instance._intersectsWith(this.instance.containerCache) &&
1631                                                 $.contains(thisSortable.instance.element[0], this.instance.element[0])
1632                                         ) {
1633                                                 innermostIntersecting = false;
1634                                         }
1635                                         return innermostIntersecting;
1636                                 });
1637                         }
1638
1639
1640                         if(innermostIntersecting) {
1641                                 //If it intersects, we use a little isOver variable and set it once, so our move-in stuff gets fired only once
1642                                 if(!this.instance.isOver) {
1643
1644                                         this.instance.isOver = 1;
1645                                         //Now we fake the start of dragging for the sortable instance,
1646                                         //by cloning the list group item, appending it to the sortable and using it as inst.currentItem
1647                                         //We can then fire the start event of the sortable with our passed browser event, and our own helper (so it doesn't create a new one)
1648                                         this.instance.currentItem = $(that).clone().removeAttr("id").appendTo(this.instance.element).data("ui-sortable-item", true);
1649                                         this.instance.options._helper = this.instance.options.helper; //Store helper option to later restore it
1650                                         this.instance.options.helper = function() { return ui.helper[0]; };
1651
1652                                         event.target = this.instance.currentItem[0];
1653                                         this.instance._mouseCapture(event, true);
1654                                         this.instance._mouseStart(event, true, true);
1655
1656                                         //Because the browser event is way off the new appended portlet, we modify a couple of variables to reflect the changes
1657                                         this.instance.offset.click.top = inst.offset.click.top;
1658                                         this.instance.offset.click.left = inst.offset.click.left;
1659                                         this.instance.offset.parent.left -= inst.offset.parent.left - this.instance.offset.parent.left;
1660                                         this.instance.offset.parent.top -= inst.offset.parent.top - this.instance.offset.parent.top;
1661
1662                                         inst._trigger("toSortable", event);
1663                                         inst.dropped = this.instance.element; //draggable revert needs that
1664                                         //hack so receive/update callbacks work (mostly)
1665                                         inst.currentItem = inst.element;
1666                                         this.instance.fromOutside = inst;
1667
1668                                 }
1669
1670                                 //Provided we did all the previous steps, we can fire the drag event of the sortable on every draggable drag, when it intersects with the sortable
1671                                 if(this.instance.currentItem) {
1672                                         this.instance._mouseDrag(event);
1673                                 }
1674
1675                         } else {
1676
1677                                 //If it doesn't intersect with the sortable, and it intersected before,
1678                                 //we fake the drag stop of the sortable, but make sure it doesn't remove the helper by using cancelHelperRemoval
1679                                 if(this.instance.isOver) {
1680
1681                                         this.instance.isOver = 0;
1682                                         this.instance.cancelHelperRemoval = true;
1683
1684                                         //Prevent reverting on this forced stop
1685                                         this.instance.options.revert = false;
1686
1687                                         // The out event needs to be triggered independently
1688                                         this.instance._trigger("out", event, this.instance._uiHash(this.instance));
1689
1690                                         this.instance._mouseStop(event, true);
1691                                         this.instance.options.helper = this.instance.options._helper;
1692
1693                                         //Now we remove our currentItem, the list group clone again, and the placeholder, and animate the helper back to it's original size
1694                                         this.instance.currentItem.remove();
1695                                         if(this.instance.placeholder) {
1696                                                 this.instance.placeholder.remove();
1697                                         }
1698
1699                                         inst._trigger("fromSortable", event);
1700                                         inst.dropped = false; //draggable revert needs that
1701                                 }
1702
1703                         }
1704
1705                 });
1706
1707         }
1708 });
1709
1710 $.ui.plugin.add("draggable", "cursor", {
1711         start: function() {
1712                 var t = $("body"), o = $(this).data("ui-draggable").options;
1713                 if (t.css("cursor")) {
1714                         o._cursor = t.css("cursor");
1715                 }
1716                 t.css("cursor", o.cursor);
1717         },
1718         stop: function() {
1719                 var o = $(this).data("ui-draggable").options;
1720                 if (o._cursor) {
1721                         $("body").css("cursor", o._cursor);
1722                 }
1723         }
1724 });
1725
1726 $.ui.plugin.add("draggable", "opacity", {
1727         start: function(event, ui) {
1728                 var t = $(ui.helper), o = $(this).data("ui-draggable").options;
1729                 if(t.css("opacity")) {
1730                         o._opacity = t.css("opacity");
1731                 }
1732                 t.css("opacity", o.opacity);
1733         },
1734         stop: function(event, ui) {
1735                 var o = $(this).data("ui-draggable").options;
1736                 if(o._opacity) {
1737                         $(ui.helper).css("opacity", o._opacity);
1738                 }
1739         }
1740 });
1741
1742 $.ui.plugin.add("draggable", "scroll", {
1743         start: function() {
1744                 var i = $(this).data("ui-draggable");
1745                 if(i.scrollParent[0] !== document && i.scrollParent[0].tagName !== "HTML") {
1746                         i.overflowOffset = i.scrollParent.offset();
1747                 }
1748         },
1749         drag: function( event ) {
1750
1751                 var i = $(this).data("ui-draggable"), o = i.options, scrolled = false;
1752
1753                 if(i.scrollParent[0] !== document && i.scrollParent[0].tagName !== "HTML") {
1754
1755                         if(!o.axis || o.axis !== "x") {
1756                                 if((i.overflowOffset.top + i.scrollParent[0].offsetHeight) - event.pageY < o.scrollSensitivity) {
1757                                         i.scrollParent[0].scrollTop = scrolled = i.scrollParent[0].scrollTop + o.scrollSpeed;
1758                                 } else if(event.pageY - i.overflowOffset.top < o.scrollSensitivity) {
1759                                         i.scrollParent[0].scrollTop = scrolled = i.scrollParent[0].scrollTop - o.scrollSpeed;
1760                                 }
1761                         }
1762
1763                         if(!o.axis || o.axis !== "y") {
1764                                 if((i.overflowOffset.left + i.scrollParent[0].offsetWidth) - event.pageX < o.scrollSensitivity) {
1765                                         i.scrollParent[0].scrollLeft = scrolled = i.scrollParent[0].scrollLeft + o.scrollSpeed;
1766                                 } else if(event.pageX - i.overflowOffset.left < o.scrollSensitivity) {
1767                                         i.scrollParent[0].scrollLeft = scrolled = i.scrollParent[0].scrollLeft - o.scrollSpeed;
1768                                 }
1769                         }
1770
1771                 } else {
1772
1773                         if(!o.axis || o.axis !== "x") {
1774                                 if(event.pageY - $(document).scrollTop() < o.scrollSensitivity) {
1775                                         scrolled = $(document).scrollTop($(document).scrollTop() - o.scrollSpeed);
1776                                 } else if($(window).height() - (event.pageY - $(document).scrollTop()) < o.scrollSensitivity) {
1777                                         scrolled = $(document).scrollTop($(document).scrollTop() + o.scrollSpeed);
1778                                 }
1779                         }
1780
1781                         if(!o.axis || o.axis !== "y") {
1782                                 if(event.pageX - $(document).scrollLeft() < o.scrollSensitivity) {
1783                                         scrolled = $(document).scrollLeft($(document).scrollLeft() - o.scrollSpeed);
1784                                 } else if($(window).width() - (event.pageX - $(document).scrollLeft()) < o.scrollSensitivity) {
1785                                         scrolled = $(document).scrollLeft($(document).scrollLeft() + o.scrollSpeed);
1786                                 }
1787                         }
1788
1789                 }
1790
1791                 if(scrolled !== false && $.ui.ddmanager && !o.dropBehaviour) {
1792                         $.ui.ddmanager.prepareOffsets(i, event);
1793                 }
1794
1795         }
1796 });
1797
1798 $.ui.plugin.add("draggable", "snap", {
1799         start: function() {
1800
1801                 var i = $(this).data("ui-draggable"),
1802                         o = i.options;
1803
1804                 i.snapElements = [];
1805
1806                 $(o.snap.constructor !== String ? ( o.snap.items || ":data(ui-draggable)" ) : o.snap).each(function() {
1807                         var $t = $(this),
1808                                 $o = $t.offset();
1809                         if(this !== i.element[0]) {
1810                                 i.snapElements.push({
1811                                         item: this,
1812                                         width: $t.outerWidth(), height: $t.outerHeight(),
1813                                         top: $o.top, left: $o.left
1814                                 });
1815                         }
1816                 });
1817
1818         },
1819         drag: function(event, ui) {
1820
1821                 var ts, bs, ls, rs, l, r, t, b, i, first,
1822                         inst = $(this).data("ui-draggable"),
1823                         o = inst.options,
1824                         d = o.snapTolerance,
1825                         x1 = ui.offset.left, x2 = x1 + inst.helperProportions.width,
1826                         y1 = ui.offset.top, y2 = y1 + inst.helperProportions.height;
1827
1828                 for (i = inst.snapElements.length - 1; i >= 0; i--){
1829
1830                         l = inst.snapElements[i].left;
1831                         r = l + inst.snapElements[i].width;
1832                         t = inst.snapElements[i].top;
1833                         b = t + inst.snapElements[i].height;
1834
1835                         if ( x2 < l - d || x1 > r + d || y2 < t - d || y1 > b + d || !$.contains( inst.snapElements[ i ].item.ownerDocument, inst.snapElements[ i ].item ) ) {
1836                                 if(inst.snapElements[i].snapping) {
1837                                         (inst.options.snap.release && inst.options.snap.release.call(inst.element, event, $.extend(inst._uiHash(), { snapItem: inst.snapElements[i].item })));
1838                                 }
1839                                 inst.snapElements[i].snapping = false;
1840                                 continue;
1841                         }
1842
1843                         if(o.snapMode !== "inner") {
1844                                 ts = Math.abs(t - y2) <= d;
1845                                 bs = Math.abs(b - y1) <= d;
1846                                 ls = Math.abs(l - x2) <= d;
1847                                 rs = Math.abs(r - x1) <= d;
1848                                 if(ts) {
1849                                         ui.position.top = inst._convertPositionTo("relative", { top: t - inst.helperProportions.height, left: 0 }).top - inst.margins.top;
1850                                 }
1851                                 if(bs) {
1852                                         ui.position.top = inst._convertPositionTo("relative", { top: b, left: 0 }).top - inst.margins.top;
1853                                 }
1854                                 if(ls) {
1855                                         ui.position.left = inst._convertPositionTo("relative", { top: 0, left: l - inst.helperProportions.width }).left - inst.margins.left;
1856                                 }
1857                                 if(rs) {
1858                                         ui.position.left = inst._convertPositionTo("relative", { top: 0, left: r }).left - inst.margins.left;
1859                                 }
1860                         }
1861
1862                         first = (ts || bs || ls || rs);
1863
1864                         if(o.snapMode !== "outer") {
1865                                 ts = Math.abs(t - y1) <= d;
1866                                 bs = Math.abs(b - y2) <= d;
1867                                 ls = Math.abs(l - x1) <= d;
1868                                 rs = Math.abs(r - x2) <= d;
1869                                 if(ts) {
1870                                         ui.position.top = inst._convertPositionTo("relative", { top: t, left: 0 }).top - inst.margins.top;
1871                                 }
1872                                 if(bs) {
1873                                         ui.position.top = inst._convertPositionTo("relative", { top: b - inst.helperProportions.height, left: 0 }).top - inst.margins.top;
1874                                 }
1875                                 if(ls) {
1876                                         ui.position.left = inst._convertPositionTo("relative", { top: 0, left: l }).left - inst.margins.left;
1877                                 }
1878                                 if(rs) {
1879                                         ui.position.left = inst._convertPositionTo("relative", { top: 0, left: r - inst.helperProportions.width }).left - inst.margins.left;
1880                                 }
1881                         }
1882
1883                         if(!inst.snapElements[i].snapping && (ts || bs || ls || rs || first)) {
1884                                 (inst.options.snap.snap && inst.options.snap.snap.call(inst.element, event, $.extend(inst._uiHash(), { snapItem: inst.snapElements[i].item })));
1885                         }
1886                         inst.snapElements[i].snapping = (ts || bs || ls || rs || first);
1887
1888                 }
1889
1890         }
1891 });
1892
1893 $.ui.plugin.add("draggable", "stack", {
1894         start: function() {
1895                 var min,
1896                         o = this.data("ui-draggable").options,
1897                         group = $.makeArray($(o.stack)).sort(function(a,b) {
1898                                 return (parseInt($(a).css("zIndex"),10) || 0) - (parseInt($(b).css("zIndex"),10) || 0);
1899                         });
1900
1901                 if (!group.length) { return; }
1902
1903                 min = parseInt($(group[0]).css("zIndex"), 10) || 0;
1904                 $(group).each(function(i) {
1905                         $(this).css("zIndex", min + i);
1906                 });
1907                 this.css("zIndex", (min + group.length));
1908         }
1909 });
1910
1911 $.ui.plugin.add("draggable", "zIndex", {
1912         start: function(event, ui) {
1913                 var t = $(ui.helper), o = $(this).data("ui-draggable").options;
1914                 if(t.css("zIndex")) {
1915                         o._zIndex = t.css("zIndex");
1916                 }
1917                 t.css("zIndex", o.zIndex);
1918         },
1919         stop: function(event, ui) {
1920                 var o = $(this).data("ui-draggable").options;
1921                 if(o._zIndex) {
1922                         $(ui.helper).css("zIndex", o._zIndex);
1923                 }
1924         }
1925 });
1926
1927 })(jQuery);
1928
1929 (function( $, undefined ) {
1930
1931 function isOverAxis( x, reference, size ) {
1932         return ( x > reference ) && ( x < ( reference + size ) );
1933 }
1934
1935 $.widget("ui.droppable", {
1936         version: "1.10.3",
1937         widgetEventPrefix: "drop",
1938         options: {
1939                 accept: "*",
1940                 activeClass: false,
1941                 addClasses: true,
1942                 greedy: false,
1943                 hoverClass: false,
1944                 scope: "default",
1945                 tolerance: "intersect",
1946
1947                 // callbacks
1948                 activate: null,
1949                 deactivate: null,
1950                 drop: null,
1951                 out: null,
1952                 over: null
1953         },
1954         _create: function() {
1955
1956                 var o = this.options,
1957                         accept = o.accept;
1958
1959                 this.isover = false;
1960                 this.isout = true;
1961
1962                 this.accept = $.isFunction(accept) ? accept : function(d) {
1963                         return d.is(accept);
1964                 };
1965
1966                 //Store the droppable's proportions
1967                 this.proportions = { width: this.element[0].offsetWidth, height: this.element[0].offsetHeight };
1968
1969                 // Add the reference and positions to the manager
1970                 $.ui.ddmanager.droppables[o.scope] = $.ui.ddmanager.droppables[o.scope] || [];
1971                 $.ui.ddmanager.droppables[o.scope].push(this);
1972
1973                 (o.addClasses && this.element.addClass("ui-droppable"));
1974
1975         },
1976
1977         _destroy: function() {
1978                 var i = 0,
1979                         drop = $.ui.ddmanager.droppables[this.options.scope];
1980
1981                 for ( ; i < drop.length; i++ ) {
1982                         if ( drop[i] === this ) {
1983                                 drop.splice(i, 1);
1984                         }
1985                 }
1986
1987                 this.element.removeClass("ui-droppable ui-droppable-disabled");
1988         },
1989
1990         _setOption: function(key, value) {
1991
1992                 if(key === "accept") {
1993                         this.accept = $.isFunction(value) ? value : function(d) {
1994                                 return d.is(value);
1995                         };
1996                 }
1997                 $.Widget.prototype._setOption.apply(this, arguments);
1998         },
1999
2000         _activate: function(event) {
2001                 var draggable = $.ui.ddmanager.current;
2002                 if(this.options.activeClass) {
2003                         this.element.addClass(this.options.activeClass);
2004                 }
2005                 if(draggable){
2006                         this._trigger("activate", event, this.ui(draggable));
2007                 }
2008         },
2009
2010         _deactivate: function(event) {
2011                 var draggable = $.ui.ddmanager.current;
2012                 if(this.options.activeClass) {
2013                         this.element.removeClass(this.options.activeClass);
2014                 }
2015                 if(draggable){
2016                         this._trigger("deactivate", event, this.ui(draggable));
2017                 }
2018         },
2019
2020         _over: function(event) {
2021
2022                 var draggable = $.ui.ddmanager.current;
2023
2024                 // Bail if draggable and droppable are same element
2025                 if (!draggable || (draggable.currentItem || draggable.element)[0] === this.element[0]) {
2026                         return;
2027                 }
2028
2029                 if (this.accept.call(this.element[0],(draggable.currentItem || draggable.element))) {
2030                         if(this.options.hoverClass) {
2031                                 this.element.addClass(this.options.hoverClass);
2032                         }
2033                         this._trigger("over", event, this.ui(draggable));
2034                 }
2035
2036         },
2037
2038         _out: function(event) {
2039
2040                 var draggable = $.ui.ddmanager.current;
2041
2042                 // Bail if draggable and droppable are same element
2043                 if (!draggable || (draggable.currentItem || draggable.element)[0] === this.element[0]) {
2044                         return;
2045                 }
2046
2047                 if (this.accept.call(this.element[0],(draggable.currentItem || draggable.element))) {
2048                         if(this.options.hoverClass) {
2049                                 this.element.removeClass(this.options.hoverClass);
2050                         }
2051                         this._trigger("out", event, this.ui(draggable));
2052                 }
2053
2054         },
2055
2056         _drop: function(event,custom) {
2057
2058                 var draggable = custom || $.ui.ddmanager.current,
2059                         childrenIntersection = false;
2060
2061                 // Bail if draggable and droppable are same element
2062                 if (!draggable || (draggable.currentItem || draggable.element)[0] === this.element[0]) {
2063                         return false;
2064                 }
2065
2066                 this.element.find(":data(ui-droppable)").not(".ui-draggable-dragging").each(function() {
2067                         var inst = $.data(this, "ui-droppable");
2068                         if(
2069                                 inst.options.greedy &&
2070                                 !inst.options.disabled &&
2071                                 inst.options.scope === draggable.options.scope &&
2072                                 inst.accept.call(inst.element[0], (draggable.currentItem || draggable.element)) &&
2073                                 $.ui.intersect(draggable, $.extend(inst, { offset: inst.element.offset() }), inst.options.tolerance)
2074                         ) { childrenIntersection = true; return false; }
2075                 });
2076                 if(childrenIntersection) {
2077                         return false;
2078                 }
2079
2080                 if(this.accept.call(this.element[0],(draggable.currentItem || draggable.element))) {
2081                         if(this.options.activeClass) {
2082                                 this.element.removeClass(this.options.activeClass);
2083                         }
2084                         if(this.options.hoverClass) {
2085                                 this.element.removeClass(this.options.hoverClass);
2086                         }
2087                         this._trigger("drop", event, this.ui(draggable));
2088                         return this.element;
2089                 }
2090
2091                 return false;
2092
2093         },
2094
2095         ui: function(c) {
2096                 return {
2097                         draggable: (c.currentItem || c.element),
2098                         helper: c.helper,
2099                         position: c.position,
2100                         offset: c.positionAbs
2101                 };
2102         }
2103
2104 });
2105
2106 $.ui.intersect = function(draggable, droppable, toleranceMode) {
2107
2108         if (!droppable.offset) {
2109                 return false;
2110         }
2111
2112         var draggableLeft, draggableTop,
2113                 x1 = (draggable.positionAbs || draggable.position.absolute).left, x2 = x1 + draggable.helperProportions.width,
2114                 y1 = (draggable.positionAbs || draggable.position.absolute).top, y2 = y1 + draggable.helperProportions.height,
2115                 l = droppable.offset.left, r = l + droppable.proportions.width,
2116                 t = droppable.offset.top, b = t + droppable.proportions.height;
2117
2118         switch (toleranceMode) {
2119                 case "fit":
2120                         return (l <= x1 && x2 <= r && t <= y1 && y2 <= b);
2121                 case "intersect":
2122                         return (l < x1 + (draggable.helperProportions.width / 2) && // Right Half
2123                                 x2 - (draggable.helperProportions.width / 2) < r && // Left Half
2124                                 t < y1 + (draggable.helperProportions.height / 2) && // Bottom Half
2125                                 y2 - (draggable.helperProportions.height / 2) < b ); // Top Half
2126                 case "pointer":
2127                         draggableLeft = ((draggable.positionAbs || draggable.position.absolute).left + (draggable.clickOffset || draggable.offset.click).left);
2128                         draggableTop = ((draggable.positionAbs || draggable.position.absolute).top + (draggable.clickOffset || draggable.offset.click).top);
2129                         return isOverAxis( draggableTop, t, droppable.proportions.height ) && isOverAxis( draggableLeft, l, droppable.proportions.width );
2130                 case "touch":
2131                         return (
2132                                 (y1 >= t && y1 <= b) || // Top edge touching
2133                                 (y2 >= t && y2 <= b) || // Bottom edge touching
2134                                 (y1 < t && y2 > b)              // Surrounded vertically
2135                         ) && (
2136                                 (x1 >= l && x1 <= r) || // Left edge touching
2137                                 (x2 >= l && x2 <= r) || // Right edge touching
2138                                 (x1 < l && x2 > r)              // Surrounded horizontally
2139                         );
2140                 default:
2141                         return false;
2142                 }
2143
2144 };
2145
2146 /*
2147         This manager tracks offsets of draggables and droppables
2148 */
2149 $.ui.ddmanager = {
2150         current: null,
2151         droppables: { "default": [] },
2152         prepareOffsets: function(t, event) {
2153
2154                 var i, j,
2155                         m = $.ui.ddmanager.droppables[t.options.scope] || [],
2156                         type = event ? event.type : null, // workaround for #2317
2157                         list = (t.currentItem || t.element).find(":data(ui-droppable)").addBack();
2158
2159                 droppablesLoop: for (i = 0; i < m.length; i++) {
2160
2161                         //No disabled and non-accepted
2162                         if(m[i].options.disabled || (t && !m[i].accept.call(m[i].element[0],(t.currentItem || t.element)))) {
2163                                 continue;
2164                         }
2165
2166                         // Filter out elements in the current dragged item
2167                         for (j=0; j < list.length; j++) {
2168                                 if(list[j] === m[i].element[0]) {
2169                                         m[i].proportions.height = 0;
2170                                         continue droppablesLoop;
2171                                 }
2172                         }
2173
2174                         m[i].visible = m[i].element.css("display") !== "none";
2175                         if(!m[i].visible) {
2176                                 continue;
2177                         }
2178
2179                         //Activate the droppable if used directly from draggables
2180                         if(type === "mousedown") {
2181                                 m[i]._activate.call(m[i], event);
2182                         }
2183
2184                         m[i].offset = m[i].element.offset();
2185                         m[i].proportions = { width: m[i].element[0].offsetWidth, height: m[i].element[0].offsetHeight };
2186
2187                 }
2188
2189         },
2190         drop: function(draggable, event) {
2191
2192                 var dropped = false;
2193                 // Create a copy of the droppables in case the list changes during the drop (#9116)
2194                 $.each(($.ui.ddmanager.droppables[draggable.options.scope] || []).slice(), function() {
2195
2196                         if(!this.options) {
2197                                 return;
2198                         }
2199                         if (!this.options.disabled && this.visible && $.ui.intersect(draggable, this, this.options.tolerance)) {
2200                                 dropped = this._drop.call(this, event) || dropped;
2201                         }
2202
2203                         if (!this.options.disabled && this.visible && this.accept.call(this.element[0],(draggable.currentItem || draggable.element))) {
2204                                 this.isout = true;
2205                                 this.isover = false;
2206                                 this._deactivate.call(this, event);
2207                         }
2208
2209                 });
2210                 return dropped;
2211
2212         },
2213         dragStart: function( draggable, event ) {
2214                 //Listen for scrolling so that if the dragging causes scrolling the position of the droppables can be recalculated (see #5003)
2215                 draggable.element.parentsUntil( "body" ).bind( "scroll.droppable", function() {
2216                         if( !draggable.options.refreshPositions ) {
2217                                 $.ui.ddmanager.prepareOffsets( draggable, event );
2218                         }
2219                 });
2220         },
2221         drag: function(draggable, event) {
2222
2223                 //If you have a highly dynamic page, you might try this option. It renders positions every time you move the mouse.
2224                 if(draggable.options.refreshPositions) {
2225                         $.ui.ddmanager.prepareOffsets(draggable, event);
2226                 }
2227
2228                 //Run through all droppables and check their positions based on specific tolerance options
2229                 $.each($.ui.ddmanager.droppables[draggable.options.scope] || [], function() {
2230
2231                         if(this.options.disabled || this.greedyChild || !this.visible) {
2232                                 return;
2233                         }
2234
2235                         var parentInstance, scope, parent,
2236                                 intersects = $.ui.intersect(draggable, this, this.options.tolerance),
2237                                 c = !intersects && this.isover ? "isout" : (intersects && !this.isover ? "isover" : null);
2238                         if(!c) {
2239                                 return;
2240                         }
2241
2242                         if (this.options.greedy) {
2243                                 // find droppable parents with same scope
2244                                 scope = this.options.scope;
2245                                 parent = this.element.parents(":data(ui-droppable)").filter(function () {
2246                                         return $.data(this, "ui-droppable").options.scope === scope;
2247                                 });
2248
2249                                 if (parent.length) {
2250                                         parentInstance = $.data(parent[0], "ui-droppable");
2251                                         parentInstance.greedyChild = (c === "isover");
2252                                 }
2253                         }
2254
2255                         // we just moved into a greedy child
2256                         if (parentInstance && c === "isover") {
2257                                 parentInstance.isover = false;
2258                                 parentInstance.isout = true;
2259                                 parentInstance._out.call(parentInstance, event);
2260                         }
2261
2262                         this[c] = true;
2263                         this[c === "isout" ? "isover" : "isout"] = false;
2264                         this[c === "isover" ? "_over" : "_out"].call(this, event);
2265
2266                         // we just moved out of a greedy child
2267                         if (parentInstance && c === "isout") {
2268                                 parentInstance.isout = false;
2269                                 parentInstance.isover = true;
2270                                 parentInstance._over.call(parentInstance, event);
2271                         }
2272                 });
2273
2274         },
2275         dragStop: function( draggable, event ) {
2276                 draggable.element.parentsUntil( "body" ).unbind( "scroll.droppable" );
2277                 //Call prepareOffsets one final time since IE does not fire return scroll events when overflow was caused by drag (see #5003)
2278                 if( !draggable.options.refreshPositions ) {
2279                         $.ui.ddmanager.prepareOffsets( draggable, event );
2280                 }
2281         }
2282 };
2283
2284 })(jQuery);
2285
2286 (function( $, undefined ) {
2287
2288 function num(v) {
2289         return parseInt(v, 10) || 0;
2290 }
2291
2292 function isNumber(value) {
2293         return !isNaN(parseInt(value, 10));
2294 }
2295
2296 $.widget("ui.resizable", $.ui.mouse, {
2297         version: "1.10.3",
2298         widgetEventPrefix: "resize",
2299         options: {
2300                 alsoResize: false,
2301                 animate: false,
2302                 animateDuration: "slow",
2303                 animateEasing: "swing",
2304                 aspectRatio: false,
2305                 autoHide: false,
2306                 containment: false,
2307                 ghost: false,
2308                 grid: false,
2309                 handles: "e,s,se",
2310                 helper: false,
2311                 maxHeight: null,
2312                 maxWidth: null,
2313                 minHeight: 10,
2314                 minWidth: 10,
2315                 // See #7960
2316                 zIndex: 90,
2317
2318                 // callbacks
2319                 resize: null,
2320                 start: null,
2321                 stop: null
2322         },
2323         _create: function() {
2324
2325                 var n, i, handle, axis, hname,
2326                         that = this,
2327                         o = this.options;
2328                 this.element.addClass("ui-resizable");
2329
2330                 $.extend(this, {
2331                         _aspectRatio: !!(o.aspectRatio),
2332                         aspectRatio: o.aspectRatio,
2333                         originalElement: this.element,
2334                         _proportionallyResizeElements: [],
2335                         _helper: o.helper || o.ghost || o.animate ? o.helper || "ui-resizable-helper" : null
2336                 });
2337
2338                 //Wrap the element if it cannot hold child nodes
2339                 if(this.element[0].nodeName.match(/canvas|textarea|input|select|button|img/i)) {
2340
2341                         //Create a wrapper element and set the wrapper to the new current internal element
2342                         this.element.wrap(
2343                                 $("<div class='ui-wrapper' style='overflow: hidden;'></div>").css({
2344                                         position: this.element.css("position"),
2345                                         width: this.element.outerWidth(),
2346                                         height: this.element.outerHeight(),
2347                                         top: this.element.css("top"),
2348                                         left: this.element.css("left")
2349                                 })
2350                         );
2351
2352                         //Overwrite the original this.element
2353                         this.element = this.element.parent().data(
2354                                 "ui-resizable", this.element.data("ui-resizable")
2355                         );
2356
2357                         this.elementIsWrapper = true;
2358
2359                         //Move margins to the wrapper
2360                         this.element.css({ marginLeft: this.originalElement.css("marginLeft"), marginTop: this.originalElement.css("marginTop"), marginRight: this.originalElement.css("marginRight"), marginBottom: this.originalElement.css("marginBottom") });
2361                         this.originalElement.css({ marginLeft: 0, marginTop: 0, marginRight: 0, marginBottom: 0});
2362
2363                         //Prevent Safari textarea resize
2364                         this.originalResizeStyle = this.originalElement.css("resize");
2365                         this.originalElement.css("resize", "none");
2366
2367                         //Push the actual element to our proportionallyResize internal array
2368                         this._proportionallyResizeElements.push(this.originalElement.css({ position: "static", zoom: 1, display: "block" }));
2369
2370                         // avoid IE jump (hard set the margin)
2371                         this.originalElement.css({ margin: this.originalElement.css("margin") });
2372
2373                         // fix handlers offset
2374                         this._proportionallyResize();
2375
2376                 }
2377
2378                 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" });
2379                 if(this.handles.constructor === String) {
2380
2381                         if ( this.handles === "all") {
2382                                 this.handles = "n,e,s,w,se,sw,ne,nw";
2383                         }
2384
2385                         n = this.handles.split(",");
2386                         this.handles = {};
2387
2388                         for(i = 0; i < n.length; i++) {
2389
2390                                 handle = $.trim(n[i]);
2391                                 hname = "ui-resizable-"+handle;
2392                                 axis = $("<div class='ui-resizable-handle " + hname + "'></div>");
2393
2394                                 // Apply zIndex to all handles - see #7960
2395                                 axis.css({ zIndex: o.zIndex });
2396
2397                                 //TODO : What's going on here?
2398                                 if ("se" === handle) {
2399                                         axis.addClass("ui-icon ui-icon-gripsmall-diagonal-se");
2400                                 }
2401
2402                                 //Insert into internal handles object and append to element
2403                                 this.handles[handle] = ".ui-resizable-"+handle;
2404                                 this.element.append(axis);
2405                         }
2406
2407                 }
2408
2409                 this._renderAxis = function(target) {
2410
2411                         var i, axis, padPos, padWrapper;
2412
2413                         target = target || this.element;
2414
2415                         for(i in this.handles) {
2416
2417                                 if(this.handles[i].constructor === String) {
2418                                         this.handles[i] = $(this.handles[i], this.element).show();
2419                                 }
2420
2421                                 //Apply pad to wrapper element, needed to fix axis position (textarea, inputs, scrolls)
2422                                 if (this.elementIsWrapper && this.originalElement[0].nodeName.match(/textarea|input|select|button/i)) {
2423
2424                                         axis = $(this.handles[i], this.element);
2425
2426                                         //Checking the correct pad and border
2427                                         padWrapper = /sw|ne|nw|se|n|s/.test(i) ? axis.outerHeight() : axis.outerWidth();
2428
2429                                         //The padding type i have to apply...
2430                                         padPos = [ "padding",
2431                                                 /ne|nw|n/.test(i) ? "Top" :
2432                                                 /se|sw|s/.test(i) ? "Bottom" :
2433                                                 /^e$/.test(i) ? "Right" : "Left" ].join("");
2434
2435                                         target.css(padPos, padWrapper);
2436
2437                                         this._proportionallyResize();
2438
2439                                 }
2440
2441                                 //TODO: What's that good for? There's not anything to be executed left
2442                                 if(!$(this.handles[i]).length) {
2443                                         continue;
2444                                 }
2445                         }
2446                 };
2447
2448                 //TODO: make renderAxis a prototype function
2449                 this._renderAxis(this.element);
2450
2451                 this._handles = $(".ui-resizable-handle", this.element)
2452                         .disableSelection();
2453
2454                 //Matching axis name
2455                 this._handles.mouseover(function() {
2456                         if (!that.resizing) {
2457                                 if (this.className) {
2458                                         axis = this.className.match(/ui-resizable-(se|sw|ne|nw|n|e|s|w)/i);
2459                                 }
2460                                 //Axis, default = se
2461                                 that.axis = axis && axis[1] ? axis[1] : "se";
2462                         }
2463                 });
2464
2465                 //If we want to auto hide the elements
2466                 if (o.autoHide) {
2467                         this._handles.hide();
2468                         $(this.element)
2469                                 .addClass("ui-resizable-autohide")
2470                                 .mouseenter(function() {
2471                                         if (o.disabled) {
2472                                                 return;
2473                                         }
2474                                         $(this).removeClass("ui-resizable-autohide");
2475                                         that._handles.show();
2476                                 })
2477                                 .mouseleave(function(){
2478                                         if (o.disabled) {
2479                                                 return;
2480                                         }
2481                                         if (!that.resizing) {
2482                                                 $(this).addClass("ui-resizable-autohide");
2483                                                 that._handles.hide();
2484                                         }
2485                                 });
2486                 }
2487
2488                 //Initialize the mouse interaction
2489                 this._mouseInit();
2490
2491         },
2492
2493         _destroy: function() {
2494
2495                 this._mouseDestroy();
2496
2497                 var wrapper,
2498                         _destroy = function(exp) {
2499                                 $(exp).removeClass("ui-resizable ui-resizable-disabled ui-resizable-resizing")
2500                                         .removeData("resizable").removeData("ui-resizable").unbind(".resizable").find(".ui-resizable-handle").remove();
2501                         };
2502
2503                 //TODO: Unwrap at same DOM position
2504                 if (this.elementIsWrapper) {
2505                         _destroy(this.element);
2506                         wrapper = this.element;
2507                         this.originalElement.css({
2508                                 position: wrapper.css("position"),
2509                                 width: wrapper.outerWidth(),
2510                                 height: wrapper.outerHeight(),
2511                                 top: wrapper.css("top"),
2512                                 left: wrapper.css("left")
2513                         }).insertAfter( wrapper );
2514                         wrapper.remove();
2515                 }
2516
2517                 this.originalElement.css("resize", this.originalResizeStyle);
2518                 _destroy(this.originalElement);
2519
2520                 return this;
2521         },
2522
2523         _mouseCapture: function(event) {
2524                 var i, handle,
2525                         capture = false;
2526
2527                 for (i in this.handles) {
2528                         handle = $(this.handles[i])[0];
2529                         if (handle === event.target || $.contains(handle, event.target)) {
2530                                 capture = true;
2531                         }
2532                 }
2533
2534                 return !this.options.disabled && capture;
2535         },
2536
2537         _mouseStart: function(event) {
2538
2539                 var curleft, curtop, cursor,
2540                         o = this.options,
2541                         iniPos = this.element.position(),
2542                         el = this.element;
2543
2544                 this.resizing = true;
2545
2546                 // bugfix for http://dev.jquery.com/ticket/1749
2547                 if ( (/absolute/).test( el.css("position") ) ) {
2548                         el.css({ position: "absolute", top: el.css("top"), left: el.css("left") });
2549                 } else if (el.is(".ui-draggable")) {
2550                         el.css({ position: "absolute", top: iniPos.top, left: iniPos.left });
2551                 }
2552
2553                 this._renderProxy();
2554
2555                 curleft = num(this.helper.css("left"));
2556                 curtop = num(this.helper.css("top"));
2557
2558                 if (o.containment) {
2559                         curleft += $(o.containment).scrollLeft() || 0;
2560                         curtop += $(o.containment).scrollTop() || 0;
2561                 }
2562
2563                 //Store needed variables
2564                 this.offset = this.helper.offset();
2565                 this.position = { left: curleft, top: curtop };
2566                 this.size = this._helper ? { width: el.outerWidth(), height: el.outerHeight() } : { width: el.width(), height: el.height() };
2567                 this.originalSize = this._helper ? { width: el.outerWidth(), height: el.outerHeight() } : { width: el.width(), height: el.height() };
2568                 this.originalPosition = { left: curleft, top: curtop };
2569                 this.sizeDiff = { width: el.outerWidth() - el.width(), height: el.outerHeight() - el.height() };
2570                 this.originalMousePosition = { left: event.pageX, top: event.pageY };
2571
2572                 //Aspect Ratio
2573                 this.aspectRatio = (typeof o.aspectRatio === "number") ? o.aspectRatio : ((this.originalSize.width / this.originalSize.height) || 1);
2574
2575                 cursor = $(".ui-resizable-" + this.axis).css("cursor");
2576                 $("body").css("cursor", cursor === "auto" ? this.axis + "-resize" : cursor);
2577
2578                 el.addClass("ui-resizable-resizing");
2579                 this._propagate("start", event);
2580                 return true;
2581         },
2582
2583         _mouseDrag: function(event) {
2584
2585                 //Increase performance, avoid regex
2586                 var data,
2587                         el = this.helper, props = {},
2588                         smp = this.originalMousePosition,
2589                         a = this.axis,
2590                         prevTop = this.position.top,
2591                         prevLeft = this.position.left,
2592                         prevWidth = this.size.width,
2593                         prevHeight = this.size.height,
2594                         dx = (event.pageX-smp.left)||0,
2595                         dy = (event.pageY-smp.top)||0,
2596                         trigger = this._change[a];
2597
2598                 if (!trigger) {
2599                         return false;
2600                 }
2601
2602                 // Calculate the attrs that will be change
2603                 data = trigger.apply(this, [event, dx, dy]);
2604
2605                 // Put this in the mouseDrag handler since the user can start pressing shift while resizing
2606                 this._updateVirtualBoundaries(event.shiftKey);
2607                 if (this._aspectRatio || event.shiftKey) {
2608                         data = this._updateRatio(data, event);
2609                 }
2610
2611                 data = this._respectSize(data, event);
2612
2613                 this._updateCache(data);
2614
2615                 // plugins callbacks need to be called first
2616                 this._propagate("resize", event);
2617
2618                 if (this.position.top !== prevTop) {
2619                         props.top = this.position.top + "px";
2620                 }
2621                 if (this.position.left !== prevLeft) {
2622                         props.left = this.position.left + "px";
2623                 }
2624                 if (this.size.width !== prevWidth) {
2625                         props.width = this.size.width + "px";
2626                 }
2627                 if (this.size.height !== prevHeight) {
2628                         props.height = this.size.height + "px";
2629                 }
2630                 el.css(props);
2631
2632                 if (!this._helper && this._proportionallyResizeElements.length) {
2633                         this._proportionallyResize();
2634                 }
2635
2636                 // Call the user callback if the element was resized
2637                 if ( ! $.isEmptyObject(props) ) {
2638                         this._trigger("resize", event, this.ui());
2639                 }
2640
2641                 return false;
2642         },
2643
2644         _mouseStop: function(event) {
2645
2646                 this.resizing = false;
2647                 var pr, ista, soffseth, soffsetw, s, left, top,
2648                         o = this.options, that = this;
2649
2650                 if(this._helper) {
2651
2652                         pr = this._proportionallyResizeElements;
2653                         ista = pr.length && (/textarea/i).test(pr[0].nodeName);
2654                         soffseth = ista && $.ui.hasScroll(pr[0], "left") /* TODO - jump height */ ? 0 : that.sizeDiff.height;
2655                         soffsetw = ista ? 0 : that.sizeDiff.width;
2656
2657                         s = { width: (that.helper.width()  - soffsetw), height: (that.helper.height() - soffseth) };
2658                         left = (parseInt(that.element.css("left"), 10) + (that.position.left - that.originalPosition.left)) || null;
2659                         top = (parseInt(that.element.css("top"), 10) + (that.position.top - that.originalPosition.top)) || null;
2660
2661                         if (!o.animate) {
2662                                 this.element.css($.extend(s, { top: top, left: left }));
2663                         }
2664
2665                         that.helper.height(that.size.height);
2666                         that.helper.width(that.size.width);
2667
2668                         if (this._helper && !o.animate) {
2669                                 this._proportionallyResize();
2670                         }
2671                 }
2672
2673                 $("body").css("cursor", "auto");
2674
2675                 this.element.removeClass("ui-resizable-resizing");
2676
2677                 this._propagate("stop", event);
2678
2679                 if (this._helper) {
2680                         this.helper.remove();
2681                 }
2682
2683                 return false;
2684
2685         },
2686
2687         _updateVirtualBoundaries: function(forceAspectRatio) {
2688                 var pMinWidth, pMaxWidth, pMinHeight, pMaxHeight, b,
2689                         o = this.options;
2690
2691                 b = {
2692                         minWidth: isNumber(o.minWidth) ? o.minWidth : 0,
2693                         maxWidth: isNumber(o.maxWidth) ? o.maxWidth : Infinity,
2694                         minHeight: isNumber(o.minHeight) ? o.minHeight : 0,
2695                         maxHeight: isNumber(o.maxHeight) ? o.maxHeight : Infinity
2696                 };
2697
2698                 if(this._aspectRatio || forceAspectRatio) {
2699                         // We want to create an enclosing box whose aspect ration is the requested one
2700                         // First, compute the "projected" size for each dimension based on the aspect ratio and other dimension
2701                         pMinWidth = b.minHeight * this.aspectRatio;
2702                         pMinHeight = b.minWidth / this.aspectRatio;
2703                         pMaxWidth = b.maxHeight * this.aspectRatio;
2704                         pMaxHeight = b.maxWidth / this.aspectRatio;
2705
2706                         if(pMinWidth > b.minWidth) {
2707                                 b.minWidth = pMinWidth;
2708                         }
2709                         if(pMinHeight > b.minHeight) {
2710                                 b.minHeight = pMinHeight;
2711                         }
2712                         if(pMaxWidth < b.maxWidth) {
2713                                 b.maxWidth = pMaxWidth;
2714                         }
2715                         if(pMaxHeight < b.maxHeight) {
2716                                 b.maxHeight = pMaxHeight;
2717                         }
2718                 }
2719                 this._vBoundaries = b;
2720         },
2721
2722         _updateCache: function(data) {
2723                 this.offset = this.helper.offset();
2724                 if (isNumber(data.left)) {
2725                         this.position.left = data.left;
2726                 }
2727                 if (isNumber(data.top)) {
2728                         this.position.top = data.top;
2729                 }
2730                 if (isNumber(data.height)) {
2731                         this.size.height = data.height;
2732                 }
2733                 if (isNumber(data.width)) {
2734                         this.size.width = data.width;
2735                 }
2736         },
2737
2738         _updateRatio: function( data ) {
2739
2740                 var cpos = this.position,
2741                         csize = this.size,
2742                         a = this.axis;
2743
2744                 if (isNumber(data.height)) {
2745                         data.width = (data.height * this.aspectRatio);
2746                 } else if (isNumber(data.width)) {
2747                         data.height = (data.width / this.aspectRatio);
2748                 }
2749
2750                 if (a === "sw") {
2751                         data.left = cpos.left + (csize.width - data.width);
2752                         data.top = null;
2753                 }
2754                 if (a === "nw") {
2755                         data.top = cpos.top + (csize.height - data.height);
2756                         data.left = cpos.left + (csize.width - data.width);
2757                 }
2758
2759                 return data;
2760         },
2761
2762         _respectSize: function( data ) {
2763
2764                 var o = this._vBoundaries,
2765                         a = this.axis,
2766                         ismaxw = isNumber(data.width) && o.maxWidth && (o.maxWidth < data.width), ismaxh = isNumber(data.height) && o.maxHeight && (o.maxHeight < data.height),
2767                         isminw = isNumber(data.width) && o.minWidth && (o.minWidth > data.width), isminh = isNumber(data.height) && o.minHeight && (o.minHeight > data.height),
2768                         dw = this.originalPosition.left + this.originalSize.width,
2769                         dh = this.position.top + this.size.height,
2770                         cw = /sw|nw|w/.test(a), ch = /nw|ne|n/.test(a);
2771                 if (isminw) {
2772                         data.width = o.minWidth;
2773                 }
2774                 if (isminh) {
2775                         data.height = o.minHeight;
2776                 }
2777                 if (ismaxw) {
2778                         data.width = o.maxWidth;
2779                 }
2780                 if (ismaxh) {
2781                         data.height = o.maxHeight;
2782                 }
2783
2784                 if (isminw && cw) {
2785                         data.left = dw - o.minWidth;
2786                 }
2787                 if (ismaxw && cw) {
2788                         data.left = dw - o.maxWidth;
2789                 }
2790                 if (isminh && ch) {
2791                         data.top = dh - o.minHeight;
2792                 }
2793                 if (ismaxh && ch) {
2794                         data.top = dh - o.maxHeight;
2795                 }
2796
2797                 // fixing jump error on top/left - bug #2330
2798                 if (!data.width && !data.height && !data.left && data.top) {
2799                         data.top = null;
2800                 } else if (!data.width && !data.height && !data.top && data.left) {
2801                         data.left = null;
2802                 }
2803
2804                 return data;
2805         },
2806
2807         _proportionallyResize: function() {
2808
2809                 if (!this._proportionallyResizeElements.length) {
2810                         return;
2811                 }
2812
2813                 var i, j, borders, paddings, prel,
2814                         element = this.helper || this.element;
2815
2816                 for ( i=0; i < this._proportionallyResizeElements.length; i++) {
2817
2818                         prel = this._proportionallyResizeElements[i];
2819
2820                         if (!this.borderDif) {
2821                                 this.borderDif = [];
2822                                 borders = [prel.css("borderTopWidth"), prel.css("borderRightWidth"), prel.css("borderBottomWidth"), prel.css("borderLeftWidth")];
2823                                 paddings = [prel.css("paddingTop"), prel.css("paddingRight"), prel.css("paddingBottom"), prel.css("paddingLeft")];
2824
2825                                 for ( j = 0; j < borders.length; j++ ) {
2826                                         this.borderDif[ j ] = ( parseInt( borders[ j ], 10 ) || 0 ) + ( parseInt( paddings[ j ], 10 ) || 0 );
2827                                 }
2828                         }
2829
2830                         prel.css({
2831                                 height: (element.height() - this.borderDif[0] - this.borderDif[2]) || 0,
2832                                 width: (element.width() - this.borderDif[1] - this.borderDif[3]) || 0
2833                         });
2834
2835                 }
2836
2837         },
2838
2839         _renderProxy: function() {
2840
2841                 var el = this.element, o = this.options;
2842                 this.elementOffset = el.offset();
2843
2844                 if(this._helper) {
2845
2846                         this.helper = this.helper || $("<div style='overflow:hidden;'></div>");
2847
2848                         this.helper.addClass(this._helper).css({
2849                                 width: this.element.outerWidth() - 1,
2850                                 height: this.element.outerHeight() - 1,
2851                                 position: "absolute",
2852                                 left: this.elementOffset.left +"px",
2853                                 top: this.elementOffset.top +"px",
2854                                 zIndex: ++o.zIndex //TODO: Don't modify option
2855                         });
2856
2857                         this.helper
2858                                 .appendTo("body")
2859                                 .disableSelection();
2860
2861                 } else {
2862                         this.helper = this.element;
2863                 }
2864
2865         },
2866
2867         _change: {
2868                 e: function(event, dx) {
2869                         return { width: this.originalSize.width + dx };
2870                 },
2871                 w: function(event, dx) {
2872                         var cs = this.originalSize, sp = this.originalPosition;
2873                         return { left: sp.left + dx, width: cs.width - dx };
2874                 },
2875                 n: function(event, dx, dy) {
2876                         var cs = this.originalSize, sp = this.originalPosition;
2877                         return { top: sp.top + dy, height: cs.height - dy };
2878                 },
2879                 s: function(event, dx, dy) {
2880                         return { height: this.originalSize.height + dy };
2881                 },
2882                 se: function(event, dx, dy) {
2883                         return $.extend(this._change.s.apply(this, arguments), this._change.e.apply(this, [event, dx, dy]));
2884                 },
2885                 sw: function(event, dx, dy) {
2886                         return $.extend(this._change.s.apply(this, arguments), this._change.w.apply(this, [event, dx, dy]));
2887                 },
2888                 ne: function(event, dx, dy) {
2889                         return $.extend(this._change.n.apply(this, arguments), this._change.e.apply(this, [event, dx, dy]));
2890                 },
2891                 nw: function(event, dx, dy) {
2892                         return $.extend(this._change.n.apply(this, arguments), this._change.w.apply(this, [event, dx, dy]));
2893                 }
2894         },
2895
2896         _propagate: function(n, event) {
2897                 $.ui.plugin.call(this, n, [event, this.ui()]);
2898                 (n !== "resize" && this._trigger(n, event, this.ui()));
2899         },
2900
2901         plugins: {},
2902
2903         ui: function() {
2904                 return {
2905                         originalElement: this.originalElement,
2906                         element: this.element,
2907                         helper: this.helper,
2908                         position: this.position,
2909                         size: this.size,
2910                         originalSize: this.originalSize,
2911                         originalPosition: this.originalPosition
2912                 };
2913         }
2914
2915 });
2916
2917 /*
2918  * Resizable Extensions
2919  */
2920
2921 $.ui.plugin.add("resizable", "animate", {
2922
2923         stop: function( event ) {
2924                 var that = $(this).data("ui-resizable"),
2925                         o = that.options,
2926                         pr = that._proportionallyResizeElements,
2927                         ista = pr.length && (/textarea/i).test(pr[0].nodeName),
2928                         soffseth = ista && $.ui.hasScroll(pr[0], "left") /* TODO - jump height */ ? 0 : that.sizeDiff.height,
2929                         soffsetw = ista ? 0 : that.sizeDiff.width,
2930                         style = { width: (that.size.width - soffsetw), height: (that.size.height - soffseth) },
2931                         left = (parseInt(that.element.css("left"), 10) + (that.position.left - that.originalPosition.left)) || null,
2932                         top = (parseInt(that.element.css("top"), 10) + (that.position.top - that.originalPosition.top)) || null;
2933
2934                 that.element.animate(
2935                         $.extend(style, top && left ? { top: top, left: left } : {}), {
2936                                 duration: o.animateDuration,
2937                                 easing: o.animateEasing,
2938                                 step: function() {
2939
2940                                         var data = {
2941                                                 width: parseInt(that.element.css("width"), 10),
2942                                                 height: parseInt(that.element.css("height"), 10),
2943                                                 top: parseInt(that.element.css("top"), 10),
2944                                                 left: parseInt(that.element.css("left"), 10)
2945                                         };
2946
2947                                         if (pr && pr.length) {
2948                                                 $(pr[0]).css({ width: data.width, height: data.height });
2949                                         }
2950
2951                                         // propagating resize, and updating values for each animation step
2952                                         that._updateCache(data);
2953                                         that._propagate("resize", event);
2954
2955                                 }
2956                         }
2957                 );
2958         }
2959
2960 });
2961
2962 $.ui.plugin.add("resizable", "containment", {
2963
2964         start: function() {
2965                 var element, p, co, ch, cw, width, height,
2966                         that = $(this).data("ui-resizable"),
2967                         o = that.options,
2968                         el = that.element,
2969                         oc = o.containment,
2970                         ce = (oc instanceof $) ? oc.get(0) : (/parent/.test(oc)) ? el.parent().get(0) : oc;
2971
2972                 if (!ce) {
2973                         return;
2974                 }
2975
2976                 that.containerElement = $(ce);
2977
2978                 if (/document/.test(oc) || oc === document) {
2979                         that.containerOffset = { left: 0, top: 0 };
2980                         that.containerPosition = { left: 0, top: 0 };
2981
2982                         that.parentData = {
2983                                 element: $(document), left: 0, top: 0,
2984                                 width: $(document).width(), height: $(document).height() || document.body.parentNode.scrollHeight
2985                         };
2986                 }
2987
2988                 // i'm a node, so compute top, left, right, bottom
2989                 else {
2990                         element = $(ce);
2991                         p = [];
2992                         $([ "Top", "Right", "Left", "Bottom" ]).each(function(i, name) { p[i] = num(element.css("padding" + name)); });
2993
2994                         that.containerOffset = element.offset();
2995                         that.containerPosition = element.position();
2996                         that.containerSize = { height: (element.innerHeight() - p[3]), width: (element.innerWidth() - p[1]) };
2997
2998                         co = that.containerOffset;
2999                         ch = that.containerSize.height;
3000                         cw = that.containerSize.width;
3001                         width = ($.ui.hasScroll(ce, "left") ? ce.scrollWidth : cw );
3002                         height = ($.ui.hasScroll(ce) ? ce.scrollHeight : ch);
3003
3004                         that.parentData = {
3005                                 element: ce, left: co.left, top: co.top, width: width, height: height
3006                         };
3007                 }
3008         },
3009
3010         resize: function( event ) {
3011                 var woset, hoset, isParent, isOffsetRelative,
3012                         that = $(this).data("ui-resizable"),
3013                         o = that.options,
3014                         co = that.containerOffset, cp = that.position,
3015                         pRatio = that._aspectRatio || event.shiftKey,
3016                         cop = { top:0, left:0 }, ce = that.containerElement;
3017
3018                 if (ce[0] !== document && (/static/).test(ce.css("position"))) {
3019                         cop = co;
3020                 }
3021
3022                 if (cp.left < (that._helper ? co.left : 0)) {
3023                         that.size.width = that.size.width + (that._helper ? (that.position.left - co.left) : (that.position.left - cop.left));
3024                         if (pRatio) {
3025                                 that.size.height = that.size.width / that.aspectRatio;
3026                         }
3027                         that.position.left = o.helper ? co.left : 0;
3028                 }
3029
3030                 if (cp.top < (that._helper ? co.top : 0)) {
3031                         that.size.height = that.size.height + (that._helper ? (that.position.top - co.top) : that.position.top);
3032                         if (pRatio) {
3033                                 that.size.width = that.size.height * that.aspectRatio;
3034                         }
3035                         that.position.top = that._helper ? co.top : 0;
3036                 }
3037
3038                 that.offset.left = that.parentData.left+that.position.left;
3039                 that.offset.top = that.parentData.top+that.position.top;
3040
3041                 woset = Math.abs( (that._helper ? that.offset.left - cop.left : (that.offset.left - cop.left)) + that.sizeDiff.width );
3042                 hoset = Math.abs( (that._helper ? that.offset.top - cop.top : (that.offset.top - co.top)) + that.sizeDiff.height );
3043
3044                 isParent = that.containerElement.get(0) === that.element.parent().get(0);
3045                 isOffsetRelative = /relative|absolute/.test(that.containerElement.css("position"));
3046
3047                 if(isParent && isOffsetRelative) {
3048                         woset -= that.parentData.left;
3049                 }
3050
3051                 if (woset + that.size.width >= that.parentData.width) {
3052                         that.size.width = that.parentData.width - woset;
3053                         if (pRatio) {
3054                                 that.size.height = that.size.width / that.aspectRatio;
3055                         }
3056                 }
3057
3058                 if (hoset + that.size.height >= that.parentData.height) {
3059                         that.size.height = that.parentData.height - hoset;
3060                         if (pRatio) {
3061                                 that.size.width = that.size.height * that.aspectRatio;
3062                         }
3063                 }
3064         },
3065
3066         stop: function(){
3067                 var that = $(this).data("ui-resizable"),
3068                         o = that.options,
3069                         co = that.containerOffset,
3070                         cop = that.containerPosition,
3071                         ce = that.containerElement,
3072                         helper = $(that.helper),
3073                         ho = helper.offset(),
3074                         w = helper.outerWidth() - that.sizeDiff.width,
3075                         h = helper.outerHeight() - that.sizeDiff.height;
3076
3077                 if (that._helper && !o.animate && (/relative/).test(ce.css("position"))) {
3078                         $(this).css({ left: ho.left - cop.left - co.left, width: w, height: h });
3079                 }
3080
3081                 if (that._helper && !o.animate && (/static/).test(ce.css("position"))) {
3082                         $(this).css({ left: ho.left - cop.left - co.left, width: w, height: h });
3083                 }
3084
3085         }
3086 });
3087
3088 $.ui.plugin.add("resizable", "alsoResize", {
3089
3090         start: function () {
3091                 var that = $(this).data("ui-resizable"),
3092                         o = that.options,
3093                         _store = function (exp) {
3094                                 $(exp).each(function() {
3095                                         var el = $(this);
3096                                         el.data("ui-resizable-alsoresize", {
3097                                                 width: parseInt(el.width(), 10), height: parseInt(el.height(), 10),
3098                                                 left: parseInt(el.css("left"), 10), top: parseInt(el.css("top"), 10)
3099                                         });
3100                                 });
3101                         };
3102
3103                 if (typeof(o.alsoResize) === "object" && !o.alsoResize.parentNode) {
3104                         if (o.alsoResize.length) { o.alsoResize = o.alsoResize[0]; _store(o.alsoResize); }
3105                         else { $.each(o.alsoResize, function (exp) { _store(exp); }); }
3106                 }else{
3107                         _store(o.alsoResize);
3108                 }
3109         },
3110
3111         resize: function (event, ui) {
3112                 var that = $(this).data("ui-resizable"),
3113                         o = that.options,
3114                         os = that.originalSize,
3115                         op = that.originalPosition,
3116                         delta = {
3117                                 height: (that.size.height - os.height) || 0, width: (that.size.width - os.width) || 0,
3118                                 top: (that.position.top - op.top) || 0, left: (that.position.left - op.left) || 0
3119                         },
3120
3121                         _alsoResize = function (exp, c) {
3122                                 $(exp).each(function() {
3123                                         var el = $(this), start = $(this).data("ui-resizable-alsoresize"), style = {},
3124                                                 css = c && c.length ? c : el.parents(ui.originalElement[0]).length ? ["width", "height"] : ["width", "height", "top", "left"];
3125
3126                                         $.each(css, function (i, prop) {
3127                                                 var sum = (start[prop]||0) + (delta[prop]||0);
3128                                                 if (sum && sum >= 0) {
3129                                                         style[prop] = sum || null;
3130                                                 }
3131                                         });
3132
3133                                         el.css(style);
3134                                 });
3135                         };
3136
3137                 if (typeof(o.alsoResize) === "object" && !o.alsoResize.nodeType) {
3138                         $.each(o.alsoResize, function (exp, c) { _alsoResize(exp, c); });
3139                 }else{
3140                         _alsoResize(o.alsoResize);
3141                 }
3142         },
3143
3144         stop: function () {
3145                 $(this).removeData("resizable-alsoresize");
3146         }
3147 });
3148
3149 $.ui.plugin.add("resizable", "ghost", {
3150
3151         start: function() {
3152
3153                 var that = $(this).data("ui-resizable"), o = that.options, cs = that.size;
3154
3155                 that.ghost = that.originalElement.clone();
3156                 that.ghost
3157                         .css({ opacity: 0.25, display: "block", position: "relative", height: cs.height, width: cs.width, margin: 0, left: 0, top: 0 })
3158                         .addClass("ui-resizable-ghost")
3159                         .addClass(typeof o.ghost === "string" ? o.ghost : "");
3160
3161                 that.ghost.appendTo(that.helper);
3162
3163         },
3164
3165         resize: function(){
3166                 var that = $(this).data("ui-resizable");
3167                 if (that.ghost) {
3168                         that.ghost.css({ position: "relative", height: that.size.height, width: that.size.width });
3169                 }
3170         },
3171
3172         stop: function() {
3173                 var that = $(this).data("ui-resizable");
3174                 if (that.ghost && that.helper) {
3175                         that.helper.get(0).removeChild(that.ghost.get(0));
3176                 }
3177         }
3178
3179 });
3180
3181 $.ui.plugin.add("resizable", "grid", {
3182
3183         resize: function() {
3184                 var that = $(this).data("ui-resizable"),
3185                         o = that.options,
3186                         cs = that.size,
3187                         os = that.originalSize,
3188                         op = that.originalPosition,
3189                         a = that.axis,
3190                         grid = typeof o.grid === "number" ? [o.grid, o.grid] : o.grid,
3191                         gridX = (grid[0]||1),
3192                         gridY = (grid[1]||1),
3193                         ox = Math.round((cs.width - os.width) / gridX) * gridX,
3194                         oy = Math.round((cs.height - os.height) / gridY) * gridY,
3195                         newWidth = os.width + ox,
3196                         newHeight = os.height + oy,
3197                         isMaxWidth = o.maxWidth && (o.maxWidth < newWidth),
3198                         isMaxHeight = o.maxHeight && (o.maxHeight < newHeight),
3199                         isMinWidth = o.minWidth && (o.minWidth > newWidth),
3200                         isMinHeight = o.minHeight && (o.minHeight > newHeight);
3201
3202                 o.grid = grid;
3203
3204                 if (isMinWidth) {
3205                         newWidth = newWidth + gridX;
3206                 }
3207                 if (isMinHeight) {
3208                         newHeight = newHeight + gridY;
3209                 }
3210                 if (isMaxWidth) {
3211                         newWidth = newWidth - gridX;
3212                 }
3213                 if (isMaxHeight) {
3214                         newHeight = newHeight - gridY;
3215                 }
3216
3217                 if (/^(se|s|e)$/.test(a)) {
3218                         that.size.width = newWidth;
3219                         that.size.height = newHeight;
3220                 } else if (/^(ne)$/.test(a)) {
3221                         that.size.width = newWidth;
3222                         that.size.height = newHeight;
3223                         that.position.top = op.top - oy;
3224                 } else if (/^(sw)$/.test(a)) {
3225                         that.size.width = newWidth;
3226                         that.size.height = newHeight;
3227                         that.position.left = op.left - ox;
3228                 } else {
3229                         that.size.width = newWidth;
3230                         that.size.height = newHeight;
3231                         that.position.top = op.top - oy;
3232                         that.position.left = op.left - ox;
3233                 }
3234         }
3235
3236 });
3237
3238 })(jQuery);
3239
3240 (function( $, undefined ) {
3241
3242 $.widget("ui.selectable", $.ui.mouse, {
3243         version: "1.10.3",
3244         options: {
3245                 appendTo: "body",
3246                 autoRefresh: true,
3247                 distance: 0,
3248                 filter: "*",
3249                 tolerance: "touch",
3250
3251                 // callbacks
3252                 selected: null,
3253                 selecting: null,
3254                 start: null,
3255                 stop: null,
3256                 unselected: null,
3257                 unselecting: null
3258         },
3259         _create: function() {
3260                 var selectees,
3261                         that = this;
3262
3263                 this.element.addClass("ui-selectable");
3264
3265                 this.dragged = false;
3266
3267                 // cache selectee children based on filter
3268                 this.refresh = function() {
3269                         selectees = $(that.options.filter, that.element[0]);
3270                         selectees.addClass("ui-selectee");
3271                         selectees.each(function() {
3272                                 var $this = $(this),
3273                                         pos = $this.offset();
3274                                 $.data(this, "selectable-item", {
3275                                         element: this,
3276                                         $element: $this,
3277                                         left: pos.left,
3278                                         top: pos.top,
3279                                         right: pos.left + $this.outerWidth(),
3280                                         bottom: pos.top + $this.outerHeight(),
3281                                         startselected: false,
3282                                         selected: $this.hasClass("ui-selected"),
3283                                         selecting: $this.hasClass("ui-selecting"),
3284                                         unselecting: $this.hasClass("ui-unselecting")
3285                                 });
3286                         });
3287                 };
3288                 this.refresh();
3289
3290                 this.selectees = selectees.addClass("ui-selectee");
3291
3292                 this._mouseInit();
3293
3294                 this.helper = $("<div class='ui-selectable-helper'></div>");
3295         },
3296
3297         _destroy: function() {
3298                 this.selectees
3299                         .removeClass("ui-selectee")
3300                         .removeData("selectable-item");
3301                 this.element
3302                         .removeClass("ui-selectable ui-selectable-disabled");
3303                 this._mouseDestroy();
3304         },
3305
3306         _mouseStart: function(event) {
3307                 var that = this,
3308                         options = this.options;
3309
3310                 this.opos = [event.pageX, event.pageY];
3311
3312                 if (this.options.disabled) {
3313                         return;
3314                 }
3315
3316                 this.selectees = $(options.filter, this.element[0]);
3317
3318                 this._trigger("start", event);
3319
3320                 $(options.appendTo).append(this.helper);
3321                 // position helper (lasso)
3322                 this.helper.css({
3323                         "left": event.pageX,
3324                         "top": event.pageY,
3325                         "width": 0,
3326                         "height": 0
3327                 });
3328
3329                 if (options.autoRefresh) {
3330                         this.refresh();
3331                 }
3332
3333                 this.selectees.filter(".ui-selected").each(function() {
3334                         var selectee = $.data(this, "selectable-item");
3335                         selectee.startselected = true;
3336                         if (!event.metaKey && !event.ctrlKey) {
3337                                 selectee.$element.removeClass("ui-selected");
3338                                 selectee.selected = false;
3339                                 selectee.$element.addClass("ui-unselecting");
3340                                 selectee.unselecting = true;
3341                                 // selectable UNSELECTING callback
3342                                 that._trigger("unselecting", event, {
3343                                         unselecting: selectee.element
3344                                 });
3345                         }
3346                 });
3347
3348                 $(event.target).parents().addBack().each(function() {
3349                         var doSelect,
3350                                 selectee = $.data(this, "selectable-item");
3351                         if (selectee) {
3352                                 doSelect = (!event.metaKey && !event.ctrlKey) || !selectee.$element.hasClass("ui-selected");
3353                                 selectee.$element
3354                                         .removeClass(doSelect ? "ui-unselecting" : "ui-selected")
3355                                         .addClass(doSelect ? "ui-selecting" : "ui-unselecting");
3356                                 selectee.unselecting = !doSelect;
3357                                 selectee.selecting = doSelect;
3358                                 selectee.selected = doSelect;
3359                                 // selectable (UN)SELECTING callback
3360                                 if (doSelect) {
3361                                         that._trigger("selecting", event, {
3362                                                 selecting: selectee.element
3363                                         });
3364                                 } else {
3365                                         that._trigger("unselecting", event, {
3366                                                 unselecting: selectee.element
3367                                         });
3368                                 }
3369                                 return false;
3370                         }
3371                 });
3372
3373         },
3374
3375         _mouseDrag: function(event) {
3376
3377                 this.dragged = true;
3378
3379                 if (this.options.disabled) {
3380                         return;
3381                 }
3382
3383                 var tmp,
3384                         that = this,
3385                         options = this.options,
3386                         x1 = this.opos[0],
3387                         y1 = this.opos[1],
3388                         x2 = event.pageX,
3389                         y2 = event.pageY;
3390
3391                 if (x1 > x2) { tmp = x2; x2 = x1; x1 = tmp; }
3392                 if (y1 > y2) { tmp = y2; y2 = y1; y1 = tmp; }
3393                 this.helper.css({left: x1, top: y1, width: x2-x1, height: y2-y1});
3394
3395                 this.selectees.each(function() {
3396                         var selectee = $.data(this, "selectable-item"),
3397                                 hit = false;
3398
3399                         //prevent helper from being selected if appendTo: selectable
3400                         if (!selectee || selectee.element === that.element[0]) {
3401                                 return;
3402                         }
3403
3404                         if (options.tolerance === "touch") {
3405                                 hit = ( !(selectee.left > x2 || selectee.right < x1 || selectee.top > y2 || selectee.bottom < y1) );
3406                         } else if (options.tolerance === "fit") {
3407                                 hit = (selectee.left > x1 && selectee.right < x2 && selectee.top > y1 && selectee.bottom < y2);
3408                         }
3409
3410                         if (hit) {
3411                                 // SELECT
3412                                 if (selectee.selected) {
3413                                         selectee.$element.removeClass("ui-selected");
3414                                         selectee.selected = false;
3415                                 }
3416                                 if (selectee.unselecting) {
3417                                         selectee.$element.removeClass("ui-unselecting");
3418                                         selectee.unselecting = false;
3419                                 }
3420                                 if (!selectee.selecting) {
3421                                         selectee.$element.addClass("ui-selecting");
3422                                         selectee.selecting = true;
3423                                         // selectable SELECTING callback
3424                                         that._trigger("selecting", event, {
3425                                                 selecting: selectee.element
3426                                         });
3427                                 }
3428                         } else {
3429                                 // UNSELECT
3430                                 if (selectee.selecting) {
3431                                         if ((event.metaKey || event.ctrlKey) && selectee.startselected) {
3432                                                 selectee.$element.removeClass("ui-selecting");
3433                                                 selectee.selecting = false;
3434                                                 selectee.$element.addClass("ui-selected");
3435                                                 selectee.selected = true;
3436                                         } else {
3437                                                 selectee.$element.removeClass("ui-selecting");
3438                                                 selectee.selecting = false;
3439                                                 if (selectee.startselected) {
3440                                                         selectee.$element.addClass("ui-unselecting");
3441                                                         selectee.unselecting = true;
3442                                                 }
3443                                                 // selectable UNSELECTING callback
3444                                                 that._trigger("unselecting", event, {
3445                                                         unselecting: selectee.element
3446                                                 });
3447                                         }
3448                                 }
3449                                 if (selectee.selected) {
3450                                         if (!event.metaKey && !event.ctrlKey && !selectee.startselected) {
3451                                                 selectee.$element.removeClass("ui-selected");
3452                                                 selectee.selected = false;
3453
3454                                                 selectee.$element.addClass("ui-unselecting");
3455                                                 selectee.unselecting = true;
3456                                                 // selectable UNSELECTING callback
3457                                                 that._trigger("unselecting", event, {
3458                                                         unselecting: selectee.element
3459                                                 });
3460                                         }
3461                                 }
3462                         }
3463                 });
3464
3465                 return false;
3466         },
3467
3468         _mouseStop: function(event) {
3469                 var that = this;
3470
3471                 this.dragged = false;
3472
3473                 $(".ui-unselecting", this.element[0]).each(function() {
3474                         var selectee = $.data(this, "selectable-item");
3475                         selectee.$element.removeClass("ui-unselecting");
3476                         selectee.unselecting = false;
3477                         selectee.startselected = false;
3478                         that._trigger("unselected", event, {
3479                                 unselected: selectee.element
3480                         });
3481                 });
3482                 $(".ui-selecting", this.element[0]).each(function() {
3483                         var selectee = $.data(this, "selectable-item");
3484                         selectee.$element.removeClass("ui-selecting").addClass("ui-selected");
3485                         selectee.selecting = false;
3486                         selectee.selected = true;
3487                         selectee.startselected = true;
3488                         that._trigger("selected", event, {
3489                                 selected: selectee.element
3490                         });
3491                 });
3492                 this._trigger("stop", event);
3493
3494                 this.helper.remove();
3495
3496                 return false;
3497         }
3498
3499 });
3500
3501 })(jQuery);
3502
3503 (function( $, undefined ) {
3504
3505 /*jshint loopfunc: true */
3506
3507 function isOverAxis( x, reference, size ) {
3508         return ( x > reference ) && ( x < ( reference + size ) );
3509 }
3510
3511 function isFloating(item) {
3512         return (/left|right/).test(item.css("float")) || (/inline|table-cell/).test(item.css("display"));
3513 }
3514
3515 $.widget("ui.sortable", $.ui.mouse, {
3516         version: "1.10.3",
3517         widgetEventPrefix: "sort",
3518         ready: false,
3519         options: {
3520                 appendTo: "parent",
3521                 axis: false,
3522                 connectWith: false,
3523                 containment: false,
3524                 cursor: "auto",
3525                 cursorAt: false,
3526                 dropOnEmpty: true,
3527                 forcePlaceholderSize: false,
3528                 forceHelperSize: false,
3529                 grid: false,
3530                 handle: false,
3531                 helper: "original",
3532                 items: "> *",
3533                 opacity: false,
3534                 placeholder: false,
3535                 revert: false,
3536                 scroll: true,
3537                 scrollSensitivity: 20,
3538                 scrollSpeed: 20,
3539                 scope: "default",
3540                 tolerance: "intersect",
3541                 zIndex: 1000,
3542
3543                 // callbacks
3544                 activate: null,
3545                 beforeStop: null,
3546                 change: null,
3547                 deactivate: null,
3548                 out: null,
3549                 over: null,
3550                 receive: null,
3551                 remove: null,
3552                 sort: null,
3553                 start: null,
3554                 stop: null,
3555                 update: null
3556         },
3557         _create: function() {
3558
3559                 var o = this.options;
3560                 this.containerCache = {};
3561                 this.element.addClass("ui-sortable");
3562
3563                 //Get the items
3564                 this.refresh();
3565
3566                 //Let's determine if the items are being displayed horizontally
3567                 this.floating = this.items.length ? o.axis === "x" || isFloating(this.items[0].item) : false;
3568
3569                 //Let's determine the parent's offset
3570                 this.offset = this.element.offset();
3571
3572                 //Initialize mouse events for interaction
3573                 this._mouseInit();
3574
3575                 //We're ready to go
3576                 this.ready = true;
3577
3578         },
3579
3580         _destroy: function() {
3581                 this.element
3582                         .removeClass("ui-sortable ui-sortable-disabled");
3583                 this._mouseDestroy();
3584
3585                 for ( var i = this.items.length - 1; i >= 0; i-- ) {
3586                         this.items[i].item.removeData(this.widgetName + "-item");
3587                 }
3588
3589                 return this;
3590         },
3591
3592         _setOption: function(key, value){
3593                 if ( key === "disabled" ) {
3594                         this.options[ key ] = value;
3595
3596                         this.widget().toggleClass( "ui-sortable-disabled", !!value );
3597                 } else {
3598                         // Don't call widget base _setOption for disable as it adds ui-state-disabled class
3599                         $.Widget.prototype._setOption.apply(this, arguments);
3600                 }
3601         },
3602
3603         _mouseCapture: function(event, overrideHandle) {
3604                 var currentItem = null,
3605                         validHandle = false,
3606                         that = this;
3607
3608                 if (this.reverting) {
3609                         return false;
3610                 }
3611
3612                 if(this.options.disabled || this.options.type === "static") {
3613                         return false;
3614                 }
3615
3616                 //We have to refresh the items data once first
3617                 this._refreshItems(event);
3618
3619                 //Find out if the clicked node (or one of its parents) is a actual item in this.items
3620                 $(event.target).parents().each(function() {
3621                         if($.data(this, that.widgetName + "-item") === that) {
3622                                 currentItem = $(this);
3623                                 return false;
3624                         }
3625                 });
3626                 if($.data(event.target, that.widgetName + "-item") === that) {
3627                         currentItem = $(event.target);
3628                 }
3629
3630                 if(!currentItem) {
3631                         return false;
3632                 }
3633                 if(this.options.handle && !overrideHandle) {
3634                         $(this.options.handle, currentItem).find("*").addBack().each(function() {
3635                                 if(this === event.target) {
3636                                         validHandle = true;
3637                                 }
3638                         });
3639                         if(!validHandle) {
3640                                 return false;
3641                         }
3642                 }
3643
3644                 this.currentItem = currentItem;
3645                 this._removeCurrentsFromItems();
3646                 return true;
3647
3648         },
3649
3650         _mouseStart: function(event, overrideHandle, noActivation) {
3651
3652                 var i, body,
3653                         o = this.options;
3654
3655                 this.currentContainer = this;
3656
3657                 //We only need to call refreshPositions, because the refreshItems call has been moved to mouseCapture
3658                 this.refreshPositions();
3659
3660                 //Create and append the visible helper
3661                 this.helper = this._createHelper(event);
3662
3663                 //Cache the helper size
3664                 this._cacheHelperProportions();
3665
3666                 /*
3667                  * - Position generation -
3668                  * This block generates everything position related - it's the core of draggables.
3669                  */
3670
3671                 //Cache the margins of the original element
3672                 this._cacheMargins();
3673
3674                 //Get the next scrolling parent
3675                 this.scrollParent = this.helper.scrollParent();
3676
3677                 //The element's absolute position on the page minus margins
3678                 this.offset = this.currentItem.offset();
3679                 this.offset = {
3680                         top: this.offset.top - this.margins.top,
3681                         left: this.offset.left - this.margins.left
3682                 };
3683
3684                 $.extend(this.offset, {
3685                         click: { //Where the click happened, relative to the element
3686                                 left: event.pageX - this.offset.left,
3687                                 top: event.pageY - this.offset.top
3688                         },
3689                         parent: this._getParentOffset(),
3690                         relative: this._getRelativeOffset() //This is a relative to absolute position minus the actual position calculation - only used for relative positioned helper
3691                 });
3692
3693                 // Only after we got the offset, we can change the helper's position to absolute
3694                 // TODO: Still need to figure out a way to make relative sorting possible
3695                 this.helper.css("position", "absolute");
3696                 this.cssPosition = this.helper.css("position");
3697
3698                 //Generate the original position
3699                 this.originalPosition = this._generatePosition(event);
3700                 this.originalPageX = event.pageX;
3701                 this.originalPageY = event.pageY;
3702
3703                 //Adjust the mouse offset relative to the helper if "cursorAt" is supplied
3704                 (o.cursorAt && this._adjustOffsetFromHelper(o.cursorAt));
3705
3706                 //Cache the former DOM position
3707                 this.domPosition = { prev: this.currentItem.prev()[0], parent: this.currentItem.parent()[0] };
3708
3709                 //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
3710                 if(this.helper[0] !== this.currentItem[0]) {
3711                         this.currentItem.hide();
3712                 }
3713
3714                 //Create the placeholder
3715                 this._createPlaceholder();
3716
3717                 //Set a containment if given in the options
3718                 if(o.containment) {
3719                         this._setContainment();
3720                 }
3721
3722                 if( o.cursor && o.cursor !== "auto" ) { // cursor option
3723                         body = this.document.find( "body" );
3724
3725                         // support: IE
3726                         this.storedCursor = body.css( "cursor" );
3727                         body.css( "cursor", o.cursor );
3728
3729                         this.storedStylesheet = $( "<style>*{ cursor: "+o.cursor+" !important; }</style>" ).appendTo( body );
3730                 }
3731
3732                 if(o.opacity) { // opacity option
3733                         if (this.helper.css("opacity")) {
3734                                 this._storedOpacity = this.helper.css("opacity");
3735                         }
3736                         this.helper.css("opacity", o.opacity);
3737                 }
3738
3739                 if(o.zIndex) { // zIndex option
3740                         if (this.helper.css("zIndex")) {
3741                                 this._storedZIndex = this.helper.css("zIndex");
3742                         }
3743                         this.helper.css("zIndex", o.zIndex);
3744                 }
3745
3746                 //Prepare scrolling
3747                 if(this.scrollParent[0] !== document && this.scrollParent[0].tagName !== "HTML") {
3748                         this.overflowOffset = this.scrollParent.offset();
3749                 }
3750
3751                 //Call callbacks
3752                 this._trigger("start", event, this._uiHash());
3753
3754                 //Recache the helper size
3755                 if(!this._preserveHelperProportions) {
3756                         this._cacheHelperProportions();
3757                 }
3758
3759
3760                 //Post "activate" events to possible containers
3761                 if( !noActivation ) {
3762                         for ( i = this.containers.length - 1; i >= 0; i-- ) {
3763                                 this.containers[ i ]._trigger( "activate", event, this._uiHash( this ) );
3764                         }
3765                 }
3766
3767                 //Prepare possible droppables
3768                 if($.ui.ddmanager) {
3769                         $.ui.ddmanager.current = this;
3770                 }
3771
3772                 if ($.ui.ddmanager && !o.dropBehaviour) {
3773                         $.ui.ddmanager.prepareOffsets(this, event);
3774                 }
3775
3776                 this.dragging = true;
3777
3778                 this.helper.addClass("ui-sortable-helper");
3779                 this._mouseDrag(event); //Execute the drag once - this causes the helper not to be visible before getting its correct position
3780                 return true;
3781
3782         },
3783
3784         _mouseDrag: function(event) {
3785                 var i, item, itemElement, intersection,
3786                         o = this.options,
3787                         scrolled = false;
3788
3789                 //Compute the helpers position
3790                 this.position = this._generatePosition(event);
3791                 this.positionAbs = this._convertPositionTo("absolute");
3792
3793                 if (!this.lastPositionAbs) {
3794                         this.lastPositionAbs = this.positionAbs;
3795                 }
3796
3797                 //Do scrolling
3798                 if(this.options.scroll) {
3799                         if(this.scrollParent[0] !== document && this.scrollParent[0].tagName !== "HTML") {
3800
3801                                 if((this.overflowOffset.top + this.scrollParent[0].offsetHeight) - event.pageY < o.scrollSensitivity) {
3802                                         this.scrollParent[0].scrollTop = scrolled = this.scrollParent[0].scrollTop + o.scrollSpeed;
3803                                 } else if(event.pageY - this.overflowOffset.top < o.scrollSensitivity) {
3804                                         this.scrollParent[0].scrollTop = scrolled = this.scrollParent[0].scrollTop - o.scrollSpeed;
3805                                 }
3806
3807                                 if((this.overflowOffset.left + this.scrollParent[0].offsetWidth) - event.pageX < o.scrollSensitivity) {
3808                                         this.scrollParent[0].scrollLeft = scrolled = this.scrollParent[0].scrollLeft + o.scrollSpeed;
3809                                 } else if(event.pageX - this.overflowOffset.left < o.scrollSensitivity) {
3810                                         this.scrollParent[0].scrollLeft = scrolled = this.scrollParent[0].scrollLeft - o.scrollSpeed;
3811                                 }
3812
3813                         } else {
3814
3815                                 if(event.pageY - $(document).scrollTop() < o.scrollSensitivity) {
3816                                         scrolled = $(document).scrollTop($(document).scrollTop() - o.scrollSpeed);
3817                                 } else if($(window).height() - (event.pageY - $(document).scrollTop()) < o.scrollSensitivity) {
3818                                         scrolled = $(document).scrollTop($(document).scrollTop() + o.scrollSpeed);
3819                                 }
3820
3821                                 if(event.pageX - $(document).scrollLeft() < o.scrollSensitivity) {
3822                                         scrolled = $(document).scrollLeft($(document).scrollLeft() - o.scrollSpeed);
3823                                 } else if($(window).width() - (event.pageX - $(document).scrollLeft()) < o.scrollSensitivity) {
3824                                         scrolled = $(document).scrollLeft($(document).scrollLeft() + o.scrollSpeed);
3825                                 }
3826
3827                         }
3828
3829                         if(scrolled !== false && $.ui.ddmanager && !o.dropBehaviour) {
3830                                 $.ui.ddmanager.prepareOffsets(this, event);
3831                         }
3832                 }
3833
3834                 //Regenerate the absolute position used for position checks
3835                 this.positionAbs = this._convertPositionTo("absolute");
3836
3837                 //Set the helper position
3838                 if(!this.options.axis || this.options.axis !== "y") {
3839                         this.helper[0].style.left = this.position.left+"px";
3840                 }
3841                 if(!this.options.axis || this.options.axis !== "x") {
3842                         this.helper[0].style.top = this.position.top+"px";
3843                 }
3844
3845                 //Rearrange
3846                 for (i = this.items.length - 1; i >= 0; i--) {
3847
3848                         //Cache variables and intersection, continue if no intersection
3849                         item = this.items[i];
3850                         itemElement = item.item[0];
3851                         intersection = this._intersectsWithPointer(item);
3852                         if (!intersection) {
3853                                 continue;
3854                         }
3855
3856                         // Only put the placeholder inside the current Container, skip all
3857                         // items form other containers. This works because when moving
3858                         // an item from one container to another the
3859                         // currentContainer is switched before the placeholder is moved.
3860                         //
3861                         // Without this moving items in "sub-sortables" can cause the placeholder to jitter
3862                         // beetween the outer and inner container.
3863                         if (item.instance !== this.currentContainer) {
3864                                 continue;
3865                         }
3866
3867                         // cannot intersect with itself
3868                         // no useless actions that have been done before
3869                         // no action if the item moved is the parent of the item checked
3870                         if (itemElement !== this.currentItem[0] &&
3871                                 this.placeholder[intersection === 1 ? "next" : "prev"]()[0] !== itemElement &&
3872                                 !$.contains(this.placeholder[0], itemElement) &&
3873                                 (this.options.type === "semi-dynamic" ? !$.contains(this.element[0], itemElement) : true)
3874                         ) {
3875
3876                                 this.direction = intersection === 1 ? "down" : "up";
3877
3878                                 if (this.options.tolerance === "pointer" || this._intersectsWithSides(item)) {
3879                                         this._rearrange(event, item);
3880                                 } else {
3881                                         break;
3882                                 }
3883
3884                                 this._trigger("change", event, this._uiHash());
3885                                 break;
3886                         }
3887                 }
3888
3889                 //Post events to containers
3890                 this._contactContainers(event);
3891
3892                 //Interconnect with droppables
3893                 if($.ui.ddmanager) {
3894                         $.ui.ddmanager.drag(this, event);
3895                 }
3896
3897                 //Call callbacks
3898                 this._trigger("sort", event, this._uiHash());
3899
3900                 this.lastPositionAbs = this.positionAbs;
3901                 return false;
3902
3903         },
3904
3905         _mouseStop: function(event, noPropagation) {
3906
3907                 if(!event) {
3908                         return;
3909                 }
3910
3911                 //If we are using droppables, inform the manager about the drop
3912                 if ($.ui.ddmanager && !this.options.dropBehaviour) {
3913                         $.ui.ddmanager.drop(this, event);
3914                 }
3915
3916                 if(this.options.revert) {
3917                         var that = this,
3918                                 cur = this.placeholder.offset(),
3919                                 axis = this.options.axis,
3920                                 animation = {};
3921
3922                         if ( !axis || axis === "x" ) {
3923                                 animation.left = cur.left - this.offset.parent.left - this.margins.left + (this.offsetParent[0] === document.body ? 0 : this.offsetParent[0].scrollLeft);
3924                         }
3925                         if ( !axis || axis === "y" ) {
3926                                 animation.top = cur.top - this.offset.parent.top - this.margins.top + (this.offsetParent[0] === document.body ? 0 : this.offsetParent[0].scrollTop);
3927                         }
3928                         this.reverting = true;
3929                         $(this.helper).animate( animation, parseInt(this.options.revert, 10) || 500, function() {
3930                                 that._clear(event);
3931                         });
3932                 } else {
3933                         this._clear(event, noPropagation);
3934                 }
3935
3936                 return false;
3937
3938         },
3939
3940         cancel: function() {
3941
3942                 if(this.dragging) {
3943
3944                         this._mouseUp({ target: null });
3945
3946                         if(this.options.helper === "original") {
3947                                 this.currentItem.css(this._storedCSS).removeClass("ui-sortable-helper");
3948                         } else {
3949                                 this.currentItem.show();
3950                         }
3951
3952                         //Post deactivating events to containers
3953                         for (var i = this.containers.length - 1; i >= 0; i--){
3954                                 this.containers[i]._trigger("deactivate", null, this._uiHash(this));
3955                                 if(this.containers[i].containerCache.over) {
3956                                         this.containers[i]._trigger("out", null, this._uiHash(this));
3957                                         this.containers[i].containerCache.over = 0;
3958                                 }
3959                         }
3960
3961                 }
3962
3963                 if (this.placeholder) {
3964                         //$(this.placeholder[0]).remove(); would have been the jQuery way - unfortunately, it unbinds ALL events from the original node!
3965                         if(this.placeholder[0].parentNode) {
3966                                 this.placeholder[0].parentNode.removeChild(this.placeholder[0]);
3967                         }
3968                         if(this.options.helper !== "original" && this.helper && this.helper[0].parentNode) {
3969                                 this.helper.remove();
3970                         }
3971
3972                         $.extend(this, {
3973                                 helper: null,
3974                                 dragging: false,
3975                                 reverting: false,
3976                                 _noFinalSort: null
3977                         });
3978
3979                         if(this.domPosition.prev) {
3980                                 $(this.domPosition.prev).after(this.currentItem);
3981                         } else {
3982                                 $(this.domPosition.parent).prepend(this.currentItem);
3983                         }
3984                 }
3985
3986                 return this;
3987
3988         },
3989
3990         serialize: function(o) {
3991
3992                 var items = this._getItemsAsjQuery(o && o.connected),
3993                         str = [];
3994                 o = o || {};
3995
3996                 $(items).each(function() {
3997                         var res = ($(o.item || this).attr(o.attribute || "id") || "").match(o.expression || (/(.+)[\-=_](.+)/));
3998                         if (res) {
3999                                 str.push((o.key || res[1]+"[]")+"="+(o.key && o.expression ? res[1] : res[2]));
4000                         }
4001                 });
4002
4003                 if(!str.length && o.key) {
4004                         str.push(o.key + "=");
4005                 }
4006
4007                 return str.join("&");
4008
4009         },
4010
4011         toArray: function(o) {
4012
4013                 var items = this._getItemsAsjQuery(o && o.connected),
4014                         ret = [];
4015
4016                 o = o || {};
4017
4018                 items.each(function() { ret.push($(o.item || this).attr(o.attribute || "id") || ""); });
4019                 return ret;
4020
4021         },
4022
4023         /* Be careful with the following core functions */
4024         _intersectsWith: function(item) {
4025
4026                 var x1 = this.positionAbs.left,
4027                         x2 = x1 + this.helperProportions.width,
4028                         y1 = this.positionAbs.top,
4029                         y2 = y1 + this.helperProportions.height,
4030                         l = item.left,
4031                         r = l + item.width,
4032                         t = item.top,
4033                         b = t + item.height,
4034                         dyClick = this.offset.click.top,
4035                         dxClick = this.offset.click.left,
4036                         isOverElementHeight = ( this.options.axis === "x" ) || ( ( y1 + dyClick ) > t && ( y1 + dyClick ) < b ),
4037                         isOverElementWidth = ( this.options.axis === "y" ) || ( ( x1 + dxClick ) > l && ( x1 + dxClick ) < r ),
4038                         isOverElement = isOverElementHeight && isOverElementWidth;
4039
4040                 if ( this.options.tolerance === "pointer" ||
4041                         this.options.forcePointerForContainers ||
4042                         (this.options.tolerance !== "pointer" && this.helperProportions[this.floating ? "width" : "height"] > item[this.floating ? "width" : "height"])
4043                 ) {
4044                         return isOverElement;
4045                 } else {
4046
4047                         return (l < x1 + (this.helperProportions.width / 2) && // Right Half
4048                                 x2 - (this.helperProportions.width / 2) < r && // Left Half
4049                                 t < y1 + (this.helperProportions.height / 2) && // Bottom Half
4050                                 y2 - (this.helperProportions.height / 2) < b ); // Top Half
4051
4052                 }
4053         },
4054
4055         _intersectsWithPointer: function(item) {
4056
4057                 var isOverElementHeight = (this.options.axis === "x") || isOverAxis(this.positionAbs.top + this.offset.click.top, item.top, item.height),
4058                         isOverElementWidth = (this.options.axis === "y") || isOverAxis(this.positionAbs.left + this.offset.click.left, item.left, item.width),
4059                         isOverElement = isOverElementHeight && isOverElementWidth,
4060                         verticalDirection = this._getDragVerticalDirection(),
4061                         horizontalDirection = this._getDragHorizontalDirection();
4062
4063                 if (!isOverElement) {
4064                         return false;
4065                 }
4066
4067                 return this.floating ?
4068                         ( ((horizontalDirection && horizontalDirection === "right") || verticalDirection === "down") ? 2 : 1 )
4069                         : ( verticalDirection && (verticalDirection === "down" ? 2 : 1) );
4070
4071         },
4072
4073         _intersectsWithSides: function(item) {
4074
4075                 var isOverBottomHalf = isOverAxis(this.positionAbs.top + this.offset.click.top, item.top + (item.height/2), item.height),
4076                         isOverRightHalf = isOverAxis(this.positionAbs.left + this.offset.click.left, item.left + (item.width/2), item.width),
4077                         verticalDirection = this._getDragVerticalDirection(),
4078                         horizontalDirection = this._getDragHorizontalDirection();
4079
4080                 if (this.floating && horizontalDirection) {
4081                         return ((horizontalDirection === "right" && isOverRightHalf) || (horizontalDirection === "left" && !isOverRightHalf));
4082                 } else {
4083                         return verticalDirection && ((verticalDirection === "down" && isOverBottomHalf) || (verticalDirection === "up" && !isOverBottomHalf));
4084                 }
4085
4086         },
4087
4088         _getDragVerticalDirection: function() {
4089                 var delta = this.positionAbs.top - this.lastPositionAbs.top;
4090                 return delta !== 0 && (delta > 0 ? "down" : "up");
4091         },
4092
4093         _getDragHorizontalDirection: function() {
4094                 var delta = this.positionAbs.left - this.lastPositionAbs.left;
4095                 return delta !== 0 && (delta > 0 ? "right" : "left");
4096         },
4097
4098         refresh: function(event) {
4099                 this._refreshItems(event);
4100                 this.refreshPositions();
4101                 return this;
4102         },
4103
4104         _connectWith: function() {
4105                 var options = this.options;
4106                 return options.connectWith.constructor === String ? [options.connectWith] : options.connectWith;
4107         },
4108
4109         _getItemsAsjQuery: function(connected) {
4110
4111                 var i, j, cur, inst,
4112                         items = [],
4113                         queries = [],
4114                         connectWith = this._connectWith();
4115
4116                 if(connectWith && connected) {
4117                         for (i = connectWith.length - 1; i >= 0; i--){
4118                                 cur = $(connectWith[i]);
4119                                 for ( j = cur.length - 1; j >= 0; j--){
4120                                         inst = $.data(cur[j], this.widgetFullName);
4121                                         if(inst && inst !== this && !inst.options.disabled) {
4122                                                 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]);
4123                                         }
4124                                 }
4125                         }
4126                 }
4127
4128                 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]);
4129
4130                 for (i = queries.length - 1; i >= 0; i--){
4131                         queries[i][0].each(function() {
4132                                 items.push(this);
4133                         });
4134                 }
4135
4136                 return $(items);
4137
4138         },
4139
4140         _removeCurrentsFromItems: function() {
4141
4142                 var list = this.currentItem.find(":data(" + this.widgetName + "-item)");
4143
4144                 this.items = $.grep(this.items, function (item) {
4145                         for (var j=0; j < list.length; j++) {
4146                                 if(list[j] === item.item[0]) {
4147                                         return false;
4148                                 }
4149                         }
4150                         return true;
4151                 });
4152
4153         },
4154
4155         _refreshItems: function(event) {
4156
4157                 this.items = [];
4158                 this.containers = [this];
4159
4160                 var i, j, cur, inst, targetData, _queries, item, queriesLength,
4161                         items = this.items,
4162                         queries = [[$.isFunction(this.options.items) ? this.options.items.call(this.element[0], event, { item: this.currentItem }) : $(this.options.items, this.element), this]],
4163                         connectWith = this._connectWith();
4164
4165                 if(connectWith && this.ready) { //Shouldn't be run the first time through due to massive slow-down
4166                         for (i = connectWith.length - 1; i >= 0; i--){
4167                                 cur = $(connectWith[i]);
4168                                 for (j = cur.length - 1; j >= 0; j--){
4169                                         inst = $.data(cur[j], this.widgetFullName);
4170                                         if(inst && inst !== this && !inst.options.disabled) {
4171                                                 queries.push([$.isFunction(inst.options.items) ? inst.options.items.call(inst.element[0], event, { item: this.currentItem }) : $(inst.options.items, inst.element), inst]);
4172                                                 this.containers.push(inst);
4173                                         }
4174                                 }
4175                         }
4176                 }
4177
4178                 for (i = queries.length - 1; i >= 0; i--) {
4179                         targetData = queries[i][1];
4180                         _queries = queries[i][0];
4181
4182                         for (j=0, queriesLength = _queries.length; j < queriesLength; j++) {
4183                                 item = $(_queries[j]);
4184
4185                                 item.data(this.widgetName + "-item", targetData); // Data for target checking (mouse manager)
4186
4187                                 items.push({
4188                                         item: item,
4189                                         instance: targetData,
4190                                         width: 0, height: 0,
4191                                         left: 0, top: 0
4192                                 });
4193                         }
4194                 }
4195
4196         },
4197
4198         refreshPositions: function(fast) {
4199
4200                 //This has to be redone because due to the item being moved out/into the offsetParent, the offsetParent's position will change
4201                 if(this.offsetParent && this.helper) {
4202                         this.offset.parent = this._getParentOffset();
4203                 }
4204
4205                 var i, item, t, p;
4206
4207                 for (i = this.items.length - 1; i >= 0; i--){
4208                         item = this.items[i];
4209
4210                         //We ignore calculating positions of all connected containers when we're not over them
4211                         if(item.instance !== this.currentContainer && this.currentContainer && item.item[0] !== this.currentItem[0]) {
4212                                 continue;
4213                         }
4214
4215                         t = this.options.toleranceElement ? $(this.options.toleranceElement, item.item) : item.item;
4216
4217                         if (!fast) {
4218                                 item.width = t.outerWidth();
4219                                 item.height = t.outerHeight();
4220                         }
4221
4222                         p = t.offset();
4223                         item.left = p.left;
4224                         item.top = p.top;
4225                 }
4226
4227                 if(this.options.custom && this.options.custom.refreshContainers) {
4228                         this.options.custom.refreshContainers.call(this);
4229                 } else {
4230                         for (i = this.containers.length - 1; i >= 0; i--){
4231                                 p = this.containers[i].element.offset();
4232                                 this.containers[i].containerCache.left = p.left;
4233                                 this.containers[i].containerCache.top = p.top;
4234                                 this.containers[i].containerCache.width = this.containers[i].element.outerWidth();
4235                                 this.containers[i].containerCache.height = this.containers[i].element.outerHeight();
4236                         }
4237                 }
4238
4239                 return this;
4240         },
4241
4242         _createPlaceholder: function(that) {
4243                 that = that || this;
4244                 var className,
4245                         o = that.options;
4246
4247                 if(!o.placeholder || o.placeholder.constructor === String) {
4248                         className = o.placeholder;
4249                         o.placeholder = {
4250                                 element: function() {
4251
4252                                         var nodeName = that.currentItem[0].nodeName.toLowerCase(),
4253                                                 element = $( "<" + nodeName + ">", that.document[0] )
4254                                                         .addClass(className || that.currentItem[0].className+" ui-sortable-placeholder")
4255                                                         .removeClass("ui-sortable-helper");
4256
4257                                         if ( nodeName === "tr" ) {
4258                                                 that.currentItem.children().each(function() {
4259                                                         $( "<td>&#160;</td>", that.document[0] )
4260                                                                 .attr( "colspan", $( this ).attr( "colspan" ) || 1 )
4261                                                                 .appendTo( element );
4262                                                 });
4263                                         } else if ( nodeName === "img" ) {
4264                                                 element.attr( "src", that.currentItem.attr( "src" ) );
4265                                         }
4266
4267                                         if ( !className ) {
4268                                                 element.css( "visibility", "hidden" );
4269                                         }
4270
4271                                         return element;
4272                                 },
4273                                 update: function(container, p) {
4274
4275                                         // 1. If a className is set as 'placeholder option, we don't force sizes - the class is responsible for that
4276                                         // 2. The option 'forcePlaceholderSize can be enabled to force it even if a class name is specified
4277                                         if(className && !o.forcePlaceholderSize) {
4278                                                 return;
4279                                         }
4280
4281                                         //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
4282                                         if(!p.height()) { p.height(that.currentItem.innerHeight() - parseInt(that.currentItem.css("paddingTop")||0, 10) - parseInt(that.currentItem.css("paddingBottom")||0, 10)); }
4283                                         if(!p.width()) { p.width(that.currentItem.innerWidth() - parseInt(that.currentItem.css("paddingLeft")||0, 10) - parseInt(that.currentItem.css("paddingRight")||0, 10)); }
4284                                 }
4285                         };
4286                 }
4287
4288                 //Create the placeholder
4289                 that.placeholder = $(o.placeholder.element.call(that.element, that.currentItem));
4290
4291                 //Append it after the actual current item
4292                 that.currentItem.after(that.placeholder);
4293
4294                 //Update the size of the placeholder (TODO: Logic to fuzzy, see line 316/317)
4295                 o.placeholder.update(that, that.placeholder);
4296
4297         },
4298
4299         _contactContainers: function(event) {
4300                 var i, j, dist, itemWithLeastDistance, posProperty, sizeProperty, base, cur, nearBottom, floating,
4301                         innermostContainer = null,
4302                         innermostIndex = null;
4303
4304                 // get innermost container that intersects with item
4305                 for (i = this.containers.length - 1; i >= 0; i--) {
4306
4307                         // never consider a container that's located within the item itself
4308                         if($.contains(this.currentItem[0], this.containers[i].element[0])) {
4309                                 continue;
4310                         }
4311
4312                         if(this._intersectsWith(this.containers[i].containerCache)) {
4313
4314                                 // if we've already found a container and it's more "inner" than this, then continue
4315                                 if(innermostContainer && $.contains(this.containers[i].element[0], innermostContainer.element[0])) {
4316                                         continue;
4317                                 }
4318
4319                                 innermostContainer = this.containers[i];
4320                                 innermostIndex = i;
4321
4322                         } else {
4323                                 // container doesn't intersect. trigger "out" event if necessary
4324                                 if(this.containers[i].containerCache.over) {
4325                                         this.containers[i]._trigger("out", event, this._uiHash(this));
4326                                         this.containers[i].containerCache.over = 0;
4327                                 }
4328                         }
4329
4330                 }
4331
4332                 // if no intersecting containers found, return
4333                 if(!innermostContainer) {
4334                         return;
4335                 }
4336
4337                 // move the item into the container if it's not there already
4338                 if(this.containers.length === 1) {
4339                         if (!this.containers[innermostIndex].containerCache.over) {
4340                                 this.containers[innermostIndex]._trigger("over", event, this._uiHash(this));
4341                                 this.containers[innermostIndex].containerCache.over = 1;
4342                         }
4343                 } else {
4344
4345                         //When entering a new container, we will find the item with the least distance and append our item near it
4346                         dist = 10000;
4347                         itemWithLeastDistance = null;
4348                         floating = innermostContainer.floating || isFloating(this.currentItem);
4349                         posProperty = floating ? "left" : "top";
4350                         sizeProperty = floating ? "width" : "height";
4351                         base = this.positionAbs[posProperty] + this.offset.click[posProperty];
4352                         for (j = this.items.length - 1; j >= 0; j--) {
4353                                 if(!$.contains(this.containers[innermostIndex].element[0], this.items[j].item[0])) {
4354                                         continue;
4355                                 }
4356                                 if(this.items[j].item[0] === this.currentItem[0]) {
4357                                         continue;
4358                                 }
4359                                 if (floating && !isOverAxis(this.positionAbs.top + this.offset.click.top, this.items[j].top, this.items[j].height)) {
4360                                         continue;
4361                                 }
4362                                 cur = this.items[j].item.offset()[posProperty];
4363                                 nearBottom = false;
4364                                 if(Math.abs(cur - base) > Math.abs(cur + this.items[j][sizeProperty] - base)){
4365                                         nearBottom = true;
4366                                         cur += this.items[j][sizeProperty];
4367                                 }
4368
4369                                 if(Math.abs(cur - base) < dist) {
4370                                         dist = Math.abs(cur - base); itemWithLeastDistance = this.items[j];
4371                                         this.direction = nearBottom ? "up": "down";
4372                                 }
4373                         }
4374
4375                         //Check if dropOnEmpty is enabled
4376                         if(!itemWithLeastDistance && !this.options.dropOnEmpty) {
4377                                 return;
4378                         }
4379
4380                         if(this.currentContainer === this.containers[innermostIndex]) {
4381                                 return;
4382                         }
4383
4384                         itemWithLeastDistance ? this._rearrange(event, itemWithLeastDistance, null, true) : this._rearrange(event, null, this.containers[innermostIndex].element, true);
4385                         this._trigger("change", event, this._uiHash());
4386                         this.containers[innermostIndex]._trigger("change", event, this._uiHash(this));
4387                         this.currentContainer = this.containers[innermostIndex];
4388
4389                         //Update the placeholder
4390                         this.options.placeholder.update(this.currentContainer, this.placeholder);
4391
4392                         this.containers[innermostIndex]._trigger("over", event, this._uiHash(this));
4393                         this.containers[innermostIndex].containerCache.over = 1;
4394                 }
4395
4396
4397         },
4398
4399         _createHelper: function(event) {
4400
4401                 var o = this.options,
4402                         helper = $.isFunction(o.helper) ? $(o.helper.apply(this.element[0], [event, this.currentItem])) : (o.helper === "clone" ? this.currentItem.clone() : this.currentItem);
4403
4404                 //Add the helper to the DOM if that didn't happen already
4405                 if(!helper.parents("body").length) {
4406                         $(o.appendTo !== "parent" ? o.appendTo : this.currentItem[0].parentNode)[0].appendChild(helper[0]);
4407                 }
4408
4409                 if(helper[0] === this.currentItem[0]) {
4410                         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") };
4411                 }
4412
4413                 if(!helper[0].style.width || o.forceHelperSize) {
4414                         helper.width(this.currentItem.width());
4415                 }
4416                 if(!helper[0].style.height || o.forceHelperSize) {
4417                         helper.height(this.currentItem.height());
4418                 }
4419
4420                 return helper;
4421
4422         },
4423
4424         _adjustOffsetFromHelper: function(obj) {
4425                 if (typeof obj === "string") {
4426                         obj = obj.split(" ");
4427                 }
4428                 if ($.isArray(obj)) {
4429                         obj = {left: +obj[0], top: +obj[1] || 0};
4430                 }
4431                 if ("left" in obj) {
4432                         this.offset.click.left = obj.left + this.margins.left;
4433                 }
4434                 if ("right" in obj) {
4435                         this.offset.click.left = this.helperProportions.width - obj.right + this.margins.left;
4436                 }
4437                 if ("top" in obj) {
4438                         this.offset.click.top = obj.top + this.margins.top;
4439                 }
4440                 if ("bottom" in obj) {
4441                         this.offset.click.top = this.helperProportions.height - obj.bottom + this.margins.top;
4442                 }
4443         },
4444
4445         _getParentOffset: function() {
4446
4447
4448                 //Get the offsetParent and cache its position
4449                 this.offsetParent = this.helper.offsetParent();
4450                 var po = this.offsetParent.offset();
4451
4452                 // This is a special case where we need to modify a offset calculated on start, since the following happened:
4453                 // 1. The position of the helper is absolute, so it's position is calculated based on the next positioned parent
4454                 // 2. The actual offset parent is a child of the scroll parent, and the scroll parent isn't the document, which means that
4455                 //    the scroll is included in the initial calculation of the offset of the parent, and never recalculated upon drag
4456                 if(this.cssPosition === "absolute" && this.scrollParent[0] !== document && $.contains(this.scrollParent[0], this.offsetParent[0])) {
4457                         po.left += this.scrollParent.scrollLeft();
4458                         po.top += this.scrollParent.scrollTop();
4459                 }
4460
4461                 // This needs to be actually done for all browsers, since pageX/pageY includes this information
4462                 // with an ugly IE fix
4463                 if( this.offsetParent[0] === document.body || (this.offsetParent[0].tagName && this.offsetParent[0].tagName.toLowerCase() === "html" && $.ui.ie)) {
4464                         po = { top: 0, left: 0 };
4465                 }
4466
4467                 return {
4468                         top: po.top + (parseInt(this.offsetParent.css("borderTopWidth"),10) || 0),
4469                         left: po.left + (parseInt(this.offsetParent.css("borderLeftWidth"),10) || 0)
4470                 };
4471
4472         },
4473
4474         _getRelativeOffset: function() {
4475
4476                 if(this.cssPosition === "relative") {
4477                         var p = this.currentItem.position();
4478                         return {
4479                                 top: p.top - (parseInt(this.helper.css("top"),10) || 0) + this.scrollParent.scrollTop(),
4480                                 left: p.left - (parseInt(this.helper.css("left"),10) || 0) + this.scrollParent.scrollLeft()
4481                         };
4482                 } else {
4483                         return { top: 0, left: 0 };
4484                 }
4485
4486         },
4487
4488         _cacheMargins: function() {
4489                 this.margins = {
4490                         left: (parseInt(this.currentItem.css("marginLeft"),10) || 0),
4491                         top: (parseInt(this.currentItem.css("marginTop"),10) || 0)
4492                 };
4493         },
4494
4495         _cacheHelperProportions: function() {
4496                 this.helperProportions = {
4497                         width: this.helper.outerWidth(),
4498                         height: this.helper.outerHeight()
4499                 };
4500         },
4501
4502         _setContainment: function() {
4503
4504                 var ce, co, over,
4505                         o = this.options;
4506                 if(o.containment === "parent") {
4507                         o.containment = this.helper[0].parentNode;
4508                 }
4509                 if(o.containment === "document" || o.containment === "window") {
4510                         this.containment = [
4511                                 0 - this.offset.relative.left - this.offset.parent.left,
4512                                 0 - this.offset.relative.top - this.offset.parent.top,
4513                                 $(o.containment === "document" ? document : window).width() - this.helperProportions.width - this.margins.left,
4514                                 ($(o.containment === "document" ? document : window).height() || document.body.parentNode.scrollHeight) - this.helperProportions.height - this.margins.top
4515                         ];
4516                 }
4517
4518                 if(!(/^(document|window|parent)$/).test(o.containment)) {
4519                         ce = $(o.containment)[0];
4520                         co = $(o.containment).offset();
4521                         over = ($(ce).css("overflow") !== "hidden");
4522
4523                         this.containment = [
4524                                 co.left + (parseInt($(ce).css("borderLeftWidth"),10) || 0) + (parseInt($(ce).css("paddingLeft"),10) || 0) - this.margins.left,
4525                                 co.top + (parseInt($(ce).css("borderTopWidth"),10) || 0) + (parseInt($(ce).css("paddingTop"),10) || 0) - this.margins.top,
4526                                 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,
4527                                 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
4528                         ];
4529                 }
4530
4531         },
4532
4533         _convertPositionTo: function(d, pos) {
4534
4535                 if(!pos) {
4536                         pos = this.position;
4537                 }
4538                 var mod = d === "absolute" ? 1 : -1,
4539                         scroll = this.cssPosition === "absolute" && !(this.scrollParent[0] !== document && $.contains(this.scrollParent[0], this.offsetParent[0])) ? this.offsetParent : this.scrollParent,
4540                         scrollIsRootNode = (/(html|body)/i).test(scroll[0].tagName);
4541
4542                 return {
4543                         top: (
4544                                 pos.top +                                                                                                                               // The absolute mouse position
4545                                 this.offset.relative.top * mod +                                                                                // Only for relative positioned nodes: Relative offset from element to offset parent
4546                                 this.offset.parent.top * mod -                                                                                  // The offsetParent's offset without borders (offset + border)
4547                                 ( ( this.cssPosition === "fixed" ? -this.scrollParent.scrollTop() : ( scrollIsRootNode ? 0 : scroll.scrollTop() ) ) * mod)
4548                         ),
4549                         left: (
4550                                 pos.left +                                                                                                                              // The absolute mouse position
4551                                 this.offset.relative.left * mod +                                                                               // Only for relative positioned nodes: Relative offset from element to offset parent
4552                                 this.offset.parent.left * mod   -                                                                               // The offsetParent's offset without borders (offset + border)
4553                                 ( ( this.cssPosition === "fixed" ? -this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 : scroll.scrollLeft() ) * mod)
4554                         )
4555                 };
4556
4557         },
4558
4559         _generatePosition: function(event) {
4560
4561                 var top, left,
4562                         o = this.options,
4563                         pageX = event.pageX,
4564                         pageY = event.pageY,
4565                         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);
4566
4567                 // This is another very weird special case that only happens for relative elements:
4568                 // 1. If the css position is relative
4569                 // 2. and the scroll parent is the document or similar to the offset parent
4570                 // we have to refresh the relative offset during the scroll so there are no jumps
4571                 if(this.cssPosition === "relative" && !(this.scrollParent[0] !== document && this.scrollParent[0] !== this.offsetParent[0])) {
4572                         this.offset.relative = this._getRelativeOffset();
4573                 }
4574
4575                 /*
4576                  * - Position constraining -
4577                  * Constrain the position to a mix of grid, containment.
4578                  */
4579
4580                 if(this.originalPosition) { //If we are not dragging yet, we won't check for options
4581
4582                         if(this.containment) {
4583                                 if(event.pageX - this.offset.click.left < this.containment[0]) {
4584                                         pageX = this.containment[0] + this.offset.click.left;
4585                                 }
4586                                 if(event.pageY - this.offset.click.top < this.containment[1]) {
4587                                         pageY = this.containment[1] + this.offset.click.top;
4588                                 }
4589                                 if(event.pageX - this.offset.click.left > this.containment[2]) {
4590                                         pageX = this.containment[2] + this.offset.click.left;
4591                                 }
4592                                 if(event.pageY - this.offset.click.top > this.containment[3]) {
4593                                         pageY = this.containment[3] + this.offset.click.top;
4594                                 }
4595                         }
4596
4597                         if(o.grid) {
4598                                 top = this.originalPageY + Math.round((pageY - this.originalPageY) / o.grid[1]) * o.grid[1];
4599                                 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;
4600
4601                                 left = this.originalPageX + Math.round((pageX - this.originalPageX) / o.grid[0]) * o.grid[0];
4602                                 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;
4603                         }
4604
4605                 }
4606
4607                 return {
4608                         top: (
4609                                 pageY -                                                                                                                         // The absolute mouse position
4610                                 this.offset.click.top -                                                                                                 // Click offset (relative to the element)
4611                                 this.offset.relative.top        -                                                                                       // Only for relative positioned nodes: Relative offset from element to offset parent
4612                                 this.offset.parent.top +                                                                                                // The offsetParent's offset without borders (offset + border)
4613                                 ( ( this.cssPosition === "fixed" ? -this.scrollParent.scrollTop() : ( scrollIsRootNode ? 0 : scroll.scrollTop() ) ))
4614                         ),
4615                         left: (
4616                                 pageX -                                                                                                                         // The absolute mouse position
4617                                 this.offset.click.left -                                                                                                // Click offset (relative to the element)
4618                                 this.offset.relative.left       -                                                                                       // Only for relative positioned nodes: Relative offset from element to offset parent
4619                                 this.offset.parent.left +                                                                                               // The offsetParent's offset without borders (offset + border)
4620                                 ( ( this.cssPosition === "fixed" ? -this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 : scroll.scrollLeft() ))
4621                         )
4622                 };
4623
4624         },
4625
4626         _rearrange: function(event, i, a, hardRefresh) {
4627
4628                 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));
4629
4630                 //Various things done here to improve the performance:
4631                 // 1. we create a setTimeout, that calls refreshPositions
4632                 // 2. on the instance, we have a counter variable, that get's higher after every append
4633                 // 3. on the local scope, we copy the counter variable, and check in the timeout, if it's still the same
4634                 // 4. this lets only the last addition to the timeout stack through
4635                 this.counter = this.counter ? ++this.counter : 1;
4636                 var counter = this.counter;
4637
4638                 this._delay(function() {
4639                         if(counter === this.counter) {
4640                                 this.refreshPositions(!hardRefresh); //Precompute after each DOM insertion, NOT on mousemove
4641                         }
4642                 });
4643
4644         },
4645
4646         _clear: function(event, noPropagation) {
4647
4648                 this.reverting = false;
4649                 // We delay all events that have to be triggered to after the point where the placeholder has been removed and
4650                 // everything else normalized again
4651                 var i,
4652                         delayedTriggers = [];
4653
4654                 // We first have to update the dom position of the actual currentItem
4655                 // Note: don't do it if the current item is already removed (by a user), or it gets reappended (see #4088)
4656                 if(!this._noFinalSort && this.currentItem.parent().length) {
4657                         this.placeholder.before(this.currentItem);
4658                 }
4659                 this._noFinalSort = null;
4660
4661                 if(this.helper[0] === this.currentItem[0]) {
4662                         for(i in this._storedCSS) {
4663                                 if(this._storedCSS[i] === "auto" || this._storedCSS[i] === "static") {
4664                                         this._storedCSS[i] = "";
4665                                 }
4666                         }
4667                         this.currentItem.css(this._storedCSS).removeClass("ui-sortable-helper");
4668                 } else {
4669                         this.currentItem.show();
4670                 }
4671
4672                 if(this.fromOutside && !noPropagation) {
4673                         delayedTriggers.push(function(event) { this._trigger("receive", event, this._uiHash(this.fromOutside)); });
4674                 }
4675                 if((this.fromOutside || this.domPosition.prev !== this.currentItem.prev().not(".ui-sortable-helper")[0] || this.domPosition.parent !== this.currentItem.parent()[0]) && !noPropagation) {
4676                         delayedTriggers.push(function(event) { this._trigger("update", event, this._uiHash()); }); //Trigger update callback if the DOM position has changed
4677                 }
4678
4679                 // Check if the items Container has Changed and trigger appropriate
4680                 // events.
4681                 if (this !== this.currentContainer) {
4682                         if(!noPropagation) {
4683                                 delayedTriggers.push(function(event) { this._trigger("remove", event, this._uiHash()); });
4684                                 delayedTriggers.push((function(c) { return function(event) { c._trigger("receive", event, this._uiHash(this)); };  }).call(this, this.currentContainer));
4685                                 delayedTriggers.push((function(c) { return function(event) { c._trigger("update", event, this._uiHash(this));  }; }).call(this, this.currentContainer));
4686                         }
4687                 }
4688
4689
4690                 //Post events to containers
4691                 for (i = this.containers.length - 1; i >= 0; i--){
4692                         if(!noPropagation) {
4693                                 delayedTriggers.push((function(c) { return function(event) { c._trigger("deactivate", event, this._uiHash(this)); };  }).call(this, this.containers[i]));
4694                         }
4695                         if(this.containers[i].containerCache.over) {
4696                                 delayedTriggers.push((function(c) { return function(event) { c._trigger("out", event, this._uiHash(this)); };  }).call(this, this.containers[i]));
4697                                 this.containers[i].containerCache.over = 0;
4698                         }
4699                 }
4700
4701                 //Do what was originally in plugins
4702                 if ( this.storedCursor ) {
4703                         this.document.find( "body" ).css( "cursor", this.storedCursor );
4704                         this.storedStylesheet.remove();
4705                 }
4706                 if(this._storedOpacity) {
4707                         this.helper.css("opacity", this._storedOpacity);
4708                 }
4709                 if(this._storedZIndex) {
4710                         this.helper.css("zIndex", this._storedZIndex === "auto" ? "" : this._storedZIndex);
4711                 }
4712
4713                 this.dragging = false;
4714                 if(this.cancelHelperRemoval) {
4715                         if(!noPropagation) {
4716                                 this._trigger("beforeStop", event, this._uiHash());
4717                                 for (i=0; i < delayedTriggers.length; i++) {
4718                                         delayedTriggers[i].call(this, event);
4719                                 } //Trigger all delayed events
4720                                 this._trigger("stop", event, this._uiHash());
4721                         }
4722
4723                         this.fromOutside = false;
4724                         return false;
4725                 }
4726
4727                 if(!noPropagation) {
4728                         this._trigger("beforeStop", event, this._uiHash());
4729                 }
4730
4731                 //$(this.placeholder[0]).remove(); would have been the jQuery way - unfortunately, it unbinds ALL events from the original node!
4732                 this.placeholder[0].parentNode.removeChild(this.placeholder[0]);
4733
4734                 if(this.helper[0] !== this.currentItem[0]) {
4735                         this.helper.remove();
4736                 }
4737                 this.helper = null;
4738
4739                 if(!noPropagation) {
4740                         for (i=0; i < delayedTriggers.length; i++) {
4741                                 delayedTriggers[i].call(this, event);
4742                         } //Trigger all delayed events
4743                         this._trigger("stop", event, this._uiHash());
4744                 }
4745
4746                 this.fromOutside = false;
4747                 return true;
4748
4749         },
4750
4751         _trigger: function() {
4752                 if ($.Widget.prototype._trigger.apply(this, arguments) === false) {
4753                         this.cancel();
4754                 }
4755         },
4756
4757         _uiHash: function(_inst) {
4758                 var inst = _inst || this;
4759                 return {
4760                         helper: inst.helper,
4761                         placeholder: inst.placeholder || $([]),
4762                         position: inst.position,
4763                         originalPosition: inst.originalPosition,
4764                         offset: inst.positionAbs,
4765                         item: inst.currentItem,
4766                         sender: _inst ? _inst.element : null
4767                 };
4768         }
4769
4770 });
4771
4772 })(jQuery);
4773
4774 (function($, undefined) {
4775
4776 var dataSpace = "ui-effects-";
4777
4778 $.effects = {
4779         effect: {}
4780 };
4781
4782 /*!
4783  * jQuery Color Animations v2.1.2
4784  * https://github.com/jquery/jquery-color
4785  *
4786  * Copyright 2013 jQuery Foundation and other contributors
4787  * Released under the MIT license.
4788  * http://jquery.org/license
4789  *
4790  * Date: Wed Jan 16 08:47:09 2013 -0600
4791  */
4792 (function( jQuery, undefined ) {
4793
4794         var stepHooks = "backgroundColor borderBottomColor borderLeftColor borderRightColor borderTopColor color columnRuleColor outlineColor textDecorationColor textEmphasisColor",
4795
4796         // plusequals test for += 100 -= 100
4797         rplusequals = /^([\-+])=\s*(\d+\.?\d*)/,
4798         // a set of RE's that can match strings and generate color tuples.
4799         stringParsers = [{
4800                         re: /rgba?\(\s*(\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(\d{1,3})\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/,
4801                         parse: function( execResult ) {
4802                                 return [
4803                                         execResult[ 1 ],
4804                                         execResult[ 2 ],
4805                                         execResult[ 3 ],
4806                                         execResult[ 4 ]
4807                                 ];
4808                         }
4809                 }, {
4810                         re: /rgba?\(\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/,
4811                         parse: function( execResult ) {
4812                                 return [
4813                                         execResult[ 1 ] * 2.55,
4814                                         execResult[ 2 ] * 2.55,
4815                                         execResult[ 3 ] * 2.55,
4816                                         execResult[ 4 ]
4817                                 ];
4818                         }
4819                 }, {
4820                         // this regex ignores A-F because it's compared against an already lowercased string
4821                         re: /#([a-f0-9]{2})([a-f0-9]{2})([a-f0-9]{2})/,
4822                         parse: function( execResult ) {
4823                                 return [
4824                                         parseInt( execResult[ 1 ], 16 ),
4825                                         parseInt( execResult[ 2 ], 16 ),
4826                                         parseInt( execResult[ 3 ], 16 )
4827                                 ];
4828                         }
4829                 }, {
4830                         // this regex ignores A-F because it's compared against an already lowercased string
4831                         re: /#([a-f0-9])([a-f0-9])([a-f0-9])/,
4832                         parse: function( execResult ) {
4833                                 return [
4834                                         parseInt( execResult[ 1 ] + execResult[ 1 ], 16 ),
4835                                         parseInt( execResult[ 2 ] + execResult[ 2 ], 16 ),
4836                                         parseInt( execResult[ 3 ] + execResult[ 3 ], 16 )
4837                                 ];
4838                         }
4839                 }, {
4840                         re: /hsla?\(\s*(\d+(?:\.\d+)?)\s*,\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/,
4841                         space: "hsla",
4842                         parse: function( execResult ) {
4843                                 return [
4844                                         execResult[ 1 ],
4845                                         execResult[ 2 ] / 100,
4846                                         execResult[ 3 ] / 100,
4847                                         execResult[ 4 ]
4848                                 ];
4849                         }
4850                 }],
4851
4852         // jQuery.Color( )
4853         color = jQuery.Color = function( color, green, blue, alpha ) {
4854                 return new jQuery.Color.fn.parse( color, green, blue, alpha );
4855         },
4856         spaces = {
4857                 rgba: {
4858                         props: {
4859                                 red: {
4860                                         idx: 0,
4861                                         type: "byte"
4862                                 },
4863                                 green: {
4864                                         idx: 1,
4865                                         type: "byte"
4866                                 },
4867                                 blue: {
4868                                         idx: 2,
4869                                         type: "byte"
4870                                 }
4871                         }
4872                 },
4873
4874                 hsla: {
4875                         props: {
4876                                 hue: {
4877                                         idx: 0,
4878                                         type: "degrees"
4879                                 },
4880                                 saturation: {
4881                                         idx: 1,
4882                                         type: "percent"
4883                                 },
4884                                 lightness: {
4885                                         idx: 2,
4886                                         type: "percent"
4887                                 }
4888                         }
4889                 }
4890         },
4891         propTypes = {
4892                 "byte": {
4893                         floor: true,
4894                         max: 255
4895                 },
4896                 "percent": {
4897                         max: 1
4898                 },
4899                 "degrees": {
4900                         mod: 360,
4901                         floor: true
4902                 }
4903         },
4904         support = color.support = {},
4905
4906         // element for support tests
4907         supportElem = jQuery( "<p>" )[ 0 ],
4908
4909         // colors = jQuery.Color.names
4910         colors,
4911
4912         // local aliases of functions called often
4913         each = jQuery.each;
4914
4915 // determine rgba support immediately
4916 supportElem.style.cssText = "background-color:rgba(1,1,1,.5)";
4917 support.rgba = supportElem.style.backgroundColor.indexOf( "rgba" ) > -1;
4918
4919 // define cache name and alpha properties
4920 // for rgba and hsla spaces
4921 each( spaces, function( spaceName, space ) {
4922         space.cache = "_" + spaceName;
4923         space.props.alpha = {
4924                 idx: 3,
4925                 type: "percent",
4926                 def: 1
4927         };
4928 });
4929
4930 function clamp( value, prop, allowEmpty ) {
4931         var type = propTypes[ prop.type ] || {};
4932
4933         if ( value == null ) {
4934                 return (allowEmpty || !prop.def) ? null : prop.def;
4935         }
4936
4937         // ~~ is an short way of doing floor for positive numbers
4938         value = type.floor ? ~~value : parseFloat( value );
4939
4940         // IE will pass in empty strings as value for alpha,
4941         // which will hit this case
4942         if ( isNaN( value ) ) {
4943                 return prop.def;
4944         }
4945
4946         if ( type.mod ) {
4947                 // we add mod before modding to make sure that negatives values
4948                 // get converted properly: -10 -> 350
4949                 return (value + type.mod) % type.mod;
4950         }
4951
4952         // for now all property types without mod have min and max
4953         return 0 > value ? 0 : type.max < value ? type.max : value;
4954 }
4955
4956 function stringParse( string ) {
4957         var inst = color(),
4958                 rgba = inst._rgba = [];
4959
4960         string = string.toLowerCase();
4961
4962         each( stringParsers, function( i, parser ) {
4963                 var parsed,
4964                         match = parser.re.exec( string ),
4965                         values = match && parser.parse( match ),
4966                         spaceName = parser.space || "rgba";
4967
4968                 if ( values ) {
4969                         parsed = inst[ spaceName ]( values );
4970
4971                         // if this was an rgba parse the assignment might happen twice
4972                         // oh well....
4973                         inst[ spaces[ spaceName ].cache ] = parsed[ spaces[ spaceName ].cache ];
4974                         rgba = inst._rgba = parsed._rgba;
4975
4976                         // exit each( stringParsers ) here because we matched
4977                         return false;
4978                 }
4979         });
4980
4981         // Found a stringParser that handled it
4982         if ( rgba.length ) {
4983
4984                 // if this came from a parsed string, force "transparent" when alpha is 0
4985                 // chrome, (and maybe others) return "transparent" as rgba(0,0,0,0)
4986                 if ( rgba.join() === "0,0,0,0" ) {
4987                         jQuery.extend( rgba, colors.transparent );
4988                 }
4989                 return inst;
4990         }
4991
4992         // named colors
4993         return colors[ string ];
4994 }
4995
4996 color.fn = jQuery.extend( color.prototype, {
4997         parse: function( red, green, blue, alpha ) {
4998                 if ( red === undefined ) {
4999                         this._rgba = [ null, null, null, null ];
5000                         return this;
5001                 }
5002                 if ( red.jquery || red.nodeType ) {
5003                         red = jQuery( red ).css( green );
5004                         green = undefined;
5005                 }
5006
5007                 var inst = this,
5008                         type = jQuery.type( red ),
5009                         rgba = this._rgba = [];
5010
5011                 // more than 1 argument specified - assume ( red, green, blue, alpha )
5012                 if ( green !== undefined ) {
5013                         red = [ red, green, blue, alpha ];
5014                         type = "array";
5015                 }
5016
5017                 if ( type === "string" ) {
5018                         return this.parse( stringParse( red ) || colors._default );
5019                 }
5020
5021                 if ( type === "array" ) {
5022                         each( spaces.rgba.props, function( key, prop ) {
5023                                 rgba[ prop.idx ] = clamp( red[ prop.idx ], prop );
5024                         });
5025                         return this;
5026                 }
5027
5028                 if ( type === "object" ) {
5029                         if ( red instanceof color ) {
5030                                 each( spaces, function( spaceName, space ) {
5031                                         if ( red[ space.cache ] ) {
5032                                                 inst[ space.cache ] = red[ space.cache ].slice();
5033                                         }
5034                                 });
5035                         } else {
5036                                 each( spaces, function( spaceName, space ) {
5037                                         var cache = space.cache;
5038                                         each( space.props, function( key, prop ) {
5039
5040                                                 // if the cache doesn't exist, and we know how to convert
5041                                                 if ( !inst[ cache ] && space.to ) {
5042
5043                                                         // if the value was null, we don't need to copy it
5044                                                         // if the key was alpha, we don't need to copy it either
5045                                                         if ( key === "alpha" || red[ key ] == null ) {
5046                                                                 return;
5047                                                         }
5048                                                         inst[ cache ] = space.to( inst._rgba );
5049                                                 }
5050
5051                                                 // this is the only case where we allow nulls for ALL properties.
5052                                                 // call clamp with alwaysAllowEmpty
5053                                                 inst[ cache ][ prop.idx ] = clamp( red[ key ], prop, true );
5054                                         });
5055
5056                                         // everything defined but alpha?
5057                                         if ( inst[ cache ] && jQuery.inArray( null, inst[ cache ].slice( 0, 3 ) ) < 0 ) {
5058                                                 // use the default of 1
5059                                                 inst[ cache ][ 3 ] = 1;
5060                                                 if ( space.from ) {
5061                                                         inst._rgba = space.from( inst[ cache ] );
5062                                                 }
5063                                         }
5064                                 });
5065                         }
5066                         return this;
5067                 }
5068         },
5069         is: function( compare ) {
5070                 var is = color( compare ),
5071                         same = true,
5072                         inst = this;
5073
5074                 each( spaces, function( _, space ) {
5075                         var localCache,
5076                                 isCache = is[ space.cache ];
5077                         if (isCache) {
5078                                 localCache = inst[ space.cache ] || space.to && space.to( inst._rgba ) || [];
5079                                 each( space.props, function( _, prop ) {
5080                                         if ( isCache[ prop.idx ] != null ) {
5081                                                 same = ( isCache[ prop.idx ] === localCache[ prop.idx ] );
5082                                                 return same;
5083                                         }
5084                                 });
5085                         }
5086                         return same;
5087                 });
5088                 return same;
5089         },
5090         _space: function() {
5091                 var used = [],
5092                         inst = this;
5093                 each( spaces, function( spaceName, space ) {
5094                         if ( inst[ space.cache ] ) {
5095                                 used.push( spaceName );
5096                         }
5097                 });
5098                 return used.pop();
5099         },
5100         transition: function( other, distance ) {
5101                 var end = color( other ),
5102                         spaceName = end._space(),
5103                         space = spaces[ spaceName ],
5104                         startColor = this.alpha() === 0 ? color( "transparent" ) : this,
5105                         start = startColor[ space.cache ] || space.to( startColor._rgba ),
5106                         result = start.slice();
5107
5108                 end = end[ space.cache ];
5109                 each( space.props, function( key, prop ) {
5110                         var index = prop.idx,
5111                                 startValue = start[ index ],
5112                                 endValue = end[ index ],
5113                                 type = propTypes[ prop.type ] || {};
5114
5115                         // if null, don't override start value
5116                         if ( endValue === null ) {
5117                                 return;
5118                         }
5119                         // if null - use end
5120                         if ( startValue === null ) {
5121                                 result[ index ] = endValue;
5122                         } else {
5123                                 if ( type.mod ) {
5124                                         if ( endValue - startValue > type.mod / 2 ) {
5125                                                 startValue += type.mod;
5126                                         } else if ( startValue - endValue > type.mod / 2 ) {
5127                                                 startValue -= type.mod;
5128                                         }
5129                                 }
5130                                 result[ index ] = clamp( ( endValue - startValue ) * distance + startValue, prop );
5131                         }
5132                 });
5133                 return this[ spaceName ]( result );
5134         },
5135         blend: function( opaque ) {
5136                 // if we are already opaque - return ourself
5137                 if ( this._rgba[ 3 ] === 1 ) {
5138                         return this;
5139                 }
5140
5141                 var rgb = this._rgba.slice(),
5142                         a = rgb.pop(),
5143                         blend = color( opaque )._rgba;
5144
5145                 return color( jQuery.map( rgb, function( v, i ) {
5146                         return ( 1 - a ) * blend[ i ] + a * v;
5147                 }));
5148         },
5149         toRgbaString: function() {
5150                 var prefix = "rgba(",
5151                         rgba = jQuery.map( this._rgba, function( v, i ) {
5152                                 return v == null ? ( i > 2 ? 1 : 0 ) : v;
5153                         });
5154
5155                 if ( rgba[ 3 ] === 1 ) {
5156                         rgba.pop();
5157                         prefix = "rgb(";
5158                 }
5159
5160                 return prefix + rgba.join() + ")";
5161         },
5162         toHslaString: function() {
5163                 var prefix = "hsla(",
5164                         hsla = jQuery.map( this.hsla(), function( v, i ) {
5165                                 if ( v == null ) {
5166                                         v = i > 2 ? 1 : 0;
5167                                 }
5168
5169                                 // catch 1 and 2
5170                                 if ( i && i < 3 ) {
5171                                         v = Math.round( v * 100 ) + "%";
5172                                 }
5173                                 return v;
5174                         });
5175
5176                 if ( hsla[ 3 ] === 1 ) {
5177                         hsla.pop();
5178                         prefix = "hsl(";
5179                 }
5180                 return prefix + hsla.join() + ")";
5181         },
5182         toHexString: function( includeAlpha ) {
5183                 var rgba = this._rgba.slice(),
5184                         alpha = rgba.pop();
5185
5186                 if ( includeAlpha ) {
5187                         rgba.push( ~~( alpha * 255 ) );
5188                 }
5189
5190                 return "#" + jQuery.map( rgba, function( v ) {
5191
5192                         // default to 0 when nulls exist
5193                         v = ( v || 0 ).toString( 16 );
5194                         return v.length === 1 ? "0" + v : v;
5195                 }).join("");
5196         },
5197         toString: function() {
5198                 return this._rgba[ 3 ] === 0 ? "transparent" : this.toRgbaString();
5199         }
5200 });
5201 color.fn.parse.prototype = color.fn;
5202
5203 // hsla conversions adapted from:
5204 // https://code.google.com/p/maashaack/source/browse/packages/graphics/trunk/src/graphics/colors/HUE2RGB.as?r=5021
5205
5206 function hue2rgb( p, q, h ) {
5207         h = ( h + 1 ) % 1;
5208         if ( h * 6 < 1 ) {
5209                 return p + (q - p) * h * 6;
5210         }
5211         if ( h * 2 < 1) {
5212                 return q;
5213         }
5214         if ( h * 3 < 2 ) {
5215                 return p + (q - p) * ((2/3) - h) * 6;
5216         }
5217         return p;
5218 }
5219
5220 spaces.hsla.to = function ( rgba ) {
5221         if ( rgba[ 0 ] == null || rgba[ 1 ] == null || rgba[ 2 ] == null ) {
5222                 return [ null, null, null, rgba[ 3 ] ];
5223         }
5224         var r = rgba[ 0 ] / 255,
5225                 g = rgba[ 1 ] / 255,
5226                 b = rgba[ 2 ] / 255,
5227                 a = rgba[ 3 ],
5228                 max = Math.max( r, g, b ),
5229                 min = Math.min( r, g, b ),
5230                 diff = max - min,
5231                 add = max + min,
5232                 l = add * 0.5,
5233                 h, s;
5234
5235         if ( min === max ) {
5236                 h = 0;
5237         } else if ( r === max ) {
5238                 h = ( 60 * ( g - b ) / diff ) + 360;
5239         } else if ( g === max ) {
5240                 h = ( 60 * ( b - r ) / diff ) + 120;
5241         } else {
5242                 h = ( 60 * ( r - g ) / diff ) + 240;
5243         }
5244
5245         // chroma (diff) == 0 means greyscale which, by definition, saturation = 0%
5246         // otherwise, saturation is based on the ratio of chroma (diff) to lightness (add)
5247         if ( diff === 0 ) {
5248                 s = 0;
5249         } else if ( l <= 0.5 ) {
5250                 s = diff / add;
5251         } else {
5252                 s = diff / ( 2 - add );
5253         }
5254         return [ Math.round(h) % 360, s, l, a == null ? 1 : a ];
5255 };
5256
5257 spaces.hsla.from = function ( hsla ) {
5258         if ( hsla[ 0 ] == null || hsla[ 1 ] == null || hsla[ 2 ] == null ) {
5259                 return [ null, null, null, hsla[ 3 ] ];
5260         }
5261         var h = hsla[ 0 ] / 360,
5262                 s = hsla[ 1 ],
5263                 l = hsla[ 2 ],
5264                 a = hsla[ 3 ],
5265                 q = l <= 0.5 ? l * ( 1 + s ) : l + s - l * s,
5266                 p = 2 * l - q;
5267
5268         return [
5269                 Math.round( hue2rgb( p, q, h + ( 1 / 3 ) ) * 255 ),
5270                 Math.round( hue2rgb( p, q, h ) * 255 ),
5271                 Math.round( hue2rgb( p, q, h - ( 1 / 3 ) ) * 255 ),
5272                 a
5273         ];
5274 };
5275
5276
5277 each( spaces, function( spaceName, space ) {
5278         var props = space.props,
5279                 cache = space.cache,
5280                 to = space.to,
5281                 from = space.from;
5282
5283         // makes rgba() and hsla()
5284         color.fn[ spaceName ] = function( value ) {
5285
5286                 // generate a cache for this space if it doesn't exist
5287                 if ( to && !this[ cache ] ) {
5288                         this[ cache ] = to( this._rgba );
5289                 }
5290                 if ( value === undefined ) {
5291                         return this[ cache ].slice();
5292                 }
5293
5294                 var ret,
5295                         type = jQuery.type( value ),
5296                         arr = ( type === "array" || type === "object" ) ? value : arguments,
5297                         local = this[ cache ].slice();
5298
5299                 each( props, function( key, prop ) {
5300                         var val = arr[ type === "object" ? key : prop.idx ];
5301                         if ( val == null ) {
5302                                 val = local[ prop.idx ];
5303                         }
5304                         local[ prop.idx ] = clamp( val, prop );
5305                 });
5306
5307                 if ( from ) {
5308                         ret = color( from( local ) );
5309                         ret[ cache ] = local;
5310                         return ret;
5311                 } else {
5312                         return color( local );
5313                 }
5314         };
5315
5316         // makes red() green() blue() alpha() hue() saturation() lightness()
5317         each( props, function( key, prop ) {
5318                 // alpha is included in more than one space
5319                 if ( color.fn[ key ] ) {
5320                         return;
5321                 }
5322                 color.fn[ key ] = function( value ) {
5323                         var vtype = jQuery.type( value ),
5324                                 fn = ( key === "alpha" ? ( this._hsla ? "hsla" : "rgba" ) : spaceName ),
5325                                 local = this[ fn ](),
5326                                 cur = local[ prop.idx ],
5327                                 match;
5328
5329                         if ( vtype === "undefined" ) {
5330                                 return cur;
5331                         }
5332
5333                         if ( vtype === "function" ) {
5334                                 value = value.call( this, cur );
5335                                 vtype = jQuery.type( value );
5336                         }
5337                         if ( value == null && prop.empty ) {
5338                                 return this;
5339                         }
5340                         if ( vtype === "string" ) {
5341                                 match = rplusequals.exec( value );
5342                                 if ( match ) {
5343                                         value = cur + parseFloat( match[ 2 ] ) * ( match[ 1 ] === "+" ? 1 : -1 );
5344                                 }
5345                         }
5346                         local[ prop.idx ] = value;
5347                         return this[ fn ]( local );
5348                 };
5349         });
5350 });
5351
5352 // add cssHook and .fx.step function for each named hook.
5353 // accept a space separated string of properties
5354 color.hook = function( hook ) {
5355         var hooks = hook.split( " " );
5356         each( hooks, function( i, hook ) {
5357                 jQuery.cssHooks[ hook ] = {
5358                         set: function( elem, value ) {
5359                                 var parsed, curElem,
5360                                         backgroundColor = "";
5361
5362                                 if ( value !== "transparent" && ( jQuery.type( value ) !== "string" || ( parsed = stringParse( value ) ) ) ) {
5363                                         value = color( parsed || value );
5364                                         if ( !support.rgba && value._rgba[ 3 ] !== 1 ) {
5365                                                 curElem = hook === "backgroundColor" ? elem.parentNode : elem;
5366                                                 while (
5367                                                         (backgroundColor === "" || backgroundColor === "transparent") &&
5368                                                         curElem && curElem.style
5369                                                 ) {
5370                                                         try {
5371                                                                 backgroundColor = jQuery.css( curElem, "backgroundColor" );
5372                                                                 curElem = curElem.parentNode;
5373                                                         } catch ( e ) {
5374                                                         }
5375                                                 }
5376
5377                                                 value = value.blend( backgroundColor && backgroundColor !== "transparent" ?
5378                                                         backgroundColor :
5379                                                         "_default" );
5380                                         }
5381
5382                                         value = value.toRgbaString();
5383                                 }
5384                                 try {
5385                                         elem.style[ hook ] = value;
5386                                 } catch( e ) {
5387                                         // wrapped to prevent IE from throwing errors on "invalid" values like 'auto' or 'inherit'
5388                                 }
5389                         }
5390                 };
5391                 jQuery.fx.step[ hook ] = function( fx ) {
5392                         if ( !fx.colorInit ) {
5393                                 fx.start = color( fx.elem, hook );
5394                                 fx.end = color( fx.end );
5395                                 fx.colorInit = true;
5396                         }
5397                         jQuery.cssHooks[ hook ].set( fx.elem, fx.start.transition( fx.end, fx.pos ) );
5398                 };
5399         });
5400
5401 };
5402
5403 color.hook( stepHooks );
5404
5405 jQuery.cssHooks.borderColor = {
5406         expand: function( value ) {
5407                 var expanded = {};
5408
5409                 each( [ "Top", "Right", "Bottom", "Left" ], function( i, part ) {
5410                         expanded[ "border" + part + "Color" ] = value;
5411                 });
5412                 return expanded;
5413         }
5414 };
5415
5416 // Basic color names only.
5417 // Usage of any of the other color names requires adding yourself or including
5418 // jquery.color.svg-names.js.
5419 colors = jQuery.Color.names = {
5420         // 4.1. Basic color keywords
5421         aqua: "#00ffff",
5422         black: "#000000",
5423         blue: "#0000ff",
5424         fuchsia: "#ff00ff",
5425         gray: "#808080",
5426         green: "#008000",
5427         lime: "#00ff00",
5428         maroon: "#800000",
5429         navy: "#000080",
5430         olive: "#808000",
5431         purple: "#800080",
5432         red: "#ff0000",
5433         silver: "#c0c0c0",
5434         teal: "#008080",
5435         white: "#ffffff",
5436         yellow: "#ffff00",
5437
5438         // 4.2.3. "transparent" color keyword
5439         transparent: [ null, null, null, 0 ],
5440
5441         _default: "#ffffff"
5442 };
5443
5444 })( jQuery );
5445
5446
5447 /******************************************************************************/
5448 /****************************** CLASS ANIMATIONS ******************************/
5449 /******************************************************************************/
5450 (function() {
5451
5452 var classAnimationActions = [ "add", "remove", "toggle" ],
5453         shorthandStyles = {
5454                 border: 1,
5455                 borderBottom: 1,
5456                 borderColor: 1,
5457                 borderLeft: 1,
5458                 borderRight: 1,
5459                 borderTop: 1,
5460                 borderWidth: 1,
5461                 margin: 1,
5462                 padding: 1
5463         };
5464
5465 $.each([ "borderLeftStyle", "borderRightStyle", "borderBottomStyle", "borderTopStyle" ], function( _, prop ) {
5466         $.fx.step[ prop ] = function( fx ) {
5467                 if ( fx.end !== "none" && !fx.setAttr || fx.pos === 1 && !fx.setAttr ) {
5468                         jQuery.style( fx.elem, prop, fx.end );
5469                         fx.setAttr = true;
5470                 }
5471         };
5472 });
5473
5474 function getElementStyles( elem ) {
5475         var key, len,
5476                 style = elem.ownerDocument.defaultView ?
5477                         elem.ownerDocument.defaultView.getComputedStyle( elem, null ) :
5478                         elem.currentStyle,
5479                 styles = {};
5480
5481         if ( style && style.length && style[ 0 ] && style[ style[ 0 ] ] ) {
5482                 len = style.length;
5483                 while ( len-- ) {
5484                         key = style[ len ];
5485                         if ( typeof style[ key ] === "string" ) {
5486                                 styles[ $.camelCase( key ) ] = style[ key ];
5487                         }
5488                 }
5489         // support: Opera, IE <9
5490         } else {
5491                 for ( key in style ) {
5492                         if ( typeof style[ key ] === "string" ) {
5493                                 styles[ key ] = style[ key ];
5494                         }
5495                 }
5496         }
5497
5498         return styles;
5499 }
5500
5501
5502 function styleDifference( oldStyle, newStyle ) {
5503         var diff = {},
5504                 name, value;
5505
5506         for ( name in newStyle ) {
5507                 value = newStyle[ name ];
5508                 if ( oldStyle[ name ] !== value ) {
5509                         if ( !shorthandStyles[ name ] ) {
5510                                 if ( $.fx.step[ name ] || !isNaN( parseFloat( value ) ) ) {
5511                                         diff[ name ] = value;
5512                                 }
5513                         }
5514                 }
5515         }
5516
5517         return diff;
5518 }
5519
5520 // support: jQuery <1.8
5521 if ( !$.fn.addBack ) {
5522         $.fn.addBack = function( selector ) {
5523                 return this.add( selector == null ?
5524                         this.prevObject : this.prevObject.filter( selector )
5525                 );
5526         };
5527 }
5528
5529 $.effects.animateClass = function( value, duration, easing, callback ) {
5530         var o = $.speed( duration, easing, callback );
5531
5532         return this.queue( function() {
5533                 var animated = $( this ),
5534                         baseClass = animated.attr( "class" ) || "",
5535                         applyClassChange,
5536                         allAnimations = o.children ? animated.find( "*" ).addBack() : animated;
5537
5538                 // map the animated objects to store the original styles.
5539                 allAnimations = allAnimations.map(function() {
5540                         var el = $( this );
5541                         return {
5542                                 el: el,
5543                                 start: getElementStyles( this )
5544                         };
5545                 });
5546
5547                 // apply class change
5548                 applyClassChange = function() {
5549                         $.each( classAnimationActions, function(i, action) {
5550                                 if ( value[ action ] ) {
5551                                         animated[ action + "Class" ]( value[ action ] );
5552                                 }
5553                         });
5554                 };
5555                 applyClassChange();
5556
5557                 // map all animated objects again - calculate new styles and diff
5558                 allAnimations = allAnimations.map(function() {
5559                         this.end = getElementStyles( this.el[ 0 ] );
5560                         this.diff = styleDifference( this.start, this.end );
5561                         return this;
5562                 });
5563
5564                 // apply original class
5565                 animated.attr( "class", baseClass );
5566
5567                 // map all animated objects again - this time collecting a promise
5568                 allAnimations = allAnimations.map(function() {
5569                         var styleInfo = this,
5570                                 dfd = $.Deferred(),
5571                                 opts = $.extend({}, o, {
5572                                         queue: false,
5573                                         complete: function() {
5574                                                 dfd.resolve( styleInfo );
5575                                         }
5576                                 });
5577
5578                         this.el.animate( this.diff, opts );
5579                         return dfd.promise();
5580                 });
5581
5582                 // once all animations have completed:
5583                 $.when.apply( $, allAnimations.get() ).done(function() {
5584
5585                         // set the final class
5586                         applyClassChange();
5587
5588                         // for each animated element,
5589                         // clear all css properties that were animated
5590                         $.each( arguments, function() {
5591                                 var el = this.el;
5592                                 $.each( this.diff, function(key) {
5593                                         el.css( key, "" );
5594                                 });
5595                         });
5596
5597                         // this is guarnteed to be there if you use jQuery.speed()
5598                         // it also handles dequeuing the next anim...
5599                         o.complete.call( animated[ 0 ] );
5600                 });
5601         });
5602 };
5603
5604 $.fn.extend({
5605         addClass: (function( orig ) {
5606                 return function( classNames, speed, easing, callback ) {
5607                         return speed ?
5608                                 $.effects.animateClass.call( this,
5609                                         { add: classNames }, speed, easing, callback ) :
5610                                 orig.apply( this, arguments );
5611                 };
5612         })( $.fn.addClass ),
5613
5614         removeClass: (function( orig ) {
5615                 return function( classNames, speed, easing, callback ) {
5616                         return arguments.length > 1 ?
5617                                 $.effects.animateClass.call( this,
5618                                         { remove: classNames }, speed, easing, callback ) :
5619                                 orig.apply( this, arguments );
5620                 };
5621         })( $.fn.removeClass ),
5622
5623         toggleClass: (function( orig ) {
5624                 return function( classNames, force, speed, easing, callback ) {
5625                         if ( typeof force === "boolean" || force === undefined ) {
5626                                 if ( !speed ) {
5627                                         // without speed parameter
5628                                         return orig.apply( this, arguments );
5629                                 } else {
5630                                         return $.effects.animateClass.call( this,
5631                                                 (force ? { add: classNames } : { remove: classNames }),
5632                                                 speed, easing, callback );
5633                                 }
5634                         } else {
5635                                 // without force parameter
5636                                 return $.effects.animateClass.call( this,
5637                                         { toggle: classNames }, force, speed, easing );
5638                         }
5639                 };
5640         })( $.fn.toggleClass ),
5641
5642         switchClass: function( remove, add, speed, easing, callback) {
5643                 return $.effects.animateClass.call( this, {
5644                         add: add,
5645                         remove: remove
5646                 }, speed, easing, callback );
5647         }
5648 });
5649
5650 })();
5651
5652 /******************************************************************************/
5653 /*********************************** EFFECTS **********************************/
5654 /******************************************************************************/
5655
5656 (function() {
5657
5658 $.extend( $.effects, {
5659         version: "1.10.3",
5660
5661         // Saves a set of properties in a data storage
5662         save: function( element, set ) {
5663                 for( var i=0; i < set.length; i++ ) {
5664                         if ( set[ i ] !== null ) {
5665                                 element.data( dataSpace + set[ i ], element[ 0 ].style[ set[ i ] ] );
5666                         }
5667                 }
5668         },
5669
5670         // Restores a set of previously saved properties from a data storage
5671         restore: function( element, set ) {
5672                 var val, i;
5673                 for( i=0; i < set.length; i++ ) {
5674                         if ( set[ i ] !== null ) {
5675                                 val = element.data( dataSpace + set[ i ] );
5676                                 // support: jQuery 1.6.2
5677                                 // http://bugs.jquery.com/ticket/9917
5678                                 // jQuery 1.6.2 incorrectly returns undefined for any falsy value.
5679                                 // We can't differentiate between "" and 0 here, so we just assume
5680                                 // empty string since it's likely to be a more common value...
5681                                 if ( val === undefined ) {
5682                                         val = "";
5683                                 }
5684                                 element.css( set[ i ], val );
5685                         }
5686                 }
5687         },
5688
5689         setMode: function( el, mode ) {
5690                 if (mode === "toggle") {
5691                         mode = el.is( ":hidden" ) ? "show" : "hide";
5692                 }
5693                 return mode;
5694         },
5695
5696         // Translates a [top,left] array into a baseline value
5697         // this should be a little more flexible in the future to handle a string & hash
5698         getBaseline: function( origin, original ) {
5699                 var y, x;
5700                 switch ( origin[ 0 ] ) {
5701                         case "top": y = 0; break;
5702                         case "middle": y = 0.5; break;
5703                         case "bottom": y = 1; break;
5704                         default: y = origin[ 0 ] / original.height;
5705                 }
5706                 switch ( origin[ 1 ] ) {
5707                         case "left": x = 0; break;
5708                         case "center": x = 0.5; break;
5709                         case "right": x = 1; break;
5710                         default: x = origin[ 1 ] / original.width;
5711                 }
5712                 return {
5713                         x: x,
5714                         y: y
5715                 };
5716         },
5717
5718         // Wraps the element around a wrapper that copies position properties
5719         createWrapper: function( element ) {
5720
5721                 // if the element is already wrapped, return it
5722                 if ( element.parent().is( ".ui-effects-wrapper" )) {
5723                         return element.parent();
5724                 }
5725
5726                 // wrap the element
5727                 var props = {
5728                                 width: element.outerWidth(true),
5729                                 height: element.outerHeight(true),
5730                                 "float": element.css( "float" )
5731                         },
5732                         wrapper = $( "<div></div>" )
5733                                 .addClass( "ui-effects-wrapper" )
5734                                 .css({
5735                                         fontSize: "100%",
5736                                         background: "transparent",
5737                                         border: "none",
5738                                         margin: 0,
5739                                         padding: 0
5740                                 }),
5741                         // Store the size in case width/height are defined in % - Fixes #5245
5742                         size = {
5743                                 width: element.width(),
5744                                 height: element.height()
5745                         },
5746                         active = document.activeElement;
5747
5748                 // support: Firefox
5749                 // Firefox incorrectly exposes anonymous content
5750                 // https://bugzilla.mozilla.org/show_bug.cgi?id=561664
5751                 try {
5752                         active.id;
5753                 } catch( e ) {
5754                         active = document.body;
5755                 }
5756
5757                 element.wrap( wrapper );
5758
5759                 // Fixes #7595 - Elements lose focus when wrapped.
5760                 if ( element[ 0 ] === active || $.contains( element[ 0 ], active ) ) {
5761                         $( active ).focus();
5762                 }
5763
5764                 wrapper = element.parent(); //Hotfix for jQuery 1.4 since some change in wrap() seems to actually lose the reference to the wrapped element
5765
5766                 // transfer positioning properties to the wrapper
5767                 if ( element.css( "position" ) === "static" ) {
5768                         wrapper.css({ position: "relative" });
5769                         element.css({ position: "relative" });
5770                 } else {
5771                         $.extend( props, {
5772                                 position: element.css( "position" ),
5773                                 zIndex: element.css( "z-index" )
5774                         });
5775                         $.each([ "top", "left", "bottom", "right" ], function(i, pos) {
5776                                 props[ pos ] = element.css( pos );
5777                                 if ( isNaN( parseInt( props[ pos ], 10 ) ) ) {
5778                                         props[ pos ] = "auto";
5779                                 }
5780                         });
5781                         element.css({
5782                                 position: "relative",
5783                                 top: 0,
5784                                 left: 0,
5785                                 right: "auto",
5786                                 bottom: "auto"
5787                         });
5788                 }
5789                 element.css(size);
5790
5791                 return wrapper.css( props ).show();
5792         },
5793
5794         removeWrapper: function( element ) {
5795                 var active = document.activeElement;
5796
5797                 if ( element.parent().is( ".ui-effects-wrapper" ) ) {
5798                         element.parent().replaceWith( element );
5799
5800                         // Fixes #7595 - Elements lose focus when wrapped.
5801                         if ( element[ 0 ] === active || $.contains( element[ 0 ], active ) ) {
5802                                 $( active ).focus();
5803                         }
5804                 }
5805
5806
5807                 return element;
5808         },
5809
5810         setTransition: function( element, list, factor, value ) {
5811                 value = value || {};
5812                 $.each( list, function( i, x ) {
5813                         var unit = element.cssUnit( x );
5814                         if ( unit[ 0 ] > 0 ) {
5815                                 value[ x ] = unit[ 0 ] * factor + unit[ 1 ];
5816                         }
5817                 });
5818                 return value;
5819         }
5820 });
5821
5822 // return an effect options object for the given parameters:
5823 function _normalizeArguments( effect, options, speed, callback ) {
5824
5825         // allow passing all options as the first parameter
5826         if ( $.isPlainObject( effect ) ) {
5827                 options = effect;
5828                 effect = effect.effect;
5829         }
5830
5831         // convert to an object
5832         effect = { effect: effect };
5833
5834         // catch (effect, null, ...)
5835         if ( options == null ) {
5836                 options = {};
5837         }
5838
5839         // catch (effect, callback)
5840         if ( $.isFunction( options ) ) {
5841                 callback = options;
5842                 speed = null;
5843                 options = {};
5844         }
5845
5846         // catch (effect, speed, ?)
5847         if ( typeof options === "number" || $.fx.speeds[ options ] ) {
5848                 callback = speed;
5849                 speed = options;
5850                 options = {};
5851         }
5852
5853         // catch (effect, options, callback)
5854         if ( $.isFunction( speed ) ) {
5855                 callback = speed;
5856                 speed = null;
5857         }
5858
5859         // add options to effect
5860         if ( options ) {
5861                 $.extend( effect, options );
5862         }
5863
5864         speed = speed || options.duration;
5865         effect.duration = $.fx.off ? 0 :
5866                 typeof speed === "number" ? speed :
5867                 speed in $.fx.speeds ? $.fx.speeds[ speed ] :
5868                 $.fx.speeds._default;
5869
5870         effect.complete = callback || options.complete;
5871
5872         return effect;
5873 }
5874
5875 function standardAnimationOption( option ) {
5876         // Valid standard speeds (nothing, number, named speed)
5877         if ( !option || typeof option === "number" || $.fx.speeds[ option ] ) {
5878                 return true;
5879         }
5880
5881         // Invalid strings - treat as "normal" speed
5882         if ( typeof option === "string" && !$.effects.effect[ option ] ) {
5883                 return true;
5884         }
5885
5886         // Complete callback
5887         if ( $.isFunction( option ) ) {
5888                 return true;
5889         }
5890
5891         // Options hash (but not naming an effect)
5892         if ( typeof option === "object" && !option.effect ) {
5893                 return true;
5894         }
5895
5896         // Didn't match any standard API
5897         return false;
5898 }
5899
5900 $.fn.extend({
5901         effect: function( /* effect, options, speed, callback */ ) {
5902                 var args = _normalizeArguments.apply( this, arguments ),
5903                         mode = args.mode,
5904                         queue = args.queue,
5905                         effectMethod = $.effects.effect[ args.effect ];
5906
5907                 if ( $.fx.off || !effectMethod ) {
5908                         // delegate to the original method (e.g., .show()) if possible
5909                         if ( mode ) {
5910                                 return this[ mode ]( args.duration, args.complete );
5911                         } else {
5912                                 return this.each( function() {
5913                                         if ( args.complete ) {
5914                                                 args.complete.call( this );
5915                                         }
5916                                 });
5917                         }
5918                 }
5919
5920                 function run( next ) {
5921                         var elem = $( this ),
5922                                 complete = args.complete,
5923                                 mode = args.mode;
5924
5925                         function done() {
5926                                 if ( $.isFunction( complete ) ) {
5927                                         complete.call( elem[0] );
5928                                 }
5929                                 if ( $.isFunction( next ) ) {
5930                                         next();
5931                                 }
5932                         }
5933
5934                         // If the element already has the correct final state, delegate to
5935                         // the core methods so the internal tracking of "olddisplay" works.
5936                         if ( elem.is( ":hidden" ) ? mode === "hide" : mode === "show" ) {
5937                                 elem[ mode ]();
5938                                 done();
5939                         } else {
5940                                 effectMethod.call( elem[0], args, done );
5941                         }
5942                 }
5943
5944                 return queue === false ? this.each( run ) : this.queue( queue || "fx", run );
5945         },
5946
5947         show: (function( orig ) {
5948                 return function( option ) {
5949                         if ( standardAnimationOption( option ) ) {
5950                                 return orig.apply( this, arguments );
5951                         } else {
5952                                 var args = _normalizeArguments.apply( this, arguments );
5953                                 args.mode = "show";
5954                                 return this.effect.call( this, args );
5955                         }
5956                 };
5957         })( $.fn.show ),
5958
5959         hide: (function( orig ) {
5960                 return function( option ) {
5961                         if ( standardAnimationOption( option ) ) {
5962                                 return orig.apply( this, arguments );
5963                         } else {
5964                                 var args = _normalizeArguments.apply( this, arguments );
5965                                 args.mode = "hide";
5966                                 return this.effect.call( this, args );
5967                         }
5968                 };
5969         })( $.fn.hide ),
5970
5971         toggle: (function( orig ) {
5972                 return function( option ) {
5973                         if ( standardAnimationOption( option ) || typeof option === "boolean" ) {
5974                                 return orig.apply( this, arguments );
5975                         } else {
5976                                 var args = _normalizeArguments.apply( this, arguments );
5977                                 args.mode = "toggle";
5978                                 return this.effect.call( this, args );
5979                         }
5980                 };
5981         })( $.fn.toggle ),
5982
5983         // helper functions
5984         cssUnit: function(key) {
5985                 var style = this.css( key ),
5986                         val = [];
5987
5988                 $.each( [ "em", "px", "%", "pt" ], function( i, unit ) {
5989                         if ( style.indexOf( unit ) > 0 ) {
5990                                 val = [ parseFloat( style ), unit ];
5991                         }
5992                 });
5993                 return val;
5994         }
5995 });
5996
5997 })();
5998
5999 /******************************************************************************/
6000 /*********************************** EASING ***********************************/
6001 /******************************************************************************/
6002
6003 (function() {
6004
6005 // based on easing equations from Robert Penner (http://www.robertpenner.com/easing)
6006
6007 var baseEasings = {};
6008
6009 $.each( [ "Quad", "Cubic", "Quart", "Quint", "Expo" ], function( i, name ) {
6010         baseEasings[ name ] = function( p ) {
6011                 return Math.pow( p, i + 2 );
6012         };
6013 });
6014
6015 $.extend( baseEasings, {
6016         Sine: function ( p ) {
6017                 return 1 - Math.cos( p * Math.PI / 2 );
6018         },
6019         Circ: function ( p ) {
6020                 return 1 - Math.sqrt( 1 - p * p );
6021         },
6022         Elastic: function( p ) {
6023                 return p === 0 || p === 1 ? p :
6024                         -Math.pow( 2, 8 * (p - 1) ) * Math.sin( ( (p - 1) * 80 - 7.5 ) * Math.PI / 15 );
6025         },
6026         Back: function( p ) {
6027                 return p * p * ( 3 * p - 2 );
6028         },
6029         Bounce: function ( p ) {
6030                 var pow2,
6031                         bounce = 4;
6032
6033                 while ( p < ( ( pow2 = Math.pow( 2, --bounce ) ) - 1 ) / 11 ) {}
6034                 return 1 / Math.pow( 4, 3 - bounce ) - 7.5625 * Math.pow( ( pow2 * 3 - 2 ) / 22 - p, 2 );
6035         }
6036 });
6037
6038 $.each( baseEasings, function( name, easeIn ) {
6039         $.easing[ "easeIn" + name ] = easeIn;
6040         $.easing[ "easeOut" + name ] = function( p ) {
6041                 return 1 - easeIn( 1 - p );
6042         };
6043         $.easing[ "easeInOut" + name ] = function( p ) {
6044                 return p < 0.5 ?
6045                         easeIn( p * 2 ) / 2 :
6046                         1 - easeIn( p * -2 + 2 ) / 2;
6047         };
6048 });
6049
6050 })();
6051
6052 })(jQuery);
6053
6054 (function( $, undefined ) {
6055
6056 var uid = 0,
6057         hideProps = {},
6058         showProps = {};
6059
6060 hideProps.height = hideProps.paddingTop = hideProps.paddingBottom =
6061         hideProps.borderTopWidth = hideProps.borderBottomWidth = "hide";
6062 showProps.height = showProps.paddingTop = showProps.paddingBottom =
6063         showProps.borderTopWidth = showProps.borderBottomWidth = "show";
6064
6065 $.widget( "ui.accordion", {
6066         version: "1.10.3",
6067         options: {
6068                 active: 0,
6069                 animate: {},
6070                 collapsible: false,
6071                 event: "click",
6072                 header: "> li > :first-child,> :not(li):even",
6073                 heightStyle: "auto",
6074                 icons: {
6075                         activeHeader: "ui-icon-triangle-1-s",
6076                         header: "ui-icon-triangle-1-e"
6077                 },
6078
6079                 // callbacks
6080                 activate: null,
6081                 beforeActivate: null
6082         },
6083
6084         _create: function() {
6085                 var options = this.options;
6086                 this.prevShow = this.prevHide = $();
6087                 this.element.addClass( "ui-accordion ui-widget ui-helper-reset" )
6088                         // ARIA
6089                         .attr( "role", "tablist" );
6090
6091                 // don't allow collapsible: false and active: false / null
6092                 if ( !options.collapsible && (options.active === false || options.active == null) ) {
6093                         options.active = 0;
6094                 }
6095
6096                 this._processPanels();
6097                 // handle negative values
6098                 if ( options.active < 0 ) {
6099                         options.active += this.headers.length;
6100                 }
6101                 this._refresh();
6102         },
6103
6104         _getCreateEventData: function() {
6105                 return {
6106                         header: this.active,
6107                         panel: !this.active.length ? $() : this.active.next(),
6108                         content: !this.active.length ? $() : this.active.next()
6109                 };
6110         },
6111
6112         _createIcons: function() {
6113                 var icons = this.options.icons;
6114                 if ( icons ) {
6115                         $( "<span>" )
6116                                 .addClass( "ui-accordion-header-icon ui-icon " + icons.header )
6117                                 .prependTo( this.headers );
6118                         this.active.children( ".ui-accordion-header-icon" )
6119                                 .removeClass( icons.header )
6120                                 .addClass( icons.activeHeader );
6121                         this.headers.addClass( "ui-accordion-icons" );
6122                 }
6123         },
6124
6125         _destroyIcons: function() {
6126                 this.headers
6127                         .removeClass( "ui-accordion-icons" )
6128                         .children( ".ui-accordion-header-icon" )
6129                                 .remove();
6130         },
6131
6132         _destroy: function() {
6133                 var contents;
6134
6135                 // clean up main element
6136                 this.element
6137                         .removeClass( "ui-accordion ui-widget ui-helper-reset" )
6138                         .removeAttr( "role" );
6139
6140                 // clean up headers
6141                 this.headers
6142                         .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" )
6143                         .removeAttr( "role" )
6144                         .removeAttr( "aria-selected" )
6145                         .removeAttr( "aria-controls" )
6146                         .removeAttr( "tabIndex" )
6147                         .each(function() {
6148                                 if ( /^ui-accordion/.test( this.id ) ) {
6149                                         this.removeAttribute( "id" );
6150                                 }
6151                         });
6152                 this._destroyIcons();
6153
6154                 // clean up content panels
6155                 contents = this.headers.next()
6156                         .css( "display", "" )
6157                         .removeAttr( "role" )
6158                         .removeAttr( "aria-expanded" )
6159                         .removeAttr( "aria-hidden" )
6160                         .removeAttr( "aria-labelledby" )
6161                         .removeClass( "ui-helper-reset ui-widget-content ui-corner-bottom ui-accordion-content ui-accordion-content-active ui-state-disabled" )
6162                         .each(function() {
6163                                 if ( /^ui-accordion/.test( this.id ) ) {
6164                                         this.removeAttribute( "id" );
6165                                 }
6166                         });
6167                 if ( this.options.heightStyle !== "content" ) {
6168                         contents.css( "height", "" );
6169                 }
6170         },
6171
6172         _setOption: function( key, value ) {
6173                 if ( key === "active" ) {
6174                         // _activate() will handle invalid values and update this.options
6175                         this._activate( value );
6176                         return;
6177                 }
6178
6179                 if ( key === "event" ) {
6180                         if ( this.options.event ) {
6181                                 this._off( this.headers, this.options.event );
6182                         }
6183                         this._setupEvents( value );
6184                 }
6185
6186                 this._super( key, value );
6187
6188                 // setting collapsible: false while collapsed; open first panel
6189                 if ( key === "collapsible" && !value && this.options.active === false ) {
6190                         this._activate( 0 );
6191                 }
6192
6193                 if ( key === "icons" ) {
6194                         this._destroyIcons();
6195                         if ( value ) {
6196                                 this._createIcons();
6197                         }
6198                 }
6199
6200                 // #5332 - opacity doesn't cascade to positioned elements in IE
6201                 // so we need to add the disabled class to the headers and panels
6202                 if ( key === "disabled" ) {
6203                         this.headers.add( this.headers.next() )
6204                                 .toggleClass( "ui-state-disabled", !!value );
6205                 }
6206         },
6207
6208         _keydown: function( event ) {
6209                 /*jshint maxcomplexity:15*/
6210                 if ( event.altKey || event.ctrlKey ) {
6211                         return;
6212                 }
6213
6214                 var keyCode = $.ui.keyCode,
6215                         length = this.headers.length,
6216                         currentIndex = this.headers.index( event.target ),
6217                         toFocus = false;
6218
6219                 switch ( event.keyCode ) {
6220                         case keyCode.RIGHT:
6221                         case keyCode.DOWN:
6222                                 toFocus = this.headers[ ( currentIndex + 1 ) % length ];
6223                                 break;
6224                         case keyCode.LEFT:
6225                         case keyCode.UP:
6226                                 toFocus = this.headers[ ( currentIndex - 1 + length ) % length ];
6227                                 break;
6228                         case keyCode.SPACE:
6229                         case keyCode.ENTER:
6230                                 this._eventHandler( event );
6231                                 break;
6232                         case keyCode.HOME:
6233                                 toFocus = this.headers[ 0 ];
6234                                 break;
6235                         case keyCode.END:
6236                                 toFocus = this.headers[ length - 1 ];
6237                                 break;
6238                 }
6239
6240                 if ( toFocus ) {
6241                         $( event.target ).attr( "tabIndex", -1 );
6242                         $( toFocus ).attr( "tabIndex", 0 );
6243                         toFocus.focus();
6244                         event.preventDefault();
6245                 }
6246         },
6247
6248         _panelKeyDown : function( event ) {
6249                 if ( event.keyCode === $.ui.keyCode.UP && event.ctrlKey ) {
6250                         $( event.currentTarget ).prev().focus();
6251                 }
6252         },
6253
6254         refresh: function() {
6255                 var options = this.options;
6256                 this._processPanels();
6257
6258                 // was collapsed or no panel
6259                 if ( ( options.active === false && options.collapsible === true ) || !this.headers.length ) {
6260                         options.active = false;
6261                         this.active = $();
6262                 // active false only when collapsible is true
6263                 } else if ( options.active === false ) {
6264                         this._activate( 0 );
6265                 // was active, but active panel is gone
6266                 } else if ( this.active.length && !$.contains( this.element[ 0 ], this.active[ 0 ] ) ) {
6267                         // all remaining panel are disabled
6268                         if ( this.headers.length === this.headers.find(".ui-state-disabled").length ) {
6269                                 options.active = false;
6270                                 this.active = $();
6271                         // activate previous panel
6272                         } else {
6273                                 this._activate( Math.max( 0, options.active - 1 ) );
6274                         }
6275                 // was active, active panel still exists
6276                 } else {
6277                         // make sure active index is correct
6278                         options.active = this.headers.index( this.active );
6279                 }
6280
6281                 this._destroyIcons();
6282
6283                 this._refresh();
6284         },
6285
6286         _processPanels: function() {
6287                 this.headers = this.element.find( this.options.header )
6288                         .addClass( "ui-accordion-header ui-helper-reset ui-state-default ui-corner-all" );
6289
6290                 this.headers.next()
6291                         .addClass( "ui-accordion-content ui-helper-reset ui-widget-content ui-corner-bottom" )
6292                         .filter(":not(.ui-accordion-content-active)")
6293                         .hide();
6294         },
6295
6296         _refresh: function() {
6297                 var maxHeight,
6298                         options = this.options,
6299                         heightStyle = options.heightStyle,
6300                         parent = this.element.parent(),
6301                         accordionId = this.accordionId = "ui-accordion-" +
6302                                 (this.element.attr( "id" ) || ++uid);
6303
6304                 this.active = this._findActive( options.active )
6305                         .addClass( "ui-accordion-header-active ui-state-active ui-corner-top" )
6306                         .removeClass( "ui-corner-all" );
6307                 this.active.next()
6308                         .addClass( "ui-accordion-content-active" )
6309                         .show();
6310
6311                 this.headers
6312                         .attr( "role", "tab" )
6313                         .each(function( i ) {
6314                                 var header = $( this ),
6315                                         headerId = header.attr( "id" ),
6316                                         panel = header.next(),
6317                                         panelId = panel.attr( "id" );
6318                                 if ( !headerId ) {
6319                                         headerId = accordionId + "-header-" + i;
6320                                         header.attr( "id", headerId );
6321                                 }
6322                                 if ( !panelId ) {
6323                                         panelId = accordionId + "-panel-" + i;
6324                                         panel.attr( "id", panelId );
6325                                 }
6326                                 header.attr( "aria-controls", panelId );
6327                                 panel.attr( "aria-labelledby", headerId );
6328                         })
6329                         .next()
6330                                 .attr( "role", "tabpanel" );
6331
6332                 this.headers
6333                         .not( this.active )
6334                         .attr({
6335                                 "aria-selected": "false",
6336                                 tabIndex: -1
6337                         })
6338                         .next()
6339                                 .attr({
6340                                         "aria-expanded": "false",
6341                                         "aria-hidden": "true"
6342                                 })
6343                                 .hide();
6344
6345                 // make sure at least one header is in the tab order
6346                 if ( !this.active.length ) {
6347                         this.headers.eq( 0 ).attr( "tabIndex", 0 );
6348                 } else {
6349                         this.active.attr({
6350                                 "aria-selected": "true",
6351                                 tabIndex: 0
6352                         })
6353                         .next()
6354                                 .attr({
6355                                         "aria-expanded": "true",
6356                                         "aria-hidden": "false"
6357                                 });
6358                 }
6359
6360                 this._createIcons();
6361
6362                 this._setupEvents( options.event );
6363
6364                 if ( heightStyle === "fill" ) {
6365                         maxHeight = parent.height();
6366                         this.element.siblings( ":visible" ).each(function() {
6367                                 var elem = $( this ),
6368                                         position = elem.css( "position" );
6369
6370                                 if ( position === "absolute" || position === "fixed" ) {
6371                                         return;
6372                                 }
6373                                 maxHeight -= elem.outerHeight( true );
6374                         });
6375
6376                         this.headers.each(function() {
6377                                 maxHeight -= $( this ).outerHeight( true );
6378                         });
6379
6380                         this.headers.next()
6381                                 .each(function() {
6382                                         $( this ).height( Math.max( 0, maxHeight -
6383                                                 $( this ).innerHeight() + $( this ).height() ) );
6384                                 })
6385                                 .css( "overflow", "auto" );
6386                 } else if ( heightStyle === "auto" ) {
6387                         maxHeight = 0;
6388                         this.headers.next()
6389                                 .each(function() {
6390                                         maxHeight = Math.max( maxHeight, $( this ).css( "height", "" ).height() );
6391                                 })
6392                                 .height( maxHeight );
6393                 }
6394         },
6395
6396         _activate: function( index ) {
6397                 var active = this._findActive( index )[ 0 ];
6398
6399                 // trying to activate the already active panel
6400                 if ( active === this.active[ 0 ] ) {
6401                         return;
6402                 }
6403
6404                 // trying to collapse, simulate a click on the currently active header
6405                 active = active || this.active[ 0 ];
6406
6407                 this._eventHandler({
6408                         target: active,
6409                         currentTarget: active,
6410                         preventDefault: $.noop
6411                 });
6412         },
6413
6414         _findActive: function( selector ) {
6415                 return typeof selector === "number" ? this.headers.eq( selector ) : $();
6416         },
6417
6418         _setupEvents: function( event ) {
6419                 var events = {
6420                         keydown: "_keydown"
6421                 };
6422                 if ( event ) {
6423                         $.each( event.split(" "), function( index, eventName ) {
6424                                 events[ eventName ] = "_eventHandler";
6425                         });
6426                 }
6427
6428                 this._off( this.headers.add( this.headers.next() ) );
6429                 this._on( this.headers, events );
6430                 this._on( this.headers.next(), { keydown: "_panelKeyDown" });
6431                 this._hoverable( this.headers );
6432                 this._focusable( this.headers );
6433         },
6434
6435         _eventHandler: function( event ) {
6436                 var options = this.options,
6437                         active = this.active,
6438                         clicked = $( event.currentTarget ),
6439                         clickedIsActive = clicked[ 0 ] === active[ 0 ],
6440                         collapsing = clickedIsActive && options.collapsible,
6441                         toShow = collapsing ? $() : clicked.next(),
6442                         toHide = active.next(),
6443                         eventData = {
6444                                 oldHeader: active,
6445                                 oldPanel: toHide,
6446                                 newHeader: collapsing ? $() : clicked,
6447                                 newPanel: toShow
6448                         };
6449
6450                 event.preventDefault();
6451
6452                 if (
6453                                 // click on active header, but not collapsible
6454                                 ( clickedIsActive && !options.collapsible ) ||
6455                                 // allow canceling activation
6456                                 ( this._trigger( "beforeActivate", event, eventData ) === false ) ) {
6457                         return;
6458                 }
6459
6460                 options.active = collapsing ? false : this.headers.index( clicked );
6461
6462                 // when the call to ._toggle() comes after the class changes
6463                 // it causes a very odd bug in IE 8 (see #6720)
6464                 this.active = clickedIsActive ? $() : clicked;
6465                 this._toggle( eventData );
6466
6467                 // switch classes
6468                 // corner classes on the previously active header stay after the animation
6469                 active.removeClass( "ui-accordion-header-active ui-state-active" );
6470                 if ( options.icons ) {
6471                         active.children( ".ui-accordion-header-icon" )
6472                                 .removeClass( options.icons.activeHeader )
6473                                 .addClass( options.icons.header );
6474                 }
6475
6476                 if ( !clickedIsActive ) {
6477                         clicked
6478                                 .removeClass( "ui-corner-all" )
6479                                 .addClass( "ui-accordion-header-active ui-state-active ui-corner-top" );
6480                         if ( options.icons ) {
6481                                 clicked.children( ".ui-accordion-header-icon" )
6482                                         .removeClass( options.icons.header )
6483                                         .addClass( options.icons.activeHeader );
6484                         }
6485
6486                         clicked
6487                                 .next()
6488                                 .addClass( "ui-accordion-content-active" );
6489                 }
6490         },
6491
6492         _toggle: function( data ) {
6493                 var toShow = data.newPanel,
6494                         toHide = this.prevShow.length ? this.prevShow : data.oldPanel;
6495
6496                 // handle activating a panel during the animation for another activation
6497                 this.prevShow.add( this.prevHide ).stop( true, true );
6498                 this.prevShow = toShow;
6499                 this.prevHide = toHide;
6500
6501                 if ( this.options.animate ) {
6502                         this._animate( toShow, toHide, data );
6503                 } else {
6504                         toHide.hide();
6505                         toShow.show();
6506                         this._toggleComplete( data );
6507                 }
6508
6509                 toHide.attr({
6510                         "aria-expanded": "false",
6511                         "aria-hidden": "true"
6512                 });
6513                 toHide.prev().attr( "aria-selected", "false" );
6514                 // if we're switching panels, remove the old header from the tab order
6515                 // if we're opening from collapsed state, remove the previous header from the tab order
6516                 // if we're collapsing, then keep the collapsing header in the tab order
6517                 if ( toShow.length && toHide.length ) {
6518                         toHide.prev().attr( "tabIndex", -1 );
6519                 } else if ( toShow.length ) {
6520                         this.headers.filter(function() {
6521                                 return $( this ).attr( "tabIndex" ) === 0;
6522                         })
6523                         .attr( "tabIndex", -1 );
6524                 }
6525
6526                 toShow
6527                         .attr({
6528                                 "aria-expanded": "true",
6529                                 "aria-hidden": "false"
6530                         })
6531                         .prev()
6532                                 .attr({
6533                                         "aria-selected": "true",
6534                                         tabIndex: 0
6535                                 });
6536         },
6537
6538         _animate: function( toShow, toHide, data ) {
6539                 var total, easing, duration,
6540                         that = this,
6541                         adjust = 0,
6542                         down = toShow.length &&
6543                                 ( !toHide.length || ( toShow.index() < toHide.index() ) ),
6544                         animate = this.options.animate || {},
6545                         options = down && animate.down || animate,
6546                         complete = function() {
6547                                 that._toggleComplete( data );
6548                         };
6549
6550                 if ( typeof options === "number" ) {
6551                         duration = options;
6552                 }
6553                 if ( typeof options === "string" ) {
6554                         easing = options;
6555                 }
6556                 // fall back from options to animation in case of partial down settings
6557                 easing = easing || options.easing || animate.easing;
6558                 duration = duration || options.duration || animate.duration;
6559
6560                 if ( !toHide.length ) {
6561                         return toShow.animate( showProps, duration, easing, complete );
6562                 }
6563                 if ( !toShow.length ) {
6564                         return toHide.animate( hideProps, duration, easing, complete );
6565                 }
6566
6567                 total = toShow.show().outerHeight();
6568                 toHide.animate( hideProps, {
6569                         duration: duration,
6570                         easing: easing,
6571                         step: function( now, fx ) {
6572                                 fx.now = Math.round( now );
6573                         }
6574                 });
6575                 toShow
6576                         .hide()
6577                         .animate( showProps, {
6578                                 duration: duration,
6579                                 easing: easing,
6580                                 complete: complete,
6581                                 step: function( now, fx ) {
6582                                         fx.now = Math.round( now );
6583                                         if ( fx.prop !== "height" ) {
6584                                                 adjust += fx.now;
6585                                         } else if ( that.options.heightStyle !== "content" ) {
6586                                                 fx.now = Math.round( total - toHide.outerHeight() - adjust );
6587                                                 adjust = 0;
6588                                         }
6589                                 }
6590                         });
6591         },
6592
6593         _toggleComplete: function( data ) {
6594                 var toHide = data.oldPanel;
6595
6596                 toHide
6597                         .removeClass( "ui-accordion-content-active" )
6598                         .prev()
6599                                 .removeClass( "ui-corner-top" )
6600                                 .addClass( "ui-corner-all" );
6601
6602                 // Work around for rendering bug in IE (#5421)
6603                 if ( toHide.length ) {
6604                         toHide.parent()[0].className = toHide.parent()[0].className;
6605                 }
6606
6607                 this._trigger( "activate", null, data );
6608         }
6609 });
6610
6611 })( jQuery );
6612
6613 (function( $, undefined ) {
6614
6615 // used to prevent race conditions with remote data sources
6616 var requestIndex = 0;
6617
6618 $.widget( "ui.autocomplete", {
6619         version: "1.10.3",
6620         defaultElement: "<input>",
6621         options: {
6622                 appendTo: null,
6623                 autoFocus: false,
6624                 delay: 300,
6625                 minLength: 1,
6626                 position: {
6627                         my: "left top",
6628                         at: "left bottom",
6629                         collision: "none"
6630                 },
6631                 source: null,
6632
6633                 // callbacks
6634                 change: null,
6635                 close: null,
6636                 focus: null,
6637                 open: null,
6638                 response: null,
6639                 search: null,
6640                 select: null
6641         },
6642
6643         pending: 0,
6644
6645         _create: function() {
6646                 // Some browsers only repeat keydown events, not keypress events,
6647                 // so we use the suppressKeyPress flag to determine if we've already
6648                 // handled the keydown event. #7269
6649                 // Unfortunately the code for & in keypress is the same as the up arrow,
6650                 // so we use the suppressKeyPressRepeat flag to avoid handling keypress
6651                 // events when we know the keydown event was used to modify the
6652                 // search term. #7799
6653                 var suppressKeyPress, suppressKeyPressRepeat, suppressInput,
6654                         nodeName = this.element[0].nodeName.toLowerCase(),
6655                         isTextarea = nodeName === "textarea",
6656                         isInput = nodeName === "input";
6657
6658                 this.isMultiLine =
6659                         // Textareas are always multi-line
6660                         isTextarea ? true :
6661                         // Inputs are always single-line, even if inside a contentEditable element
6662                         // IE also treats inputs as contentEditable
6663                         isInput ? false :
6664                         // All other element types are determined by whether or not they're contentEditable
6665                         this.element.prop( "isContentEditable" );
6666
6667                 this.valueMethod = this.element[ isTextarea || isInput ? "val" : "text" ];
6668                 this.isNewMenu = true;
6669
6670                 this.element
6671                         .addClass( "ui-autocomplete-input" )
6672                         .attr( "autocomplete", "off" );
6673
6674                 this._on( this.element, {
6675                         keydown: function( event ) {
6676                                 /*jshint maxcomplexity:15*/
6677                                 if ( this.element.prop( "readOnly" ) ) {
6678                                         suppressKeyPress = true;
6679                                         suppressInput = true;
6680                                         suppressKeyPressRepeat = true;
6681                                         return;
6682                                 }
6683
6684                                 suppressKeyPress = false;
6685                                 suppressInput = false;
6686                                 suppressKeyPressRepeat = false;
6687                                 var keyCode = $.ui.keyCode;
6688                                 switch( event.keyCode ) {
6689                                 case keyCode.PAGE_UP:
6690                                         suppressKeyPress = true;
6691                                         this._move( "previousPage", event );
6692                                         break;
6693                                 case keyCode.PAGE_DOWN:
6694                                         suppressKeyPress = true;
6695                                         this._move( "nextPage", event );
6696                                         break;
6697                                 case keyCode.UP:
6698                                         suppressKeyPress = true;
6699                                         this._keyEvent( "previous", event );
6700                                         break;
6701                                 case keyCode.DOWN:
6702                                         suppressKeyPress = true;
6703                                         this._keyEvent( "next", event );
6704                                         break;
6705                                 case keyCode.ENTER:
6706                                 case keyCode.NUMPAD_ENTER:
6707                                         // when menu is open and has focus
6708                                         if ( this.menu.active ) {
6709                                                 // #6055 - Opera still allows the keypress to occur
6710                                                 // which causes forms to submit
6711                                                 suppressKeyPress = true;
6712                                                 event.preventDefault();
6713                                                 this.menu.select( event );
6714                                         }
6715                                         break;
6716                                 case keyCode.TAB:
6717                                         if ( this.menu.active ) {
6718                                                 this.menu.select( event );
6719                                         }
6720                                         break;
6721                                 case keyCode.ESCAPE:
6722                                         if ( this.menu.element.is( ":visible" ) ) {
6723                                                 this._value( this.term );
6724                                                 this.close( event );
6725                                                 // Different browsers have different default behavior for escape
6726                                                 // Single press can mean undo or clear
6727                                                 // Double press in IE means clear the whole form
6728                                                 event.preventDefault();
6729                                         }
6730                                         break;
6731                                 default:
6732                                         suppressKeyPressRepeat = true;
6733                                         // search timeout should be triggered before the input value is changed
6734                                         this._searchTimeout( event );
6735                                         break;
6736                                 }
6737                         },
6738                         keypress: function( event ) {
6739                                 if ( suppressKeyPress ) {
6740                                         suppressKeyPress = false;
6741                                         if ( !this.isMultiLine || this.menu.element.is( ":visible" ) ) {
6742                                                 event.preventDefault();
6743                                         }
6744                                         return;
6745                                 }
6746                                 if ( suppressKeyPressRepeat ) {
6747                                         return;
6748                                 }
6749
6750                                 // replicate some key handlers to allow them to repeat in Firefox and Opera
6751                                 var keyCode = $.ui.keyCode;
6752                                 switch( event.keyCode ) {
6753                                 case keyCode.PAGE_UP:
6754                                         this._move( "previousPage", event );
6755                                         break;
6756                                 case keyCode.PAGE_DOWN:
6757                                         this._move( "nextPage", event );
6758                                         break;
6759                                 case keyCode.UP:
6760                                         this._keyEvent( "previous", event );
6761                                         break;
6762                                 case keyCode.DOWN:
6763                                         this._keyEvent( "next", event );
6764                                         break;
6765                                 }
6766                         },
6767                         input: function( event ) {
6768                                 if ( suppressInput ) {
6769                                         suppressInput = false;
6770                                         event.preventDefault();
6771                                         return;
6772                                 }
6773                                 this._searchTimeout( event );
6774                         },
6775                         focus: function() {
6776                                 this.selectedItem = null;
6777                                 this.previous = this._value();
6778                         },
6779                         blur: function( event ) {
6780                                 if ( this.cancelBlur ) {
6781                                         delete this.cancelBlur;
6782                                         return;
6783                                 }
6784
6785                                 clearTimeout( this.searching );
6786                                 this.close( event );
6787                                 this._change( event );
6788                         }
6789                 });
6790
6791                 this._initSource();
6792                 this.menu = $( "<ul>" )
6793                         .addClass( "ui-autocomplete ui-front" )
6794                         .appendTo( this._appendTo() )
6795                         .menu({
6796                                 // disable ARIA support, the live region takes care of that
6797                                 role: null
6798                         })
6799                         .hide()
6800                         .data( "ui-menu" );
6801
6802                 this._on( this.menu.element, {
6803                         mousedown: function( event ) {
6804                                 // prevent moving focus out of the text field
6805                                 event.preventDefault();
6806
6807                                 // IE doesn't prevent moving focus even with event.preventDefault()
6808                                 // so we set a flag to know when we should ignore the blur event
6809                                 this.cancelBlur = true;
6810                                 this._delay(function() {
6811                                         delete this.cancelBlur;
6812                                 });
6813
6814                                 // clicking on the scrollbar causes focus to shift to the body
6815                                 // but we can't detect a mouseup or a click immediately afterward
6816                                 // so we have to track the next mousedown and close the menu if
6817                                 // the user clicks somewhere outside of the autocomplete
6818                                 var menuElement = this.menu.element[ 0 ];
6819                                 if ( !$( event.target ).closest( ".ui-menu-item" ).length ) {
6820                                         this._delay(function() {
6821                                                 var that = this;
6822                                                 this.document.one( "mousedown", function( event ) {
6823                                                         if ( event.target !== that.element[ 0 ] &&
6824                                                                         event.target !== menuElement &&
6825                                                                         !$.contains( menuElement, event.target ) ) {
6826                                                                 that.close();
6827                                                         }
6828                                                 });
6829                                         });
6830                                 }
6831                         },
6832                         menufocus: function( event, ui ) {
6833                                 // support: Firefox
6834                                 // Prevent accidental activation of menu items in Firefox (#7024 #9118)
6835                                 if ( this.isNewMenu ) {
6836                                         this.isNewMenu = false;
6837                                         if ( event.originalEvent && /^mouse/.test( event.originalEvent.type ) ) {
6838                                                 this.menu.blur();
6839
6840                                                 this.document.one( "mousemove", function() {
6841                                                         $( event.target ).trigger( event.originalEvent );
6842                                                 });
6843
6844                                                 return;
6845                                         }
6846                                 }
6847
6848                                 var item = ui.item.data( "ui-autocomplete-item" );
6849                                 if ( false !== this._trigger( "focus", event, { item: item } ) ) {
6850                                         // use value to match what will end up in the input, if it was a key event
6851                                         if ( event.originalEvent && /^key/.test( event.originalEvent.type ) ) {
6852                                                 this._value( item.value );
6853                                         }
6854                                 } else {
6855                                         // Normally the input is populated with the item's value as the
6856                                         // menu is navigated, causing screen readers to notice a change and
6857                                         // announce the item. Since the focus event was canceled, this doesn't
6858                                         // happen, so we update the live region so that screen readers can
6859                                         // still notice the change and announce it.
6860                                         this.liveRegion.text( item.value );
6861                                 }
6862                         },
6863                         menuselect: function( event, ui ) {
6864                                 var item = ui.item.data( "ui-autocomplete-item" ),
6865                                         previous = this.previous;
6866
6867                                 // only trigger when focus was lost (click on menu)
6868                                 if ( this.element[0] !== this.document[0].activeElement ) {
6869                                         this.element.focus();
6870                                         this.previous = previous;
6871                                         // #6109 - IE triggers two focus events and the second
6872                                         // is asynchronous, so we need to reset the previous
6873                                         // term synchronously and asynchronously :-(
6874                                         this._delay(function() {
6875                                                 this.previous = previous;
6876                                                 this.selectedItem = item;
6877                                         });
6878                                 }
6879
6880                                 if ( false !== this._trigger( "select", event, { item: item } ) ) {
6881                                         this._value( item.value );
6882                                 }
6883                                 // reset the term after the select event
6884                                 // this allows custom select handling to work properly
6885                                 this.term = this._value();
6886
6887                                 this.close( event );
6888                                 this.selectedItem = item;
6889                         }
6890                 });
6891
6892                 this.liveRegion = $( "<span>", {
6893                                 role: "status",
6894                                 "aria-live": "polite"
6895                         })
6896                         .addClass( "ui-helper-hidden-accessible" )
6897                         .insertBefore( this.element );
6898
6899                 // turning off autocomplete prevents the browser from remembering the
6900                 // value when navigating through history, so we re-enable autocomplete
6901                 // if the page is unloaded before the widget is destroyed. #7790
6902                 this._on( this.window, {
6903                         beforeunload: function() {
6904                                 this.element.removeAttr( "autocomplete" );
6905                         }
6906                 });
6907         },
6908
6909         _destroy: function() {
6910                 clearTimeout( this.searching );
6911                 this.element
6912                         .removeClass( "ui-autocomplete-input" )
6913                         .removeAttr( "autocomplete" );
6914                 this.menu.element.remove();
6915                 this.liveRegion.remove();
6916         },
6917
6918         _setOption: function( key, value ) {
6919                 this._super( key, value );
6920                 if ( key === "source" ) {
6921                         this._initSource();
6922                 }
6923                 if ( key === "appendTo" ) {
6924                         this.menu.element.appendTo( this._appendTo() );
6925                 }
6926                 if ( key === "disabled" && value && this.xhr ) {
6927                         this.xhr.abort();
6928                 }
6929         },
6930
6931         _appendTo: function() {
6932                 var element = this.options.appendTo;
6933
6934                 if ( element ) {
6935                         element = element.jquery || element.nodeType ?
6936                                 $( element ) :
6937                                 this.document.find( element ).eq( 0 );
6938                 }
6939
6940                 if ( !element ) {
6941                         element = this.element.closest( ".ui-front" );
6942                 }
6943
6944                 if ( !element.length ) {
6945                         element = this.document[0].body;
6946                 }
6947
6948                 return element;
6949         },
6950
6951         _initSource: function() {
6952                 var array, url,
6953                         that = this;
6954                 if ( $.isArray(this.options.source) ) {
6955                         array = this.options.source;
6956                         this.source = function( request, response ) {
6957                                 response( $.ui.autocomplete.filter( array, request.term ) );
6958                         };
6959                 } else if ( typeof this.options.source === "string" ) {
6960                         url = this.options.source;
6961                         this.source = function( request, response ) {
6962                                 if ( that.xhr ) {
6963                                         that.xhr.abort();
6964                                 }
6965                                 that.xhr = $.ajax({
6966                                         url: url,
6967                                         data: request,
6968                                         dataType: "json",
6969                                         success: function( data ) {
6970                                                 response( data );
6971                                         },
6972                                         error: function() {
6973                                                 response( [] );
6974                                         }
6975                                 });
6976                         };
6977                 } else {
6978                         this.source = this.options.source;
6979                 }
6980         },
6981
6982         _searchTimeout: function( event ) {
6983                 clearTimeout( this.searching );
6984                 this.searching = this._delay(function() {
6985                         // only search if the value has changed
6986                         if ( this.term !== this._value() ) {
6987                                 this.selectedItem = null;
6988                                 this.search( null, event );
6989                         }
6990                 }, this.options.delay );
6991         },
6992
6993         search: function( value, event ) {
6994                 value = value != null ? value : this._value();
6995
6996                 // always save the actual value, not the one passed as an argument
6997                 this.term = this._value();
6998
6999                 if ( value.length < this.options.minLength ) {
7000                         return this.close( event );
7001                 }
7002
7003                 if ( this._trigger( "search", event ) === false ) {
7004                         return;
7005                 }
7006
7007                 return this._search( value );
7008         },
7009
7010         _search: function( value ) {
7011                 this.pending++;
7012                 this.element.addClass( "ui-autocomplete-loading" );
7013                 this.cancelSearch = false;
7014
7015                 this.source( { term: value }, this._response() );
7016         },
7017
7018         _response: function() {
7019                 var that = this,
7020                         index = ++requestIndex;
7021
7022                 return function( content ) {
7023                         if ( index === requestIndex ) {
7024                                 that.__response( content );
7025                         }
7026
7027                         that.pending--;
7028                         if ( !that.pending ) {
7029                                 that.element.removeClass( "ui-autocomplete-loading" );
7030                         }
7031                 };
7032         },
7033
7034         __response: function( content ) {
7035                 if ( content ) {
7036                         content = this._normalize( content );
7037                 }
7038                 this._trigger( "response", null, { content: content } );
7039                 if ( !this.options.disabled && content && content.length && !this.cancelSearch ) {
7040                         this._suggest( content );
7041                         this._trigger( "open" );
7042                 } else {
7043                         // use ._close() instead of .close() so we don't cancel future searches
7044                         this._close();
7045                 }
7046         },
7047
7048         close: function( event ) {
7049                 this.cancelSearch = true;
7050                 this._close( event );
7051         },
7052
7053         _close: function( event ) {
7054                 if ( this.menu.element.is( ":visible" ) ) {
7055                         this.menu.element.hide();
7056                         this.menu.blur();
7057                         this.isNewMenu = true;
7058                         this._trigger( "close", event );
7059                 }
7060         },
7061
7062         _change: function( event ) {
7063                 if ( this.previous !== this._value() ) {
7064                         this._trigger( "change", event, { item: this.selectedItem } );
7065                 }
7066         },
7067
7068         _normalize: function( items ) {
7069                 // assume all items have the right format when the first item is complete
7070                 if ( items.length && items[0].label && items[0].value ) {
7071                         return items;
7072                 }
7073                 return $.map( items, function( item ) {
7074                         if ( typeof item === "string" ) {
7075                                 return {
7076                                         label: item,
7077                                         value: item
7078                                 };
7079                         }
7080                         return $.extend({
7081                                 label: item.label || item.value,
7082                                 value: item.value || item.label
7083                         }, item );
7084                 });
7085         },
7086
7087         _suggest: function( items ) {
7088                 var ul = this.menu.element.empty();
7089                 this._renderMenu( ul, items );
7090                 this.isNewMenu = true;
7091                 this.menu.refresh();
7092
7093                 // size and position menu
7094                 ul.show();
7095                 this._resizeMenu();
7096                 ul.position( $.extend({
7097                         of: this.element
7098                 }, this.options.position ));
7099
7100                 if ( this.options.autoFocus ) {
7101                         this.menu.next();
7102                 }
7103         },
7104
7105         _resizeMenu: function() {
7106                 var ul = this.menu.element;
7107                 ul.outerWidth( Math.max(
7108                         // Firefox wraps long text (possibly a rounding bug)
7109                         // so we add 1px to avoid the wrapping (#7513)
7110                         ul.width( "" ).outerWidth() + 1,
7111                         this.element.outerWidth()
7112                 ) );
7113         },
7114
7115         _renderMenu: function( ul, items ) {
7116                 var that = this;
7117                 $.each( items, function( index, item ) {
7118                         that._renderItemData( ul, item );
7119                 });
7120         },
7121
7122         _renderItemData: function( ul, item ) {
7123                 return this._renderItem( ul, item ).data( "ui-autocomplete-item", item );
7124         },
7125
7126         _renderItem: function( ul, item ) {
7127                 return $( "<li>" )
7128                         .append( $( "<a>" ).text( item.label ) )
7129                         .appendTo( ul );
7130         },
7131
7132         _move: function( direction, event ) {
7133                 if ( !this.menu.element.is( ":visible" ) ) {
7134                         this.search( null, event );
7135                         return;
7136                 }
7137                 if ( this.menu.isFirstItem() && /^previous/.test( direction ) ||
7138                                 this.menu.isLastItem() && /^next/.test( direction ) ) {
7139                         this._value( this.term );
7140                         this.menu.blur();
7141                         return;
7142                 }
7143                 this.menu[ direction ]( event );
7144         },
7145
7146         widget: function() {
7147                 return this.menu.element;
7148         },
7149
7150         _value: function() {
7151                 return this.valueMethod.apply( this.element, arguments );
7152         },
7153
7154         _keyEvent: function( keyEvent, event ) {
7155                 if ( !this.isMultiLine || this.menu.element.is( ":visible" ) ) {
7156                         this._move( keyEvent, event );
7157
7158                         // prevents moving cursor to beginning/end of the text field in some browsers
7159                         event.preventDefault();
7160                 }
7161         }
7162 });
7163
7164 $.extend( $.ui.autocomplete, {
7165         escapeRegex: function( value ) {
7166                 return value.replace(/[\-\[\]{}()*+?.,\\\^$|#\s]/g, "\\$&");
7167         },
7168         filter: function(array, term) {
7169                 var matcher = new RegExp( $.ui.autocomplete.escapeRegex(term), "i" );
7170                 return $.grep( array, function(value) {
7171                         return matcher.test( value.label || value.value || value );
7172                 });
7173         }
7174 });
7175
7176
7177 // live region extension, adding a `messages` option
7178 // NOTE: This is an experimental API. We are still investigating
7179 // a full solution for string manipulation and internationalization.
7180 $.widget( "ui.autocomplete", $.ui.autocomplete, {
7181         options: {
7182                 messages: {
7183                         noResults: "No search results.",
7184                         results: function( amount ) {
7185                                 return amount + ( amount > 1 ? " results are" : " result is" ) +
7186                                         " available, use up and down arrow keys to navigate.";
7187                         }
7188                 }
7189         },
7190
7191         __response: function( content ) {
7192                 var message;
7193                 this._superApply( arguments );
7194                 if ( this.options.disabled || this.cancelSearch ) {
7195                         return;
7196                 }
7197                 if ( content && content.length ) {
7198                         message = this.options.messages.results( content.length );
7199                 } else {
7200                         message = this.options.messages.noResults;
7201                 }
7202                 this.liveRegion.text( message );
7203         }
7204 });
7205
7206 }( jQuery ));
7207
7208 (function( $, undefined ) {
7209
7210 var lastActive, startXPos, startYPos, clickDragged,
7211         baseClasses = "ui-button ui-widget ui-state-default ui-corner-all",
7212         stateClasses = "ui-state-hover ui-state-active ",
7213         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",
7214         formResetHandler = function() {
7215                 var form = $( this );
7216                 setTimeout(function() {
7217                         form.find( ":ui-button" ).button( "refresh" );
7218                 }, 1 );
7219         },
7220         radioGroup = function( radio ) {
7221                 var name = radio.name,
7222                         form = radio.form,
7223                         radios = $( [] );
7224                 if ( name ) {
7225                         name = name.replace( /'/g, "\\'" );
7226                         if ( form ) {
7227                                 radios = $( form ).find( "[name='" + name + "']" );
7228                         } else {
7229                                 radios = $( "[name='" + name + "']", radio.ownerDocument )
7230                                         .filter(function() {
7231                                                 return !this.form;
7232                                         });
7233                         }
7234                 }
7235                 return radios;
7236         };
7237
7238 $.widget( "ui.button", {
7239         version: "1.10.3",
7240         defaultElement: "<button>",
7241         options: {
7242                 disabled: null,
7243                 text: true,
7244                 label: null,
7245                 icons: {
7246                         primary: null,
7247                         secondary: null
7248                 }
7249         },
7250         _create: function() {
7251                 this.element.closest( "form" )
7252                         .unbind( "reset" + this.eventNamespace )
7253                         .bind( "reset" + this.eventNamespace, formResetHandler );
7254
7255                 if ( typeof this.options.disabled !== "boolean" ) {
7256                         this.options.disabled = !!this.element.prop( "disabled" );
7257                 } else {
7258                         this.element.prop( "disabled", this.options.disabled );
7259                 }
7260
7261                 this._determineButtonType();
7262                 this.hasTitle = !!this.buttonElement.attr( "title" );
7263
7264                 var that = this,
7265                         options = this.options,
7266                         toggleButton = this.type === "checkbox" || this.type === "radio",
7267                         activeClass = !toggleButton ? "ui-state-active" : "",
7268                         focusClass = "ui-state-focus";
7269
7270                 if ( options.label === null ) {
7271                         options.label = (this.type === "input" ? this.buttonElement.val() : this.buttonElement.html());
7272                 }
7273
7274                 this._hoverable( this.buttonElement );
7275
7276                 this.buttonElement
7277                         .addClass( baseClasses )
7278                         .attr( "role", "button" )
7279                         .bind( "mouseenter" + this.eventNamespace, function() {
7280                                 if ( options.disabled ) {
7281                                         return;
7282                                 }
7283                                 if ( this === lastActive ) {
7284                                         $( this ).addClass( "ui-state-active" );
7285                                 }
7286                         })
7287                         .bind( "mouseleave" + this.eventNamespace, function() {
7288                                 if ( options.disabled ) {
7289                                         return;
7290                                 }
7291                                 $( this ).removeClass( activeClass );
7292                         })
7293                         .bind( "click" + this.eventNamespace, function( event ) {
7294                                 if ( options.disabled ) {
7295                                         event.preventDefault();
7296                                         event.stopImmediatePropagation();
7297                                 }
7298                         });
7299
7300                 this.element
7301                         .bind( "focus" + this.eventNamespace, function() {
7302                                 // no need to check disabled, focus won't be triggered anyway
7303                                 that.buttonElement.addClass( focusClass );
7304                         })
7305                         .bind( "blur" + this.eventNamespace, function() {
7306                                 that.buttonElement.removeClass( focusClass );
7307                         });
7308
7309                 if ( toggleButton ) {
7310                         this.element.bind( "change" + this.eventNamespace, function() {
7311                                 if ( clickDragged ) {
7312                                         return;
7313                                 }
7314                                 that.refresh();
7315                         });
7316                         // if mouse moves between mousedown and mouseup (drag) set clickDragged flag
7317                         // prevents issue where button state changes but checkbox/radio checked state
7318                         // does not in Firefox (see ticket #6970)
7319                         this.buttonElement
7320                                 .bind( "mousedown" + this.eventNamespace, function( event ) {
7321                                         if ( options.disabled ) {
7322                                                 return;
7323                                         }
7324                                         clickDragged = false;
7325                                         startXPos = event.pageX;
7326                                         startYPos = event.pageY;
7327                                 })
7328                                 .bind( "mouseup" + this.eventNamespace, function( event ) {
7329                                         if ( options.disabled ) {
7330                                                 return;
7331                                         }
7332                                         if ( startXPos !== event.pageX || startYPos !== event.pageY ) {
7333                                                 clickDragged = true;
7334                                         }
7335                         });
7336                 }
7337
7338                 if ( this.type === "checkbox" ) {
7339                         this.buttonElement.bind( "click" + this.eventNamespace, function() {
7340                                 if ( options.disabled || clickDragged ) {
7341                                         return false;
7342                                 }
7343                         });
7344                 } else if ( this.type === "radio" ) {
7345                         this.buttonElement.bind( "click" + this.eventNamespace, function() {
7346                                 if ( options.disabled || clickDragged ) {
7347                                         return false;
7348                                 }
7349                                 $( this ).addClass( "ui-state-active" );
7350                                 that.buttonElement.attr( "aria-pressed", "true" );
7351
7352                                 var radio = that.element[ 0 ];
7353                                 radioGroup( radio )
7354                                         .not( radio )
7355                                         .map(function() {
7356                                                 return $( this ).button( "widget" )[ 0 ];
7357                                         })
7358                                         .removeClass( "ui-state-active" )
7359                                         .attr( "aria-pressed", "false" );
7360                         });
7361                 } else {
7362                         this.buttonElement
7363                                 .bind( "mousedown" + this.eventNamespace, function() {
7364                                         if ( options.disabled ) {
7365                                                 return false;
7366                                         }
7367                                         $( this ).addClass( "ui-state-active" );
7368                                         lastActive = this;
7369                                         that.document.one( "mouseup", function() {
7370                                                 lastActive = null;
7371                                         });
7372                                 })
7373                                 .bind( "mouseup" + this.eventNamespace, function() {
7374                                         if ( options.disabled ) {
7375                                                 return false;
7376                                         }
7377                                         $( this ).removeClass( "ui-state-active" );
7378                                 })
7379                                 .bind( "keydown" + this.eventNamespace, function(event) {
7380                                         if ( options.disabled ) {
7381                                                 return false;
7382                                         }
7383                                         if ( event.keyCode === $.ui.keyCode.SPACE || event.keyCode === $.ui.keyCode.ENTER ) {
7384                                                 $( this ).addClass( "ui-state-active" );
7385                                         }
7386                                 })
7387                                 // see #8559, we bind to blur here in case the button element loses
7388                                 // focus between keydown and keyup, it would be left in an "active" state
7389                                 .bind( "keyup" + this.eventNamespace + " blur" + this.eventNamespace, function() {
7390                                         $( this ).removeClass( "ui-state-active" );
7391                                 });
7392
7393                         if ( this.buttonElement.is("a") ) {
7394                                 this.buttonElement.keyup(function(event) {
7395                                         if ( event.keyCode === $.ui.keyCode.SPACE ) {
7396                                                 // TODO pass through original event correctly (just as 2nd argument doesn't work)
7397                                                 $( this ).click();
7398                                         }
7399                                 });
7400                         }
7401                 }
7402
7403                 // TODO: pull out $.Widget's handling for the disabled option into
7404                 // $.Widget.prototype._setOptionDisabled so it's easy to proxy and can
7405                 // be overridden by individual plugins
7406                 this._setOption( "disabled", options.disabled );
7407                 this._resetButton();
7408         },
7409
7410         _determineButtonType: function() {
7411                 var ancestor, labelSelector, checked;
7412
7413                 if ( this.element.is("[type=checkbox]") ) {
7414                         this.type = "checkbox";
7415                 } else if ( this.element.is("[type=radio]") ) {
7416                         this.type = "radio";
7417                 } else if ( this.element.is("input") ) {
7418                         this.type = "input";
7419                 } else {
7420                         this.type = "button";
7421                 }
7422
7423                 if ( this.type === "checkbox" || this.type === "radio" ) {
7424                         // we don't search against the document in case the element
7425                         // is disconnected from the DOM
7426                         ancestor = this.element.parents().last();
7427                         labelSelector = "label[for='" + this.element.attr("id") + "']";
7428                         this.buttonElement = ancestor.find( labelSelector );
7429                         if ( !this.buttonElement.length ) {
7430                                 ancestor = ancestor.length ? ancestor.siblings() : this.element.siblings();
7431                                 this.buttonElement = ancestor.filter( labelSelector );
7432                                 if ( !this.buttonElement.length ) {
7433                                         this.buttonElement = ancestor.find( labelSelector );
7434                                 }
7435                         }
7436                         this.element.addClass( "ui-helper-hidden-accessible" );
7437
7438                         checked = this.element.is( ":checked" );
7439                         if ( checked ) {
7440                                 this.buttonElement.addClass( "ui-state-active" );
7441                         }
7442                         this.buttonElement.prop( "aria-pressed", checked );
7443                 } else {
7444                         this.buttonElement = this.element;
7445                 }
7446         },
7447
7448         widget: function() {
7449                 return this.buttonElement;
7450         },
7451
7452         _destroy: function() {
7453                 this.element
7454                         .removeClass( "ui-helper-hidden-accessible" );
7455                 this.buttonElement
7456                         .removeClass( baseClasses + " " + stateClasses + " " + typeClasses )
7457                         .removeAttr( "role" )
7458                         .removeAttr( "aria-pressed" )
7459                         .html( this.buttonElement.find(".ui-button-text").html() );
7460
7461                 if ( !this.hasTitle ) {
7462                         this.buttonElement.removeAttr( "title" );
7463                 }
7464         },
7465
7466         _setOption: function( key, value ) {
7467                 this._super( key, value );
7468                 if ( key === "disabled" ) {
7469                         if ( value ) {
7470                                 this.element.prop( "disabled", true );
7471                         } else {
7472                                 this.element.prop( "disabled", false );
7473                         }
7474                         return;
7475                 }
7476                 this._resetButton();
7477         },
7478
7479         refresh: function() {
7480                 //See #8237 & #8828
7481                 var isDisabled = this.element.is( "input, button" ) ? this.element.is( ":disabled" ) : this.element.hasClass( "ui-button-disabled" );
7482
7483                 if ( isDisabled !== this.options.disabled ) {
7484                         this._setOption( "disabled", isDisabled );
7485                 }
7486                 if ( this.type === "radio" ) {
7487                         radioGroup( this.element[0] ).each(function() {
7488                                 if ( $( this ).is( ":checked" ) ) {
7489                                         $( this ).button( "widget" )
7490                                                 .addClass( "ui-state-active" )
7491                                                 .attr( "aria-pressed", "true" );
7492                                 } else {
7493                                         $( this ).button( "widget" )
7494                                                 .removeClass( "ui-state-active" )
7495                                                 .attr( "aria-pressed", "false" );
7496                                 }
7497                         });
7498                 } else if ( this.type === "checkbox" ) {
7499                         if ( this.element.is( ":checked" ) ) {
7500                                 this.buttonElement
7501                                         .addClass( "ui-state-active" )
7502                                         .attr( "aria-pressed", "true" );
7503                         } else {
7504                                 this.buttonElement
7505                                         .removeClass( "ui-state-active" )
7506                                         .attr( "aria-pressed", "false" );
7507                         }
7508                 }
7509         },
7510
7511         _resetButton: function() {
7512                 if ( this.type === "input" ) {
7513                         if ( this.options.label ) {
7514                                 this.element.val( this.options.label );
7515                         }
7516                         return;
7517                 }
7518                 var buttonElement = this.buttonElement.removeClass( typeClasses ),
7519                         buttonText = $( "<span></span>", this.document[0] )
7520                                 .addClass( "ui-button-text" )
7521                                 .html( this.options.label )
7522                                 .appendTo( buttonElement.empty() )
7523                                 .text(),
7524                         icons = this.options.icons,
7525                         multipleIcons = icons.primary && icons.secondary,
7526                         buttonClasses = [];
7527
7528                 if ( icons.primary || icons.secondary ) {
7529                         if ( this.options.text ) {
7530                                 buttonClasses.push( "ui-button-text-icon" + ( multipleIcons ? "s" : ( icons.primary ? "-primary" : "-secondary" ) ) );
7531                         }
7532
7533                         if ( icons.primary ) {
7534                                 buttonElement.prepend( "<span class='ui-button-icon-primary ui-icon " + icons.primary + "'></span>" );
7535                         }
7536
7537                         if ( icons.secondary ) {
7538                                 buttonElement.append( "<span class='ui-button-icon-secondary ui-icon " + icons.secondary + "'></span>" );
7539                         }
7540
7541                         if ( !this.options.text ) {
7542                                 buttonClasses.push( multipleIcons ? "ui-button-icons-only" : "ui-button-icon-only" );
7543
7544                                 if ( !this.hasTitle ) {
7545                                         buttonElement.attr( "title", $.trim( buttonText ) );
7546                                 }
7547                         }
7548                 } else {
7549                         buttonClasses.push( "ui-button-text-only" );
7550                 }
7551                 buttonElement.addClass( buttonClasses.join( " " ) );
7552         }
7553 });
7554
7555 $.widget( "ui.buttonset", {
7556         version: "1.10.3",
7557         options: {
7558                 items: "button, input[type=button], input[type=submit], input[type=reset], input[type=checkbox], input[type=radio], a, :data(ui-button)"
7559         },
7560
7561         _create: function() {
7562                 this.element.addClass( "ui-buttonset" );
7563         },
7564
7565         _init: function() {
7566                 this.refresh();
7567         },
7568
7569         _setOption: function( key, value ) {
7570                 if ( key === "disabled" ) {
7571                         this.buttons.button( "option", key, value );
7572                 }
7573
7574                 this._super( key, value );
7575         },
7576
7577         refresh: function() {
7578                 var rtl = this.element.css( "direction" ) === "rtl";
7579
7580                 this.buttons = this.element.find( this.options.items )
7581                         .filter( ":ui-button" )
7582                                 .button( "refresh" )
7583                         .end()
7584                         .not( ":ui-button" )
7585                                 .button()
7586                         .end()
7587                         .map(function() {
7588                                 return $( this ).button( "widget" )[ 0 ];
7589                         })
7590                                 .removeClass( "ui-corner-all ui-corner-left ui-corner-right" )
7591                                 .filter( ":first" )
7592                                         .addClass( rtl ? "ui-corner-right" : "ui-corner-left" )
7593                                 .end()
7594                                 .filter( ":last" )
7595                                         .addClass( rtl ? "ui-corner-left" : "ui-corner-right" )
7596                                 .end()
7597                         .end();
7598         },
7599
7600         _destroy: function() {
7601                 this.element.removeClass( "ui-buttonset" );
7602                 this.buttons
7603                         .map(function() {
7604                                 return $( this ).button( "widget" )[ 0 ];
7605                         })
7606                                 .removeClass( "ui-corner-left ui-corner-right" )
7607                         .end()
7608                         .button( "destroy" );
7609         }
7610 });
7611
7612 }( jQuery ) );
7613
7614 (function( $, undefined ) {
7615
7616 $.extend($.ui, { datepicker: { version: "1.10.3" } });
7617
7618 var PROP_NAME = "datepicker",
7619         instActive;
7620
7621 /* Date picker manager.
7622    Use the singleton instance of this class, $.datepicker, to interact with the date picker.
7623    Settings for (groups of) date pickers are maintained in an instance object,
7624    allowing multiple different settings on the same page. */
7625
7626 function Datepicker() {
7627         this._curInst = null; // The current instance in use
7628         this._keyEvent = false; // If the last event was a key event
7629         this._disabledInputs = []; // List of date picker inputs that have been disabled
7630         this._datepickerShowing = false; // True if the popup picker is showing , false if not
7631         this._inDialog = false; // True if showing within a "dialog", false if not
7632         this._mainDivId = "ui-datepicker-div"; // The ID of the main datepicker division
7633         this._inlineClass = "ui-datepicker-inline"; // The name of the inline marker class
7634         this._appendClass = "ui-datepicker-append"; // The name of the append marker class
7635         this._triggerClass = "ui-datepicker-trigger"; // The name of the trigger marker class
7636         this._dialogClass = "ui-datepicker-dialog"; // The name of the dialog marker class
7637         this._disableClass = "ui-datepicker-disabled"; // The name of the disabled covering marker class
7638         this._unselectableClass = "ui-datepicker-unselectable"; // The name of the unselectable cell marker class
7639         this._currentClass = "ui-datepicker-current-day"; // The name of the current day marker class
7640         this._dayOverClass = "ui-datepicker-days-cell-over"; // The name of the day hover marker class
7641         this.regional = []; // Available regional settings, indexed by language code
7642         this.regional[""] = { // Default regional settings
7643                 closeText: "Done", // Display text for close link
7644                 prevText: "Prev", // Display text for previous month link
7645                 nextText: "Next", // Display text for next month link
7646                 currentText: "Today", // Display text for current month link
7647                 monthNames: ["January","February","March","April","May","June",
7648                         "July","August","September","October","November","December"], // Names of months for drop-down and formatting
7649                 monthNamesShort: ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"], // For formatting
7650                 dayNames: ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"], // For formatting
7651                 dayNamesShort: ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"], // For formatting
7652                 dayNamesMin: ["Su","Mo","Tu","We","Th","Fr","Sa"], // Column headings for days starting at Sunday
7653                 weekHeader: "Wk", // Column header for week of the year
7654                 dateFormat: "mm/dd/yy", // See format options on parseDate
7655                 firstDay: 0, // The first day of the week, Sun = 0, Mon = 1, ...
7656                 isRTL: false, // True if right-to-left language, false if left-to-right
7657                 showMonthAfterYear: false, // True if the year select precedes month, false for month then year
7658                 yearSuffix: "" // Additional text to append to the year in the month headers
7659         };
7660         this._defaults = { // Global defaults for all the date picker instances
7661                 showOn: "focus", // "focus" for popup on focus,
7662                         // "button" for trigger button, or "both" for either
7663                 showAnim: "fadeIn", // Name of jQuery animation for popup
7664                 showOptions: {}, // Options for enhanced animations
7665                 defaultDate: null, // Used when field is blank: actual date,
7666                         // +/-number for offset from today, null for today
7667                 appendText: "", // Display text following the input box, e.g. showing the format
7668                 buttonText: "...", // Text for trigger button
7669                 buttonImage: "", // URL for trigger button image
7670                 buttonImageOnly: false, // True if the image appears alone, false if it appears on a button
7671                 hideIfNoPrevNext: false, // True to hide next/previous month links
7672                         // if not applicable, false to just disable them
7673                 navigationAsDateFormat: false, // True if date formatting applied to prev/today/next links
7674                 gotoCurrent: false, // True if today link goes back to current selection instead
7675                 changeMonth: false, // True if month can be selected directly, false if only prev/next
7676                 changeYear: false, // True if year can be selected directly, false if only prev/next
7677                 yearRange: "c-10:c+10", // Range of years to display in drop-down,
7678                         // either relative to today's year (-nn:+nn), relative to currently displayed year
7679                         // (c-nn:c+nn), absolute (nnnn:nnnn), or a combination of the above (nnnn:-n)
7680                 showOtherMonths: false, // True to show dates in other months, false to leave blank
7681                 selectOtherMonths: false, // True to allow selection of dates in other months, false for unselectable
7682                 showWeek: false, // True to show week of the year, false to not show it
7683                 calculateWeek: this.iso8601Week, // How to calculate the week of the year,
7684                         // takes a Date and returns the number of the week for it
7685                 shortYearCutoff: "+10", // Short year values < this are in the current century,
7686                         // > this are in the previous century,
7687                         // string value starting with "+" for current year + value
7688                 minDate: null, // The earliest selectable date, or null for no limit
7689                 maxDate: null, // The latest selectable date, or null for no limit
7690                 duration: "fast", // Duration of display/closure
7691                 beforeShowDay: null, // Function that takes a date and returns an array with
7692                         // [0] = true if selectable, false if not, [1] = custom CSS class name(s) or "",
7693                         // [2] = cell title (optional), e.g. $.datepicker.noWeekends
7694                 beforeShow: null, // Function that takes an input field and
7695                         // returns a set of custom settings for the date picker
7696                 onSelect: null, // Define a callback function when a date is selected
7697                 onChangeMonthYear: null, // Define a callback function when the month or year is changed
7698                 onClose: null, // Define a callback function when the datepicker is closed
7699                 numberOfMonths: 1, // Number of months to show at a time
7700                 showCurrentAtPos: 0, // The position in multipe months at which to show the current month (starting at 0)
7701                 stepMonths: 1, // Number of months to step back/forward
7702                 stepBigMonths: 12, // Number of months to step back/forward for the big links
7703                 altField: "", // Selector for an alternate field to store selected dates into
7704                 altFormat: "", // The date format to use for the alternate field
7705                 constrainInput: true, // The input is constrained by the current date format
7706                 showButtonPanel: false, // True to show button panel, false to not show it
7707                 autoSize: false, // True to size the input for the date format, false to leave as is
7708                 disabled: false // The initial disabled state
7709         };
7710         $.extend(this._defaults, this.regional[""]);
7711         this.dpDiv = bindHover($("<div id='" + this._mainDivId + "' class='ui-datepicker ui-widget ui-widget-content ui-helper-clearfix ui-corner-all'></div>"));
7712 }
7713
7714 $.extend(Datepicker.prototype, {
7715         /* Class name added to elements to indicate already configured with a date picker. */
7716         markerClassName: "hasDatepicker",
7717
7718         //Keep track of the maximum number of rows displayed (see #7043)
7719         maxRows: 4,
7720
7721         // TODO rename to "widget" when switching to widget factory
7722         _widgetDatepicker: function() {
7723                 return this.dpDiv;
7724         },
7725
7726         /* Override the default settings for all instances of the date picker.
7727          * @param  settings  object - the new settings to use as defaults (anonymous object)
7728          * @return the manager object
7729          */
7730         setDefaults: function(settings) {
7731                 extendRemove(this._defaults, settings || {});
7732                 return this;
7733         },
7734
7735         /* Attach the date picker to a jQuery selection.
7736          * @param  target       element - the target input field or division or span
7737          * @param  settings  object - the new settings to use for this date picker instance (anonymous)
7738          */
7739         _attachDatepicker: function(target, settings) {
7740                 var nodeName, inline, inst;
7741                 nodeName = target.nodeName.toLowerCase();
7742                 inline = (nodeName === "div" || nodeName === "span");
7743                 if (!target.id) {
7744                         this.uuid += 1;
7745                         target.id = "dp" + this.uuid;
7746                 }
7747                 inst = this._newInst($(target), inline);
7748                 inst.settings = $.extend({}, settings || {});
7749                 if (nodeName === "input") {
7750                         this._connectDatepicker(target, inst);
7751                 } else if (inline) {
7752                         this._inlineDatepicker(target, inst);
7753                 }
7754         },
7755
7756         /* Create a new instance object. */
7757         _newInst: function(target, inline) {
7758                 var id = target[0].id.replace(/([^A-Za-z0-9_\-])/g, "\\\\$1"); // escape jQuery meta chars
7759                 return {id: id, input: target, // associated target
7760                         selectedDay: 0, selectedMonth: 0, selectedYear: 0, // current selection
7761                         drawMonth: 0, drawYear: 0, // month being drawn
7762                         inline: inline, // is datepicker inline or not
7763                         dpDiv: (!inline ? this.dpDiv : // presentation div
7764                         bindHover($("<div class='" + this._inlineClass + " ui-datepicker ui-widget ui-widget-content ui-helper-clearfix ui-corner-all'></div>")))};
7765         },
7766
7767         /* Attach the date picker to an input field. */
7768         _connectDatepicker: function(target, inst) {
7769                 var input = $(target);
7770                 inst.append = $([]);
7771                 inst.trigger = $([]);
7772                 if (input.hasClass(this.markerClassName)) {
7773                         return;
7774                 }
7775                 this._attachments(input, inst);
7776                 input.addClass(this.markerClassName).keydown(this._doKeyDown).
7777                         keypress(this._doKeyPress).keyup(this._doKeyUp);
7778                 this._autoSize(inst);
7779                 $.data(target, PROP_NAME, inst);
7780                 //If disabled option is true, disable the datepicker once it has been attached to the input (see ticket #5665)
7781                 if( inst.settings.disabled ) {
7782                         this._disableDatepicker( target );
7783                 }
7784         },
7785
7786         /* Make attachments based on settings. */
7787         _attachments: function(input, inst) {
7788                 var showOn, buttonText, buttonImage,
7789                         appendText = this._get(inst, "appendText"),
7790                         isRTL = this._get(inst, "isRTL");
7791
7792                 if (inst.append) {
7793                         inst.append.remove();
7794                 }
7795                 if (appendText) {
7796                         inst.append = $("<span class='" + this._appendClass + "'>" + appendText + "</span>");
7797                         input[isRTL ? "before" : "after"](inst.append);
7798                 }
7799
7800                 input.unbind("focus", this._showDatepicker);
7801
7802                 if (inst.trigger) {
7803                         inst.trigger.remove();
7804                 }
7805
7806                 showOn = this._get(inst, "showOn");
7807                 if (showOn === "focus" || showOn === "both") { // pop-up date picker when in the marked field
7808                         input.focus(this._showDatepicker);
7809                 }
7810                 if (showOn === "button" || showOn === "both") { // pop-up date picker when button clicked
7811                         buttonText = this._get(inst, "buttonText");
7812                         buttonImage = this._get(inst, "buttonImage");
7813                         inst.trigger = $(this._get(inst, "buttonImageOnly") ?
7814                                 $("<img/>").addClass(this._triggerClass).
7815                                         attr({ src: buttonImage, alt: buttonText, title: buttonText }) :
7816                                 $("<button type='button'></button>").addClass(this._triggerClass).
7817                                         html(!buttonImage ? buttonText : $("<img/>").attr(
7818                                         { src:buttonImage, alt:buttonText, title:buttonText })));
7819                         input[isRTL ? "before" : "after"](inst.trigger);
7820                         inst.trigger.click(function() {
7821                                 if ($.datepicker._datepickerShowing && $.datepicker._lastInput === input[0]) {
7822                                         $.datepicker._hideDatepicker();
7823                                 } else if ($.datepicker._datepickerShowing && $.datepicker._lastInput !== input[0]) {
7824                                         $.datepicker._hideDatepicker();
7825                                         $.datepicker._showDatepicker(input[0]);
7826                                 } else {
7827                                         $.datepicker._showDatepicker(input[0]);
7828                                 }
7829                                 return false;
7830                         });
7831                 }
7832         },
7833
7834         /* Apply the maximum length for the date format. */
7835         _autoSize: function(inst) {
7836                 if (this._get(inst, "autoSize") && !inst.inline) {
7837                         var findMax, max, maxI, i,
7838                                 date = new Date(2009, 12 - 1, 20), // Ensure double digits
7839                                 dateFormat = this._get(inst, "dateFormat");
7840
7841                         if (dateFormat.match(/[DM]/)) {
7842                                 findMax = function(names) {
7843                                         max = 0;
7844                                         maxI = 0;
7845                                         for (i = 0; i < names.length; i++) {
7846                                                 if (names[i].length > max) {
7847                                                         max = names[i].length;
7848                                                         maxI = i;
7849                                                 }
7850                                         }
7851                                         return maxI;
7852                                 };
7853                                 date.setMonth(findMax(this._get(inst, (dateFormat.match(/MM/) ?
7854                                         "monthNames" : "monthNamesShort"))));
7855                                 date.setDate(findMax(this._get(inst, (dateFormat.match(/DD/) ?
7856                                         "dayNames" : "dayNamesShort"))) + 20 - date.getDay());
7857                         }
7858                         inst.input.attr("size", this._formatDate(inst, date).length);
7859                 }
7860         },
7861
7862         /* Attach an inline date picker to a div. */
7863         _inlineDatepicker: function(target, inst) {
7864                 var divSpan = $(target);
7865                 if (divSpan.hasClass(this.markerClassName)) {
7866                         return;
7867                 }
7868                 divSpan.addClass(this.markerClassName).append(inst.dpDiv);
7869                 $.data(target, PROP_NAME, inst);
7870                 this._setDate(inst, this._getDefaultDate(inst), true);
7871                 this._updateDatepicker(inst);
7872                 this._updateAlternate(inst);
7873                 //If disabled option is true, disable the datepicker before showing it (see ticket #5665)
7874                 if( inst.settings.disabled ) {
7875                         this._disableDatepicker( target );
7876                 }
7877                 // Set display:block in place of inst.dpDiv.show() which won't work on disconnected elements
7878                 // http://bugs.jqueryui.com/ticket/7552 - A Datepicker created on a detached div has zero height
7879                 inst.dpDiv.css( "display", "block" );
7880         },
7881
7882         /* Pop-up the date picker in a "dialog" box.
7883          * @param  input element - ignored
7884          * @param  date string or Date - the initial date to display
7885          * @param  onSelect  function - the function to call when a date is selected
7886          * @param  settings  object - update the dialog date picker instance's settings (anonymous object)
7887          * @param  pos int[2] - coordinates for the dialog's position within the screen or
7888          *                                      event - with x/y coordinates or
7889          *                                      leave empty for default (screen centre)
7890          * @return the manager object
7891          */
7892         _dialogDatepicker: function(input, date, onSelect, settings, pos) {
7893                 var id, browserWidth, browserHeight, scrollX, scrollY,
7894                         inst = this._dialogInst; // internal instance
7895
7896                 if (!inst) {
7897                         this.uuid += 1;
7898                         id = "dp" + this.uuid;
7899                         this._dialogInput = $("<input type='text' id='" + id +
7900                                 "' style='position: absolute; top: -100px; width: 0px;'/>");
7901                         this._dialogInput.keydown(this._doKeyDown);
7902                         $("body").append(this._dialogInput);
7903                         inst = this._dialogInst = this._newInst(this._dialogInput, false);
7904                         inst.settings = {};
7905                         $.data(this._dialogInput[0], PROP_NAME, inst);
7906                 }
7907                 extendRemove(inst.settings, settings || {});
7908                 date = (date && date.constructor === Date ? this._formatDate(inst, date) : date);
7909                 this._dialogInput.val(date);
7910
7911                 this._pos = (pos ? (pos.length ? pos : [pos.pageX, pos.pageY]) : null);
7912                 if (!this._pos) {
7913                         browserWidth = document.documentElement.clientWidth;
7914                         browserHeight = document.documentElement.clientHeight;
7915                         scrollX = document.documentElement.scrollLeft || document.body.scrollLeft;
7916                         scrollY = document.documentElement.scrollTop || document.body.scrollTop;
7917                         this._pos = // should use actual width/height below
7918                                 [(browserWidth / 2) - 100 + scrollX, (browserHeight / 2) - 150 + scrollY];
7919                 }
7920
7921                 // move input on screen for focus, but hidden behind dialog
7922                 this._dialogInput.css("left", (this._pos[0] + 20) + "px").css("top", this._pos[1] + "px");
7923                 inst.settings.onSelect = onSelect;
7924                 this._inDialog = true;
7925                 this.dpDiv.addClass(this._dialogClass);
7926                 this._showDatepicker(this._dialogInput[0]);
7927                 if ($.blockUI) {
7928                         $.blockUI(this.dpDiv);
7929                 }
7930                 $.data(this._dialogInput[0], PROP_NAME, inst);
7931                 return this;
7932         },
7933
7934         /* Detach a datepicker from its control.
7935          * @param  target       element - the target input field or division or span
7936          */
7937         _destroyDatepicker: function(target) {
7938                 var nodeName,
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                 $.removeData(target, PROP_NAME);
7948                 if (nodeName === "input") {
7949                         inst.append.remove();
7950                         inst.trigger.remove();
7951                         $target.removeClass(this.markerClassName).
7952                                 unbind("focus", this._showDatepicker).
7953                                 unbind("keydown", this._doKeyDown).
7954                                 unbind("keypress", this._doKeyPress).
7955                                 unbind("keyup", this._doKeyUp);
7956                 } else if (nodeName === "div" || nodeName === "span") {
7957                         $target.removeClass(this.markerClassName).empty();
7958                 }
7959         },
7960
7961         /* Enable the date picker to a jQuery selection.
7962          * @param  target       element - the target input field or division or span
7963          */
7964         _enableDatepicker: function(target) {
7965                 var nodeName, inline,
7966                         $target = $(target),
7967                         inst = $.data(target, PROP_NAME);
7968
7969                 if (!$target.hasClass(this.markerClassName)) {
7970                         return;
7971                 }
7972
7973                 nodeName = target.nodeName.toLowerCase();
7974                 if (nodeName === "input") {
7975                         target.disabled = false;
7976                         inst.trigger.filter("button").
7977                                 each(function() { this.disabled = false; }).end().
7978                                 filter("img").css({opacity: "1.0", cursor: ""});
7979                 } else if (nodeName === "div" || nodeName === "span") {
7980                         inline = $target.children("." + this._inlineClass);
7981                         inline.children().removeClass("ui-state-disabled");
7982                         inline.find("select.ui-datepicker-month, select.ui-datepicker-year").
7983                                 prop("disabled", false);
7984                 }
7985                 this._disabledInputs = $.map(this._disabledInputs,
7986                         function(value) { return (value === target ? null : value); }); // delete entry
7987         },
7988
7989         /* Disable the date picker to a jQuery selection.
7990          * @param  target       element - the target input field or division or span
7991          */
7992         _disableDatepicker: function(target) {
7993                 var nodeName, inline,
7994                         $target = $(target),
7995                         inst = $.data(target, PROP_NAME);
7996
7997                 if (!$target.hasClass(this.markerClassName)) {
7998                         return;
7999                 }
8000
8001                 nodeName = target.nodeName.toLowerCase();
8002                 if (nodeName === "input") {
8003                         target.disabled = true;
8004                         inst.trigger.filter("button").
8005                                 each(function() { this.disabled = true; }).end().
8006                                 filter("img").css({opacity: "0.5", cursor: "default"});
8007                 } else if (nodeName === "div" || nodeName === "span") {
8008                         inline = $target.children("." + this._inlineClass);
8009                         inline.children().addClass("ui-state-disabled");
8010                         inline.find("select.ui-datepicker-month, select.ui-datepicker-year").
8011                                 prop("disabled", true);
8012                 }
8013                 this._disabledInputs = $.map(this._disabledInputs,
8014                         function(value) { return (value === target ? null : value); }); // delete entry
8015                 this._disabledInputs[this._disabledInputs.length] = target;
8016         },
8017
8018         /* Is the first field in a jQuery collection disabled as a datepicker?
8019          * @param  target       element - the target input field or division or span
8020          * @return boolean - true if disabled, false if enabled
8021          */
8022         _isDisabledDatepicker: function(target) {
8023                 if (!target) {
8024                         return false;
8025                 }
8026                 for (var i = 0; i < this._disabledInputs.length; i++) {
8027                         if (this._disabledInputs[i] === target) {
8028                                 return true;
8029                         }
8030                 }
8031                 return false;
8032         },
8033
8034         /* Retrieve the instance data for the target control.
8035          * @param  target  element - the target input field or division or span
8036          * @return  object - the associated instance data
8037          * @throws  error if a jQuery problem getting data
8038          */
8039         _getInst: function(target) {
8040                 try {
8041                         return $.data(target, PROP_NAME);
8042                 }
8043                 catch (err) {
8044                         throw "Missing instance data for this datepicker";
8045                 }
8046         },
8047
8048         /* Update or retrieve the settings for a date picker attached to an input field or division.
8049          * @param  target  element - the target input field or division or span
8050          * @param  name object - the new settings to update or
8051          *                              string - the name of the setting to change or retrieve,
8052          *                              when retrieving also "all" for all instance settings or
8053          *                              "defaults" for all global defaults
8054          * @param  value   any - the new value for the setting
8055          *                              (omit if above is an object or to retrieve a value)
8056          */
8057         _optionDatepicker: function(target, name, value) {
8058                 var settings, date, minDate, maxDate,
8059                         inst = this._getInst(target);
8060
8061                 if (arguments.length === 2 && typeof name === "string") {
8062                         return (name === "defaults" ? $.extend({}, $.datepicker._defaults) :
8063                                 (inst ? (name === "all" ? $.extend({}, inst.settings) :
8064                                 this._get(inst, name)) : null));
8065                 }
8066
8067                 settings = name || {};
8068                 if (typeof name === "string") {
8069                         settings = {};
8070                         settings[name] = value;
8071                 }
8072
8073                 if (inst) {
8074                         if (this._curInst === inst) {
8075                                 this._hideDatepicker();
8076                         }
8077
8078                         date = this._getDateDatepicker(target, true);
8079                         minDate = this._getMinMaxDate(inst, "min");
8080                         maxDate = this._getMinMaxDate(inst, "max");
8081                         extendRemove(inst.settings, settings);
8082                         // reformat the old minDate/maxDate values if dateFormat changes and a new minDate/maxDate isn't provided
8083                         if (minDate !== null && settings.dateFormat !== undefined && settings.minDate === undefined) {
8084                                 inst.settings.minDate = this._formatDate(inst, minDate);
8085                         }
8086                         if (maxDate !== null && settings.dateFormat !== undefined && settings.maxDate === undefined) {
8087                                 inst.settings.maxDate = this._formatDate(inst, maxDate);
8088                         }
8089                         if ( "disabled" in settings ) {
8090                                 if ( settings.disabled ) {
8091                                         this._disableDatepicker(target);
8092                                 } else {
8093                                         this._enableDatepicker(target);
8094                                 }
8095                         }
8096                         this._attachments($(target), inst);
8097                         this._autoSize(inst);
8098                         this._setDate(inst, date);
8099                         this._updateAlternate(inst);
8100                         this._updateDatepicker(inst);
8101                 }
8102         },
8103
8104         // change method deprecated
8105         _changeDatepicker: function(target, name, value) {
8106                 this._optionDatepicker(target, name, value);
8107         },
8108
8109         /* Redraw the date picker attached to an input field or division.
8110          * @param  target  element - the target input field or division or span
8111          */
8112         _refreshDatepicker: function(target) {
8113                 var inst = this._getInst(target);
8114                 if (inst) {
8115                         this._updateDatepicker(inst);
8116                 }
8117         },
8118
8119         /* Set the dates for a jQuery selection.
8120          * @param  target element - the target input field or division or span
8121          * @param  date Date - the new date
8122          */
8123         _setDateDatepicker: function(target, date) {
8124                 var inst = this._getInst(target);
8125                 if (inst) {
8126                         this._setDate(inst, date);
8127                         this._updateDatepicker(inst);
8128                         this._updateAlternate(inst);
8129                 }
8130         },
8131
8132         /* Get the date(s) for the first entry in a jQuery selection.
8133          * @param  target element - the target input field or division or span
8134          * @param  noDefault boolean - true if no default date is to be used
8135          * @return Date - the current date
8136          */
8137         _getDateDatepicker: function(target, noDefault) {
8138                 var inst = this._getInst(target);
8139                 if (inst && !inst.inline) {
8140                         this._setDateFromField(inst, noDefault);
8141                 }
8142                 return (inst ? this._getDate(inst) : null);
8143         },
8144
8145         /* Handle keystrokes. */
8146         _doKeyDown: function(event) {
8147                 var onSelect, dateStr, sel,
8148                         inst = $.datepicker._getInst(event.target),
8149                         handled = true,
8150                         isRTL = inst.dpDiv.is(".ui-datepicker-rtl");
8151
8152                 inst._keyEvent = true;
8153                 if ($.datepicker._datepickerShowing) {
8154                         switch (event.keyCode) {
8155                                 case 9: $.datepicker._hideDatepicker();
8156                                                 handled = false;
8157                                                 break; // hide on tab out
8158                                 case 13: sel = $("td." + $.datepicker._dayOverClass + ":not(." +
8159                                                                         $.datepicker._currentClass + ")", inst.dpDiv);
8160                                                 if (sel[0]) {
8161                                                         $.datepicker._selectDay(event.target, inst.selectedMonth, inst.selectedYear, sel[0]);
8162                                                 }
8163
8164                                                 onSelect = $.datepicker._get(inst, "onSelect");
8165                                                 if (onSelect) {
8166                                                         dateStr = $.datepicker._formatDate(inst);
8167
8168                                                         // trigger custom callback
8169                                                         onSelect.apply((inst.input ? inst.input[0] : null), [dateStr, inst]);
8170                                                 } else {
8171                                                         $.datepicker._hideDatepicker();
8172                                                 }
8173
8174                                                 return false; // don't submit the form
8175                                 case 27: $.datepicker._hideDatepicker();
8176                                                 break; // hide on escape
8177                                 case 33: $.datepicker._adjustDate(event.target, (event.ctrlKey ?
8178                                                         -$.datepicker._get(inst, "stepBigMonths") :
8179                                                         -$.datepicker._get(inst, "stepMonths")), "M");
8180                                                 break; // previous month/year on page up/+ ctrl
8181                                 case 34: $.datepicker._adjustDate(event.target, (event.ctrlKey ?
8182                                                         +$.datepicker._get(inst, "stepBigMonths") :
8183                                                         +$.datepicker._get(inst, "stepMonths")), "M");
8184                                                 break; // next month/year on page down/+ ctrl
8185                                 case 35: if (event.ctrlKey || event.metaKey) {
8186                                                         $.datepicker._clearDate(event.target);
8187                                                 }
8188                                                 handled = event.ctrlKey || event.metaKey;
8189                                                 break; // clear on ctrl or command +end
8190                                 case 36: if (event.ctrlKey || event.metaKey) {
8191                                                         $.datepicker._gotoToday(event.target);
8192                                                 }
8193                                                 handled = event.ctrlKey || event.metaKey;
8194                                                 break; // current on ctrl or command +home
8195                                 case 37: if (event.ctrlKey || event.metaKey) {
8196                                                         $.datepicker._adjustDate(event.target, (isRTL ? +1 : -1), "D");
8197                                                 }
8198                                                 handled = event.ctrlKey || event.metaKey;
8199                                                 // -1 day on ctrl or command +left
8200                                                 if (event.originalEvent.altKey) {
8201                                                         $.datepicker._adjustDate(event.target, (event.ctrlKey ?
8202                                                                 -$.datepicker._get(inst, "stepBigMonths") :
8203                                                                 -$.datepicker._get(inst, "stepMonths")), "M");
8204                                                 }
8205                                                 // next month/year on alt +left on Mac
8206                                                 break;
8207                                 case 38: if (event.ctrlKey || event.metaKey) {
8208                                                         $.datepicker._adjustDate(event.target, -7, "D");
8209                                                 }
8210                                                 handled = event.ctrlKey || event.metaKey;
8211                                                 break; // -1 week on ctrl or command +up
8212                                 case 39: if (event.ctrlKey || event.metaKey) {
8213                                                         $.datepicker._adjustDate(event.target, (isRTL ? -1 : +1), "D");
8214                                                 }
8215                                                 handled = event.ctrlKey || event.metaKey;
8216                                                 // +1 day on ctrl or command +right
8217                                                 if (event.originalEvent.altKey) {
8218                                                         $.datepicker._adjustDate(event.target, (event.ctrlKey ?
8219                                                                 +$.datepicker._get(inst, "stepBigMonths") :
8220                                                                 +$.datepicker._get(inst, "stepMonths")), "M");
8221                                                 }
8222                                                 // next month/year on alt +right
8223                                                 break;
8224                                 case 40: if (event.ctrlKey || event.metaKey) {
8225                                                         $.datepicker._adjustDate(event.target, +7, "D");
8226                                                 }
8227                                                 handled = event.ctrlKey || event.metaKey;
8228                                                 break; // +1 week on ctrl or command +down
8229                                 default: handled = false;
8230                         }
8231                 } else if (event.keyCode === 36 && event.ctrlKey) { // display the date picker on ctrl+home
8232                         $.datepicker._showDatepicker(this);
8233                 } else {
8234                         handled = false;
8235                 }
8236
8237                 if (handled) {
8238                         event.preventDefault();
8239                         event.stopPropagation();
8240                 }
8241         },
8242
8243         /* Filter entered characters - based on date format. */
8244         _doKeyPress: function(event) {
8245                 var chars, chr,
8246                         inst = $.datepicker._getInst(event.target);
8247
8248                 if ($.datepicker._get(inst, "constrainInput")) {
8249                         chars = $.datepicker._possibleChars($.datepicker._get(inst, "dateFormat"));
8250                         chr = String.fromCharCode(event.charCode == null ? event.keyCode : event.charCode);
8251                         return event.ctrlKey || event.metaKey || (chr < " " || !chars || chars.indexOf(chr) > -1);
8252                 }
8253         },
8254
8255         /* Synchronise manual entry and field/alternate field. */
8256         _doKeyUp: function(event) {
8257                 var date,
8258                         inst = $.datepicker._getInst(event.target);
8259
8260                 if (inst.input.val() !== inst.lastVal) {
8261                         try {
8262                                 date = $.datepicker.parseDate($.datepicker._get(inst, "dateFormat"),
8263                                         (inst.input ? inst.input.val() : null),
8264                                         $.datepicker._getFormatConfig(inst));
8265
8266                                 if (date) { // only if valid
8267                                         $.datepicker._setDateFromField(inst);
8268                                         $.datepicker._updateAlternate(inst);
8269                                         $.datepicker._updateDatepicker(inst);
8270                                 }
8271                         }
8272                         catch (err) {
8273                         }
8274                 }
8275                 return true;
8276         },
8277
8278         /* Pop-up the date picker for a given input field.
8279          * If false returned from beforeShow event handler do not show.
8280          * @param  input  element - the input field attached to the date picker or
8281          *                                      event - if triggered by focus
8282          */
8283         _showDatepicker: function(input) {
8284                 input = input.target || input;
8285                 if (input.nodeName.toLowerCase() !== "input") { // find from button/image trigger
8286                         input = $("input", input.parentNode)[0];
8287                 }
8288
8289                 if ($.datepicker._isDisabledDatepicker(input) || $.datepicker._lastInput === input) { // already here
8290                         return;
8291                 }
8292
8293                 var inst, beforeShow, beforeShowSettings, isFixed,
8294                         offset, showAnim, duration;
8295
8296                 inst = $.datepicker._getInst(input);
8297                 if ($.datepicker._curInst && $.datepicker._curInst !== inst) {
8298                         $.datepicker._curInst.dpDiv.stop(true, true);
8299                         if ( inst && $.datepicker._datepickerShowing ) {
8300                                 $.datepicker._hideDatepicker( $.datepicker._curInst.input[0] );
8301                         }
8302                 }
8303
8304                 beforeShow = $.datepicker._get(inst, "beforeShow");
8305                 beforeShowSettings = beforeShow ? beforeShow.apply(input, [input, inst]) : {};
8306                 if(beforeShowSettings === false){
8307                         return;
8308                 }
8309                 extendRemove(inst.settings, beforeShowSettings);
8310
8311                 inst.lastVal = null;
8312                 $.datepicker._lastInput = input;
8313                 $.datepicker._setDateFromField(inst);
8314
8315                 if ($.datepicker._inDialog) { // hide cursor
8316                         input.value = "";
8317                 }
8318                 if (!$.datepicker._pos) { // position below input
8319                         $.datepicker._pos = $.datepicker._findPos(input);
8320                         $.datepicker._pos[1] += input.offsetHeight; // add the height
8321                 }
8322
8323                 isFixed = false;
8324                 $(input).parents().each(function() {
8325                         isFixed |= $(this).css("position") === "fixed";
8326                         return !isFixed;
8327                 });
8328
8329                 offset = {left: $.datepicker._pos[0], top: $.datepicker._pos[1]};
8330                 $.datepicker._pos = null;
8331                 //to avoid flashes on Firefox
8332                 inst.dpDiv.empty();
8333                 // determine sizing offscreen
8334                 inst.dpDiv.css({position: "absolute", display: "block", top: "-1000px"});
8335                 $.datepicker._updateDatepicker(inst);
8336                 // fix width for dynamic number of date pickers
8337                 // and adjust position before showing
8338                 offset = $.datepicker._checkOffset(inst, offset, isFixed);
8339                 inst.dpDiv.css({position: ($.datepicker._inDialog && $.blockUI ?
8340                         "static" : (isFixed ? "fixed" : "absolute")), display: "none",
8341                         left: offset.left + "px", top: offset.top + "px"});
8342
8343                 if (!inst.inline) {
8344                         showAnim = $.datepicker._get(inst, "showAnim");
8345                         duration = $.datepicker._get(inst, "duration");
8346                         inst.dpDiv.zIndex($(input).zIndex()+1);
8347                         $.datepicker._datepickerShowing = true;
8348
8349                         if ( $.effects && $.effects.effect[ showAnim ] ) {
8350                                 inst.dpDiv.show(showAnim, $.datepicker._get(inst, "showOptions"), duration);
8351                         } else {
8352                                 inst.dpDiv[showAnim || "show"](showAnim ? duration : null);
8353                         }
8354
8355                         if ( $.datepicker._shouldFocusInput( inst ) ) {
8356                                 inst.input.focus();
8357                         }
8358
8359                         $.datepicker._curInst = inst;
8360                 }
8361         },
8362
8363         /* Generate the date picker content. */
8364         _updateDatepicker: function(inst) {
8365                 this.maxRows = 4; //Reset the max number of rows being displayed (see #7043)
8366                 instActive = inst; // for delegate hover events
8367                 inst.dpDiv.empty().append(this._generateHTML(inst));
8368                 this._attachHandlers(inst);
8369                 inst.dpDiv.find("." + this._dayOverClass + " a").mouseover();
8370
8371                 var origyearshtml,
8372                         numMonths = this._getNumberOfMonths(inst),
8373                         cols = numMonths[1],
8374                         width = 17;
8375
8376                 inst.dpDiv.removeClass("ui-datepicker-multi-2 ui-datepicker-multi-3 ui-datepicker-multi-4").width("");
8377                 if (cols > 1) {
8378                         inst.dpDiv.addClass("ui-datepicker-multi-" + cols).css("width", (width * cols) + "em");
8379                 }
8380                 inst.dpDiv[(numMonths[0] !== 1 || numMonths[1] !== 1 ? "add" : "remove") +
8381                         "Class"]("ui-datepicker-multi");
8382                 inst.dpDiv[(this._get(inst, "isRTL") ? "add" : "remove") +
8383                         "Class"]("ui-datepicker-rtl");
8384
8385                 if (inst === $.datepicker._curInst && $.datepicker._datepickerShowing && $.datepicker._shouldFocusInput( inst ) ) {
8386                         inst.input.focus();
8387                 }
8388
8389                 // deffered render of the years select (to avoid flashes on Firefox)
8390                 if( inst.yearshtml ){
8391                         origyearshtml = inst.yearshtml;
8392                         setTimeout(function(){
8393                                 //assure that inst.yearshtml didn't change.
8394                                 if( origyearshtml === inst.yearshtml && inst.yearshtml ){
8395                                         inst.dpDiv.find("select.ui-datepicker-year:first").replaceWith(inst.yearshtml);
8396                                 }
8397                                 origyearshtml = inst.yearshtml = null;
8398                         }, 0);
8399                 }
8400         },
8401
8402         // #6694 - don't focus the input if it's already focused
8403         // this breaks the change event in IE
8404         // Support: IE and jQuery <1.9
8405         _shouldFocusInput: function( inst ) {
8406                 return inst.input && inst.input.is( ":visible" ) && !inst.input.is( ":disabled" ) && !inst.input.is( ":focus" );
8407         },
8408
8409         /* Check positioning to remain on screen. */
8410         _checkOffset: function(inst, offset, isFixed) {
8411                 var dpWidth = inst.dpDiv.outerWidth(),
8412                         dpHeight = inst.dpDiv.outerHeight(),
8413                         inputWidth = inst.input ? inst.input.outerWidth() : 0,
8414                         inputHeight = inst.input ? inst.input.outerHeight() : 0,
8415                         viewWidth = document.documentElement.clientWidth + (isFixed ? 0 : $(document).scrollLeft()),
8416                         viewHeight = document.documentElement.clientHeight + (isFixed ? 0 : $(document).scrollTop());
8417
8418                 offset.left -= (this._get(inst, "isRTL") ? (dpWidth - inputWidth) : 0);
8419                 offset.left -= (isFixed && offset.left === inst.input.offset().left) ? $(document).scrollLeft() : 0;
8420                 offset.top -= (isFixed && offset.top === (inst.input.offset().top + inputHeight)) ? $(document).scrollTop() : 0;
8421
8422                 // now check if datepicker is showing outside window viewport - move to a better place if so.
8423                 offset.left -= Math.min(offset.left, (offset.left + dpWidth > viewWidth && viewWidth > dpWidth) ?
8424                         Math.abs(offset.left + dpWidth - viewWidth) : 0);
8425                 offset.top -= Math.min(offset.top, (offset.top + dpHeight > viewHeight && viewHeight > dpHeight) ?
8426                         Math.abs(dpHeight + inputHeight) : 0);
8427
8428                 return offset;
8429         },
8430
8431         /* Find an object's position on the screen. */
8432         _findPos: function(obj) {
8433                 var position,
8434                         inst = this._getInst(obj),
8435                         isRTL = this._get(inst, "isRTL");
8436
8437                 while (obj && (obj.type === "hidden" || obj.nodeType !== 1 || $.expr.filters.hidden(obj))) {
8438                         obj = obj[isRTL ? "previousSibling" : "nextSibling"];
8439                 }
8440
8441                 position = $(obj).offset();
8442                 return [position.left, position.top];
8443         },
8444
8445         /* Hide the date picker from view.
8446          * @param  input  element - the input field attached to the date picker
8447          */
8448         _hideDatepicker: function(input) {
8449                 var showAnim, duration, postProcess, onClose,
8450                         inst = this._curInst;
8451
8452                 if (!inst || (input && inst !== $.data(input, PROP_NAME))) {
8453                         return;
8454                 }
8455
8456                 if (this._datepickerShowing) {
8457                         showAnim = this._get(inst, "showAnim");
8458                         duration = this._get(inst, "duration");
8459                         postProcess = function() {
8460                                 $.datepicker._tidyDialog(inst);
8461                         };
8462
8463                         // DEPRECATED: after BC for 1.8.x $.effects[ showAnim ] is not needed
8464                         if ( $.effects && ( $.effects.effect[ showAnim ] || $.effects[ showAnim ] ) ) {
8465                                 inst.dpDiv.hide(showAnim, $.datepicker._get(inst, "showOptions"), duration, postProcess);
8466                         } else {
8467                                 inst.dpDiv[(showAnim === "slideDown" ? "slideUp" :
8468                                         (showAnim === "fadeIn" ? "fadeOut" : "hide"))]((showAnim ? duration : null), postProcess);
8469                         }
8470
8471                         if (!showAnim) {
8472                                 postProcess();
8473                         }
8474                         this._datepickerShowing = false;
8475
8476                         onClose = this._get(inst, "onClose");
8477                         if (onClose) {
8478                                 onClose.apply((inst.input ? inst.input[0] : null), [(inst.input ? inst.input.val() : ""), inst]);
8479                         }
8480
8481                         this._lastInput = null;
8482                         if (this._inDialog) {
8483                                 this._dialogInput.css({ position: "absolute", left: "0", top: "-100px" });
8484                                 if ($.blockUI) {
8485                                         $.unblockUI();
8486                                         $("body").append(this.dpDiv);
8487                                 }
8488                         }
8489                         this._inDialog = false;
8490                 }
8491         },
8492
8493         /* Tidy up after a dialog display. */
8494         _tidyDialog: function(inst) {
8495                 inst.dpDiv.removeClass(this._dialogClass).unbind(".ui-datepicker-calendar");
8496         },
8497
8498         /* Close date picker if clicked elsewhere. */
8499         _checkExternalClick: function(event) {
8500                 if (!$.datepicker._curInst) {
8501                         return;
8502                 }
8503
8504                 var $target = $(event.target),
8505                         inst = $.datepicker._getInst($target[0]);
8506
8507                 if ( ( ( $target[0].id !== $.datepicker._mainDivId &&
8508                                 $target.parents("#" + $.datepicker._mainDivId).length === 0 &&
8509                                 !$target.hasClass($.datepicker.markerClassName) &&
8510                                 !$target.closest("." + $.datepicker._triggerClass).length &&
8511                                 $.datepicker._datepickerShowing && !($.datepicker._inDialog && $.blockUI) ) ) ||
8512                         ( $target.hasClass($.datepicker.markerClassName) && $.datepicker._curInst !== inst ) ) {
8513                                 $.datepicker._hideDatepicker();
8514                 }
8515         },
8516
8517         /* Adjust one of the date sub-fields. */
8518         _adjustDate: function(id, offset, period) {
8519                 var target = $(id),
8520                         inst = this._getInst(target[0]);
8521
8522                 if (this._isDisabledDatepicker(target[0])) {
8523                         return;
8524                 }
8525                 this._adjustInstDate(inst, offset +
8526                         (period === "M" ? this._get(inst, "showCurrentAtPos") : 0), // undo positioning
8527                         period);
8528                 this._updateDatepicker(inst);
8529         },
8530
8531         /* Action for current link. */
8532         _gotoToday: function(id) {
8533                 var date,
8534                         target = $(id),
8535                         inst = this._getInst(target[0]);
8536
8537                 if (this._get(inst, "gotoCurrent") && inst.currentDay) {
8538                         inst.selectedDay = inst.currentDay;
8539                         inst.drawMonth = inst.selectedMonth = inst.currentMonth;
8540                         inst.drawYear = inst.selectedYear = inst.currentYear;
8541                 } else {
8542                         date = new Date();
8543                         inst.selectedDay = date.getDate();
8544                         inst.drawMonth = inst.selectedMonth = date.getMonth();
8545                         inst.drawYear = inst.selectedYear = date.getFullYear();
8546                 }
8547                 this._notifyChange(inst);
8548                 this._adjustDate(target);
8549         },
8550
8551         /* Action for selecting a new month/year. */
8552         _selectMonthYear: function(id, select, period) {
8553                 var target = $(id),
8554                         inst = this._getInst(target[0]);
8555
8556                 inst["selected" + (period === "M" ? "Month" : "Year")] =
8557                 inst["draw" + (period === "M" ? "Month" : "Year")] =
8558                         parseInt(select.options[select.selectedIndex].value,10);
8559
8560                 this._notifyChange(inst);
8561                 this._adjustDate(target);
8562         },
8563
8564         /* Action for selecting a day. */
8565         _selectDay: function(id, month, year, td) {
8566                 var inst,
8567                         target = $(id);
8568
8569                 if ($(td).hasClass(this._unselectableClass) || this._isDisabledDatepicker(target[0])) {
8570                         return;
8571                 }
8572
8573                 inst = this._getInst(target[0]);
8574                 inst.selectedDay = inst.currentDay = $("a", td).html();
8575                 inst.selectedMonth = inst.currentMonth = month;
8576                 inst.selectedYear = inst.currentYear = year;
8577                 this._selectDate(id, this._formatDate(inst,
8578                         inst.currentDay, inst.currentMonth, inst.currentYear));
8579         },
8580
8581         /* Erase the input field and hide the date picker. */
8582         _clearDate: function(id) {
8583                 var target = $(id);
8584                 this._selectDate(target, "");
8585         },
8586
8587         /* Update the input field with the selected date. */
8588         _selectDate: function(id, dateStr) {
8589                 var onSelect,
8590                         target = $(id),
8591                         inst = this._getInst(target[0]);
8592
8593                 dateStr = (dateStr != null ? dateStr : this._formatDate(inst));
8594                 if (inst.input) {
8595                         inst.input.val(dateStr);
8596                 }
8597                 this._updateAlternate(inst);
8598
8599                 onSelect = this._get(inst, "onSelect");
8600                 if (onSelect) {
8601                         onSelect.apply((inst.input ? inst.input[0] : null), [dateStr, inst]);  // trigger custom callback
8602                 } else if (inst.input) {
8603                         inst.input.trigger("change"); // fire the change event
8604                 }
8605
8606                 if (inst.inline){
8607                         this._updateDatepicker(inst);
8608                 } else {
8609                         this._hideDatepicker();
8610                         this._lastInput = inst.input[0];
8611                         if (typeof(inst.input[0]) !== "object") {
8612                                 inst.input.focus(); // restore focus
8613                         }
8614                         this._lastInput = null;
8615                 }
8616         },
8617
8618         /* Update any alternate field to synchronise with the main field. */
8619         _updateAlternate: function(inst) {
8620                 var altFormat, date, dateStr,
8621                         altField = this._get(inst, "altField");
8622
8623                 if (altField) { // update alternate field too
8624                         altFormat = this._get(inst, "altFormat") || this._get(inst, "dateFormat");
8625                         date = this._getDate(inst);
8626                         dateStr = this.formatDate(altFormat, date, this._getFormatConfig(inst));
8627                         $(altField).each(function() { $(this).val(dateStr); });
8628                 }
8629         },
8630
8631         /* Set as beforeShowDay function to prevent selection of weekends.
8632          * @param  date  Date - the date to customise
8633          * @return [boolean, string] - is this date selectable?, what is its CSS class?
8634          */
8635         noWeekends: function(date) {
8636                 var day = date.getDay();
8637                 return [(day > 0 && day < 6), ""];
8638         },
8639
8640         /* Set as calculateWeek to determine the week of the year based on the ISO 8601 definition.
8641          * @param  date  Date - the date to get the week for
8642          * @return  number - the number of the week within the year that contains this date
8643          */
8644         iso8601Week: function(date) {
8645                 var time,
8646                         checkDate = new Date(date.getTime());
8647
8648                 // Find Thursday of this week starting on Monday
8649                 checkDate.setDate(checkDate.getDate() + 4 - (checkDate.getDay() || 7));
8650
8651                 time = checkDate.getTime();
8652                 checkDate.setMonth(0); // Compare with Jan 1
8653                 checkDate.setDate(1);
8654                 return Math.floor(Math.round((time - checkDate) / 86400000) / 7) + 1;
8655         },
8656
8657         /* Parse a string value into a date object.
8658          * See formatDate below for the possible formats.
8659          *
8660          * @param  format string - the expected format of the date
8661          * @param  value string - the date in the above format
8662          * @param  settings Object - attributes include:
8663          *                                      shortYearCutoff  number - the cutoff year for determining the century (optional)
8664          *                                      dayNamesShort   string[7] - abbreviated names of the days from Sunday (optional)
8665          *                                      dayNames                string[7] - names of the days from Sunday (optional)
8666          *                                      monthNamesShort string[12] - abbreviated names of the months (optional)
8667          *                                      monthNames              string[12] - names of the months (optional)
8668          * @return  Date - the extracted date value or null if value is blank
8669          */
8670         parseDate: function (format, value, settings) {
8671                 if (format == null || value == null) {
8672                         throw "Invalid arguments";
8673                 }
8674
8675                 value = (typeof value === "object" ? value.toString() : value + "");
8676                 if (value === "") {
8677                         return null;
8678                 }
8679
8680                 var iFormat, dim, extra,
8681                         iValue = 0,
8682                         shortYearCutoffTemp = (settings ? settings.shortYearCutoff : null) || this._defaults.shortYearCutoff,
8683                         shortYearCutoff = (typeof shortYearCutoffTemp !== "string" ? shortYearCutoffTemp :
8684                                 new Date().getFullYear() % 100 + parseInt(shortYearCutoffTemp, 10)),
8685                         dayNamesShort = (settings ? settings.dayNamesShort : null) || this._defaults.dayNamesShort,
8686                         dayNames = (settings ? settings.dayNames : null) || this._defaults.dayNames,
8687                         monthNamesShort = (settings ? settings.monthNamesShort : null) || this._defaults.monthNamesShort,
8688                         monthNames = (settings ? settings.monthNames : null) || this._defaults.monthNames,
8689                         year = -1,
8690                         month = -1,
8691                         day = -1,
8692                         doy = -1,
8693                         literal = false,
8694                         date,
8695                         // Check whether a format character is doubled
8696                         lookAhead = function(match) {
8697                                 var matches = (iFormat + 1 < format.length && format.charAt(iFormat + 1) === match);
8698                                 if (matches) {
8699                                         iFormat++;
8700                                 }
8701                                 return matches;
8702                         },
8703                         // Extract a number from the string value
8704                         getNumber = function(match) {
8705                                 var isDoubled = lookAhead(match),
8706                                         size = (match === "@" ? 14 : (match === "!" ? 20 :
8707                                         (match === "y" && isDoubled ? 4 : (match === "o" ? 3 : 2)))),
8708                                         digits = new RegExp("^\\d{1," + size + "}"),
8709                                         num = value.substring(iValue).match(digits);
8710                                 if (!num) {
8711                                         throw "Missing number at position " + iValue;
8712                                 }
8713                                 iValue += num[0].length;
8714                                 return parseInt(num[0], 10);
8715                         },
8716                         // Extract a name from the string value and convert to an index
8717                         getName = function(match, shortNames, longNames) {
8718                                 var index = -1,
8719                                         names = $.map(lookAhead(match) ? longNames : shortNames, function (v, k) {
8720                                                 return [ [k, v] ];
8721                                         }).sort(function (a, b) {
8722                                                 return -(a[1].length - b[1].length);
8723                                         });
8724
8725                                 $.each(names, function (i, pair) {
8726                                         var name = pair[1];
8727                                         if (value.substr(iValue, name.length).toLowerCase() === name.toLowerCase()) {
8728                                                 index = pair[0];
8729                                                 iValue += name.length;
8730                                                 return false;
8731                                         }
8732                                 });
8733                                 if (index !== -1) {
8734                                         return index + 1;
8735                                 } else {
8736                                         throw "Unknown name at position " + iValue;
8737                                 }
8738                         },
8739                         // Confirm that a literal character matches the string value
8740                         checkLiteral = function() {
8741                                 if (value.charAt(iValue) !== format.charAt(iFormat)) {
8742                                         throw "Unexpected literal at position " + iValue;
8743                                 }
8744                                 iValue++;
8745                         };
8746
8747                 for (iFormat = 0; iFormat < format.length; iFormat++) {
8748                         if (literal) {
8749                                 if (format.charAt(iFormat) === "'" && !lookAhead("'")) {
8750                                         literal = false;
8751                                 } else {
8752                                         checkLiteral();
8753                                 }
8754                         } else {
8755                                 switch (format.charAt(iFormat)) {
8756                                         case "d":
8757                                                 day = getNumber("d");
8758                                                 break;
8759                                         case "D":
8760                                                 getName("D", dayNamesShort, dayNames);
8761                                                 break;
8762                                         case "o":
8763                                                 doy = getNumber("o");
8764                                                 break;
8765                                         case "m":
8766                                                 month = getNumber("m");
8767                                                 break;
8768                                         case "M":
8769                                                 month = getName("M", monthNamesShort, monthNames);
8770                                                 break;
8771                                         case "y":
8772                                                 year = getNumber("y");
8773                                                 break;
8774                                         case "@":
8775                                                 date = new Date(getNumber("@"));
8776                                                 year = date.getFullYear();
8777                                                 month = date.getMonth() + 1;
8778                                                 day = date.getDate();
8779                                                 break;
8780                                         case "!":
8781                                                 date = new Date((getNumber("!") - this._ticksTo1970) / 10000);
8782                                                 year = date.getFullYear();
8783                                                 month = date.getMonth() + 1;
8784                                                 day = date.getDate();
8785                                                 break;
8786                                         case "'":
8787                                                 if (lookAhead("'")){
8788                                                         checkLiteral();
8789                                                 } else {
8790                                                         literal = true;
8791                                                 }
8792                                                 break;
8793                                         default:
8794                                                 checkLiteral();
8795                                 }
8796                         }
8797                 }
8798
8799                 if (iValue < value.length){
8800                         extra = value.substr(iValue);
8801                         if (!/^\s+/.test(extra)) {
8802                                 throw "Extra/unparsed characters found in date: " + extra;
8803                         }
8804                 }
8805
8806                 if (year === -1) {
8807                         year = new Date().getFullYear();
8808                 } else if (year < 100) {
8809                         year += new Date().getFullYear() - new Date().getFullYear() % 100 +
8810                                 (year <= shortYearCutoff ? 0 : -100);
8811                 }
8812
8813                 if (doy > -1) {
8814                         month = 1;
8815                         day = doy;
8816                         do {
8817                                 dim = this._getDaysInMonth(year, month - 1);
8818                                 if (day <= dim) {
8819                                         break;
8820                                 }
8821                                 month++;
8822                                 day -= dim;
8823                         } while (true);
8824                 }
8825
8826                 date = this._daylightSavingAdjust(new Date(year, month - 1, day));
8827                 if (date.getFullYear() !== year || date.getMonth() + 1 !== month || date.getDate() !== day) {
8828                         throw "Invalid date"; // E.g. 31/02/00
8829                 }
8830                 return date;
8831         },
8832
8833         /* Standard date formats. */
8834         ATOM: "yy-mm-dd", // RFC 3339 (ISO 8601)
8835         COOKIE: "D, dd M yy",
8836         ISO_8601: "yy-mm-dd",
8837         RFC_822: "D, d M y",
8838         RFC_850: "DD, dd-M-y",
8839         RFC_1036: "D, d M y",
8840         RFC_1123: "D, d M yy",
8841         RFC_2822: "D, d M yy",
8842         RSS: "D, d M y", // RFC 822
8843         TICKS: "!",
8844         TIMESTAMP: "@",
8845         W3C: "yy-mm-dd", // ISO 8601
8846
8847         _ticksTo1970: (((1970 - 1) * 365 + Math.floor(1970 / 4) - Math.floor(1970 / 100) +
8848                 Math.floor(1970 / 400)) * 24 * 60 * 60 * 10000000),
8849
8850         /* Format a date object into a string value.
8851          * The format can be combinations of the following:
8852          * d  - day of month (no leading zero)
8853          * dd - day of month (two digit)
8854          * o  - day of year (no leading zeros)
8855          * oo - day of year (three digit)
8856          * D  - day name short
8857          * DD - day name long
8858          * m  - month of year (no leading zero)
8859          * mm - month of year (two digit)
8860          * M  - month name short
8861          * MM - month name long
8862          * y  - year (two digit)
8863          * yy - year (four digit)
8864          * @ - Unix timestamp (ms since 01/01/1970)
8865          * ! - Windows ticks (100ns since 01/01/0001)
8866          * "..." - literal text
8867          * '' - single quote
8868          *
8869          * @param  format string - the desired format of the date
8870          * @param  date Date - the date value to format
8871          * @param  settings Object - attributes include:
8872          *                                      dayNamesShort   string[7] - abbreviated names of the days from Sunday (optional)
8873          *                                      dayNames                string[7] - names of the days from Sunday (optional)
8874          *                                      monthNamesShort string[12] - abbreviated names of the months (optional)
8875          *                                      monthNames              string[12] - names of the months (optional)
8876          * @return  string - the date in the above format
8877          */
8878         formatDate: function (format, date, settings) {
8879                 if (!date) {
8880                         return "";
8881                 }
8882
8883                 var iFormat,
8884                         dayNamesShort = (settings ? settings.dayNamesShort : null) || this._defaults.dayNamesShort,
8885                         dayNames = (settings ? settings.dayNames : null) || this._defaults.dayNames,
8886                         monthNamesShort = (settings ? settings.monthNamesShort : null) || this._defaults.monthNamesShort,
8887                         monthNames = (settings ? settings.monthNames : null) || this._defaults.monthNames,
8888                         // Check whether a format character is doubled
8889                         lookAhead = function(match) {
8890                                 var matches = (iFormat + 1 < format.length && format.charAt(iFormat + 1) === match);
8891                                 if (matches) {
8892                                         iFormat++;
8893                                 }
8894                                 return matches;
8895                         },
8896                         // Format a number, with leading zero if necessary
8897                         formatNumber = function(match, value, len) {
8898                                 var num = "" + value;
8899                                 if (lookAhead(match)) {
8900                                         while (num.length < len) {
8901                                                 num = "0" + num;
8902                                         }
8903                                 }
8904                                 return num;
8905                         },
8906                         // Format a name, short or long as requested
8907                         formatName = function(match, value, shortNames, longNames) {
8908                                 return (lookAhead(match) ? longNames[value] : shortNames[value]);
8909                         },
8910                         output = "",
8911                         literal = false;
8912
8913                 if (date) {
8914                         for (iFormat = 0; iFormat < format.length; iFormat++) {
8915                                 if (literal) {
8916                                         if (format.charAt(iFormat) === "'" && !lookAhead("'")) {
8917                                                 literal = false;
8918                                         } else {
8919                                                 output += format.charAt(iFormat);
8920                                         }
8921                                 } else {
8922                                         switch (format.charAt(iFormat)) {
8923                                                 case "d":
8924                                                         output += formatNumber("d", date.getDate(), 2);
8925                                                         break;
8926                                                 case "D":
8927                                                         output += formatName("D", date.getDay(), dayNamesShort, dayNames);
8928                                                         break;
8929                                                 case "o":
8930                                                         output += formatNumber("o",
8931                                                                 Math.round((new Date(date.getFullYear(), date.getMonth(), date.getDate()).getTime() - new Date(date.getFullYear(), 0, 0).getTime()) / 86400000), 3);
8932                                                         break;
8933                                                 case "m":
8934                                                         output += formatNumber("m", date.getMonth() + 1, 2);
8935                                                         break;
8936                                                 case "M":
8937                                                         output += formatName("M", date.getMonth(), monthNamesShort, monthNames);
8938                                                         break;
8939                                                 case "y":
8940                                                         output += (lookAhead("y") ? date.getFullYear() :
8941                                                                 (date.getYear() % 100 < 10 ? "0" : "") + date.getYear() % 100);
8942                                                         break;
8943                                                 case "@":
8944                                                         output += date.getTime();
8945                                                         break;
8946                                                 case "!":
8947                                                         output += date.getTime() * 10000 + this._ticksTo1970;
8948                                                         break;
8949                                                 case "'":
8950                                                         if (lookAhead("'")) {
8951                                                                 output += "'";
8952                                                         } else {
8953                                                                 literal = true;
8954                                                         }
8955                                                         break;
8956                                                 default:
8957                                                         output += format.charAt(iFormat);
8958                                         }
8959                                 }
8960                         }
8961                 }
8962                 return output;
8963         },
8964
8965         /* Extract all possible characters from the date format. */
8966         _possibleChars: function (format) {
8967                 var iFormat,
8968                         chars = "",
8969                         literal = false,
8970                         // Check whether a format character is doubled
8971                         lookAhead = function(match) {
8972                                 var matches = (iFormat + 1 < format.length && format.charAt(iFormat + 1) === match);
8973                                 if (matches) {
8974                                         iFormat++;
8975                                 }
8976                                 return matches;
8977                         };
8978
8979                 for (iFormat = 0; iFormat < format.length; iFormat++) {
8980                         if (literal) {
8981                                 if (format.charAt(iFormat) === "'" && !lookAhead("'")) {
8982                                         literal = false;
8983                                 } else {
8984                                         chars += format.charAt(iFormat);
8985                                 }
8986                         } else {
8987                                 switch (format.charAt(iFormat)) {
8988                                         case "d": case "m": case "y": case "@":
8989                                                 chars += "0123456789";
8990                                                 break;
8991                                         case "D": case "M":
8992                                                 return null; // Accept anything
8993                                         case "'":
8994                                                 if (lookAhead("'")) {
8995                                                         chars += "'";
8996                                                 } else {
8997                                                         literal = true;
8998                                                 }
8999                                                 break;
9000                                         default:
9001                                                 chars += format.charAt(iFormat);
9002                                 }
9003                         }
9004                 }
9005                 return chars;
9006         },
9007
9008         /* Get a setting value, defaulting if necessary. */
9009         _get: function(inst, name) {
9010                 return inst.settings[name] !== undefined ?
9011                         inst.settings[name] : this._defaults[name];
9012         },
9013
9014         /* Parse existing date and initialise date picker. */
9015         _setDateFromField: function(inst, noDefault) {
9016                 if (inst.input.val() === inst.lastVal) {
9017                         return;
9018                 }
9019
9020                 var dateFormat = this._get(inst, "dateFormat"),
9021                         dates = inst.lastVal = inst.input ? inst.input.val() : null,
9022                         defaultDate = this._getDefaultDate(inst),
9023                         date = defaultDate,
9024                         settings = this._getFormatConfig(inst);
9025
9026                 try {
9027                         date = this.parseDate(dateFormat, dates, settings) || defaultDate;
9028                 } catch (event) {
9029                         dates = (noDefault ? "" : dates);
9030                 }
9031                 inst.selectedDay = date.getDate();
9032                 inst.drawMonth = inst.selectedMonth = date.getMonth();
9033                 inst.drawYear = inst.selectedYear = date.getFullYear();
9034                 inst.currentDay = (dates ? date.getDate() : 0);
9035                 inst.currentMonth = (dates ? date.getMonth() : 0);
9036                 inst.currentYear = (dates ? date.getFullYear() : 0);
9037                 this._adjustInstDate(inst);
9038         },
9039
9040         /* Retrieve the default date shown on opening. */
9041         _getDefaultDate: function(inst) {
9042                 return this._restrictMinMax(inst,
9043                         this._determineDate(inst, this._get(inst, "defaultDate"), new Date()));
9044         },
9045
9046         /* A date may be specified as an exact value or a relative one. */
9047         _determineDate: function(inst, date, defaultDate) {
9048                 var offsetNumeric = function(offset) {
9049                                 var date = new Date();
9050                                 date.setDate(date.getDate() + offset);
9051                                 return date;
9052                         },
9053                         offsetString = function(offset) {
9054                                 try {
9055                                         return $.datepicker.parseDate($.datepicker._get(inst, "dateFormat"),
9056                                                 offset, $.datepicker._getFormatConfig(inst));
9057                                 }
9058                                 catch (e) {
9059                                         // Ignore
9060                                 }
9061
9062                                 var date = (offset.toLowerCase().match(/^c/) ?
9063                                         $.datepicker._getDate(inst) : null) || new Date(),
9064                                         year = date.getFullYear(),
9065                                         month = date.getMonth(),
9066                                         day = date.getDate(),
9067                                         pattern = /([+\-]?[0-9]+)\s*(d|D|w|W|m|M|y|Y)?/g,
9068                                         matches = pattern.exec(offset);
9069
9070                                 while (matches) {
9071                                         switch (matches[2] || "d") {
9072                                                 case "d" : case "D" :
9073                                                         day += parseInt(matches[1],10); break;
9074                                                 case "w" : case "W" :
9075                                                         day += parseInt(matches[1],10) * 7; break;
9076                                                 case "m" : case "M" :
9077                                                         month += parseInt(matches[1],10);
9078                                                         day = Math.min(day, $.datepicker._getDaysInMonth(year, month));
9079                                                         break;
9080                                                 case "y": case "Y" :
9081                                                         year += parseInt(matches[1],10);
9082                                                         day = Math.min(day, $.datepicker._getDaysInMonth(year, month));
9083                                                         break;
9084                                         }
9085                                         matches = pattern.exec(offset);
9086                                 }
9087                                 return new Date(year, month, day);
9088                         },
9089                         newDate = (date == null || date === "" ? defaultDate : (typeof date === "string" ? offsetString(date) :
9090                                 (typeof date === "number" ? (isNaN(date) ? defaultDate : offsetNumeric(date)) : new Date(date.getTime()))));
9091
9092                 newDate = (newDate && newDate.toString() === "Invalid Date" ? defaultDate : newDate);
9093                 if (newDate) {
9094                         newDate.setHours(0);
9095                         newDate.setMinutes(0);
9096                         newDate.setSeconds(0);
9097                         newDate.setMilliseconds(0);
9098                 }
9099                 return this._daylightSavingAdjust(newDate);
9100         },
9101
9102         /* Handle switch to/from daylight saving.
9103          * Hours may be non-zero on daylight saving cut-over:
9104          * > 12 when midnight changeover, but then cannot generate
9105          * midnight datetime, so jump to 1AM, otherwise reset.
9106          * @param  date  (Date) the date to check
9107          * @return  (Date) the corrected date
9108          */
9109         _daylightSavingAdjust: function(date) {
9110                 if (!date) {
9111                         return null;
9112                 }
9113                 date.setHours(date.getHours() > 12 ? date.getHours() + 2 : 0);
9114                 return date;
9115         },
9116
9117         /* Set the date(s) directly. */
9118         _setDate: function(inst, date, noChange) {
9119                 var clear = !date,
9120                         origMonth = inst.selectedMonth,
9121                         origYear = inst.selectedYear,
9122                         newDate = this._restrictMinMax(inst, this._determineDate(inst, date, new Date()));
9123
9124                 inst.selectedDay = inst.currentDay = newDate.getDate();
9125                 inst.drawMonth = inst.selectedMonth = inst.currentMonth = newDate.getMonth();
9126                 inst.drawYear = inst.selectedYear = inst.currentYear = newDate.getFullYear();
9127                 if ((origMonth !== inst.selectedMonth || origYear !== inst.selectedYear) && !noChange) {
9128                         this._notifyChange(inst);
9129                 }
9130                 this._adjustInstDate(inst);
9131                 if (inst.input) {
9132                         inst.input.val(clear ? "" : this._formatDate(inst));
9133                 }
9134         },
9135
9136         /* Retrieve the date(s) directly. */
9137         _getDate: function(inst) {
9138                 var startDate = (!inst.currentYear || (inst.input && inst.input.val() === "") ? null :
9139                         this._daylightSavingAdjust(new Date(
9140                         inst.currentYear, inst.currentMonth, inst.currentDay)));
9141                         return startDate;
9142         },
9143
9144         /* Attach the onxxx handlers.  These are declared statically so
9145          * they work with static code transformers like Caja.
9146          */
9147         _attachHandlers: function(inst) {
9148                 var stepMonths = this._get(inst, "stepMonths"),
9149                         id = "#" + inst.id.replace( /\\\\/g, "\\" );
9150                 inst.dpDiv.find("[data-handler]").map(function () {
9151                         var handler = {
9152                                 prev: function () {
9153                                         $.datepicker._adjustDate(id, -stepMonths, "M");
9154                                 },
9155                                 next: function () {
9156                                         $.datepicker._adjustDate(id, +stepMonths, "M");
9157                                 },
9158                                 hide: function () {
9159                                         $.datepicker._hideDatepicker();
9160                                 },
9161                                 today: function () {
9162                                         $.datepicker._gotoToday(id);
9163                                 },
9164                                 selectDay: function () {
9165                                         $.datepicker._selectDay(id, +this.getAttribute("data-month"), +this.getAttribute("data-year"), this);
9166                                         return false;
9167                                 },
9168                                 selectMonth: function () {
9169                                         $.datepicker._selectMonthYear(id, this, "M");
9170                                         return false;
9171                                 },
9172                                 selectYear: function () {
9173                                         $.datepicker._selectMonthYear(id, this, "Y");
9174                                         return false;
9175                                 }
9176                         };
9177                         $(this).bind(this.getAttribute("data-event"), handler[this.getAttribute("data-handler")]);
9178                 });
9179         },
9180
9181         /* Generate the HTML for the current state of the date picker. */
9182         _generateHTML: function(inst) {
9183                 var maxDraw, prevText, prev, nextText, next, currentText, gotoDate,
9184                         controls, buttonPanel, firstDay, showWeek, dayNames, dayNamesMin,
9185                         monthNames, monthNamesShort, beforeShowDay, showOtherMonths,
9186                         selectOtherMonths, defaultDate, html, dow, row, group, col, selectedDate,
9187                         cornerClass, calender, thead, day, daysInMonth, leadDays, curRows, numRows,
9188                         printDate, dRow, tbody, daySettings, otherMonth, unselectable,
9189                         tempDate = new Date(),
9190                         today = this._daylightSavingAdjust(
9191                                 new Date(tempDate.getFullYear(), tempDate.getMonth(), tempDate.getDate())), // clear time
9192                         isRTL = this._get(inst, "isRTL"),
9193                         showButtonPanel = this._get(inst, "showButtonPanel"),
9194                         hideIfNoPrevNext = this._get(inst, "hideIfNoPrevNext"),
9195                         navigationAsDateFormat = this._get(inst, "navigationAsDateFormat"),
9196                         numMonths = this._getNumberOfMonths(inst),
9197                         showCurrentAtPos = this._get(inst, "showCurrentAtPos"),
9198                         stepMonths = this._get(inst, "stepMonths"),
9199                         isMultiMonth = (numMonths[0] !== 1 || numMonths[1] !== 1),
9200                         currentDate = this._daylightSavingAdjust((!inst.currentDay ? new Date(9999, 9, 9) :
9201                                 new Date(inst.currentYear, inst.currentMonth, inst.currentDay))),
9202                         minDate = this._getMinMaxDate(inst, "min"),
9203                         maxDate = this._getMinMaxDate(inst, "max"),
9204                         drawMonth = inst.drawMonth - showCurrentAtPos,
9205                         drawYear = inst.drawYear;
9206
9207                 if (drawMonth < 0) {
9208                         drawMonth += 12;
9209                         drawYear--;
9210                 }
9211                 if (maxDate) {
9212                         maxDraw = this._daylightSavingAdjust(new Date(maxDate.getFullYear(),
9213                                 maxDate.getMonth() - (numMonths[0] * numMonths[1]) + 1, maxDate.getDate()));
9214                         maxDraw = (minDate && maxDraw < minDate ? minDate : maxDraw);
9215                         while (this._daylightSavingAdjust(new Date(drawYear, drawMonth, 1)) > maxDraw) {
9216                                 drawMonth--;
9217                                 if (drawMonth < 0) {
9218                                         drawMonth = 11;
9219                                         drawYear--;
9220                                 }
9221                         }
9222                 }
9223                 inst.drawMonth = drawMonth;
9224                 inst.drawYear = drawYear;
9225
9226                 prevText = this._get(inst, "prevText");
9227                 prevText = (!navigationAsDateFormat ? prevText : this.formatDate(prevText,
9228                         this._daylightSavingAdjust(new Date(drawYear, drawMonth - stepMonths, 1)),
9229                         this._getFormatConfig(inst)));
9230
9231                 prev = (this._canAdjustMonth(inst, -1, drawYear, drawMonth) ?
9232                         "<a class='ui-datepicker-prev ui-corner-all' data-handler='prev' data-event='click'" +
9233                         " title='" + prevText + "'><span class='ui-icon ui-icon-circle-triangle-" + ( isRTL ? "e" : "w") + "'>" + prevText + "</span></a>" :
9234                         (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>"));
9235
9236                 nextText = this._get(inst, "nextText");
9237                 nextText = (!navigationAsDateFormat ? nextText : this.formatDate(nextText,
9238                         this._daylightSavingAdjust(new Date(drawYear, drawMonth + stepMonths, 1)),
9239                         this._getFormatConfig(inst)));
9240
9241                 next = (this._canAdjustMonth(inst, +1, drawYear, drawMonth) ?
9242                         "<a class='ui-datepicker-next ui-corner-all' data-handler='next' data-event='click'" +
9243                         " title='" + nextText + "'><span class='ui-icon ui-icon-circle-triangle-" + ( isRTL ? "w" : "e") + "'>" + nextText + "</span></a>" :
9244                         (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>"));
9245
9246                 currentText = this._get(inst, "currentText");
9247                 gotoDate = (this._get(inst, "gotoCurrent") && inst.currentDay ? currentDate : today);
9248                 currentText = (!navigationAsDateFormat ? currentText :
9249                         this.formatDate(currentText, gotoDate, this._getFormatConfig(inst)));
9250
9251                 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'>" +
9252                         this._get(inst, "closeText") + "</button>" : "");
9253
9254                 buttonPanel = (showButtonPanel) ? "<div class='ui-datepicker-buttonpane ui-widget-content'>" + (isRTL ? controls : "") +
9255                         (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'" +
9256                         ">" + currentText + "</button>" : "") + (isRTL ? "" : controls) + "</div>" : "";
9257
9258                 firstDay = parseInt(this._get(inst, "firstDay"),10);
9259                 firstDay = (isNaN(firstDay) ? 0 : firstDay);
9260
9261                 showWeek = this._get(inst, "showWeek");
9262                 dayNames = this._get(inst, "dayNames");
9263                 dayNamesMin = this._get(inst, "dayNamesMin");
9264                 monthNames = this._get(inst, "monthNames");
9265                 monthNamesShort = this._get(inst, "monthNamesShort");
9266                 beforeShowDay = this._get(inst, "beforeShowDay");
9267                 showOtherMonths = this._get(inst, "showOtherMonths");
9268                 selectOtherMonths = this._get(inst, "selectOtherMonths");
9269                 defaultDate = this._getDefaultDate(inst);
9270                 html = "";
9271                 dow;
9272                 for (row = 0; row < numMonths[0]; row++) {
9273                         group = "";
9274                         this.maxRows = 4;
9275                         for (col = 0; col < numMonths[1]; col++) {
9276                                 selectedDate = this._daylightSavingAdjust(new Date(drawYear, drawMonth, inst.selectedDay));
9277                                 cornerClass = " ui-corner-all";
9278                                 calender = "";
9279                                 if (isMultiMonth) {
9280                                         calender += "<div class='ui-datepicker-group";
9281                                         if (numMonths[1] > 1) {
9282                                                 switch (col) {
9283                                                         case 0: calender += " ui-datepicker-group-first";
9284                                                                 cornerClass = " ui-corner-" + (isRTL ? "right" : "left"); break;
9285                                                         case numMonths[1]-1: calender += " ui-datepicker-group-last";
9286                                                                 cornerClass = " ui-corner-" + (isRTL ? "left" : "right"); break;
9287                                                         default: calender += " ui-datepicker-group-middle"; cornerClass = ""; break;
9288                                                 }
9289                                         }
9290                                         calender += "'>";
9291                                 }
9292                                 calender += "<div class='ui-datepicker-header ui-widget-header ui-helper-clearfix" + cornerClass + "'>" +
9293                                         (/all|left/.test(cornerClass) && row === 0 ? (isRTL ? next : prev) : "") +
9294                                         (/all|right/.test(cornerClass) && row === 0 ? (isRTL ? prev : next) : "") +
9295                                         this._generateMonthYearHeader(inst, drawMonth, drawYear, minDate, maxDate,
9296                                         row > 0 || col > 0, monthNames, monthNamesShort) + // draw month headers
9297                                         "</div><table class='ui-datepicker-calendar'><thead>" +
9298                                         "<tr>";
9299                                 thead = (showWeek ? "<th class='ui-datepicker-week-col'>" + this._get(inst, "weekHeader") + "</th>" : "");
9300                                 for (dow = 0; dow < 7; dow++) { // days of the week
9301                                         day = (dow + firstDay) % 7;
9302                                         thead += "<th" + ((dow + firstDay + 6) % 7 >= 5 ? " class='ui-datepicker-week-end'" : "") + ">" +
9303                                                 "<span title='" + dayNames[day] + "'>" + dayNamesMin[day] + "</span></th>";
9304                                 }
9305                                 calender += thead + "</tr></thead><tbody>";
9306                                 daysInMonth = this._getDaysInMonth(drawYear, drawMonth);
9307                                 if (drawYear === inst.selectedYear && drawMonth === inst.selectedMonth) {
9308                                         inst.selectedDay = Math.min(inst.selectedDay, daysInMonth);
9309                                 }
9310                                 leadDays = (this._getFirstDayOfMonth(drawYear, drawMonth) - firstDay + 7) % 7;
9311                                 curRows = Math.ceil((leadDays + daysInMonth) / 7); // calculate the number of rows to generate
9312                                 numRows = (isMultiMonth ? this.maxRows > curRows ? this.maxRows : curRows : curRows); //If multiple months, use the higher number of rows (see #7043)
9313                                 this.maxRows = numRows;
9314                                 printDate = this._daylightSavingAdjust(new Date(drawYear, drawMonth, 1 - leadDays));
9315                                 for (dRow = 0; dRow < numRows; dRow++) { // create date picker rows
9316                                         calender += "<tr>";
9317                                         tbody = (!showWeek ? "" : "<td class='ui-datepicker-week-col'>" +
9318                                                 this._get(inst, "calculateWeek")(printDate) + "</td>");
9319                                         for (dow = 0; dow < 7; dow++) { // create date picker days
9320                                                 daySettings = (beforeShowDay ?
9321                                                         beforeShowDay.apply((inst.input ? inst.input[0] : null), [printDate]) : [true, ""]);
9322                                                 otherMonth = (printDate.getMonth() !== drawMonth);
9323                                                 unselectable = (otherMonth && !selectOtherMonths) || !daySettings[0] ||
9324                                                         (minDate && printDate < minDate) || (maxDate && printDate > maxDate);
9325                                                 tbody += "<td class='" +
9326                                                         ((dow + firstDay + 6) % 7 >= 5 ? " ui-datepicker-week-end" : "") + // highlight weekends
9327                                                         (otherMonth ? " ui-datepicker-other-month" : "") + // highlight days from other months
9328                                                         ((printDate.getTime() === selectedDate.getTime() && drawMonth === inst.selectedMonth && inst._keyEvent) || // user pressed key
9329                                                         (defaultDate.getTime() === printDate.getTime() && defaultDate.getTime() === selectedDate.getTime()) ?
9330                                                         // or defaultDate is current printedDate and defaultDate is selectedDate
9331                                                         " " + this._dayOverClass : "") + // highlight selected day
9332                                                         (unselectable ? " " + this._unselectableClass + " ui-state-disabled": "") +  // highlight unselectable days
9333                                                         (otherMonth && !showOtherMonths ? "" : " " + daySettings[1] + // highlight custom dates
9334                                                         (printDate.getTime() === currentDate.getTime() ? " " + this._currentClass : "") + // highlight selected day
9335                                                         (printDate.getTime() === today.getTime() ? " ui-datepicker-today" : "")) + "'" + // highlight today (if different)
9336                                                         ((!otherMonth || showOtherMonths) && daySettings[2] ? " title='" + daySettings[2].replace(/'/g, "&#39;") + "'" : "") + // cell title
9337                                                         (unselectable ? "" : " data-handler='selectDay' data-event='click' data-month='" + printDate.getMonth() + "' data-year='" + printDate.getFullYear() + "'") + ">" + // actions
9338                                                         (otherMonth && !showOtherMonths ? "&#xa0;" : // display for other months
9339                                                         (unselectable ? "<span class='ui-state-default'>" + printDate.getDate() + "</span>" : "<a class='ui-state-default" +
9340                                                         (printDate.getTime() === today.getTime() ? " ui-state-highlight" : "") +
9341                                                         (printDate.getTime() === currentDate.getTime() ? " ui-state-active" : "") + // highlight selected day
9342                                                         (otherMonth ? " ui-priority-secondary" : "") + // distinguish dates from other months
9343                                                         "' href='#'>" + printDate.getDate() + "</a>")) + "</td>"; // display selectable date
9344                                                 printDate.setDate(printDate.getDate() + 1);
9345                                                 printDate = this._daylightSavingAdjust(printDate);
9346                                         }
9347                                         calender += tbody + "</tr>";
9348                                 }
9349                                 drawMonth++;
9350                                 if (drawMonth > 11) {
9351                                         drawMonth = 0;
9352                                         drawYear++;
9353                                 }
9354                                 calender += "</tbody></table>" + (isMultiMonth ? "</div>" +
9355                                                         ((numMonths[0] > 0 && col === numMonths[1]-1) ? "<div class='ui-datepicker-row-break'></div>" : "") : "");
9356                                 group += calender;
9357                         }
9358                         html += group;
9359                 }
9360                 html += buttonPanel;
9361                 inst._keyEvent = false;
9362                 return html;
9363         },
9364
9365         /* Generate the month and year header. */
9366         _generateMonthYearHeader: function(inst, drawMonth, drawYear, minDate, maxDate,
9367                         secondary, monthNames, monthNamesShort) {
9368
9369                 var inMinYear, inMaxYear, month, years, thisYear, determineYear, year, endYear,
9370                         changeMonth = this._get(inst, "changeMonth"),
9371                         changeYear = this._get(inst, "changeYear"),
9372                         showMonthAfterYear = this._get(inst, "showMonthAfterYear"),
9373                         html = "<div class='ui-datepicker-title'>",
9374                         monthHtml = "";
9375
9376                 // month selection
9377                 if (secondary || !changeMonth) {
9378                         monthHtml += "<span class='ui-datepicker-month'>" + monthNames[drawMonth] + "</span>";
9379                 } else {
9380                         inMinYear = (minDate && minDate.getFullYear() === drawYear);
9381                         inMaxYear = (maxDate && maxDate.getFullYear() === drawYear);
9382                         monthHtml += "<select class='ui-datepicker-month' data-handler='selectMonth' data-event='change'>";
9383                         for ( month = 0; month < 12; month++) {
9384                                 if ((!inMinYear || month >= minDate.getMonth()) && (!inMaxYear || month <= maxDate.getMonth())) {
9385                                         monthHtml += "<option value='" + month + "'" +
9386                                                 (month === drawMonth ? " selected='selected'" : "") +
9387                                                 ">" + monthNamesShort[month] + "</option>";
9388                                 }
9389                         }
9390                         monthHtml += "</select>";
9391                 }
9392
9393                 if (!showMonthAfterYear) {
9394                         html += monthHtml + (secondary || !(changeMonth && changeYear) ? "&#xa0;" : "");
9395                 }
9396
9397                 // year selection
9398                 if ( !inst.yearshtml ) {
9399                         inst.yearshtml = "";
9400                         if (secondary || !changeYear) {
9401                                 html += "<span class='ui-datepicker-year'>" + drawYear + "</span>";
9402                         } else {
9403                                 // determine range of years to display
9404                                 years = this._get(inst, "yearRange").split(":");
9405                                 thisYear = new Date().getFullYear();
9406                                 determineYear = function(value) {
9407                                         var year = (value.match(/c[+\-].*/) ? drawYear + parseInt(value.substring(1), 10) :
9408                                                 (value.match(/[+\-].*/) ? thisYear + parseInt(value, 10) :
9409                                                 parseInt(value, 10)));
9410                                         return (isNaN(year) ? thisYear : year);
9411                                 };
9412                                 year = determineYear(years[0]);
9413                                 endYear = Math.max(year, determineYear(years[1] || ""));
9414                                 year = (minDate ? Math.max(year, minDate.getFullYear()) : year);
9415                                 endYear = (maxDate ? Math.min(endYear, maxDate.getFullYear()) : endYear);
9416                                 inst.yearshtml += "<select class='ui-datepicker-year' data-handler='selectYear' data-event='change'>";
9417                                 for (; year <= endYear; year++) {
9418                                         inst.yearshtml += "<option value='" + year + "'" +
9419                                                 (year === drawYear ? " selected='selected'" : "") +
9420                                                 ">" + year + "</option>";
9421                                 }
9422                                 inst.yearshtml += "</select>";
9423
9424                                 html += inst.yearshtml;
9425                                 inst.yearshtml = null;
9426                         }
9427                 }
9428
9429                 html += this._get(inst, "yearSuffix");
9430                 if (showMonthAfterYear) {
9431                         html += (secondary || !(changeMonth && changeYear) ? "&#xa0;" : "") + monthHtml;
9432                 }
9433                 html += "</div>"; // Close datepicker_header
9434                 return html;
9435         },
9436
9437         /* Adjust one of the date sub-fields. */
9438         _adjustInstDate: function(inst, offset, period) {
9439                 var year = inst.drawYear + (period === "Y" ? offset : 0),
9440                         month = inst.drawMonth + (period === "M" ? offset : 0),
9441                         day = Math.min(inst.selectedDay, this._getDaysInMonth(year, month)) + (period === "D" ? offset : 0),
9442                         date = this._restrictMinMax(inst, this._daylightSavingAdjust(new Date(year, month, day)));
9443
9444                 inst.selectedDay = date.getDate();
9445                 inst.drawMonth = inst.selectedMonth = date.getMonth();
9446                 inst.drawYear = inst.selectedYear = date.getFullYear();
9447                 if (period === "M" || period === "Y") {
9448                         this._notifyChange(inst);
9449                 }
9450         },
9451
9452         /* Ensure a date is within any min/max bounds. */
9453         _restrictMinMax: function(inst, date) {
9454                 var minDate = this._getMinMaxDate(inst, "min"),
9455                         maxDate = this._getMinMaxDate(inst, "max"),
9456                         newDate = (minDate && date < minDate ? minDate : date);
9457                 return (maxDate && newDate > maxDate ? maxDate : newDate);
9458         },
9459
9460         /* Notify change of month/year. */
9461         _notifyChange: function(inst) {
9462                 var onChange = this._get(inst, "onChangeMonthYear");
9463                 if (onChange) {
9464                         onChange.apply((inst.input ? inst.input[0] : null),
9465                                 [inst.selectedYear, inst.selectedMonth + 1, inst]);
9466                 }
9467         },
9468
9469         /* Determine the number of months to show. */
9470         _getNumberOfMonths: function(inst) {
9471                 var numMonths = this._get(inst, "numberOfMonths");
9472                 return (numMonths == null ? [1, 1] : (typeof numMonths === "number" ? [1, numMonths] : numMonths));
9473         },
9474
9475         /* Determine the current maximum date - ensure no time components are set. */
9476         _getMinMaxDate: function(inst, minMax) {
9477                 return this._determineDate(inst, this._get(inst, minMax + "Date"), null);
9478         },
9479
9480         /* Find the number of days in a given month. */
9481         _getDaysInMonth: function(year, month) {
9482                 return 32 - this._daylightSavingAdjust(new Date(year, month, 32)).getDate();
9483         },
9484
9485         /* Find the day of the week of the first of a month. */
9486         _getFirstDayOfMonth: function(year, month) {
9487                 return new Date(year, month, 1).getDay();
9488         },
9489
9490         /* Determines if we should allow a "next/prev" month display change. */
9491         _canAdjustMonth: function(inst, offset, curYear, curMonth) {
9492                 var numMonths = this._getNumberOfMonths(inst),
9493                         date = this._daylightSavingAdjust(new Date(curYear,
9494                         curMonth + (offset < 0 ? offset : numMonths[0] * numMonths[1]), 1));
9495
9496                 if (offset < 0) {
9497                         date.setDate(this._getDaysInMonth(date.getFullYear(), date.getMonth()));
9498                 }
9499                 return this._isInRange(inst, date);
9500         },
9501
9502         /* Is the given date in the accepted range? */
9503         _isInRange: function(inst, date) {
9504                 var yearSplit, currentYear,
9505                         minDate = this._getMinMaxDate(inst, "min"),
9506                         maxDate = this._getMinMaxDate(inst, "max"),
9507                         minYear = null,
9508                         maxYear = null,
9509                         years = this._get(inst, "yearRange");
9510                         if (years){
9511                                 yearSplit = years.split(":");
9512                                 currentYear = new Date().getFullYear();
9513                                 minYear = parseInt(yearSplit[0], 10);
9514                                 maxYear = parseInt(yearSplit[1], 10);
9515                                 if ( yearSplit[0].match(/[+\-].*/) ) {
9516                                         minYear += currentYear;
9517                                 }
9518                                 if ( yearSplit[1].match(/[+\-].*/) ) {
9519                                         maxYear += currentYear;
9520                                 }
9521                         }
9522
9523                 return ((!minDate || date.getTime() >= minDate.getTime()) &&
9524                         (!maxDate || date.getTime() <= maxDate.getTime()) &&
9525                         (!minYear || date.getFullYear() >= minYear) &&
9526                         (!maxYear || date.getFullYear() <= maxYear));
9527         },
9528
9529         /* Provide the configuration settings for formatting/parsing. */
9530         _getFormatConfig: function(inst) {
9531                 var shortYearCutoff = this._get(inst, "shortYearCutoff");
9532                 shortYearCutoff = (typeof shortYearCutoff !== "string" ? shortYearCutoff :
9533                         new Date().getFullYear() % 100 + parseInt(shortYearCutoff, 10));
9534                 return {shortYearCutoff: shortYearCutoff,
9535                         dayNamesShort: this._get(inst, "dayNamesShort"), dayNames: this._get(inst, "dayNames"),
9536                         monthNamesShort: this._get(inst, "monthNamesShort"), monthNames: this._get(inst, "monthNames")};
9537         },
9538
9539         /* Format the given date for display. */
9540         _formatDate: function(inst, day, month, year) {
9541                 if (!day) {
9542                         inst.currentDay = inst.selectedDay;
9543                         inst.currentMonth = inst.selectedMonth;
9544                         inst.currentYear = inst.selectedYear;
9545                 }
9546                 var date = (day ? (typeof day === "object" ? day :
9547                         this._daylightSavingAdjust(new Date(year, month, day))) :
9548                         this._daylightSavingAdjust(new Date(inst.currentYear, inst.currentMonth, inst.currentDay)));
9549                 return this.formatDate(this._get(inst, "dateFormat"), date, this._getFormatConfig(inst));
9550         }
9551 });
9552
9553 /*
9554  * Bind hover events for datepicker elements.
9555  * Done via delegate so the binding only occurs once in the lifetime of the parent div.
9556  * Global instActive, set by _updateDatepicker allows the handlers to find their way back to the active picker.
9557  */
9558 function bindHover(dpDiv) {
9559         var selector = "button, .ui-datepicker-prev, .ui-datepicker-next, .ui-datepicker-calendar td a";
9560         return dpDiv.delegate(selector, "mouseout", function() {
9561                         $(this).removeClass("ui-state-hover");
9562                         if (this.className.indexOf("ui-datepicker-prev") !== -1) {
9563                                 $(this).removeClass("ui-datepicker-prev-hover");
9564                         }
9565                         if (this.className.indexOf("ui-datepicker-next") !== -1) {
9566                                 $(this).removeClass("ui-datepicker-next-hover");
9567                         }
9568                 })
9569                 .delegate(selector, "mouseover", function(){
9570                         if (!$.datepicker._isDisabledDatepicker( instActive.inline ? dpDiv.parent()[0] : instActive.input[0])) {
9571                                 $(this).parents(".ui-datepicker-calendar").find("a").removeClass("ui-state-hover");
9572                                 $(this).addClass("ui-state-hover");
9573                                 if (this.className.indexOf("ui-datepicker-prev") !== -1) {
9574                                         $(this).addClass("ui-datepicker-prev-hover");
9575                                 }
9576                                 if (this.className.indexOf("ui-datepicker-next") !== -1) {
9577                                         $(this).addClass("ui-datepicker-next-hover");
9578                                 }
9579                         }
9580                 });
9581 }
9582
9583 /* jQuery extend now ignores nulls! */
9584 function extendRemove(target, props) {
9585         $.extend(target, props);
9586         for (var name in props) {
9587                 if (props[name] == null) {
9588                         target[name] = props[name];
9589                 }
9590         }
9591         return target;
9592 }
9593
9594 /* Invoke the datepicker functionality.
9595    @param  options  string - a command, optionally followed by additional parameters or
9596                                         Object - settings for attaching new datepicker functionality
9597    @return  jQuery object */
9598 $.fn.datepicker = function(options){
9599
9600         /* Verify an empty collection wasn't passed - Fixes #6976 */
9601         if ( !this.length ) {
9602                 return this;
9603         }
9604
9605         /* Initialise the date picker. */
9606         if (!$.datepicker.initialized) {
9607                 $(document).mousedown($.datepicker._checkExternalClick);
9608                 $.datepicker.initialized = true;
9609         }
9610
9611         /* Append datepicker main container to body if not exist. */
9612         if ($("#"+$.datepicker._mainDivId).length === 0) {
9613                 $("body").append($.datepicker.dpDiv);
9614         }
9615
9616         var otherArgs = Array.prototype.slice.call(arguments, 1);
9617         if (typeof options === "string" && (options === "isDisabled" || options === "getDate" || options === "widget")) {
9618                 return $.datepicker["_" + options + "Datepicker"].
9619                         apply($.datepicker, [this[0]].concat(otherArgs));
9620         }
9621         if (options === "option" && arguments.length === 2 && typeof arguments[1] === "string") {
9622                 return $.datepicker["_" + options + "Datepicker"].
9623                         apply($.datepicker, [this[0]].concat(otherArgs));
9624         }
9625         return this.each(function() {
9626                 typeof options === "string" ?
9627                         $.datepicker["_" + options + "Datepicker"].
9628                                 apply($.datepicker, [this].concat(otherArgs)) :
9629                         $.datepicker._attachDatepicker(this, options);
9630         });
9631 };
9632
9633 $.datepicker = new Datepicker(); // singleton instance
9634 $.datepicker.initialized = false;
9635 $.datepicker.uuid = new Date().getTime();
9636 $.datepicker.version = "1.10.3";
9637
9638 })(jQuery);
9639
9640 (function( $, undefined ) {
9641
9642 var sizeRelatedOptions = {
9643                 buttons: true,
9644                 height: true,
9645                 maxHeight: true,
9646                 maxWidth: true,
9647                 minHeight: true,
9648                 minWidth: true,
9649                 width: true
9650         },
9651         resizableRelatedOptions = {
9652                 maxHeight: true,
9653                 maxWidth: true,
9654                 minHeight: true,
9655                 minWidth: true
9656         };
9657
9658 $.widget( "ui.dialog", {
9659         version: "1.10.3",
9660         options: {
9661                 appendTo: "body",
9662                 autoOpen: true,
9663                 buttons: [],
9664                 closeOnEscape: true,
9665                 closeText: "close",
9666                 dialogClass: "",
9667                 draggable: true,
9668                 hide: null,
9669                 height: "auto",
9670                 maxHeight: null,
9671                 maxWidth: null,
9672                 minHeight: 150,
9673                 minWidth: 150,
9674                 modal: false,
9675                 position: {
9676                         my: "center",
9677                         at: "center",
9678                         of: window,
9679                         collision: "fit",
9680                         // Ensure the titlebar is always visible
9681                         using: function( pos ) {
9682                                 var topOffset = $( this ).css( pos ).offset().top;
9683                                 if ( topOffset < 0 ) {
9684                                         $( this ).css( "top", pos.top - topOffset );
9685                                 }
9686                         }
9687                 },
9688                 resizable: true,
9689                 show: null,
9690                 title: null,
9691                 width: 300,
9692
9693                 // callbacks
9694                 beforeClose: null,
9695                 close: null,
9696                 drag: null,
9697                 dragStart: null,
9698                 dragStop: null,
9699                 focus: null,
9700                 open: null,
9701                 resize: null,
9702                 resizeStart: null,
9703                 resizeStop: null
9704         },
9705
9706         _create: function() {
9707                 this.originalCss = {
9708                         display: this.element[0].style.display,
9709                         width: this.element[0].style.width,
9710                         minHeight: this.element[0].style.minHeight,
9711                         maxHeight: this.element[0].style.maxHeight,
9712                         height: this.element[0].style.height
9713                 };
9714                 this.originalPosition = {
9715                         parent: this.element.parent(),
9716                         index: this.element.parent().children().index( this.element )
9717                 };
9718                 this.originalTitle = this.element.attr("title");
9719                 this.options.title = this.options.title || this.originalTitle;
9720
9721                 this._createWrapper();
9722
9723                 this.element
9724                         .show()
9725                         .removeAttr("title")
9726                         .addClass("ui-dialog-content ui-widget-content")
9727                         .appendTo( this.uiDialog );
9728
9729                 this._createTitlebar();
9730                 this._createButtonPane();
9731
9732                 if ( this.options.draggable && $.fn.draggable ) {
9733                         this._makeDraggable();
9734                 }
9735                 if ( this.options.resizable && $.fn.resizable ) {
9736                         this._makeResizable();
9737                 }
9738
9739                 this._isOpen = false;
9740         },
9741
9742         _init: function() {
9743                 if ( this.options.autoOpen ) {
9744                         this.open();
9745                 }
9746         },
9747
9748         _appendTo: function() {
9749                 var element = this.options.appendTo;
9750                 if ( element && (element.jquery || element.nodeType) ) {
9751                         return $( element );
9752                 }
9753                 return this.document.find( element || "body" ).eq( 0 );
9754         },
9755
9756         _destroy: function() {
9757                 var next,
9758                         originalPosition = this.originalPosition;
9759
9760                 this._destroyOverlay();
9761
9762                 this.element
9763                         .removeUniqueId()
9764                         .removeClass("ui-dialog-content ui-widget-content")
9765                         .css( this.originalCss )
9766                         // Without detaching first, the following becomes really slow
9767                         .detach();
9768
9769                 this.uiDialog.stop( true, true ).remove();
9770
9771                 if ( this.originalTitle ) {
9772                         this.element.attr( "title", this.originalTitle );
9773                 }
9774
9775                 next = originalPosition.parent.children().eq( originalPosition.index );
9776                 // Don't try to place the dialog next to itself (#8613)
9777                 if ( next.length && next[0] !== this.element[0] ) {
9778                         next.before( this.element );
9779                 } else {
9780                         originalPosition.parent.append( this.element );
9781                 }
9782         },
9783
9784         widget: function() {
9785                 return this.uiDialog;
9786         },
9787
9788         disable: $.noop,
9789         enable: $.noop,
9790
9791         close: function( event ) {
9792                 var that = this;
9793
9794                 if ( !this._isOpen || this._trigger( "beforeClose", event ) === false ) {
9795                         return;
9796                 }
9797
9798                 this._isOpen = false;
9799                 this._destroyOverlay();
9800
9801                 if ( !this.opener.filter(":focusable").focus().length ) {
9802                         // Hiding a focused element doesn't trigger blur in WebKit
9803                         // so in case we have nothing to focus on, explicitly blur the active element
9804                         // https://bugs.webkit.org/show_bug.cgi?id=47182
9805                         $( this.document[0].activeElement ).blur();
9806                 }
9807
9808                 this._hide( this.uiDialog, this.options.hide, function() {
9809                         that._trigger( "close", event );
9810                 });
9811         },
9812
9813         isOpen: function() {
9814                 return this._isOpen;
9815         },
9816
9817         moveToTop: function() {
9818                 this._moveToTop();
9819         },
9820
9821         _moveToTop: function( event, silent ) {
9822                 var moved = !!this.uiDialog.nextAll(":visible").insertBefore( this.uiDialog ).length;
9823                 if ( moved && !silent ) {
9824                         this._trigger( "focus", event );
9825                 }
9826                 return moved;
9827         },
9828
9829         open: function() {
9830                 var that = this;
9831                 if ( this._isOpen ) {
9832                         if ( this._moveToTop() ) {
9833                                 this._focusTabbable();
9834                         }
9835                         return;
9836                 }
9837
9838                 this._isOpen = true;
9839                 this.opener = $( this.document[0].activeElement );
9840
9841                 this._size();
9842                 this._position();
9843                 this._createOverlay();
9844                 this._moveToTop( null, true );
9845                 this._show( this.uiDialog, this.options.show, function() {
9846                         that._focusTabbable();
9847                         that._trigger("focus");
9848                 });
9849
9850                 this._trigger("open");
9851         },
9852
9853         _focusTabbable: function() {
9854                 // Set focus to the first match:
9855                 // 1. First element inside the dialog matching [autofocus]
9856                 // 2. Tabbable element inside the content element
9857                 // 3. Tabbable element inside the buttonpane
9858                 // 4. The close button
9859                 // 5. The dialog itself
9860                 var hasFocus = this.element.find("[autofocus]");
9861                 if ( !hasFocus.length ) {
9862                         hasFocus = this.element.find(":tabbable");
9863                 }
9864                 if ( !hasFocus.length ) {
9865                         hasFocus = this.uiDialogButtonPane.find(":tabbable");
9866                 }
9867                 if ( !hasFocus.length ) {
9868                         hasFocus = this.uiDialogTitlebarClose.filter(":tabbable");
9869                 }
9870                 if ( !hasFocus.length ) {
9871                         hasFocus = this.uiDialog;
9872                 }
9873                 hasFocus.eq( 0 ).focus();
9874         },
9875
9876         _keepFocus: function( event ) {
9877                 function checkFocus() {
9878                         var activeElement = this.document[0].activeElement,
9879                                 isActive = this.uiDialog[0] === activeElement ||
9880                                         $.contains( this.uiDialog[0], activeElement );
9881                         if ( !isActive ) {
9882                                 this._focusTabbable();
9883                         }
9884                 }
9885                 event.preventDefault();
9886                 checkFocus.call( this );
9887                 // support: IE
9888                 // IE <= 8 doesn't prevent moving focus even with event.preventDefault()
9889                 // so we check again later
9890                 this._delay( checkFocus );
9891         },
9892
9893         _createWrapper: function() {
9894                 this.uiDialog = $("<div>")
9895                         .addClass( "ui-dialog ui-widget ui-widget-content ui-corner-all ui-front " +
9896                                 this.options.dialogClass )
9897                         .hide()
9898                         .attr({
9899                                 // Setting tabIndex makes the div focusable
9900                                 tabIndex: -1,
9901                                 role: "dialog"
9902                         })
9903                         .appendTo( this._appendTo() );
9904
9905                 this._on( this.uiDialog, {
9906                         keydown: function( event ) {
9907                                 if ( this.options.closeOnEscape && !event.isDefaultPrevented() && event.keyCode &&
9908                                                 event.keyCode === $.ui.keyCode.ESCAPE ) {
9909                                         event.preventDefault();
9910                                         this.close( event );
9911                                         return;
9912                                 }
9913
9914                                 // prevent tabbing out of dialogs
9915                                 if ( event.keyCode !== $.ui.keyCode.TAB ) {
9916                                         return;
9917                                 }
9918                                 var tabbables = this.uiDialog.find(":tabbable"),
9919                                         first = tabbables.filter(":first"),
9920                                         last  = tabbables.filter(":last");
9921
9922                                 if ( ( event.target === last[0] || event.target === this.uiDialog[0] ) && !event.shiftKey ) {
9923                                         first.focus( 1 );
9924                                         event.preventDefault();
9925                                 } else if ( ( event.target === first[0] || event.target === this.uiDialog[0] ) && event.shiftKey ) {
9926                                         last.focus( 1 );
9927                                         event.preventDefault();
9928                                 }
9929                         },
9930                         mousedown: function( event ) {
9931                                 if ( this._moveToTop( event ) ) {
9932                                         this._focusTabbable();
9933                                 }
9934                         }
9935                 });
9936
9937                 // We assume that any existing aria-describedby attribute means
9938                 // that the dialog content is marked up properly
9939                 // otherwise we brute force the content as the description
9940                 if ( !this.element.find("[aria-describedby]").length ) {
9941                         this.uiDialog.attr({
9942                                 "aria-describedby": this.element.uniqueId().attr("id")
9943                         });
9944                 }
9945         },
9946
9947         _createTitlebar: function() {
9948                 var uiDialogTitle;
9949
9950                 this.uiDialogTitlebar = $("<div>")
9951                         .addClass("ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix")
9952                         .prependTo( this.uiDialog );
9953                 this._on( this.uiDialogTitlebar, {
9954                         mousedown: function( event ) {
9955                                 // Don't prevent click on close button (#8838)
9956                                 // Focusing a dialog that is partially scrolled out of view
9957                                 // causes the browser to scroll it into view, preventing the click event
9958                                 if ( !$( event.target ).closest(".ui-dialog-titlebar-close") ) {
9959                                         // Dialog isn't getting focus when dragging (#8063)
9960                                         this.uiDialog.focus();
9961                                 }
9962                         }
9963                 });
9964
9965                 this.uiDialogTitlebarClose = $("<button></button>")
9966                         .button({
9967                                 label: this.options.closeText,
9968                                 icons: {
9969                                         primary: "ui-icon-closethick"
9970                                 },
9971                                 text: false
9972                         })
9973                         .addClass("ui-dialog-titlebar-close")
9974                         .appendTo( this.uiDialogTitlebar );
9975                 this._on( this.uiDialogTitlebarClose, {
9976                         click: function( event ) {
9977                                 event.preventDefault();
9978                                 this.close( event );
9979                         }
9980                 });
9981
9982                 uiDialogTitle = $("<span>")
9983                         .uniqueId()
9984                         .addClass("ui-dialog-title")
9985                         .prependTo( this.uiDialogTitlebar );
9986                 this._title( uiDialogTitle );
9987
9988                 this.uiDialog.attr({
9989                         "aria-labelledby": uiDialogTitle.attr("id")
9990                 });
9991         },
9992
9993         _title: function( title ) {
9994                 if ( !this.options.title ) {
9995                         title.html("&#160;");
9996                 }
9997                 title.text( this.options.title );
9998         },
9999
10000         _createButtonPane: function() {
10001                 this.uiDialogButtonPane = $("<div>")
10002                         .addClass("ui-dialog-buttonpane ui-widget-content ui-helper-clearfix");
10003
10004                 this.uiButtonSet = $("<div>")
10005                         .addClass("ui-dialog-buttonset")
10006                         .appendTo( this.uiDialogButtonPane );
10007
10008                 this._createButtons();
10009         },
10010
10011         _createButtons: function() {
10012                 var that = this,
10013                         buttons = this.options.buttons;
10014
10015                 // if we already have a button pane, remove it
10016                 this.uiDialogButtonPane.remove();
10017                 this.uiButtonSet.empty();
10018
10019                 if ( $.isEmptyObject( buttons ) || ($.isArray( buttons ) && !buttons.length) ) {
10020                         this.uiDialog.removeClass("ui-dialog-buttons");
10021                         return;
10022                 }
10023
10024                 $.each( buttons, function( name, props ) {
10025                         var click, buttonOptions;
10026                         props = $.isFunction( props ) ?
10027                                 { click: props, text: name } :
10028                                 props;
10029                         // Default to a non-submitting button
10030                         props = $.extend( { type: "button" }, props );
10031                         // Change the context for the click callback to be the main element
10032                         click = props.click;
10033                         props.click = function() {
10034                                 click.apply( that.element[0], arguments );
10035                         };
10036                         buttonOptions = {
10037                                 icons: props.icons,
10038                                 text: props.showText
10039                         };
10040                         delete props.icons;
10041                         delete props.showText;
10042                         $( "<button></button>", props )
10043                                 .button( buttonOptions )
10044                                 .appendTo( that.uiButtonSet );
10045                 });
10046                 this.uiDialog.addClass("ui-dialog-buttons");
10047                 this.uiDialogButtonPane.appendTo( this.uiDialog );
10048         },
10049
10050         _makeDraggable: function() {
10051                 var that = this,
10052                         options = this.options;
10053
10054                 function filteredUi( ui ) {
10055                         return {
10056                                 position: ui.position,
10057                                 offset: ui.offset
10058                         };
10059                 }
10060
10061                 this.uiDialog.draggable({
10062                         cancel: ".ui-dialog-content, .ui-dialog-titlebar-close",
10063                         handle: ".ui-dialog-titlebar",
10064                         containment: "document",
10065                         start: function( event, ui ) {
10066                                 $( this ).addClass("ui-dialog-dragging");
10067                                 that._blockFrames();
10068                                 that._trigger( "dragStart", event, filteredUi( ui ) );
10069                         },
10070                         drag: function( event, ui ) {
10071                                 that._trigger( "drag", event, filteredUi( ui ) );
10072                         },
10073                         stop: function( event, ui ) {
10074                                 options.position = [
10075                                         ui.position.left - that.document.scrollLeft(),
10076                                         ui.position.top - that.document.scrollTop()
10077                                 ];
10078                                 $( this ).removeClass("ui-dialog-dragging");
10079                                 that._unblockFrames();
10080                                 that._trigger( "dragStop", event, filteredUi( ui ) );
10081                         }
10082                 });
10083         },
10084
10085         _makeResizable: function() {
10086                 var that = this,
10087                         options = this.options,
10088                         handles = options.resizable,
10089                         // .ui-resizable has position: relative defined in the stylesheet
10090                         // but dialogs have to use absolute or fixed positioning
10091                         position = this.uiDialog.css("position"),
10092                         resizeHandles = typeof handles === "string" ?
10093                                 handles :
10094                                 "n,e,s,w,se,sw,ne,nw";
10095
10096                 function filteredUi( ui ) {
10097                         return {
10098                                 originalPosition: ui.originalPosition,
10099                                 originalSize: ui.originalSize,
10100                                 position: ui.position,
10101                                 size: ui.size
10102                         };
10103                 }
10104
10105                 this.uiDialog.resizable({
10106                         cancel: ".ui-dialog-content",
10107                         containment: "document",
10108                         alsoResize: this.element,
10109                         maxWidth: options.maxWidth,
10110                         maxHeight: options.maxHeight,
10111                         minWidth: options.minWidth,
10112                         minHeight: this._minHeight(),
10113                         handles: resizeHandles,
10114                         start: function( event, ui ) {
10115                                 $( this ).addClass("ui-dialog-resizing");
10116                                 that._blockFrames();
10117                                 that._trigger( "resizeStart", event, filteredUi( ui ) );
10118                         },
10119                         resize: function( event, ui ) {
10120                                 that._trigger( "resize", event, filteredUi( ui ) );
10121                         },
10122                         stop: function( event, ui ) {
10123                                 options.height = $( this ).height();
10124                                 options.width = $( this ).width();
10125                                 $( this ).removeClass("ui-dialog-resizing");
10126                                 that._unblockFrames();
10127                                 that._trigger( "resizeStop", event, filteredUi( ui ) );
10128                         }
10129                 })
10130                 .css( "position", position );
10131         },
10132
10133         _minHeight: function() {
10134                 var options = this.options;
10135
10136                 return options.height === "auto" ?
10137                         options.minHeight :
10138                         Math.min( options.minHeight, options.height );
10139         },
10140
10141         _position: function() {
10142                 // Need to show the dialog to get the actual offset in the position plugin
10143                 var isVisible = this.uiDialog.is(":visible");
10144                 if ( !isVisible ) {
10145                         this.uiDialog.show();
10146                 }
10147                 this.uiDialog.position( this.options.position );
10148                 if ( !isVisible ) {
10149                         this.uiDialog.hide();
10150                 }
10151         },
10152
10153         _setOptions: function( options ) {
10154                 var that = this,
10155                         resize = false,
10156                         resizableOptions = {};
10157
10158                 $.each( options, function( key, value ) {
10159                         that._setOption( key, value );
10160
10161                         if ( key in sizeRelatedOptions ) {
10162                                 resize = true;
10163                         }
10164                         if ( key in resizableRelatedOptions ) {
10165                                 resizableOptions[ key ] = value;
10166                         }
10167                 });
10168
10169                 if ( resize ) {
10170                         this._size();
10171                         this._position();
10172                 }
10173                 if ( this.uiDialog.is(":data(ui-resizable)") ) {
10174                         this.uiDialog.resizable( "option", resizableOptions );
10175                 }
10176         },
10177
10178         _setOption: function( key, value ) {
10179                 /*jshint maxcomplexity:15*/
10180                 var isDraggable, isResizable,
10181                         uiDialog = this.uiDialog;
10182
10183                 if ( key === "dialogClass" ) {
10184                         uiDialog
10185                                 .removeClass( this.options.dialogClass )
10186                                 .addClass( value );
10187                 }
10188
10189                 if ( key === "disabled" ) {
10190                         return;
10191                 }
10192
10193                 this._super( key, value );
10194
10195                 if ( key === "appendTo" ) {
10196                         this.uiDialog.appendTo( this._appendTo() );
10197                 }
10198
10199                 if ( key === "buttons" ) {
10200                         this._createButtons();
10201                 }
10202
10203                 if ( key === "closeText" ) {
10204                         this.uiDialogTitlebarClose.button({
10205                                 // Ensure that we always pass a string
10206                                 label: "" + value
10207                         });
10208                 }
10209
10210                 if ( key === "draggable" ) {
10211                         isDraggable = uiDialog.is(":data(ui-draggable)");
10212                         if ( isDraggable && !value ) {
10213                                 uiDialog.draggable("destroy");
10214                         }
10215
10216                         if ( !isDraggable && value ) {
10217                                 this._makeDraggable();
10218                         }
10219                 }
10220
10221                 if ( key === "position" ) {
10222                         this._position();
10223                 }
10224
10225                 if ( key === "resizable" ) {
10226                         // currently resizable, becoming non-resizable
10227                         isResizable = uiDialog.is(":data(ui-resizable)");
10228                         if ( isResizable && !value ) {
10229                                 uiDialog.resizable("destroy");
10230                         }
10231
10232                         // currently resizable, changing handles
10233                         if ( isResizable && typeof value === "string" ) {
10234                                 uiDialog.resizable( "option", "handles", value );
10235                         }
10236
10237                         // currently non-resizable, becoming resizable
10238                         if ( !isResizable && value !== false ) {
10239                                 this._makeResizable();
10240                         }
10241                 }
10242
10243                 if ( key === "title" ) {
10244                         this._title( this.uiDialogTitlebar.find(".ui-dialog-title") );
10245                 }
10246         },
10247
10248         _size: function() {
10249                 // If the user has resized the dialog, the .ui-dialog and .ui-dialog-content
10250                 // divs will both have width and height set, so we need to reset them
10251                 var nonContentHeight, minContentHeight, maxContentHeight,
10252                         options = this.options;
10253
10254                 // Reset content sizing
10255                 this.element.show().css({
10256                         width: "auto",
10257                         minHeight: 0,
10258                         maxHeight: "none",
10259                         height: 0
10260                 });
10261
10262                 if ( options.minWidth > options.width ) {
10263                         options.width = options.minWidth;
10264                 }
10265
10266                 // reset wrapper sizing
10267                 // determine the height of all the non-content elements
10268                 nonContentHeight = this.uiDialog.css({
10269                                 height: "auto",
10270                                 width: options.width
10271                         })
10272                         .outerHeight();
10273                 minContentHeight = Math.max( 0, options.minHeight - nonContentHeight );
10274                 maxContentHeight = typeof options.maxHeight === "number" ?
10275                         Math.max( 0, options.maxHeight - nonContentHeight ) :
10276                         "none";
10277
10278                 if ( options.height === "auto" ) {
10279                         this.element.css({
10280                                 minHeight: minContentHeight,
10281                                 maxHeight: maxContentHeight,
10282                                 height: "auto"
10283                         });
10284                 } else {
10285                         this.element.height( Math.max( 0, options.height - nonContentHeight ) );
10286                 }
10287
10288                 if (this.uiDialog.is(":data(ui-resizable)") ) {
10289                         this.uiDialog.resizable( "option", "minHeight", this._minHeight() );
10290                 }
10291         },
10292
10293         _blockFrames: function() {
10294                 this.iframeBlocks = this.document.find( "iframe" ).map(function() {
10295                         var iframe = $( this );
10296
10297                         return $( "<div>" )
10298                                 .css({
10299                                         position: "absolute",
10300                                         width: iframe.outerWidth(),
10301                                         height: iframe.outerHeight()
10302                                 })
10303                                 .appendTo( iframe.parent() )
10304                                 .offset( iframe.offset() )[0];
10305                 });
10306         },
10307
10308         _unblockFrames: function() {
10309                 if ( this.iframeBlocks ) {
10310                         this.iframeBlocks.remove();
10311                         delete this.iframeBlocks;
10312                 }
10313         },
10314
10315         _allowInteraction: function( event ) {
10316                 if ( $( event.target ).closest(".ui-dialog").length ) {
10317                         return true;
10318                 }
10319
10320                 // TODO: Remove hack when datepicker implements
10321                 // the .ui-front logic (#8989)
10322                 return !!$( event.target ).closest(".ui-datepicker").length;
10323         },
10324
10325         _createOverlay: function() {
10326                 if ( !this.options.modal ) {
10327                         return;
10328                 }
10329
10330                 var that = this,
10331                         widgetFullName = this.widgetFullName;
10332                 if ( !$.ui.dialog.overlayInstances ) {
10333                         // Prevent use of anchors and inputs.
10334                         // We use a delay in case the overlay is created from an
10335                         // event that we're going to be cancelling. (#2804)
10336                         this._delay(function() {
10337                                 // Handle .dialog().dialog("close") (#4065)
10338                                 if ( $.ui.dialog.overlayInstances ) {
10339                                         this.document.bind( "focusin.dialog", function( event ) {
10340                                                 if ( !that._allowInteraction( event ) ) {
10341                                                         event.preventDefault();
10342                                                         $(".ui-dialog:visible:last .ui-dialog-content")
10343                                                                 .data( widgetFullName )._focusTabbable();
10344                                                 }
10345                                         });
10346                                 }
10347                         });
10348                 }
10349
10350                 this.overlay = $("<div>")
10351                         .addClass("ui-widget-overlay ui-front")
10352                         .appendTo( this._appendTo() );
10353                 this._on( this.overlay, {
10354                         mousedown: "_keepFocus"
10355                 });
10356                 $.ui.dialog.overlayInstances++;
10357         },
10358
10359         _destroyOverlay: function() {
10360                 if ( !this.options.modal ) {
10361                         return;
10362                 }
10363
10364                 if ( this.overlay ) {
10365                         $.ui.dialog.overlayInstances--;
10366
10367                         if ( !$.ui.dialog.overlayInstances ) {
10368                                 this.document.unbind( "focusin.dialog" );
10369                         }
10370                         this.overlay.remove();
10371                         this.overlay = null;
10372                 }
10373         }
10374 });
10375
10376 $.ui.dialog.overlayInstances = 0;
10377
10378 // DEPRECATED
10379 if ( $.uiBackCompat !== false ) {
10380         // position option with array notation
10381         // just override with old implementation
10382         $.widget( "ui.dialog", $.ui.dialog, {
10383                 _position: function() {
10384                         var position = this.options.position,
10385                                 myAt = [],
10386                                 offset = [ 0, 0 ],
10387                                 isVisible;
10388
10389                         if ( position ) {
10390                                 if ( typeof position === "string" || (typeof position === "object" && "0" in position ) ) {
10391                                         myAt = position.split ? position.split(" ") : [ position[0], position[1] ];
10392                                         if ( myAt.length === 1 ) {
10393                                                 myAt[1] = myAt[0];
10394                                         }
10395
10396                                         $.each( [ "left", "top" ], function( i, offsetPosition ) {
10397                                                 if ( +myAt[ i ] === myAt[ i ] ) {
10398                                                         offset[ i ] = myAt[ i ];
10399                                                         myAt[ i ] = offsetPosition;
10400                                                 }
10401                                         });
10402
10403                                         position = {
10404                                                 my: myAt[0] + (offset[0] < 0 ? offset[0] : "+" + offset[0]) + " " +
10405                                                         myAt[1] + (offset[1] < 0 ? offset[1] : "+" + offset[1]),
10406                                                 at: myAt.join(" ")
10407                                         };
10408                                 }
10409
10410                                 position = $.extend( {}, $.ui.dialog.prototype.options.position, position );
10411                         } else {
10412                                 position = $.ui.dialog.prototype.options.position;
10413                         }
10414
10415                         // need to show the dialog to get the actual offset in the position plugin
10416                         isVisible = this.uiDialog.is(":visible");
10417                         if ( !isVisible ) {
10418                                 this.uiDialog.show();
10419                         }
10420                         this.uiDialog.position( position );
10421                         if ( !isVisible ) {
10422                                 this.uiDialog.hide();
10423                         }
10424                 }
10425         });
10426 }
10427
10428 }( jQuery ) );
10429
10430 (function( $, undefined ) {
10431
10432 var rvertical = /up|down|vertical/,
10433         rpositivemotion = /up|left|vertical|horizontal/;
10434
10435 $.effects.effect.blind = function( o, done ) {
10436         // Create element
10437         var el = $( this ),
10438                 props = [ "position", "top", "bottom", "left", "right", "height", "width" ],
10439                 mode = $.effects.setMode( el, o.mode || "hide" ),
10440                 direction = o.direction || "up",
10441                 vertical = rvertical.test( direction ),
10442                 ref = vertical ? "height" : "width",
10443                 ref2 = vertical ? "top" : "left",
10444                 motion = rpositivemotion.test( direction ),
10445                 animation = {},
10446                 show = mode === "show",
10447                 wrapper, distance, margin;
10448
10449         // if already wrapped, the wrapper's properties are my property. #6245
10450         if ( el.parent().is( ".ui-effects-wrapper" ) ) {
10451                 $.effects.save( el.parent(), props );
10452         } else {
10453                 $.effects.save( el, props );
10454         }
10455         el.show();
10456         wrapper = $.effects.createWrapper( el ).css({
10457                 overflow: "hidden"
10458         });
10459
10460         distance = wrapper[ ref ]();
10461         margin = parseFloat( wrapper.css( ref2 ) ) || 0;
10462
10463         animation[ ref ] = show ? distance : 0;
10464         if ( !motion ) {
10465                 el
10466                         .css( vertical ? "bottom" : "right", 0 )
10467                         .css( vertical ? "top" : "left", "auto" )
10468                         .css({ position: "absolute" });
10469
10470                 animation[ ref2 ] = show ? margin : distance + margin;
10471         }
10472
10473         // start at 0 if we are showing
10474         if ( show ) {
10475                 wrapper.css( ref, 0 );
10476                 if ( ! motion ) {
10477                         wrapper.css( ref2, margin + distance );
10478                 }
10479         }
10480
10481         // Animate
10482         wrapper.animate( animation, {
10483                 duration: o.duration,
10484                 easing: o.easing,
10485                 queue: false,
10486                 complete: function() {
10487                         if ( mode === "hide" ) {
10488                                 el.hide();
10489                         }
10490                         $.effects.restore( el, props );
10491                         $.effects.removeWrapper( el );
10492                         done();
10493                 }
10494         });
10495
10496 };
10497
10498 })(jQuery);
10499
10500 (function( $, undefined ) {
10501
10502 $.effects.effect.bounce = function( o, done ) {
10503         var el = $( this ),
10504                 props = [ "position", "top", "bottom", "left", "right", "height", "width" ],
10505
10506                 // defaults:
10507                 mode = $.effects.setMode( el, o.mode || "effect" ),
10508                 hide = mode === "hide",
10509                 show = mode === "show",
10510                 direction = o.direction || "up",
10511                 distance = o.distance,
10512                 times = o.times || 5,
10513
10514                 // number of internal animations
10515                 anims = times * 2 + ( show || hide ? 1 : 0 ),
10516                 speed = o.duration / anims,
10517                 easing = o.easing,
10518
10519                 // utility:
10520                 ref = ( direction === "up" || direction === "down" ) ? "top" : "left",
10521                 motion = ( direction === "up" || direction === "left" ),
10522                 i,
10523                 upAnim,
10524                 downAnim,
10525
10526                 // we will need to re-assemble the queue to stack our animations in place
10527                 queue = el.queue(),
10528                 queuelen = queue.length;
10529
10530         // Avoid touching opacity to prevent clearType and PNG issues in IE
10531         if ( show || hide ) {
10532                 props.push( "opacity" );
10533         }
10534
10535         $.effects.save( el, props );
10536         el.show();
10537         $.effects.createWrapper( el ); // Create Wrapper
10538
10539         // default distance for the BIGGEST bounce is the outer Distance / 3
10540         if ( !distance ) {
10541                 distance = el[ ref === "top" ? "outerHeight" : "outerWidth" ]() / 3;
10542         }
10543
10544         if ( show ) {
10545                 downAnim = { opacity: 1 };
10546                 downAnim[ ref ] = 0;
10547
10548                 // if we are showing, force opacity 0 and set the initial position
10549                 // then do the "first" animation
10550                 el.css( "opacity", 0 )
10551                         .css( ref, motion ? -distance * 2 : distance * 2 )
10552                         .animate( downAnim, speed, easing );
10553         }
10554
10555         // start at the smallest distance if we are hiding
10556         if ( hide ) {
10557                 distance = distance / Math.pow( 2, times - 1 );
10558         }
10559
10560         downAnim = {};
10561         downAnim[ ref ] = 0;
10562         // Bounces up/down/left/right then back to 0 -- times * 2 animations happen here
10563         for ( i = 0; i < times; i++ ) {
10564                 upAnim = {};
10565                 upAnim[ ref ] = ( motion ? "-=" : "+=" ) + distance;
10566
10567                 el.animate( upAnim, speed, easing )
10568                         .animate( downAnim, speed, easing );
10569
10570                 distance = hide ? distance * 2 : distance / 2;
10571         }
10572
10573         // Last Bounce when Hiding
10574         if ( hide ) {
10575                 upAnim = { opacity: 0 };
10576                 upAnim[ ref ] = ( motion ? "-=" : "+=" ) + distance;
10577
10578                 el.animate( upAnim, speed, easing );
10579         }
10580
10581         el.queue(function() {
10582                 if ( hide ) {
10583                         el.hide();
10584                 }
10585                 $.effects.restore( el, props );
10586                 $.effects.removeWrapper( el );
10587                 done();
10588         });
10589
10590         // inject all the animations we just queued to be first in line (after "inprogress")
10591         if ( queuelen > 1) {
10592                 queue.splice.apply( queue,
10593                         [ 1, 0 ].concat( queue.splice( queuelen, anims + 1 ) ) );
10594         }
10595         el.dequeue();
10596
10597 };
10598
10599 })(jQuery);
10600
10601 (function( $, undefined ) {
10602
10603 $.effects.effect.clip = function( o, done ) {
10604         // Create element
10605         var el = $( this ),
10606                 props = [ "position", "top", "bottom", "left", "right", "height", "width" ],
10607                 mode = $.effects.setMode( el, o.mode || "hide" ),
10608                 show = mode === "show",
10609                 direction = o.direction || "vertical",
10610                 vert = direction === "vertical",
10611                 size = vert ? "height" : "width",
10612                 position = vert ? "top" : "left",
10613                 animation = {},
10614                 wrapper, animate, distance;
10615
10616         // Save & Show
10617         $.effects.save( el, props );
10618         el.show();
10619
10620         // Create Wrapper
10621         wrapper = $.effects.createWrapper( el ).css({
10622                 overflow: "hidden"
10623         });
10624         animate = ( el[0].tagName === "IMG" ) ? wrapper : el;
10625         distance = animate[ size ]();
10626
10627         // Shift
10628         if ( show ) {
10629                 animate.css( size, 0 );
10630                 animate.css( position, distance / 2 );
10631         }
10632
10633         // Create Animation Object:
10634         animation[ size ] = show ? distance : 0;
10635         animation[ position ] = show ? 0 : distance / 2;
10636
10637         // Animate
10638         animate.animate( animation, {
10639                 queue: false,
10640                 duration: o.duration,
10641                 easing: o.easing,
10642                 complete: function() {
10643                         if ( !show ) {
10644                                 el.hide();
10645                         }
10646                         $.effects.restore( el, props );
10647                         $.effects.removeWrapper( el );
10648                         done();
10649                 }
10650         });
10651
10652 };
10653
10654 })(jQuery);
10655
10656 (function( $, undefined ) {
10657
10658 $.effects.effect.drop = function( o, done ) {
10659
10660         var el = $( this ),
10661                 props = [ "position", "top", "bottom", "left", "right", "opacity", "height", "width" ],
10662                 mode = $.effects.setMode( el, o.mode || "hide" ),
10663                 show = mode === "show",
10664                 direction = o.direction || "left",
10665                 ref = ( direction === "up" || direction === "down" ) ? "top" : "left",
10666                 motion = ( direction === "up" || direction === "left" ) ? "pos" : "neg",
10667                 animation = {
10668                         opacity: show ? 1 : 0
10669                 },
10670                 distance;
10671
10672         // Adjust
10673         $.effects.save( el, props );
10674         el.show();
10675         $.effects.createWrapper( el );
10676
10677         distance = o.distance || el[ ref === "top" ? "outerHeight": "outerWidth" ]( true ) / 2;
10678
10679         if ( show ) {
10680                 el
10681                         .css( "opacity", 0 )
10682                         .css( ref, motion === "pos" ? -distance : distance );
10683         }
10684
10685         // Animation
10686         animation[ ref ] = ( show ?
10687                 ( motion === "pos" ? "+=" : "-=" ) :
10688                 ( motion === "pos" ? "-=" : "+=" ) ) +
10689                 distance;
10690
10691         // Animate
10692         el.animate( animation, {
10693                 queue: false,
10694                 duration: o.duration,
10695                 easing: o.easing,
10696                 complete: function() {
10697                         if ( mode === "hide" ) {
10698                                 el.hide();
10699                         }
10700                         $.effects.restore( el, props );
10701                         $.effects.removeWrapper( el );
10702                         done();
10703                 }
10704         });
10705 };
10706
10707 })(jQuery);
10708
10709 (function( $, undefined ) {
10710
10711 $.effects.effect.explode = function( o, done ) {
10712
10713         var rows = o.pieces ? Math.round( Math.sqrt( o.pieces ) ) : 3,
10714                 cells = rows,
10715                 el = $( this ),
10716                 mode = $.effects.setMode( el, o.mode || "hide" ),
10717                 show = mode === "show",
10718
10719                 // show and then visibility:hidden the element before calculating offset
10720                 offset = el.show().css( "visibility", "hidden" ).offset(),
10721
10722                 // width and height of a piece
10723                 width = Math.ceil( el.outerWidth() / cells ),
10724                 height = Math.ceil( el.outerHeight() / rows ),
10725                 pieces = [],
10726
10727                 // loop
10728                 i, j, left, top, mx, my;
10729
10730         // children animate complete:
10731         function childComplete() {
10732                 pieces.push( this );
10733                 if ( pieces.length === rows * cells ) {
10734                         animComplete();
10735                 }
10736         }
10737
10738         // clone the element for each row and cell.
10739         for( i = 0; i < rows ; i++ ) { // ===>
10740                 top = offset.top + i * height;
10741                 my = i - ( rows - 1 ) / 2 ;
10742
10743                 for( j = 0; j < cells ; j++ ) { // |||
10744                         left = offset.left + j * width;
10745                         mx = j - ( cells - 1 ) / 2 ;
10746
10747                         // Create a clone of the now hidden main element that will be absolute positioned
10748                         // within a wrapper div off the -left and -top equal to size of our pieces
10749                         el
10750                                 .clone()
10751                                 .appendTo( "body" )
10752                                 .wrap( "<div></div>" )
10753                                 .css({
10754                                         position: "absolute",
10755                                         visibility: "visible",
10756                                         left: -j * width,
10757                                         top: -i * height
10758                                 })
10759
10760                         // select the wrapper - make it overflow: hidden and absolute positioned based on
10761                         // where the original was located +left and +top equal to the size of pieces
10762                                 .parent()
10763                                 .addClass( "ui-effects-explode" )
10764                                 .css({
10765                                         position: "absolute",
10766                                         overflow: "hidden",
10767                                         width: width,
10768                                         height: height,
10769                                         left: left + ( show ? mx * width : 0 ),
10770                                         top: top + ( show ? my * height : 0 ),
10771                                         opacity: show ? 0 : 1
10772                                 }).animate({
10773                                         left: left + ( show ? 0 : mx * width ),
10774                                         top: top + ( show ? 0 : my * height ),
10775                                         opacity: show ? 1 : 0
10776                                 }, o.duration || 500, o.easing, childComplete );
10777                 }
10778         }
10779
10780         function animComplete() {
10781                 el.css({
10782                         visibility: "visible"
10783                 });
10784                 $( pieces ).remove();
10785                 if ( !show ) {
10786                         el.hide();
10787                 }
10788                 done();
10789         }
10790 };
10791
10792 })(jQuery);
10793
10794 (function( $, undefined ) {
10795
10796 $.effects.effect.fade = function( o, done ) {
10797         var el = $( this ),
10798                 mode = $.effects.setMode( el, o.mode || "toggle" );
10799
10800         el.animate({
10801                 opacity: mode
10802         }, {
10803                 queue: false,
10804                 duration: o.duration,
10805                 easing: o.easing,
10806                 complete: done
10807         });
10808 };
10809
10810 })( jQuery );
10811
10812 (function( $, undefined ) {
10813
10814 $.effects.effect.fold = function( o, done ) {
10815
10816         // Create element
10817         var el = $( this ),
10818                 props = [ "position", "top", "bottom", "left", "right", "height", "width" ],
10819                 mode = $.effects.setMode( el, o.mode || "hide" ),
10820                 show = mode === "show",
10821                 hide = mode === "hide",
10822                 size = o.size || 15,
10823                 percent = /([0-9]+)%/.exec( size ),
10824                 horizFirst = !!o.horizFirst,
10825                 widthFirst = show !== horizFirst,
10826                 ref = widthFirst ? [ "width", "height" ] : [ "height", "width" ],
10827                 duration = o.duration / 2,
10828                 wrapper, distance,
10829                 animation1 = {},
10830                 animation2 = {};
10831
10832         $.effects.save( el, props );
10833         el.show();
10834
10835         // Create Wrapper
10836         wrapper = $.effects.createWrapper( el ).css({
10837                 overflow: "hidden"
10838         });
10839         distance = widthFirst ?
10840                 [ wrapper.width(), wrapper.height() ] :
10841                 [ wrapper.height(), wrapper.width() ];
10842
10843         if ( percent ) {
10844                 size = parseInt( percent[ 1 ], 10 ) / 100 * distance[ hide ? 0 : 1 ];
10845         }
10846         if ( show ) {
10847                 wrapper.css( horizFirst ? {
10848                         height: 0,
10849                         width: size
10850                 } : {
10851                         height: size,
10852                         width: 0
10853                 });
10854         }
10855
10856         // Animation
10857         animation1[ ref[ 0 ] ] = show ? distance[ 0 ] : size;
10858         animation2[ ref[ 1 ] ] = show ? distance[ 1 ] : 0;
10859
10860         // Animate
10861         wrapper
10862                 .animate( animation1, duration, o.easing )
10863                 .animate( animation2, duration, o.easing, function() {
10864                         if ( hide ) {
10865                                 el.hide();
10866                         }
10867                         $.effects.restore( el, props );
10868                         $.effects.removeWrapper( el );
10869                         done();
10870                 });
10871
10872 };
10873
10874 })(jQuery);
10875
10876 (function( $, undefined ) {
10877
10878 $.effects.effect.highlight = function( o, done ) {
10879         var elem = $( this ),
10880                 props = [ "backgroundImage", "backgroundColor", "opacity" ],
10881                 mode = $.effects.setMode( elem, o.mode || "show" ),
10882                 animation = {
10883                         backgroundColor: elem.css( "backgroundColor" )
10884                 };
10885
10886         if (mode === "hide") {
10887                 animation.opacity = 0;
10888         }
10889
10890         $.effects.save( elem, props );
10891
10892         elem
10893                 .show()
10894                 .css({
10895                         backgroundImage: "none",
10896                         backgroundColor: o.color || "#ffff99"
10897                 })
10898                 .animate( animation, {
10899                         queue: false,
10900                         duration: o.duration,
10901                         easing: o.easing,
10902                         complete: function() {
10903                                 if ( mode === "hide" ) {
10904                                         elem.hide();
10905                                 }
10906                                 $.effects.restore( elem, props );
10907                                 done();
10908                         }
10909                 });
10910 };
10911
10912 })(jQuery);
10913
10914 (function( $, undefined ) {
10915
10916 $.effects.effect.pulsate = function( o, done ) {
10917         var elem = $( this ),
10918                 mode = $.effects.setMode( elem, o.mode || "show" ),
10919                 show = mode === "show",
10920                 hide = mode === "hide",
10921                 showhide = ( show || mode === "hide" ),
10922
10923                 // showing or hiding leaves of the "last" animation
10924                 anims = ( ( o.times || 5 ) * 2 ) + ( showhide ? 1 : 0 ),
10925                 duration = o.duration / anims,
10926                 animateTo = 0,
10927                 queue = elem.queue(),
10928                 queuelen = queue.length,
10929                 i;
10930
10931         if ( show || !elem.is(":visible")) {
10932                 elem.css( "opacity", 0 ).show();
10933                 animateTo = 1;
10934         }
10935
10936         // anims - 1 opacity "toggles"
10937         for ( i = 1; i < anims; i++ ) {
10938                 elem.animate({
10939                         opacity: animateTo
10940                 }, duration, o.easing );
10941                 animateTo = 1 - animateTo;
10942         }
10943
10944         elem.animate({
10945                 opacity: animateTo
10946         }, duration, o.easing);
10947
10948         elem.queue(function() {
10949                 if ( hide ) {
10950                         elem.hide();
10951                 }
10952                 done();
10953         });
10954
10955         // We just queued up "anims" animations, we need to put them next in the queue
10956         if ( queuelen > 1 ) {
10957                 queue.splice.apply( queue,
10958                         [ 1, 0 ].concat( queue.splice( queuelen, anims + 1 ) ) );
10959         }
10960         elem.dequeue();
10961 };
10962
10963 })(jQuery);
10964
10965 (function( $, undefined ) {
10966
10967 $.effects.effect.puff = function( o, done ) {
10968         var elem = $( this ),
10969                 mode = $.effects.setMode( elem, o.mode || "hide" ),
10970                 hide = mode === "hide",
10971                 percent = parseInt( o.percent, 10 ) || 150,
10972                 factor = percent / 100,
10973                 original = {
10974                         height: elem.height(),
10975                         width: elem.width(),
10976                         outerHeight: elem.outerHeight(),
10977                         outerWidth: elem.outerWidth()
10978                 };
10979
10980         $.extend( o, {
10981                 effect: "scale",
10982                 queue: false,
10983                 fade: true,
10984                 mode: mode,
10985                 complete: done,
10986                 percent: hide ? percent : 100,
10987                 from: hide ?
10988                         original :
10989                         {
10990                                 height: original.height * factor,
10991                                 width: original.width * factor,
10992                                 outerHeight: original.outerHeight * factor,
10993                                 outerWidth: original.outerWidth * factor
10994                         }
10995         });
10996
10997         elem.effect( o );
10998 };
10999
11000 $.effects.effect.scale = function( o, done ) {
11001
11002         // Create element
11003         var el = $( this ),
11004                 options = $.extend( true, {}, o ),
11005                 mode = $.effects.setMode( el, o.mode || "effect" ),
11006                 percent = parseInt( o.percent, 10 ) ||
11007                         ( parseInt( o.percent, 10 ) === 0 ? 0 : ( mode === "hide" ? 0 : 100 ) ),
11008                 direction = o.direction || "both",
11009                 origin = o.origin,
11010                 original = {
11011                         height: el.height(),
11012                         width: el.width(),
11013                         outerHeight: el.outerHeight(),
11014                         outerWidth: el.outerWidth()
11015                 },
11016                 factor = {
11017                         y: direction !== "horizontal" ? (percent / 100) : 1,
11018                         x: direction !== "vertical" ? (percent / 100) : 1
11019                 };
11020
11021         // We are going to pass this effect to the size effect:
11022         options.effect = "size";
11023         options.queue = false;
11024         options.complete = done;
11025
11026         // Set default origin and restore for show/hide
11027         if ( mode !== "effect" ) {
11028                 options.origin = origin || ["middle","center"];
11029                 options.restore = true;
11030         }
11031
11032         options.from = o.from || ( mode === "show" ? {
11033                 height: 0,
11034                 width: 0,
11035                 outerHeight: 0,
11036                 outerWidth: 0
11037         } : original );
11038         options.to = {
11039                 height: original.height * factor.y,
11040                 width: original.width * factor.x,
11041                 outerHeight: original.outerHeight * factor.y,
11042                 outerWidth: original.outerWidth * factor.x
11043         };
11044
11045         // Fade option to support puff
11046         if ( options.fade ) {
11047                 if ( mode === "show" ) {
11048                         options.from.opacity = 0;
11049                         options.to.opacity = 1;
11050                 }
11051                 if ( mode === "hide" ) {
11052                         options.from.opacity = 1;
11053                         options.to.opacity = 0;
11054                 }
11055         }
11056
11057         // Animate
11058         el.effect( options );
11059
11060 };
11061
11062 $.effects.effect.size = function( o, done ) {
11063
11064         // Create element
11065         var original, baseline, factor,
11066                 el = $( this ),
11067                 props0 = [ "position", "top", "bottom", "left", "right", "width", "height", "overflow", "opacity" ],
11068
11069                 // Always restore
11070                 props1 = [ "position", "top", "bottom", "left", "right", "overflow", "opacity" ],
11071
11072                 // Copy for children
11073                 props2 = [ "width", "height", "overflow" ],
11074                 cProps = [ "fontSize" ],
11075                 vProps = [ "borderTopWidth", "borderBottomWidth", "paddingTop", "paddingBottom" ],
11076                 hProps = [ "borderLeftWidth", "borderRightWidth", "paddingLeft", "paddingRight" ],
11077
11078                 // Set options
11079                 mode = $.effects.setMode( el, o.mode || "effect" ),
11080                 restore = o.restore || mode !== "effect",
11081                 scale = o.scale || "both",
11082                 origin = o.origin || [ "middle", "center" ],
11083                 position = el.css( "position" ),
11084                 props = restore ? props0 : props1,
11085                 zero = {
11086                         height: 0,
11087                         width: 0,
11088                         outerHeight: 0,
11089                         outerWidth: 0
11090                 };
11091
11092         if ( mode === "show" ) {
11093                 el.show();
11094         }
11095         original = {
11096                 height: el.height(),
11097                 width: el.width(),
11098                 outerHeight: el.outerHeight(),
11099                 outerWidth: el.outerWidth()
11100         };
11101
11102         if ( o.mode === "toggle" && mode === "show" ) {
11103                 el.from = o.to || zero;
11104                 el.to = o.from || original;
11105         } else {
11106                 el.from = o.from || ( mode === "show" ? zero : original );
11107                 el.to = o.to || ( mode === "hide" ? zero : original );
11108         }
11109
11110         // Set scaling factor
11111         factor = {
11112                 from: {
11113                         y: el.from.height / original.height,
11114                         x: el.from.width / original.width
11115                 },
11116                 to: {
11117                         y: el.to.height / original.height,
11118                         x: el.to.width / original.width
11119                 }
11120         };
11121
11122         // Scale the css box
11123         if ( scale === "box" || scale === "both" ) {
11124
11125                 // Vertical props scaling
11126                 if ( factor.from.y !== factor.to.y ) {
11127                         props = props.concat( vProps );
11128                         el.from = $.effects.setTransition( el, vProps, factor.from.y, el.from );
11129                         el.to = $.effects.setTransition( el, vProps, factor.to.y, el.to );
11130                 }
11131
11132                 // Horizontal props scaling
11133                 if ( factor.from.x !== factor.to.x ) {
11134                         props = props.concat( hProps );
11135                         el.from = $.effects.setTransition( el, hProps, factor.from.x, el.from );
11136                         el.to = $.effects.setTransition( el, hProps, factor.to.x, el.to );
11137                 }
11138         }
11139
11140         // Scale the content
11141         if ( scale === "content" || scale === "both" ) {
11142
11143                 // Vertical props scaling
11144                 if ( factor.from.y !== factor.to.y ) {
11145                         props = props.concat( cProps ).concat( props2 );
11146                         el.from = $.effects.setTransition( el, cProps, factor.from.y, el.from );
11147                         el.to = $.effects.setTransition( el, cProps, factor.to.y, el.to );
11148                 }
11149         }
11150
11151         $.effects.save( el, props );
11152         el.show();
11153         $.effects.createWrapper( el );
11154         el.css( "overflow", "hidden" ).css( el.from );
11155
11156         // Adjust
11157         if (origin) { // Calculate baseline shifts
11158                 baseline = $.effects.getBaseline( origin, original );
11159                 el.from.top = ( original.outerHeight - el.outerHeight() ) * baseline.y;
11160                 el.from.left = ( original.outerWidth - el.outerWidth() ) * baseline.x;
11161                 el.to.top = ( original.outerHeight - el.to.outerHeight ) * baseline.y;
11162                 el.to.left = ( original.outerWidth - el.to.outerWidth ) * baseline.x;
11163         }
11164         el.css( el.from ); // set top & left
11165
11166         // Animate
11167         if ( scale === "content" || scale === "both" ) { // Scale the children
11168
11169                 // Add margins/font-size
11170                 vProps = vProps.concat([ "marginTop", "marginBottom" ]).concat(cProps);
11171                 hProps = hProps.concat([ "marginLeft", "marginRight" ]);
11172                 props2 = props0.concat(vProps).concat(hProps);
11173
11174                 el.find( "*[width]" ).each( function(){
11175                         var child = $( this ),
11176                                 c_original = {
11177                                         height: child.height(),
11178                                         width: child.width(),
11179                                         outerHeight: child.outerHeight(),
11180                                         outerWidth: child.outerWidth()
11181                                 };
11182                         if (restore) {
11183                                 $.effects.save(child, props2);
11184                         }
11185
11186                         child.from = {
11187                                 height: c_original.height * factor.from.y,
11188                                 width: c_original.width * factor.from.x,
11189                                 outerHeight: c_original.outerHeight * factor.from.y,
11190                                 outerWidth: c_original.outerWidth * factor.from.x
11191                         };
11192                         child.to = {
11193                                 height: c_original.height * factor.to.y,
11194                                 width: c_original.width * factor.to.x,
11195                                 outerHeight: c_original.height * factor.to.y,
11196                                 outerWidth: c_original.width * factor.to.x
11197                         };
11198
11199                         // Vertical props scaling
11200                         if ( factor.from.y !== factor.to.y ) {
11201                                 child.from = $.effects.setTransition( child, vProps, factor.from.y, child.from );
11202                                 child.to = $.effects.setTransition( child, vProps, factor.to.y, child.to );
11203                         }
11204
11205                         // Horizontal props scaling
11206                         if ( factor.from.x !== factor.to.x ) {
11207                                 child.from = $.effects.setTransition( child, hProps, factor.from.x, child.from );
11208                                 child.to = $.effects.setTransition( child, hProps, factor.to.x, child.to );
11209                         }
11210
11211                         // Animate children
11212                         child.css( child.from );
11213                         child.animate( child.to, o.duration, o.easing, function() {
11214
11215                                 // Restore children
11216                                 if ( restore ) {
11217                                         $.effects.restore( child, props2 );
11218                                 }
11219                         });
11220                 });
11221         }
11222
11223         // Animate
11224         el.animate( el.to, {
11225                 queue: false,
11226                 duration: o.duration,
11227                 easing: o.easing,
11228                 complete: function() {
11229                         if ( el.to.opacity === 0 ) {
11230                                 el.css( "opacity", el.from.opacity );
11231                         }
11232                         if( mode === "hide" ) {
11233                                 el.hide();
11234                         }
11235                         $.effects.restore( el, props );
11236                         if ( !restore ) {
11237
11238                                 // we need to calculate our new positioning based on the scaling
11239                                 if ( position === "static" ) {
11240                                         el.css({
11241                                                 position: "relative",
11242                                                 top: el.to.top,
11243                                                 left: el.to.left
11244                                         });
11245                                 } else {
11246                                         $.each([ "top", "left" ], function( idx, pos ) {
11247                                                 el.css( pos, function( _, str ) {
11248                                                         var val = parseInt( str, 10 ),
11249                                                                 toRef = idx ? el.to.left : el.to.top;
11250
11251                                                         // if original was "auto", recalculate the new value from wrapper
11252                                                         if ( str === "auto" ) {
11253                                                                 return toRef + "px";
11254                                                         }
11255
11256                                                         return val + toRef + "px";
11257                                                 });
11258                                         });
11259                                 }
11260                         }
11261
11262                         $.effects.removeWrapper( el );
11263                         done();
11264                 }
11265         });
11266
11267 };
11268
11269 })(jQuery);
11270
11271 (function( $, undefined ) {
11272
11273 $.effects.effect.shake = function( o, done ) {
11274
11275         var el = $( this ),
11276                 props = [ "position", "top", "bottom", "left", "right", "height", "width" ],
11277                 mode = $.effects.setMode( el, o.mode || "effect" ),
11278                 direction = o.direction || "left",
11279                 distance = o.distance || 20,
11280                 times = o.times || 3,
11281                 anims = times * 2 + 1,
11282                 speed = Math.round(o.duration/anims),
11283                 ref = (direction === "up" || direction === "down") ? "top" : "left",
11284                 positiveMotion = (direction === "up" || direction === "left"),
11285                 animation = {},
11286                 animation1 = {},
11287                 animation2 = {},
11288                 i,
11289
11290                 // we will need to re-assemble the queue to stack our animations in place
11291                 queue = el.queue(),
11292                 queuelen = queue.length;
11293
11294         $.effects.save( el, props );
11295         el.show();
11296         $.effects.createWrapper( el );
11297
11298         // Animation
11299         animation[ ref ] = ( positiveMotion ? "-=" : "+=" ) + distance;
11300         animation1[ ref ] = ( positiveMotion ? "+=" : "-=" ) + distance * 2;
11301         animation2[ ref ] = ( positiveMotion ? "-=" : "+=" ) + distance * 2;
11302
11303         // Animate
11304         el.animate( animation, speed, o.easing );
11305
11306         // Shakes
11307         for ( i = 1; i < times; i++ ) {
11308                 el.animate( animation1, speed, o.easing ).animate( animation2, speed, o.easing );
11309         }
11310         el
11311                 .animate( animation1, speed, o.easing )
11312                 .animate( animation, speed / 2, o.easing )
11313                 .queue(function() {
11314                         if ( mode === "hide" ) {
11315                                 el.hide();
11316                         }
11317                         $.effects.restore( el, props );
11318                         $.effects.removeWrapper( el );
11319                         done();
11320                 });
11321
11322         // inject all the animations we just queued to be first in line (after "inprogress")
11323         if ( queuelen > 1) {
11324                 queue.splice.apply( queue,
11325                         [ 1, 0 ].concat( queue.splice( queuelen, anims + 1 ) ) );
11326         }
11327         el.dequeue();
11328
11329 };
11330
11331 })(jQuery);
11332
11333 (function( $, undefined ) {
11334
11335 $.effects.effect.slide = function( o, done ) {
11336
11337         // Create element
11338         var el = $( this ),
11339                 props = [ "position", "top", "bottom", "left", "right", "width", "height" ],
11340                 mode = $.effects.setMode( el, o.mode || "show" ),
11341                 show = mode === "show",
11342                 direction = o.direction || "left",
11343                 ref = (direction === "up" || direction === "down") ? "top" : "left",
11344                 positiveMotion = (direction === "up" || direction === "left"),
11345                 distance,
11346                 animation = {};
11347
11348         // Adjust
11349         $.effects.save( el, props );
11350         el.show();
11351         distance = o.distance || el[ ref === "top" ? "outerHeight" : "outerWidth" ]( true );
11352
11353         $.effects.createWrapper( el ).css({
11354                 overflow: "hidden"
11355         });
11356
11357         if ( show ) {
11358                 el.css( ref, positiveMotion ? (isNaN(distance) ? "-" + distance : -distance) : distance );
11359         }
11360
11361         // Animation
11362         animation[ ref ] = ( show ?
11363                 ( positiveMotion ? "+=" : "-=") :
11364                 ( positiveMotion ? "-=" : "+=")) +
11365                 distance;
11366
11367         // Animate
11368         el.animate( animation, {
11369                 queue: false,
11370                 duration: o.duration,
11371                 easing: o.easing,
11372                 complete: function() {
11373                         if ( mode === "hide" ) {
11374                                 el.hide();
11375                         }
11376                         $.effects.restore( el, props );
11377                         $.effects.removeWrapper( el );
11378                         done();
11379                 }
11380         });
11381 };
11382
11383 })(jQuery);
11384
11385 (function( $, undefined ) {
11386
11387 $.effects.effect.transfer = function( o, done ) {
11388         var elem = $( this ),
11389                 target = $( o.to ),
11390                 targetFixed = target.css( "position" ) === "fixed",
11391                 body = $("body"),
11392                 fixTop = targetFixed ? body.scrollTop() : 0,
11393                 fixLeft = targetFixed ? body.scrollLeft() : 0,
11394                 endPosition = target.offset(),
11395                 animation = {
11396                         top: endPosition.top - fixTop ,
11397                         left: endPosition.left - fixLeft ,
11398                         height: target.innerHeight(),
11399                         width: target.innerWidth()
11400                 },
11401                 startPosition = elem.offset(),
11402                 transfer = $( "<div class='ui-effects-transfer'></div>" )
11403                         .appendTo( document.body )
11404                         .addClass( o.className )
11405                         .css({
11406                                 top: startPosition.top - fixTop ,
11407                                 left: startPosition.left - fixLeft ,
11408                                 height: elem.innerHeight(),
11409                                 width: elem.innerWidth(),
11410                                 position: targetFixed ? "fixed" : "absolute"
11411                         })
11412                         .animate( animation, o.duration, o.easing, function() {
11413                                 transfer.remove();
11414                                 done();
11415                         });
11416 };
11417
11418 })(jQuery);
11419
11420 (function( $, undefined ) {
11421
11422 $.widget( "ui.menu", {
11423         version: "1.10.3",
11424         defaultElement: "<ul>",
11425         delay: 300,
11426         options: {
11427                 icons: {
11428                         submenu: "ui-icon-carat-1-e"
11429                 },
11430                 menus: "ul",
11431                 position: {
11432                         my: "left top",
11433                         at: "right top"
11434                 },
11435                 role: "menu",
11436
11437                 // callbacks
11438                 blur: null,
11439                 focus: null,
11440                 select: null
11441         },
11442
11443         _create: function() {
11444                 this.activeMenu = this.element;
11445                 // flag used to prevent firing of the click handler
11446                 // as the event bubbles up through nested menus
11447                 this.mouseHandled = false;
11448                 this.element
11449                         .uniqueId()
11450                         .addClass( "ui-menu ui-widget ui-widget-content ui-corner-all" )
11451                         .toggleClass( "ui-menu-icons", !!this.element.find( ".ui-icon" ).length )
11452                         .attr({
11453                                 role: this.options.role,
11454                                 tabIndex: 0
11455                         })
11456                         // need to catch all clicks on disabled menu
11457                         // not possible through _on
11458                         .bind( "click" + this.eventNamespace, $.proxy(function( event ) {
11459                                 if ( this.options.disabled ) {
11460                                         event.preventDefault();
11461                                 }
11462                         }, this ));
11463
11464                 if ( this.options.disabled ) {
11465                         this.element
11466                                 .addClass( "ui-state-disabled" )
11467                                 .attr( "aria-disabled", "true" );
11468                 }
11469
11470                 this._on({
11471                         // Prevent focus from sticking to links inside menu after clicking
11472                         // them (focus should always stay on UL during navigation).
11473                         "mousedown .ui-menu-item > a": function( event ) {
11474                                 event.preventDefault();
11475                         },
11476                         "click .ui-state-disabled > a": function( event ) {
11477                                 event.preventDefault();
11478                         },
11479                         "click .ui-menu-item:has(a)": function( event ) {
11480                                 var target = $( event.target ).closest( ".ui-menu-item" );
11481                                 if ( !this.mouseHandled && target.not( ".ui-state-disabled" ).length ) {
11482                                         this.mouseHandled = true;
11483
11484                                         this.select( event );
11485                                         // Open submenu on click
11486                                         if ( target.has( ".ui-menu" ).length ) {
11487                                                 this.expand( event );
11488                                         } else if ( !this.element.is( ":focus" ) ) {
11489                                                 // Redirect focus to the menu
11490                                                 this.element.trigger( "focus", [ true ] );
11491
11492                                                 // If the active item is on the top level, let it stay active.
11493                                                 // Otherwise, blur the active item since it is no longer visible.
11494                                                 if ( this.active && this.active.parents( ".ui-menu" ).length === 1 ) {
11495                                                         clearTimeout( this.timer );
11496                                                 }
11497                                         }
11498                                 }
11499                         },
11500                         "mouseenter .ui-menu-item": function( event ) {
11501                                 var target = $( event.currentTarget );
11502                                 // Remove ui-state-active class from siblings of the newly focused menu item
11503                                 // to avoid a jump caused by adjacent elements both having a class with a border
11504                                 target.siblings().children( ".ui-state-active" ).removeClass( "ui-state-active" );
11505                                 this.focus( event, target );
11506                         },
11507                         mouseleave: "collapseAll",
11508                         "mouseleave .ui-menu": "collapseAll",
11509                         focus: function( event, keepActiveItem ) {
11510                                 // If there's already an active item, keep it active
11511                                 // If not, activate the first item
11512                                 var item = this.active || this.element.children( ".ui-menu-item" ).eq( 0 );
11513
11514                                 if ( !keepActiveItem ) {
11515                                         this.focus( event, item );
11516                                 }
11517                         },
11518                         blur: function( event ) {
11519                                 this._delay(function() {
11520                                         if ( !$.contains( this.element[0], this.document[0].activeElement ) ) {
11521                                                 this.collapseAll( event );
11522                                         }
11523                                 });
11524                         },
11525                         keydown: "_keydown"
11526                 });
11527
11528                 this.refresh();
11529
11530                 // Clicks outside of a menu collapse any open menus
11531                 this._on( this.document, {
11532                         click: function( event ) {
11533                                 if ( !$( event.target ).closest( ".ui-menu" ).length ) {
11534                                         this.collapseAll( event );
11535                                 }
11536
11537                                 // Reset the mouseHandled flag
11538                                 this.mouseHandled = false;
11539                         }
11540                 });
11541         },
11542
11543         _destroy: function() {
11544                 // Destroy (sub)menus
11545                 this.element
11546                         .removeAttr( "aria-activedescendant" )
11547                         .find( ".ui-menu" ).addBack()
11548                                 .removeClass( "ui-menu ui-widget ui-widget-content ui-corner-all ui-menu-icons" )
11549                                 .removeAttr( "role" )
11550                                 .removeAttr( "tabIndex" )
11551                                 .removeAttr( "aria-labelledby" )
11552                                 .removeAttr( "aria-expanded" )
11553                                 .removeAttr( "aria-hidden" )
11554                                 .removeAttr( "aria-disabled" )
11555                                 .removeUniqueId()
11556                                 .show();
11557
11558                 // Destroy menu items
11559                 this.element.find( ".ui-menu-item" )
11560                         .removeClass( "ui-menu-item" )
11561                         .removeAttr( "role" )
11562                         .removeAttr( "aria-disabled" )
11563                         .children( "a" )
11564                                 .removeUniqueId()
11565                                 .removeClass( "ui-corner-all ui-state-hover" )
11566                                 .removeAttr( "tabIndex" )
11567                                 .removeAttr( "role" )
11568                                 .removeAttr( "aria-haspopup" )
11569                                 .children().each( function() {
11570                                         var elem = $( this );
11571                                         if ( elem.data( "ui-menu-submenu-carat" ) ) {
11572                                                 elem.remove();
11573                                         }
11574                                 });
11575
11576                 // Destroy menu dividers
11577                 this.element.find( ".ui-menu-divider" ).removeClass( "ui-menu-divider ui-widget-content" );
11578         },
11579
11580         _keydown: function( event ) {
11581                 /*jshint maxcomplexity:20*/
11582                 var match, prev, character, skip, regex,
11583                         preventDefault = true;
11584
11585                 function escape( value ) {
11586                         return value.replace( /[\-\[\]{}()*+?.,\\\^$|#\s]/g, "\\$&" );
11587                 }
11588
11589                 switch ( event.keyCode ) {
11590                 case $.ui.keyCode.PAGE_UP:
11591                         this.previousPage( event );
11592                         break;
11593                 case $.ui.keyCode.PAGE_DOWN:
11594                         this.nextPage( event );
11595                         break;
11596                 case $.ui.keyCode.HOME:
11597                         this._move( "first", "first", event );
11598                         break;
11599                 case $.ui.keyCode.END:
11600                         this._move( "last", "last", event );
11601                         break;
11602                 case $.ui.keyCode.UP:
11603                         this.previous( event );
11604                         break;
11605                 case $.ui.keyCode.DOWN:
11606                         this.next( event );
11607                         break;
11608                 case $.ui.keyCode.LEFT:
11609                         this.collapse( event );
11610                         break;
11611                 case $.ui.keyCode.RIGHT:
11612                         if ( this.active && !this.active.is( ".ui-state-disabled" ) ) {
11613                                 this.expand( event );
11614                         }
11615                         break;
11616                 case $.ui.keyCode.ENTER:
11617                 case $.ui.keyCode.SPACE:
11618                         this._activate( event );
11619                         break;
11620                 case $.ui.keyCode.ESCAPE:
11621                         this.collapse( event );
11622                         break;
11623                 default:
11624                         preventDefault = false;
11625                         prev = this.previousFilter || "";
11626                         character = String.fromCharCode( event.keyCode );
11627                         skip = false;
11628
11629                         clearTimeout( this.filterTimer );
11630
11631                         if ( character === prev ) {
11632                                 skip = true;
11633                         } else {
11634                                 character = prev + character;
11635                         }
11636
11637                         regex = new RegExp( "^" + escape( character ), "i" );
11638                         match = this.activeMenu.children( ".ui-menu-item" ).filter(function() {
11639                                 return regex.test( $( this ).children( "a" ).text() );
11640                         });
11641                         match = skip && match.index( this.active.next() ) !== -1 ?
11642                                 this.active.nextAll( ".ui-menu-item" ) :
11643                                 match;
11644
11645                         // If no matches on the current filter, reset to the last character pressed
11646                         // to move down the menu to the first item that starts with that character
11647                         if ( !match.length ) {
11648                                 character = String.fromCharCode( event.keyCode );
11649                                 regex = new RegExp( "^" + escape( character ), "i" );
11650                                 match = this.activeMenu.children( ".ui-menu-item" ).filter(function() {
11651                                         return regex.test( $( this ).children( "a" ).text() );
11652                                 });
11653                         }
11654
11655                         if ( match.length ) {
11656                                 this.focus( event, match );
11657                                 if ( match.length > 1 ) {
11658                                         this.previousFilter = character;
11659                                         this.filterTimer = this._delay(function() {
11660                                                 delete this.previousFilter;
11661                                         }, 1000 );
11662                                 } else {
11663                                         delete this.previousFilter;
11664                                 }
11665                         } else {
11666                                 delete this.previousFilter;
11667                         }
11668                 }
11669
11670                 if ( preventDefault ) {
11671                         event.preventDefault();
11672                 }
11673         },
11674
11675         _activate: function( event ) {
11676                 if ( !this.active.is( ".ui-state-disabled" ) ) {
11677                         if ( this.active.children( "a[aria-haspopup='true']" ).length ) {
11678                                 this.expand( event );
11679                         } else {
11680                                 this.select( event );
11681                         }
11682                 }
11683         },
11684
11685         refresh: function() {
11686                 var menus,
11687                         icon = this.options.icons.submenu,
11688                         submenus = this.element.find( this.options.menus );
11689
11690                 // Initialize nested menus
11691                 submenus.filter( ":not(.ui-menu)" )
11692                         .addClass( "ui-menu ui-widget ui-widget-content ui-corner-all" )
11693                         .hide()
11694                         .attr({
11695                                 role: this.options.role,
11696                                 "aria-hidden": "true",
11697                                 "aria-expanded": "false"
11698                         })
11699                         .each(function() {
11700                                 var menu = $( this ),
11701                                         item = menu.prev( "a" ),
11702                                         submenuCarat = $( "<span>" )
11703                                                 .addClass( "ui-menu-icon ui-icon " + icon )
11704                                                 .data( "ui-menu-submenu-carat", true );
11705
11706                                 item
11707                                         .attr( "aria-haspopup", "true" )
11708                                         .prepend( submenuCarat );
11709                                 menu.attr( "aria-labelledby", item.attr( "id" ) );
11710                         });
11711
11712                 menus = submenus.add( this.element );
11713
11714                 // Don't refresh list items that are already adapted
11715                 menus.children( ":not(.ui-menu-item):has(a)" )
11716                         .addClass( "ui-menu-item" )
11717                         .attr( "role", "presentation" )
11718                         .children( "a" )
11719                                 .uniqueId()
11720                                 .addClass( "ui-corner-all" )
11721                                 .attr({
11722                                         tabIndex: -1,
11723                                         role: this._itemRole()
11724                                 });
11725
11726                 // Initialize unlinked menu-items containing spaces and/or dashes only as dividers
11727                 menus.children( ":not(.ui-menu-item)" ).each(function() {
11728                         var item = $( this );
11729                         // hyphen, em dash, en dash
11730                         if ( !/[^\-\u2014\u2013\s]/.test( item.text() ) ) {
11731                                 item.addClass( "ui-widget-content ui-menu-divider" );
11732                         }
11733                 });
11734
11735                 // Add aria-disabled attribute to any disabled menu item
11736                 menus.children( ".ui-state-disabled" ).attr( "aria-disabled", "true" );
11737
11738                 // If the active item has been removed, blur the menu
11739                 if ( this.active && !$.contains( this.element[ 0 ], this.active[ 0 ] ) ) {
11740                         this.blur();
11741                 }
11742         },
11743
11744         _itemRole: function() {
11745                 return {
11746                         menu: "menuitem",
11747                         listbox: "option"
11748                 }[ this.options.role ];
11749         },
11750
11751         _setOption: function( key, value ) {
11752                 if ( key === "icons" ) {
11753                         this.element.find( ".ui-menu-icon" )
11754                                 .removeClass( this.options.icons.submenu )
11755                                 .addClass( value.submenu );
11756                 }
11757                 this._super( key, value );
11758         },
11759
11760         focus: function( event, item ) {
11761                 var nested, focused;
11762                 this.blur( event, event && event.type === "focus" );
11763
11764                 this._scrollIntoView( item );
11765
11766                 this.active = item.first();
11767                 focused = this.active.children( "a" ).addClass( "ui-state-focus" );
11768                 // Only update aria-activedescendant if there's a role
11769                 // otherwise we assume focus is managed elsewhere
11770                 if ( this.options.role ) {
11771                         this.element.attr( "aria-activedescendant", focused.attr( "id" ) );
11772                 }
11773
11774                 // Highlight active parent menu item, if any
11775                 this.active
11776                         .parent()
11777                         .closest( ".ui-menu-item" )
11778                         .children( "a:first" )
11779                         .addClass( "ui-state-active" );
11780
11781                 if ( event && event.type === "keydown" ) {
11782                         this._close();
11783                 } else {
11784                         this.timer = this._delay(function() {
11785                                 this._close();
11786                         }, this.delay );
11787                 }
11788
11789                 nested = item.children( ".ui-menu" );
11790                 if ( nested.length && ( /^mouse/.test( event.type ) ) ) {
11791                         this._startOpening(nested);
11792                 }
11793                 this.activeMenu = item.parent();
11794
11795                 this._trigger( "focus", event, { item: item } );
11796         },
11797
11798         _scrollIntoView: function( item ) {
11799                 var borderTop, paddingTop, offset, scroll, elementHeight, itemHeight;
11800                 if ( this._hasScroll() ) {
11801                         borderTop = parseFloat( $.css( this.activeMenu[0], "borderTopWidth" ) ) || 0;
11802                         paddingTop = parseFloat( $.css( this.activeMenu[0], "paddingTop" ) ) || 0;
11803                         offset = item.offset().top - this.activeMenu.offset().top - borderTop - paddingTop;
11804                         scroll = this.activeMenu.scrollTop();
11805                         elementHeight = this.activeMenu.height();
11806                         itemHeight = item.height();
11807
11808                         if ( offset < 0 ) {
11809                                 this.activeMenu.scrollTop( scroll + offset );
11810                         } else if ( offset + itemHeight > elementHeight ) {
11811                                 this.activeMenu.scrollTop( scroll + offset - elementHeight + itemHeight );
11812                         }
11813                 }
11814         },
11815
11816         blur: function( event, fromFocus ) {
11817                 if ( !fromFocus ) {
11818                         clearTimeout( this.timer );
11819                 }
11820
11821                 if ( !this.active ) {
11822                         return;
11823                 }
11824
11825                 this.active.children( "a" ).removeClass( "ui-state-focus" );
11826                 this.active = null;
11827
11828                 this._trigger( "blur", event, { item: this.active } );
11829         },
11830
11831         _startOpening: function( submenu ) {
11832                 clearTimeout( this.timer );
11833
11834                 // Don't open if already open fixes a Firefox bug that caused a .5 pixel
11835                 // shift in the submenu position when mousing over the carat icon
11836                 if ( submenu.attr( "aria-hidden" ) !== "true" ) {
11837                         return;
11838                 }
11839
11840                 this.timer = this._delay(function() {
11841                         this._close();
11842                         this._open( submenu );
11843                 }, this.delay );
11844         },
11845
11846         _open: function( submenu ) {
11847                 var position = $.extend({
11848                         of: this.active
11849                 }, this.options.position );
11850
11851                 clearTimeout( this.timer );
11852                 this.element.find( ".ui-menu" ).not( submenu.parents( ".ui-menu" ) )
11853                         .hide()
11854                         .attr( "aria-hidden", "true" );
11855
11856                 submenu
11857                         .show()
11858                         .removeAttr( "aria-hidden" )
11859                         .attr( "aria-expanded", "true" )
11860                         .position( position );
11861         },
11862
11863         collapseAll: function( event, all ) {
11864                 clearTimeout( this.timer );
11865                 this.timer = this._delay(function() {
11866                         // If we were passed an event, look for the submenu that contains the event
11867                         var currentMenu = all ? this.element :
11868                                 $( event && event.target ).closest( this.element.find( ".ui-menu" ) );
11869
11870                         // If we found no valid submenu ancestor, use the main menu to close all sub menus anyway
11871                         if ( !currentMenu.length ) {
11872                                 currentMenu = this.element;
11873                         }
11874
11875                         this._close( currentMenu );
11876
11877                         this.blur( event );
11878                         this.activeMenu = currentMenu;
11879                 }, this.delay );
11880         },
11881
11882         // With no arguments, closes the currently active menu - if nothing is active
11883         // it closes all menus.  If passed an argument, it will search for menus BELOW
11884         _close: function( startMenu ) {
11885                 if ( !startMenu ) {
11886                         startMenu = this.active ? this.active.parent() : this.element;
11887                 }
11888
11889                 startMenu
11890                         .find( ".ui-menu" )
11891                                 .hide()
11892                                 .attr( "aria-hidden", "true" )
11893                                 .attr( "aria-expanded", "false" )
11894                         .end()
11895                         .find( "a.ui-state-active" )
11896                                 .removeClass( "ui-state-active" );
11897         },
11898
11899         collapse: function( event ) {
11900                 var newItem = this.active &&
11901                         this.active.parent().closest( ".ui-menu-item", this.element );
11902                 if ( newItem && newItem.length ) {
11903                         this._close();
11904                         this.focus( event, newItem );
11905                 }
11906         },
11907
11908         expand: function( event ) {
11909                 var newItem = this.active &&
11910                         this.active
11911                                 .children( ".ui-menu " )
11912                                 .children( ".ui-menu-item" )
11913                                 .first();
11914
11915                 if ( newItem && newItem.length ) {
11916                         this._open( newItem.parent() );
11917
11918                         // Delay so Firefox will not hide activedescendant change in expanding submenu from AT
11919                         this._delay(function() {
11920                                 this.focus( event, newItem );
11921                         });
11922                 }
11923         },
11924
11925         next: function( event ) {
11926                 this._move( "next", "first", event );
11927         },
11928
11929         previous: function( event ) {
11930                 this._move( "prev", "last", event );
11931         },
11932
11933         isFirstItem: function() {
11934                 return this.active && !this.active.prevAll( ".ui-menu-item" ).length;
11935         },
11936
11937         isLastItem: function() {
11938                 return this.active && !this.active.nextAll( ".ui-menu-item" ).length;
11939         },
11940
11941         _move: function( direction, filter, event ) {
11942                 var next;
11943                 if ( this.active ) {
11944                         if ( direction === "first" || direction === "last" ) {
11945                                 next = this.active
11946                                         [ direction === "first" ? "prevAll" : "nextAll" ]( ".ui-menu-item" )
11947                                         .eq( -1 );
11948                         } else {
11949                                 next = this.active
11950                                         [ direction + "All" ]( ".ui-menu-item" )
11951                                         .eq( 0 );
11952                         }
11953                 }
11954                 if ( !next || !next.length || !this.active ) {
11955                         next = this.activeMenu.children( ".ui-menu-item" )[ filter ]();
11956                 }
11957
11958                 this.focus( event, next );
11959         },
11960
11961         nextPage: function( event ) {
11962                 var item, base, height;
11963
11964                 if ( !this.active ) {
11965                         this.next( event );
11966                         return;
11967                 }
11968                 if ( this.isLastItem() ) {
11969                         return;
11970                 }
11971                 if ( this._hasScroll() ) {
11972                         base = this.active.offset().top;
11973                         height = this.element.height();
11974                         this.active.nextAll( ".ui-menu-item" ).each(function() {
11975                                 item = $( this );
11976                                 return item.offset().top - base - height < 0;
11977                         });
11978
11979                         this.focus( event, item );
11980                 } else {
11981                         this.focus( event, this.activeMenu.children( ".ui-menu-item" )
11982                                 [ !this.active ? "first" : "last" ]() );
11983                 }
11984         },
11985
11986         previousPage: function( event ) {
11987                 var item, base, height;
11988                 if ( !this.active ) {
11989                         this.next( event );
11990                         return;
11991                 }
11992                 if ( this.isFirstItem() ) {
11993                         return;
11994                 }
11995                 if ( this._hasScroll() ) {
11996                         base = this.active.offset().top;
11997                         height = this.element.height();
11998                         this.active.prevAll( ".ui-menu-item" ).each(function() {
11999                                 item = $( this );
12000                                 return item.offset().top - base + height > 0;
12001                         });
12002
12003                         this.focus( event, item );
12004                 } else {
12005                         this.focus( event, this.activeMenu.children( ".ui-menu-item" ).first() );
12006                 }
12007         },
12008
12009         _hasScroll: function() {
12010                 return this.element.outerHeight() < this.element.prop( "scrollHeight" );
12011         },
12012
12013         select: function( event ) {
12014                 // TODO: It should never be possible to not have an active item at this
12015                 // point, but the tests don't trigger mouseenter before click.
12016                 this.active = this.active || $( event.target ).closest( ".ui-menu-item" );
12017                 var ui = { item: this.active };
12018                 if ( !this.active.has( ".ui-menu" ).length ) {
12019                         this.collapseAll( event, true );
12020                 }
12021                 this._trigger( "select", event, ui );
12022         }
12023 });
12024
12025 }( jQuery ));
12026
12027 (function( $, undefined ) {
12028
12029 $.ui = $.ui || {};
12030
12031 var cachedScrollbarWidth,
12032         max = Math.max,
12033         abs = Math.abs,
12034         round = Math.round,
12035         rhorizontal = /left|center|right/,
12036         rvertical = /top|center|bottom/,
12037         roffset = /[\+\-]\d+(\.[\d]+)?%?/,
12038         rposition = /^\w+/,
12039         rpercent = /%$/,
12040         _position = $.fn.position;
12041
12042 function getOffsets( offsets, width, height ) {
12043         return [
12044                 parseFloat( offsets[ 0 ] ) * ( rpercent.test( offsets[ 0 ] ) ? width / 100 : 1 ),
12045                 parseFloat( offsets[ 1 ] ) * ( rpercent.test( offsets[ 1 ] ) ? height / 100 : 1 )
12046         ];
12047 }
12048
12049 function parseCss( element, property ) {
12050         return parseInt( $.css( element, property ), 10 ) || 0;
12051 }
12052
12053 function getDimensions( elem ) {
12054         var raw = elem[0];
12055         if ( raw.nodeType === 9 ) {
12056                 return {
12057                         width: elem.width(),
12058                         height: elem.height(),
12059                         offset: { top: 0, left: 0 }
12060                 };
12061         }
12062         if ( $.isWindow( raw ) ) {
12063                 return {
12064                         width: elem.width(),
12065                         height: elem.height(),
12066                         offset: { top: elem.scrollTop(), left: elem.scrollLeft() }
12067                 };
12068         }
12069         if ( raw.preventDefault ) {
12070                 return {
12071                         width: 0,
12072                         height: 0,
12073                         offset: { top: raw.pageY, left: raw.pageX }
12074                 };
12075         }
12076         return {
12077                 width: elem.outerWidth(),
12078                 height: elem.outerHeight(),
12079                 offset: elem.offset()
12080         };
12081 }
12082
12083 $.position = {
12084         scrollbarWidth: function() {
12085                 if ( cachedScrollbarWidth !== undefined ) {
12086                         return cachedScrollbarWidth;
12087                 }
12088                 var w1, w2,
12089                         div = $( "<div style='display:block;width:50px;height:50px;overflow:hidden;'><div style='height:100px;width:auto;'></div></div>" ),
12090                         innerDiv = div.children()[0];
12091
12092                 $( "body" ).append( div );
12093                 w1 = innerDiv.offsetWidth;
12094                 div.css( "overflow", "scroll" );
12095
12096                 w2 = innerDiv.offsetWidth;
12097
12098                 if ( w1 === w2 ) {
12099                         w2 = div[0].clientWidth;
12100                 }
12101
12102                 div.remove();
12103
12104                 return (cachedScrollbarWidth = w1 - w2);
12105         },
12106         getScrollInfo: function( within ) {
12107                 var overflowX = within.isWindow ? "" : within.element.css( "overflow-x" ),
12108                         overflowY = within.isWindow ? "" : within.element.css( "overflow-y" ),
12109                         hasOverflowX = overflowX === "scroll" ||
12110                                 ( overflowX === "auto" && within.width < within.element[0].scrollWidth ),
12111                         hasOverflowY = overflowY === "scroll" ||
12112                                 ( overflowY === "auto" && within.height < within.element[0].scrollHeight );
12113                 return {
12114                         width: hasOverflowY ? $.position.scrollbarWidth() : 0,
12115                         height: hasOverflowX ? $.position.scrollbarWidth() : 0
12116                 };
12117         },
12118         getWithinInfo: function( element ) {
12119                 var withinElement = $( element || window ),
12120                         isWindow = $.isWindow( withinElement[0] );
12121                 return {
12122                         element: withinElement,
12123                         isWindow: isWindow,
12124                         offset: withinElement.offset() || { left: 0, top: 0 },
12125                         scrollLeft: withinElement.scrollLeft(),
12126                         scrollTop: withinElement.scrollTop(),
12127                         width: isWindow ? withinElement.width() : withinElement.outerWidth(),
12128                         height: isWindow ? withinElement.height() : withinElement.outerHeight()
12129                 };
12130         }
12131 };
12132
12133 $.fn.position = function( options ) {
12134         if ( !options || !options.of ) {
12135                 return _position.apply( this, arguments );
12136         }
12137
12138         // make a copy, we don't want to modify arguments
12139         options = $.extend( {}, options );
12140
12141         var atOffset, targetWidth, targetHeight, targetOffset, basePosition, dimensions,
12142                 target = $( options.of ),
12143                 within = $.position.getWithinInfo( options.within ),
12144                 scrollInfo = $.position.getScrollInfo( within ),
12145                 collision = ( options.collision || "flip" ).split( " " ),
12146                 offsets = {};
12147
12148         dimensions = getDimensions( target );
12149         if ( target[0].preventDefault ) {
12150                 // force left top to allow flipping
12151                 options.at = "left top";
12152         }
12153         targetWidth = dimensions.width;
12154         targetHeight = dimensions.height;
12155         targetOffset = dimensions.offset;
12156         // clone to reuse original targetOffset later
12157         basePosition = $.extend( {}, targetOffset );
12158
12159         // force my and at to have valid horizontal and vertical positions
12160         // if a value is missing or invalid, it will be converted to center
12161         $.each( [ "my", "at" ], function() {
12162                 var pos = ( options[ this ] || "" ).split( " " ),
12163                         horizontalOffset,
12164                         verticalOffset;
12165
12166                 if ( pos.length === 1) {
12167                         pos = rhorizontal.test( pos[ 0 ] ) ?
12168                                 pos.concat( [ "center" ] ) :
12169                                 rvertical.test( pos[ 0 ] ) ?
12170                                         [ "center" ].concat( pos ) :
12171                                         [ "center", "center" ];
12172                 }
12173                 pos[ 0 ] = rhorizontal.test( pos[ 0 ] ) ? pos[ 0 ] : "center";
12174                 pos[ 1 ] = rvertical.test( pos[ 1 ] ) ? pos[ 1 ] : "center";
12175
12176                 // calculate offsets
12177                 horizontalOffset = roffset.exec( pos[ 0 ] );
12178                 verticalOffset = roffset.exec( pos[ 1 ] );
12179                 offsets[ this ] = [
12180                         horizontalOffset ? horizontalOffset[ 0 ] : 0,
12181                         verticalOffset ? verticalOffset[ 0 ] : 0
12182                 ];
12183
12184                 // reduce to just the positions without the offsets
12185                 options[ this ] = [
12186                         rposition.exec( pos[ 0 ] )[ 0 ],
12187                         rposition.exec( pos[ 1 ] )[ 0 ]
12188                 ];
12189         });
12190
12191         // normalize collision option
12192         if ( collision.length === 1 ) {
12193                 collision[ 1 ] = collision[ 0 ];
12194         }
12195
12196         if ( options.at[ 0 ] === "right" ) {
12197                 basePosition.left += targetWidth;
12198         } else if ( options.at[ 0 ] === "center" ) {
12199                 basePosition.left += targetWidth / 2;
12200         }
12201
12202         if ( options.at[ 1 ] === "bottom" ) {
12203                 basePosition.top += targetHeight;
12204         } else if ( options.at[ 1 ] === "center" ) {
12205                 basePosition.top += targetHeight / 2;
12206         }
12207
12208         atOffset = getOffsets( offsets.at, targetWidth, targetHeight );
12209         basePosition.left += atOffset[ 0 ];
12210         basePosition.top += atOffset[ 1 ];
12211
12212         return this.each(function() {
12213                 var collisionPosition, using,
12214                         elem = $( this ),
12215                         elemWidth = elem.outerWidth(),
12216                         elemHeight = elem.outerHeight(),
12217                         marginLeft = parseCss( this, "marginLeft" ),
12218                         marginTop = parseCss( this, "marginTop" ),
12219                         collisionWidth = elemWidth + marginLeft + parseCss( this, "marginRight" ) + scrollInfo.width,
12220                         collisionHeight = elemHeight + marginTop + parseCss( this, "marginBottom" ) + scrollInfo.height,
12221                         position = $.extend( {}, basePosition ),
12222                         myOffset = getOffsets( offsets.my, elem.outerWidth(), elem.outerHeight() );
12223
12224                 if ( options.my[ 0 ] === "right" ) {
12225                         position.left -= elemWidth;
12226                 } else if ( options.my[ 0 ] === "center" ) {
12227                         position.left -= elemWidth / 2;
12228                 }
12229
12230                 if ( options.my[ 1 ] === "bottom" ) {
12231                         position.top -= elemHeight;
12232                 } else if ( options.my[ 1 ] === "center" ) {
12233                         position.top -= elemHeight / 2;
12234                 }
12235
12236                 position.left += myOffset[ 0 ];
12237                 position.top += myOffset[ 1 ];
12238
12239                 // if the browser doesn't support fractions, then round for consistent results
12240                 if ( !$.support.offsetFractions ) {
12241                         position.left = round( position.left );
12242                         position.top = round( position.top );
12243                 }
12244
12245                 collisionPosition = {
12246                         marginLeft: marginLeft,
12247                         marginTop: marginTop
12248                 };
12249
12250                 $.each( [ "left", "top" ], function( i, dir ) {
12251                         if ( $.ui.position[ collision[ i ] ] ) {
12252                                 $.ui.position[ collision[ i ] ][ dir ]( position, {
12253                                         targetWidth: targetWidth,
12254                                         targetHeight: targetHeight,
12255                                         elemWidth: elemWidth,
12256                                         elemHeight: elemHeight,
12257                                         collisionPosition: collisionPosition,
12258                                         collisionWidth: collisionWidth,
12259                                         collisionHeight: collisionHeight,
12260                                         offset: [ atOffset[ 0 ] + myOffset[ 0 ], atOffset [ 1 ] + myOffset[ 1 ] ],
12261                                         my: options.my,
12262                                         at: options.at,
12263                                         within: within,
12264                                         elem : elem
12265                                 });
12266                         }
12267                 });
12268
12269                 if ( options.using ) {
12270                         // adds feedback as second argument to using callback, if present
12271                         using = function( props ) {
12272                                 var left = targetOffset.left - position.left,
12273                                         right = left + targetWidth - elemWidth,
12274                                         top = targetOffset.top - position.top,
12275                                         bottom = top + targetHeight - elemHeight,
12276                                         feedback = {
12277                                                 target: {
12278                                                         element: target,
12279                                                         left: targetOffset.left,
12280                                                         top: targetOffset.top,
12281                                                         width: targetWidth,
12282                                                         height: targetHeight
12283                                                 },
12284                                                 element: {
12285                                                         element: elem,
12286                                                         left: position.left,
12287                                                         top: position.top,
12288                                                         width: elemWidth,
12289                                                         height: elemHeight
12290                                                 },
12291                                                 horizontal: right < 0 ? "left" : left > 0 ? "right" : "center",
12292                                                 vertical: bottom < 0 ? "top" : top > 0 ? "bottom" : "middle"
12293                                         };
12294                                 if ( targetWidth < elemWidth && abs( left + right ) < targetWidth ) {
12295                                         feedback.horizontal = "center";
12296                                 }
12297                                 if ( targetHeight < elemHeight && abs( top + bottom ) < targetHeight ) {
12298                                         feedback.vertical = "middle";
12299                                 }
12300                                 if ( max( abs( left ), abs( right ) ) > max( abs( top ), abs( bottom ) ) ) {
12301                                         feedback.important = "horizontal";
12302                                 } else {
12303                                         feedback.important = "vertical";
12304                                 }
12305                                 options.using.call( this, props, feedback );
12306                         };
12307                 }
12308
12309                 elem.offset( $.extend( position, { using: using } ) );
12310         });
12311 };
12312
12313 $.ui.position = {
12314         fit: {
12315                 left: function( position, data ) {
12316                         var within = data.within,
12317                                 withinOffset = within.isWindow ? within.scrollLeft : within.offset.left,
12318                                 outerWidth = within.width,
12319                                 collisionPosLeft = position.left - data.collisionPosition.marginLeft,
12320                                 overLeft = withinOffset - collisionPosLeft,
12321                                 overRight = collisionPosLeft + data.collisionWidth - outerWidth - withinOffset,
12322                                 newOverRight;
12323
12324                         // element is wider than within
12325                         if ( data.collisionWidth > outerWidth ) {
12326                                 // element is initially over the left side of within
12327                                 if ( overLeft > 0 && overRight <= 0 ) {
12328                                         newOverRight = position.left + overLeft + data.collisionWidth - outerWidth - withinOffset;
12329                                         position.left += overLeft - newOverRight;
12330                                 // element is initially over right side of within
12331                                 } else if ( overRight > 0 && overLeft <= 0 ) {
12332                                         position.left = withinOffset;
12333                                 // element is initially over both left and right sides of within
12334                                 } else {
12335                                         if ( overLeft > overRight ) {
12336                                                 position.left = withinOffset + outerWidth - data.collisionWidth;
12337                                         } else {
12338                                                 position.left = withinOffset;
12339                                         }
12340                                 }
12341                         // too far left -> align with left edge
12342                         } else if ( overLeft > 0 ) {
12343                                 position.left += overLeft;
12344                         // too far right -> align with right edge
12345                         } else if ( overRight > 0 ) {
12346                                 position.left -= overRight;
12347                         // adjust based on position and margin
12348                         } else {
12349                                 position.left = max( position.left - collisionPosLeft, position.left );
12350                         }
12351                 },
12352                 top: function( position, data ) {
12353                         var within = data.within,
12354                                 withinOffset = within.isWindow ? within.scrollTop : within.offset.top,
12355                                 outerHeight = data.within.height,
12356                                 collisionPosTop = position.top - data.collisionPosition.marginTop,
12357                                 overTop = withinOffset - collisionPosTop,
12358                                 overBottom = collisionPosTop + data.collisionHeight - outerHeight - withinOffset,
12359                                 newOverBottom;
12360
12361                         // element is taller than within
12362                         if ( data.collisionHeight > outerHeight ) {
12363                                 // element is initially over the top of within
12364                                 if ( overTop > 0 && overBottom <= 0 ) {
12365                                         newOverBottom = position.top + overTop + data.collisionHeight - outerHeight - withinOffset;
12366                                         position.top += overTop - newOverBottom;
12367                                 // element is initially over bottom of within
12368                                 } else if ( overBottom > 0 && overTop <= 0 ) {
12369                                         position.top = withinOffset;
12370                                 // element is initially over both top and bottom of within
12371                                 } else {
12372                                         if ( overTop > overBottom ) {
12373                                                 position.top = withinOffset + outerHeight - data.collisionHeight;
12374                                         } else {
12375                                                 position.top = withinOffset;
12376                                         }
12377                                 }
12378                         // too far up -> align with top
12379                         } else if ( overTop > 0 ) {
12380                                 position.top += overTop;
12381                         // too far down -> align with bottom edge
12382                         } else if ( overBottom > 0 ) {
12383                                 position.top -= overBottom;
12384                         // adjust based on position and margin
12385                         } else {
12386                                 position.top = max( position.top - collisionPosTop, position.top );
12387                         }
12388                 }
12389         },
12390         flip: {
12391                 left: function( position, data ) {
12392                         var within = data.within,
12393                                 withinOffset = within.offset.left + within.scrollLeft,
12394                                 outerWidth = within.width,
12395                                 offsetLeft = within.isWindow ? within.scrollLeft : within.offset.left,
12396                                 collisionPosLeft = position.left - data.collisionPosition.marginLeft,
12397                                 overLeft = collisionPosLeft - offsetLeft,
12398                                 overRight = collisionPosLeft + data.collisionWidth - outerWidth - offsetLeft,
12399                                 myOffset = data.my[ 0 ] === "left" ?
12400                                         -data.elemWidth :
12401                                         data.my[ 0 ] === "right" ?
12402                                                 data.elemWidth :
12403                                                 0,
12404                                 atOffset = data.at[ 0 ] === "left" ?
12405                                         data.targetWidth :
12406                                         data.at[ 0 ] === "right" ?
12407                                                 -data.targetWidth :
12408                                                 0,
12409                                 offset = -2 * data.offset[ 0 ],
12410                                 newOverRight,
12411                                 newOverLeft;
12412
12413                         if ( overLeft < 0 ) {
12414                                 newOverRight = position.left + myOffset + atOffset + offset + data.collisionWidth - outerWidth - withinOffset;
12415                                 if ( newOverRight < 0 || newOverRight < abs( overLeft ) ) {
12416                                         position.left += myOffset + atOffset + offset;
12417                                 }
12418                         }
12419                         else if ( overRight > 0 ) {
12420                                 newOverLeft = position.left - data.collisionPosition.marginLeft + myOffset + atOffset + offset - offsetLeft;
12421                                 if ( newOverLeft > 0 || abs( newOverLeft ) < overRight ) {
12422                                         position.left += myOffset + atOffset + offset;
12423                                 }
12424                         }
12425                 },
12426                 top: function( position, data ) {
12427                         var within = data.within,
12428                                 withinOffset = within.offset.top + within.scrollTop,
12429                                 outerHeight = within.height,
12430                                 offsetTop = within.isWindow ? within.scrollTop : within.offset.top,
12431                                 collisionPosTop = position.top - data.collisionPosition.marginTop,
12432                                 overTop = collisionPosTop - offsetTop,
12433                                 overBottom = collisionPosTop + data.collisionHeight - outerHeight - offsetTop,
12434                                 top = data.my[ 1 ] === "top",
12435                                 myOffset = top ?
12436                                         -data.elemHeight :
12437                                         data.my[ 1 ] === "bottom" ?
12438                                                 data.elemHeight :
12439                                                 0,
12440                                 atOffset = data.at[ 1 ] === "top" ?
12441                                         data.targetHeight :
12442                                         data.at[ 1 ] === "bottom" ?
12443                                                 -data.targetHeight :
12444                                                 0,
12445                                 offset = -2 * data.offset[ 1 ],
12446                                 newOverTop,
12447                                 newOverBottom;
12448                         if ( overTop < 0 ) {
12449                                 newOverBottom = position.top + myOffset + atOffset + offset + data.collisionHeight - outerHeight - withinOffset;
12450                                 if ( ( position.top + myOffset + atOffset + offset) > overTop && ( newOverBottom < 0 || newOverBottom < abs( overTop ) ) ) {
12451                                         position.top += myOffset + atOffset + offset;
12452                                 }
12453                         }
12454                         else if ( overBottom > 0 ) {
12455                                 newOverTop = position.top -  data.collisionPosition.marginTop + myOffset + atOffset + offset - offsetTop;
12456                                 if ( ( position.top + myOffset + atOffset + offset) > overBottom && ( newOverTop > 0 || abs( newOverTop ) < overBottom ) ) {
12457                                         position.top += myOffset + atOffset + offset;
12458                                 }
12459                         }
12460                 }
12461         },
12462         flipfit: {
12463                 left: function() {
12464                         $.ui.position.flip.left.apply( this, arguments );
12465                         $.ui.position.fit.left.apply( this, arguments );
12466                 },
12467                 top: function() {
12468                         $.ui.position.flip.top.apply( this, arguments );
12469                         $.ui.position.fit.top.apply( this, arguments );
12470                 }
12471         }
12472 };
12473
12474 // fraction support test
12475 (function () {
12476         var testElement, testElementParent, testElementStyle, offsetLeft, i,
12477                 body = document.getElementsByTagName( "body" )[ 0 ],
12478                 div = document.createElement( "div" );
12479
12480         //Create a "fake body" for testing based on method used in jQuery.support
12481         testElement = document.createElement( body ? "div" : "body" );
12482         testElementStyle = {
12483                 visibility: "hidden",
12484                 width: 0,
12485                 height: 0,
12486                 border: 0,
12487                 margin: 0,
12488                 background: "none"
12489         };
12490         if ( body ) {
12491                 $.extend( testElementStyle, {
12492                         position: "absolute",
12493                         left: "-1000px",
12494                         top: "-1000px"
12495                 });
12496         }
12497         for ( i in testElementStyle ) {
12498                 testElement.style[ i ] = testElementStyle[ i ];
12499         }
12500         testElement.appendChild( div );
12501         testElementParent = body || document.documentElement;
12502         testElementParent.insertBefore( testElement, testElementParent.firstChild );
12503
12504         div.style.cssText = "position: absolute; left: 10.7432222px;";
12505
12506         offsetLeft = $( div ).offset().left;
12507         $.support.offsetFractions = offsetLeft > 10 && offsetLeft < 11;
12508
12509         testElement.innerHTML = "";
12510         testElementParent.removeChild( testElement );
12511 })();
12512
12513 }( jQuery ) );
12514
12515 (function( $, undefined ) {
12516
12517 $.widget( "ui.progressbar", {
12518         version: "1.10.3",
12519         options: {
12520                 max: 100,
12521                 value: 0,
12522
12523                 change: null,
12524                 complete: null
12525         },
12526
12527         min: 0,
12528
12529         _create: function() {
12530                 // Constrain initial value
12531                 this.oldValue = this.options.value = this._constrainedValue();
12532
12533                 this.element
12534                         .addClass( "ui-progressbar ui-widget ui-widget-content ui-corner-all" )
12535                         .attr({
12536                                 // Only set static values, aria-valuenow and aria-valuemax are
12537                                 // set inside _refreshValue()
12538                                 role: "progressbar",
12539                                 "aria-valuemin": this.min
12540                         });
12541
12542                 this.valueDiv = $( "<div class='ui-progressbar-value ui-widget-header ui-corner-left'></div>" )
12543                         .appendTo( this.element );
12544
12545                 this._refreshValue();
12546         },
12547
12548         _destroy: function() {
12549                 this.element
12550                         .removeClass( "ui-progressbar ui-widget ui-widget-content ui-corner-all" )
12551                         .removeAttr( "role" )
12552                         .removeAttr( "aria-valuemin" )
12553                         .removeAttr( "aria-valuemax" )
12554                         .removeAttr( "aria-valuenow" );
12555
12556                 this.valueDiv.remove();
12557         },
12558
12559         value: function( newValue ) {
12560                 if ( newValue === undefined ) {
12561                         return this.options.value;
12562                 }
12563
12564                 this.options.value = this._constrainedValue( newValue );
12565                 this._refreshValue();
12566         },
12567
12568         _constrainedValue: function( newValue ) {
12569                 if ( newValue === undefined ) {
12570                         newValue = this.options.value;
12571                 }
12572
12573                 this.indeterminate = newValue === false;
12574
12575                 // sanitize value
12576                 if ( typeof newValue !== "number" ) {
12577                         newValue = 0;
12578                 }
12579
12580                 return this.indeterminate ? false :
12581                         Math.min( this.options.max, Math.max( this.min, newValue ) );
12582         },
12583
12584         _setOptions: function( options ) {
12585                 // Ensure "value" option is set after other values (like max)
12586                 var value = options.value;
12587                 delete options.value;
12588
12589                 this._super( options );
12590
12591                 this.options.value = this._constrainedValue( value );
12592                 this._refreshValue();
12593         },
12594
12595         _setOption: function( key, value ) {
12596                 if ( key === "max" ) {
12597                         // Don't allow a max less than min
12598                         value = Math.max( this.min, value );
12599                 }
12600
12601                 this._super( key, value );
12602         },
12603
12604         _percentage: function() {
12605                 return this.indeterminate ? 100 : 100 * ( this.options.value - this.min ) / ( this.options.max - this.min );
12606         },
12607
12608         _refreshValue: function() {
12609                 var value = this.options.value,
12610                         percentage = this._percentage();
12611
12612                 this.valueDiv
12613                         .toggle( this.indeterminate || value > this.min )
12614                         .toggleClass( "ui-corner-right", value === this.options.max )
12615                         .width( percentage.toFixed(0) + "%" );
12616
12617                 this.element.toggleClass( "ui-progressbar-indeterminate", this.indeterminate );
12618
12619                 if ( this.indeterminate ) {
12620                         this.element.removeAttr( "aria-valuenow" );
12621                         if ( !this.overlayDiv ) {
12622                                 this.overlayDiv = $( "<div class='ui-progressbar-overlay'></div>" ).appendTo( this.valueDiv );
12623                         }
12624                 } else {
12625                         this.element.attr({
12626                                 "aria-valuemax": this.options.max,
12627                                 "aria-valuenow": value
12628                         });
12629                         if ( this.overlayDiv ) {
12630                                 this.overlayDiv.remove();
12631                                 this.overlayDiv = null;
12632                         }
12633                 }
12634
12635                 if ( this.oldValue !== value ) {
12636                         this.oldValue = value;
12637                         this._trigger( "change" );
12638                 }
12639                 if ( value === this.options.max ) {
12640                         this._trigger( "complete" );
12641                 }
12642         }
12643 });
12644
12645 })( jQuery );
12646
12647 (function( $, undefined ) {
12648
12649 // number of pages in a slider
12650 // (how many times can you page up/down to go through the whole range)
12651 var numPages = 5;
12652
12653 $.widget( "ui.slider", $.ui.mouse, {
12654         version: "1.10.3",
12655         widgetEventPrefix: "slide",
12656
12657         options: {
12658                 animate: false,
12659                 distance: 0,
12660                 max: 100,
12661                 min: 0,
12662                 orientation: "horizontal",
12663                 range: false,
12664                 step: 1,
12665                 value: 0,
12666                 values: null,
12667
12668                 // callbacks
12669                 change: null,
12670                 slide: null,
12671                 start: null,
12672                 stop: null
12673         },
12674
12675         _create: function() {
12676                 this._keySliding = false;
12677                 this._mouseSliding = false;
12678                 this._animateOff = true;
12679                 this._handleIndex = null;
12680                 this._detectOrientation();
12681                 this._mouseInit();
12682
12683                 this.element
12684                         .addClass( "ui-slider" +
12685                                 " ui-slider-" + this.orientation +
12686                                 " ui-widget" +
12687                                 " ui-widget-content" +
12688                                 " ui-corner-all");
12689
12690                 this._refresh();
12691                 this._setOption( "disabled", this.options.disabled );
12692
12693                 this._animateOff = false;
12694         },
12695
12696         _refresh: function() {
12697                 this._createRange();
12698                 this._createHandles();
12699                 this._setupEvents();
12700                 this._refreshValue();
12701         },
12702
12703         _createHandles: function() {
12704                 var i, handleCount,
12705                         options = this.options,
12706                         existingHandles = this.element.find( ".ui-slider-handle" ).addClass( "ui-state-default ui-corner-all" ),
12707                         handle = "<a class='ui-slider-handle ui-state-default ui-corner-all' href='#'></a>",
12708                         handles = [];
12709
12710                 handleCount = ( options.values && options.values.length ) || 1;
12711
12712                 if ( existingHandles.length > handleCount ) {
12713                         existingHandles.slice( handleCount ).remove();
12714                         existingHandles = existingHandles.slice( 0, handleCount );
12715                 }
12716
12717                 for ( i = existingHandles.length; i < handleCount; i++ ) {
12718                         handles.push( handle );
12719                 }
12720
12721                 this.handles = existingHandles.add( $( handles.join( "" ) ).appendTo( this.element ) );
12722
12723                 this.handle = this.handles.eq( 0 );
12724
12725                 this.handles.each(function( i ) {
12726                         $( this ).data( "ui-slider-handle-index", i );
12727                 });
12728         },
12729
12730         _createRange: function() {
12731                 var options = this.options,
12732                         classes = "";
12733
12734                 if ( options.range ) {
12735                         if ( options.range === true ) {
12736                                 if ( !options.values ) {
12737                                         options.values = [ this._valueMin(), this._valueMin() ];
12738                                 } else if ( options.values.length && options.values.length !== 2 ) {
12739                                         options.values = [ options.values[0], options.values[0] ];
12740                                 } else if ( $.isArray( options.values ) ) {
12741                                         options.values = options.values.slice(0);
12742                                 }
12743                         }
12744
12745                         if ( !this.range || !this.range.length ) {
12746                                 this.range = $( "<div></div>" )
12747                                         .appendTo( this.element );
12748
12749                                 classes = "ui-slider-range" +
12750                                 // note: this isn't the most fittingly semantic framework class for this element,
12751                                 // but worked best visually with a variety of themes
12752                                 " ui-widget-header ui-corner-all";
12753                         } else {
12754                                 this.range.removeClass( "ui-slider-range-min ui-slider-range-max" )
12755                                         // Handle range switching from true to min/max
12756                                         .css({
12757                                                 "left": "",
12758                                                 "bottom": ""
12759                                         });
12760                         }
12761
12762                         this.range.addClass( classes +
12763                                 ( ( options.range === "min" || options.range === "max" ) ? " ui-slider-range-" + options.range : "" ) );
12764                 } else {
12765                         this.range = $([]);
12766                 }
12767         },
12768
12769         _setupEvents: function() {
12770                 var elements = this.handles.add( this.range ).filter( "a" );
12771                 this._off( elements );
12772                 this._on( elements, this._handleEvents );
12773                 this._hoverable( elements );
12774                 this._focusable( elements );
12775         },
12776
12777         _destroy: function() {
12778                 this.handles.remove();
12779                 this.range.remove();
12780
12781                 this.element
12782                         .removeClass( "ui-slider" +
12783                                 " ui-slider-horizontal" +
12784                                 " ui-slider-vertical" +
12785                                 " ui-widget" +
12786                                 " ui-widget-content" +
12787                                 " ui-corner-all" );
12788
12789                 this._mouseDestroy();
12790         },
12791
12792         _mouseCapture: function( event ) {
12793                 var position, normValue, distance, closestHandle, index, allowed, offset, mouseOverHandle,
12794                         that = this,
12795                         o = this.options;
12796
12797                 if ( o.disabled ) {
12798                         return false;
12799                 }
12800
12801                 this.elementSize = {
12802                         width: this.element.outerWidth(),
12803                         height: this.element.outerHeight()
12804                 };
12805                 this.elementOffset = this.element.offset();
12806
12807                 position = { x: event.pageX, y: event.pageY };
12808                 normValue = this._normValueFromMouse( position );
12809                 distance = this._valueMax() - this._valueMin() + 1;
12810                 this.handles.each(function( i ) {
12811                         var thisDistance = Math.abs( normValue - that.values(i) );
12812                         if (( distance > thisDistance ) ||
12813                                 ( distance === thisDistance &&
12814                                         (i === that._lastChangedValue || that.values(i) === o.min ))) {
12815                                 distance = thisDistance;
12816                                 closestHandle = $( this );
12817                                 index = i;
12818                         }
12819                 });
12820
12821                 allowed = this._start( event, index );
12822                 if ( allowed === false ) {
12823                         return false;
12824                 }
12825                 this._mouseSliding = true;
12826
12827                 this._handleIndex = index;
12828
12829                 closestHandle
12830                         .addClass( "ui-state-active" )
12831                         .focus();
12832
12833                 offset = closestHandle.offset();
12834                 mouseOverHandle = !$( event.target ).parents().addBack().is( ".ui-slider-handle" );
12835                 this._clickOffset = mouseOverHandle ? { left: 0, top: 0 } : {
12836                         left: event.pageX - offset.left - ( closestHandle.width() / 2 ),
12837                         top: event.pageY - offset.top -
12838                                 ( closestHandle.height() / 2 ) -
12839                                 ( parseInt( closestHandle.css("borderTopWidth"), 10 ) || 0 ) -
12840                                 ( parseInt( closestHandle.css("borderBottomWidth"), 10 ) || 0) +
12841                                 ( parseInt( closestHandle.css("marginTop"), 10 ) || 0)
12842                 };
12843
12844                 if ( !this.handles.hasClass( "ui-state-hover" ) ) {
12845                         this._slide( event, index, normValue );
12846                 }
12847                 this._animateOff = true;
12848                 return true;
12849         },
12850
12851         _mouseStart: function() {
12852                 return true;
12853         },
12854
12855         _mouseDrag: function( event ) {
12856                 var position = { x: event.pageX, y: event.pageY },
12857                         normValue = this._normValueFromMouse( position );
12858
12859                 this._slide( event, this._handleIndex, normValue );
12860
12861                 return false;
12862         },
12863
12864         _mouseStop: function( event ) {
12865                 this.handles.removeClass( "ui-state-active" );
12866                 this._mouseSliding = false;
12867
12868                 this._stop( event, this._handleIndex );
12869                 this._change( event, this._handleIndex );
12870
12871                 this._handleIndex = null;
12872                 this._clickOffset = null;
12873                 this._animateOff = false;
12874
12875                 return false;
12876         },
12877
12878         _detectOrientation: function() {
12879                 this.orientation = ( this.options.orientation === "vertical" ) ? "vertical" : "horizontal";
12880         },
12881
12882         _normValueFromMouse: function( position ) {
12883                 var pixelTotal,
12884                         pixelMouse,
12885                         percentMouse,
12886                         valueTotal,
12887                         valueMouse;
12888
12889                 if ( this.orientation === "horizontal" ) {
12890                         pixelTotal = this.elementSize.width;
12891                         pixelMouse = position.x - this.elementOffset.left - ( this._clickOffset ? this._clickOffset.left : 0 );
12892                 } else {
12893                         pixelTotal = this.elementSize.height;
12894                         pixelMouse = position.y - this.elementOffset.top - ( this._clickOffset ? this._clickOffset.top : 0 );
12895                 }
12896
12897                 percentMouse = ( pixelMouse / pixelTotal );
12898                 if ( percentMouse > 1 ) {
12899                         percentMouse = 1;
12900                 }
12901                 if ( percentMouse < 0 ) {
12902                         percentMouse = 0;
12903                 }
12904                 if ( this.orientation === "vertical" ) {
12905                         percentMouse = 1 - percentMouse;
12906                 }
12907
12908                 valueTotal = this._valueMax() - this._valueMin();
12909                 valueMouse = this._valueMin() + percentMouse * valueTotal;
12910
12911                 return this._trimAlignValue( valueMouse );
12912         },
12913
12914         _start: function( event, index ) {
12915                 var uiHash = {
12916                         handle: this.handles[ index ],
12917                         value: this.value()
12918                 };
12919                 if ( this.options.values && this.options.values.length ) {
12920                         uiHash.value = this.values( index );
12921                         uiHash.values = this.values();
12922                 }
12923                 return this._trigger( "start", event, uiHash );
12924         },
12925
12926         _slide: function( event, index, newVal ) {
12927                 var otherVal,
12928                         newValues,
12929                         allowed;
12930
12931                 if ( this.options.values && this.options.values.length ) {
12932                         otherVal = this.values( index ? 0 : 1 );
12933
12934                         if ( ( this.options.values.length === 2 && this.options.range === true ) &&
12935                                         ( ( index === 0 && newVal > otherVal) || ( index === 1 && newVal < otherVal ) )
12936                                 ) {
12937                                 newVal = otherVal;
12938                         }
12939
12940                         if ( newVal !== this.values( index ) ) {
12941                                 newValues = this.values();
12942                                 newValues[ index ] = newVal;
12943                                 // A slide can be canceled by returning false from the slide callback
12944                                 allowed = this._trigger( "slide", event, {
12945                                         handle: this.handles[ index ],
12946                                         value: newVal,
12947                                         values: newValues
12948                                 } );
12949                                 otherVal = this.values( index ? 0 : 1 );
12950                                 if ( allowed !== false ) {
12951                                         this.values( index, newVal, true );
12952                                 }
12953                         }
12954                 } else {
12955                         if ( newVal !== this.value() ) {
12956                                 // A slide can be canceled by returning false from the slide callback
12957                                 allowed = this._trigger( "slide", event, {
12958                                         handle: this.handles[ index ],
12959                                         value: newVal
12960                                 } );
12961                                 if ( allowed !== false ) {
12962                                         this.value( newVal );
12963                                 }
12964                         }
12965                 }
12966         },
12967
12968         _stop: function( event, index ) {
12969                 var uiHash = {
12970                         handle: this.handles[ index ],
12971                         value: this.value()
12972                 };
12973                 if ( this.options.values && this.options.values.length ) {
12974                         uiHash.value = this.values( index );
12975                         uiHash.values = this.values();
12976                 }
12977
12978                 this._trigger( "stop", event, uiHash );
12979         },
12980
12981         _change: function( event, index ) {
12982                 if ( !this._keySliding && !this._mouseSliding ) {
12983                         var uiHash = {
12984                                 handle: this.handles[ index ],
12985                                 value: this.value()
12986                         };
12987                         if ( this.options.values && this.options.values.length ) {
12988                                 uiHash.value = this.values( index );
12989                                 uiHash.values = this.values();
12990                         }
12991
12992                         //store the last changed value index for reference when handles overlap
12993                         this._lastChangedValue = index;
12994
12995                         this._trigger( "change", event, uiHash );
12996                 }
12997         },
12998
12999         value: function( newValue ) {
13000                 if ( arguments.length ) {
13001                         this.options.value = this._trimAlignValue( newValue );
13002                         this._refreshValue();
13003                         this._change( null, 0 );
13004                         return;
13005                 }
13006
13007                 return this._value();
13008         },
13009
13010         values: function( index, newValue ) {
13011                 var vals,
13012                         newValues,
13013                         i;
13014
13015                 if ( arguments.length > 1 ) {
13016                         this.options.values[ index ] = this._trimAlignValue( newValue );
13017                         this._refreshValue();
13018                         this._change( null, index );
13019                         return;
13020                 }
13021
13022                 if ( arguments.length ) {
13023                         if ( $.isArray( arguments[ 0 ] ) ) {
13024                                 vals = this.options.values;
13025                                 newValues = arguments[ 0 ];
13026                                 for ( i = 0; i < vals.length; i += 1 ) {
13027                                         vals[ i ] = this._trimAlignValue( newValues[ i ] );
13028                                         this._change( null, i );
13029                                 }
13030                                 this._refreshValue();
13031                         } else {
13032                                 if ( this.options.values && this.options.values.length ) {
13033                                         return this._values( index );
13034                                 } else {
13035                                         return this.value();
13036                                 }
13037                         }
13038                 } else {
13039                         return this._values();
13040                 }
13041         },
13042
13043         _setOption: function( key, value ) {
13044                 var i,
13045                         valsLength = 0;
13046
13047                 if ( key === "range" && this.options.range === true ) {
13048                         if ( value === "min" ) {
13049                                 this.options.value = this._values( 0 );
13050                                 this.options.values = null;
13051                         } else if ( value === "max" ) {
13052                                 this.options.value = this._values( this.options.values.length-1 );
13053                                 this.options.values = null;
13054                         }
13055                 }
13056
13057                 if ( $.isArray( this.options.values ) ) {
13058                         valsLength = this.options.values.length;
13059                 }
13060
13061                 $.Widget.prototype._setOption.apply( this, arguments );
13062
13063                 switch ( key ) {
13064                         case "orientation":
13065                                 this._detectOrientation();
13066                                 this.element
13067                                         .removeClass( "ui-slider-horizontal ui-slider-vertical" )
13068                                         .addClass( "ui-slider-" + this.orientation );
13069                                 this._refreshValue();
13070                                 break;
13071                         case "value":
13072                                 this._animateOff = true;
13073                                 this._refreshValue();
13074                                 this._change( null, 0 );
13075                                 this._animateOff = false;
13076                                 break;
13077                         case "values":
13078                                 this._animateOff = true;
13079                                 this._refreshValue();
13080                                 for ( i = 0; i < valsLength; i += 1 ) {
13081                                         this._change( null, i );
13082                                 }
13083                                 this._animateOff = false;
13084                                 break;
13085                         case "min":
13086                         case "max":
13087                                 this._animateOff = true;
13088                                 this._refreshValue();
13089                                 this._animateOff = false;
13090                                 break;
13091                         case "range":
13092                                 this._animateOff = true;
13093                                 this._refresh();
13094                                 this._animateOff = false;
13095                                 break;
13096                 }
13097         },
13098
13099         //internal value getter
13100         // _value() returns value trimmed by min and max, aligned by step
13101         _value: function() {
13102                 var val = this.options.value;
13103                 val = this._trimAlignValue( val );
13104
13105                 return val;
13106         },
13107
13108         //internal values getter
13109         // _values() returns array of values trimmed by min and max, aligned by step
13110         // _values( index ) returns single value trimmed by min and max, aligned by step
13111         _values: function( index ) {
13112                 var val,
13113                         vals,
13114                         i;
13115
13116                 if ( arguments.length ) {
13117                         val = this.options.values[ index ];
13118                         val = this._trimAlignValue( val );
13119
13120                         return val;
13121                 } else if ( this.options.values && this.options.values.length ) {
13122                         // .slice() creates a copy of the array
13123                         // this copy gets trimmed by min and max and then returned
13124                         vals = this.options.values.slice();
13125                         for ( i = 0; i < vals.length; i+= 1) {
13126                                 vals[ i ] = this._trimAlignValue( vals[ i ] );
13127                         }
13128
13129                         return vals;
13130                 } else {
13131                         return [];
13132                 }
13133         },
13134
13135         // returns the step-aligned value that val is closest to, between (inclusive) min and max
13136         _trimAlignValue: function( val ) {
13137                 if ( val <= this._valueMin() ) {
13138                         return this._valueMin();
13139                 }
13140                 if ( val >= this._valueMax() ) {
13141                         return this._valueMax();
13142                 }
13143                 var step = ( this.options.step > 0 ) ? this.options.step : 1,
13144                         valModStep = (val - this._valueMin()) % step,
13145                         alignValue = val - valModStep;
13146
13147                 if ( Math.abs(valModStep) * 2 >= step ) {
13148                         alignValue += ( valModStep > 0 ) ? step : ( -step );
13149                 }
13150
13151                 // Since JavaScript has problems with large floats, round
13152                 // the final value to 5 digits after the decimal point (see #4124)
13153                 return parseFloat( alignValue.toFixed(5) );
13154         },
13155
13156         _valueMin: function() {
13157                 return this.options.min;
13158         },
13159
13160         _valueMax: function() {
13161                 return this.options.max;
13162         },
13163
13164         _refreshValue: function() {
13165                 var lastValPercent, valPercent, value, valueMin, valueMax,
13166                         oRange = this.options.range,
13167                         o = this.options,
13168                         that = this,
13169                         animate = ( !this._animateOff ) ? o.animate : false,
13170                         _set = {};
13171
13172                 if ( this.options.values && this.options.values.length ) {
13173                         this.handles.each(function( i ) {
13174                                 valPercent = ( that.values(i) - that._valueMin() ) / ( that._valueMax() - that._valueMin() ) * 100;
13175                                 _set[ that.orientation === "horizontal" ? "left" : "bottom" ] = valPercent + "%";
13176                                 $( this ).stop( 1, 1 )[ animate ? "animate" : "css" ]( _set, o.animate );
13177                                 if ( that.options.range === true ) {
13178                                         if ( that.orientation === "horizontal" ) {
13179                                                 if ( i === 0 ) {
13180                                                         that.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { left: valPercent + "%" }, o.animate );
13181                                                 }
13182                                                 if ( i === 1 ) {
13183                                                         that.range[ animate ? "animate" : "css" ]( { width: ( valPercent - lastValPercent ) + "%" }, { queue: false, duration: o.animate } );
13184                                                 }
13185                                         } else {
13186                                                 if ( i === 0 ) {
13187                                                         that.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { bottom: ( valPercent ) + "%" }, o.animate );
13188                                                 }
13189                                                 if ( i === 1 ) {
13190                                                         that.range[ animate ? "animate" : "css" ]( { height: ( valPercent - lastValPercent ) + "%" }, { queue: false, duration: o.animate } );
13191                                                 }
13192                                         }
13193                                 }
13194                                 lastValPercent = valPercent;
13195                         });
13196                 } else {
13197                         value = this.value();
13198                         valueMin = this._valueMin();
13199                         valueMax = this._valueMax();
13200                         valPercent = ( valueMax !== valueMin ) ?
13201                                         ( value - valueMin ) / ( valueMax - valueMin ) * 100 :
13202                                         0;
13203                         _set[ this.orientation === "horizontal" ? "left" : "bottom" ] = valPercent + "%";
13204                         this.handle.stop( 1, 1 )[ animate ? "animate" : "css" ]( _set, o.animate );
13205
13206                         if ( oRange === "min" && this.orientation === "horizontal" ) {
13207                                 this.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { width: valPercent + "%" }, o.animate );
13208                         }
13209                         if ( oRange === "max" && this.orientation === "horizontal" ) {
13210                                 this.range[ animate ? "animate" : "css" ]( { width: ( 100 - valPercent ) + "%" }, { queue: false, duration: o.animate } );
13211                         }
13212                         if ( oRange === "min" && this.orientation === "vertical" ) {
13213                                 this.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { height: valPercent + "%" }, o.animate );
13214                         }
13215                         if ( oRange === "max" && this.orientation === "vertical" ) {
13216                                 this.range[ animate ? "animate" : "css" ]( { height: ( 100 - valPercent ) + "%" }, { queue: false, duration: o.animate } );
13217                         }
13218                 }
13219         },
13220
13221         _handleEvents: {
13222                 keydown: function( event ) {
13223                         /*jshint maxcomplexity:25*/
13224                         var allowed, curVal, newVal, step,
13225                                 index = $( event.target ).data( "ui-slider-handle-index" );
13226
13227                         switch ( event.keyCode ) {
13228                                 case $.ui.keyCode.HOME:
13229                                 case $.ui.keyCode.END:
13230                                 case $.ui.keyCode.PAGE_UP:
13231                                 case $.ui.keyCode.PAGE_DOWN:
13232                                 case $.ui.keyCode.UP:
13233                                 case $.ui.keyCode.RIGHT:
13234                                 case $.ui.keyCode.DOWN:
13235                                 case $.ui.keyCode.LEFT:
13236                                         event.preventDefault();
13237                                         if ( !this._keySliding ) {
13238                                                 this._keySliding = true;
13239                                                 $( event.target ).addClass( "ui-state-active" );
13240                                                 allowed = this._start( event, index );
13241                                                 if ( allowed === false ) {
13242                                                         return;
13243                                                 }
13244                                         }
13245                                         break;
13246                         }
13247
13248                         step = this.options.step;
13249                         if ( this.options.values && this.options.values.length ) {
13250                                 curVal = newVal = this.values( index );
13251                         } else {
13252                                 curVal = newVal = this.value();
13253                         }
13254
13255                         switch ( event.keyCode ) {
13256                                 case $.ui.keyCode.HOME:
13257                                         newVal = this._valueMin();
13258                                         break;
13259                                 case $.ui.keyCode.END:
13260                                         newVal = this._valueMax();
13261                                         break;
13262                                 case $.ui.keyCode.PAGE_UP:
13263                                         newVal = this._trimAlignValue( curVal + ( (this._valueMax() - this._valueMin()) / numPages ) );
13264                                         break;
13265                                 case $.ui.keyCode.PAGE_DOWN:
13266                                         newVal = this._trimAlignValue( curVal - ( (this._valueMax() - this._valueMin()) / numPages ) );
13267                                         break;
13268                                 case $.ui.keyCode.UP:
13269                                 case $.ui.keyCode.RIGHT:
13270                                         if ( curVal === this._valueMax() ) {
13271                                                 return;
13272                                         }
13273                                         newVal = this._trimAlignValue( curVal + step );
13274                                         break;
13275                                 case $.ui.keyCode.DOWN:
13276                                 case $.ui.keyCode.LEFT:
13277                                         if ( curVal === this._valueMin() ) {
13278                                                 return;
13279                                         }
13280                                         newVal = this._trimAlignValue( curVal - step );
13281                                         break;
13282                         }
13283
13284                         this._slide( event, index, newVal );
13285                 },
13286                 click: function( event ) {
13287                         event.preventDefault();
13288                 },
13289                 keyup: function( event ) {
13290                         var index = $( event.target ).data( "ui-slider-handle-index" );
13291
13292                         if ( this._keySliding ) {
13293                                 this._keySliding = false;
13294                                 this._stop( event, index );
13295                                 this._change( event, index );
13296                                 $( event.target ).removeClass( "ui-state-active" );
13297                         }
13298                 }
13299         }
13300
13301 });
13302
13303 }(jQuery));
13304
13305 (function( $ ) {
13306
13307 function modifier( fn ) {
13308         return function() {
13309                 var previous = this.element.val();
13310                 fn.apply( this, arguments );
13311                 this._refresh();
13312                 if ( previous !== this.element.val() ) {
13313                         this._trigger( "change" );
13314                 }
13315         };
13316 }
13317
13318 $.widget( "ui.spinner", {
13319         version: "1.10.3",
13320         defaultElement: "<input>",
13321         widgetEventPrefix: "spin",
13322         options: {
13323                 culture: null,
13324                 icons: {
13325                         down: "ui-icon-triangle-1-s",
13326                         up: "ui-icon-triangle-1-n"
13327                 },
13328                 incremental: true,
13329                 max: null,
13330                 min: null,
13331                 numberFormat: null,
13332                 page: 10,
13333                 step: 1,
13334
13335                 change: null,
13336                 spin: null,
13337                 start: null,
13338                 stop: null
13339         },
13340
13341         _create: function() {
13342                 // handle string values that need to be parsed
13343                 this._setOption( "max", this.options.max );
13344                 this._setOption( "min", this.options.min );
13345                 this._setOption( "step", this.options.step );
13346
13347                 // format the value, but don't constrain
13348                 this._value( this.element.val(), true );
13349
13350                 this._draw();
13351                 this._on( this._events );
13352                 this._refresh();
13353
13354                 // turning off autocomplete prevents the browser from remembering the
13355                 // value when navigating through history, so we re-enable autocomplete
13356                 // if the page is unloaded before the widget is destroyed. #7790
13357                 this._on( this.window, {
13358                         beforeunload: function() {
13359                                 this.element.removeAttr( "autocomplete" );
13360                         }
13361                 });
13362         },
13363
13364         _getCreateOptions: function() {
13365                 var options = {},
13366                         element = this.element;
13367
13368                 $.each( [ "min", "max", "step" ], function( i, option ) {
13369                         var value = element.attr( option );
13370                         if ( value !== undefined && value.length ) {
13371                                 options[ option ] = value;
13372                         }
13373                 });
13374
13375                 return options;
13376         },
13377
13378         _events: {
13379                 keydown: function( event ) {
13380                         if ( this._start( event ) && this._keydown( event ) ) {
13381                                 event.preventDefault();
13382                         }
13383                 },
13384                 keyup: "_stop",
13385                 focus: function() {
13386                         this.previous = this.element.val();
13387                 },
13388                 blur: function( event ) {
13389                         if ( this.cancelBlur ) {
13390                                 delete this.cancelBlur;
13391                                 return;
13392                         }
13393
13394                         this._stop();
13395                         this._refresh();
13396                         if ( this.previous !== this.element.val() ) {
13397                                 this._trigger( "change", event );
13398                         }
13399                 },
13400                 mousewheel: function( event, delta ) {
13401                         if ( !delta ) {
13402                                 return;
13403                         }
13404                         if ( !this.spinning && !this._start( event ) ) {
13405                                 return false;
13406                         }
13407
13408                         this._spin( (delta > 0 ? 1 : -1) * this.options.step, event );
13409                         clearTimeout( this.mousewheelTimer );
13410                         this.mousewheelTimer = this._delay(function() {
13411                                 if ( this.spinning ) {
13412                                         this._stop( event );
13413                                 }
13414                         }, 100 );
13415                         event.preventDefault();
13416                 },
13417                 "mousedown .ui-spinner-button": function( event ) {
13418                         var previous;
13419
13420                         // We never want the buttons to have focus; whenever the user is
13421                         // interacting with the spinner, the focus should be on the input.
13422                         // If the input is focused then this.previous is properly set from
13423                         // when the input first received focus. If the input is not focused
13424                         // then we need to set this.previous based on the value before spinning.
13425                         previous = this.element[0] === this.document[0].activeElement ?
13426                                 this.previous : this.element.val();
13427                         function checkFocus() {
13428                                 var isActive = this.element[0] === this.document[0].activeElement;
13429                                 if ( !isActive ) {
13430                                         this.element.focus();
13431                                         this.previous = previous;
13432                                         // support: IE
13433                                         // IE sets focus asynchronously, so we need to check if focus
13434                                         // moved off of the input because the user clicked on the button.
13435                                         this._delay(function() {
13436                                                 this.previous = previous;
13437                                         });
13438                                 }
13439                         }
13440
13441                         // ensure focus is on (or stays on) the text field
13442                         event.preventDefault();
13443                         checkFocus.call( this );
13444
13445                         // support: IE
13446                         // IE doesn't prevent moving focus even with event.preventDefault()
13447                         // so we set a flag to know when we should ignore the blur event
13448                         // and check (again) if focus moved off of the input.
13449                         this.cancelBlur = true;
13450                         this._delay(function() {
13451                                 delete this.cancelBlur;
13452                                 checkFocus.call( this );
13453                         });
13454
13455                         if ( this._start( event ) === false ) {
13456                                 return;
13457                         }
13458
13459                         this._repeat( null, $( event.currentTarget ).hasClass( "ui-spinner-up" ) ? 1 : -1, event );
13460                 },
13461                 "mouseup .ui-spinner-button": "_stop",
13462                 "mouseenter .ui-spinner-button": function( event ) {
13463                         // button will add ui-state-active if mouse was down while mouseleave and kept down
13464                         if ( !$( event.currentTarget ).hasClass( "ui-state-active" ) ) {
13465                                 return;
13466                         }
13467
13468                         if ( this._start( event ) === false ) {
13469                                 return false;
13470                         }
13471                         this._repeat( null, $( event.currentTarget ).hasClass( "ui-spinner-up" ) ? 1 : -1, event );
13472                 },
13473                 // TODO: do we really want to consider this a stop?
13474                 // shouldn't we just stop the repeater and wait until mouseup before
13475                 // we trigger the stop event?
13476                 "mouseleave .ui-spinner-button": "_stop"
13477         },
13478
13479         _draw: function() {
13480                 var uiSpinner = this.uiSpinner = this.element
13481                         .addClass( "ui-spinner-input" )
13482                         .attr( "autocomplete", "off" )
13483                         .wrap( this._uiSpinnerHtml() )
13484                         .parent()
13485                                 // add buttons
13486                                 .append( this._buttonHtml() );
13487
13488                 this.element.attr( "role", "spinbutton" );
13489
13490                 // button bindings
13491                 this.buttons = uiSpinner.find( ".ui-spinner-button" )
13492                         .attr( "tabIndex", -1 )
13493                         .button()
13494                         .removeClass( "ui-corner-all" );
13495
13496                 // IE 6 doesn't understand height: 50% for the buttons
13497                 // unless the wrapper has an explicit height
13498                 if ( this.buttons.height() > Math.ceil( uiSpinner.height() * 0.5 ) &&
13499                                 uiSpinner.height() > 0 ) {
13500                         uiSpinner.height( uiSpinner.height() );
13501                 }
13502
13503                 // disable spinner if element was already disabled
13504                 if ( this.options.disabled ) {
13505                         this.disable();
13506                 }
13507         },
13508
13509         _keydown: function( event ) {
13510                 var options = this.options,
13511                         keyCode = $.ui.keyCode;
13512
13513                 switch ( event.keyCode ) {
13514                 case keyCode.UP:
13515                         this._repeat( null, 1, event );
13516                         return true;
13517                 case keyCode.DOWN:
13518                         this._repeat( null, -1, event );
13519                         return true;
13520                 case keyCode.PAGE_UP:
13521                         this._repeat( null, options.page, event );
13522                         return true;
13523                 case keyCode.PAGE_DOWN:
13524                         this._repeat( null, -options.page, event );
13525                         return true;
13526                 }
13527
13528                 return false;
13529         },
13530
13531         _uiSpinnerHtml: function() {
13532                 return "<span class='ui-spinner ui-widget ui-widget-content ui-corner-all'></span>";
13533         },
13534
13535         _buttonHtml: function() {
13536                 return "" +
13537                         "<a class='ui-spinner-button ui-spinner-up ui-corner-tr'>" +
13538                                 "<span class='ui-icon " + this.options.icons.up + "'>&#9650;</span>" +
13539                         "</a>" +
13540                         "<a class='ui-spinner-button ui-spinner-down ui-corner-br'>" +
13541                                 "<span class='ui-icon " + this.options.icons.down + "'>&#9660;</span>" +
13542                         "</a>";
13543         },
13544
13545         _start: function( event ) {
13546                 if ( !this.spinning && this._trigger( "start", event ) === false ) {
13547                         return false;
13548                 }
13549
13550                 if ( !this.counter ) {
13551                         this.counter = 1;
13552                 }
13553                 this.spinning = true;
13554                 return true;
13555         },
13556
13557         _repeat: function( i, steps, event ) {
13558                 i = i || 500;
13559
13560                 clearTimeout( this.timer );
13561                 this.timer = this._delay(function() {
13562                         this._repeat( 40, steps, event );
13563                 }, i );
13564
13565                 this._spin( steps * this.options.step, event );
13566         },
13567
13568         _spin: function( step, event ) {
13569                 var value = this.value() || 0;
13570
13571                 if ( !this.counter ) {
13572                         this.counter = 1;
13573                 }
13574
13575                 value = this._adjustValue( value + step * this._increment( this.counter ) );
13576
13577                 if ( !this.spinning || this._trigger( "spin", event, { value: value } ) !== false) {
13578                         this._value( value );
13579                         this.counter++;
13580                 }
13581         },
13582
13583         _increment: function( i ) {
13584                 var incremental = this.options.incremental;
13585
13586                 if ( incremental ) {
13587                         return $.isFunction( incremental ) ?
13588                                 incremental( i ) :
13589                                 Math.floor( i*i*i/50000 - i*i/500 + 17*i/200 + 1 );
13590                 }
13591
13592                 return 1;
13593         },
13594
13595         _precision: function() {
13596                 var precision = this._precisionOf( this.options.step );
13597                 if ( this.options.min !== null ) {
13598                         precision = Math.max( precision, this._precisionOf( this.options.min ) );
13599                 }
13600                 return precision;
13601         },
13602
13603         _precisionOf: function( num ) {
13604                 var str = num.toString(),
13605                         decimal = str.indexOf( "." );
13606                 return decimal === -1 ? 0 : str.length - decimal - 1;
13607         },
13608
13609         _adjustValue: function( value ) {
13610                 var base, aboveMin,
13611                         options = this.options;
13612
13613                 // make sure we're at a valid step
13614                 // - find out where we are relative to the base (min or 0)
13615                 base = options.min !== null ? options.min : 0;
13616                 aboveMin = value - base;
13617                 // - round to the nearest step
13618                 aboveMin = Math.round(aboveMin / options.step) * options.step;
13619                 // - rounding is based on 0, so adjust back to our base
13620                 value = base + aboveMin;
13621
13622                 // fix precision from bad JS floating point math
13623                 value = parseFloat( value.toFixed( this._precision() ) );
13624
13625                 // clamp the value
13626                 if ( options.max !== null && value > options.max) {
13627                         return options.max;
13628                 }
13629                 if ( options.min !== null && value < options.min ) {
13630                         return options.min;
13631                 }
13632
13633                 return value;
13634         },
13635
13636         _stop: function( event ) {
13637                 if ( !this.spinning ) {
13638                         return;
13639                 }
13640
13641                 clearTimeout( this.timer );
13642                 clearTimeout( this.mousewheelTimer );
13643                 this.counter = 0;
13644                 this.spinning = false;
13645                 this._trigger( "stop", event );
13646         },
13647
13648         _setOption: function( key, value ) {
13649                 if ( key === "culture" || key === "numberFormat" ) {
13650                         var prevValue = this._parse( this.element.val() );
13651                         this.options[ key ] = value;
13652                         this.element.val( this._format( prevValue ) );
13653                         return;
13654                 }
13655
13656                 if ( key === "max" || key === "min" || key === "step" ) {
13657                         if ( typeof value === "string" ) {
13658                                 value = this._parse( value );
13659                         }
13660                 }
13661                 if ( key === "icons" ) {
13662                         this.buttons.first().find( ".ui-icon" )
13663                                 .removeClass( this.options.icons.up )
13664                                 .addClass( value.up );
13665                         this.buttons.last().find( ".ui-icon" )
13666                                 .removeClass( this.options.icons.down )
13667                                 .addClass( value.down );
13668                 }
13669
13670                 this._super( key, value );
13671
13672                 if ( key === "disabled" ) {
13673                         if ( value ) {
13674                                 this.element.prop( "disabled", true );
13675                                 this.buttons.button( "disable" );
13676                         } else {
13677                                 this.element.prop( "disabled", false );
13678                                 this.buttons.button( "enable" );
13679                         }
13680                 }
13681         },
13682
13683         _setOptions: modifier(function( options ) {
13684                 this._super( options );
13685                 this._value( this.element.val() );
13686         }),
13687
13688         _parse: function( val ) {
13689                 if ( typeof val === "string" && val !== "" ) {
13690                         val = window.Globalize && this.options.numberFormat ?
13691                                 Globalize.parseFloat( val, 10, this.options.culture ) : +val;
13692                 }
13693                 return val === "" || isNaN( val ) ? null : val;
13694         },
13695
13696         _format: function( value ) {
13697                 if ( value === "" ) {
13698                         return "";
13699                 }
13700                 return window.Globalize && this.options.numberFormat ?
13701                         Globalize.format( value, this.options.numberFormat, this.options.culture ) :
13702                         value;
13703         },
13704
13705         _refresh: function() {
13706                 this.element.attr({
13707                         "aria-valuemin": this.options.min,
13708                         "aria-valuemax": this.options.max,
13709                         // TODO: what should we do with values that can't be parsed?
13710                         "aria-valuenow": this._parse( this.element.val() )
13711                 });
13712         },
13713
13714         // update the value without triggering change
13715         _value: function( value, allowAny ) {
13716                 var parsed;
13717                 if ( value !== "" ) {
13718                         parsed = this._parse( value );
13719                         if ( parsed !== null ) {
13720                                 if ( !allowAny ) {
13721                                         parsed = this._adjustValue( parsed );
13722                                 }
13723                                 value = this._format( parsed );
13724                         }
13725                 }
13726                 this.element.val( value );
13727                 this._refresh();
13728         },
13729
13730         _destroy: function() {
13731                 this.element
13732                         .removeClass( "ui-spinner-input" )
13733                         .prop( "disabled", false )
13734                         .removeAttr( "autocomplete" )
13735                         .removeAttr( "role" )
13736                         .removeAttr( "aria-valuemin" )
13737                         .removeAttr( "aria-valuemax" )
13738                         .removeAttr( "aria-valuenow" );
13739                 this.uiSpinner.replaceWith( this.element );
13740         },
13741
13742         stepUp: modifier(function( steps ) {
13743                 this._stepUp( steps );
13744         }),
13745         _stepUp: function( steps ) {
13746                 if ( this._start() ) {
13747                         this._spin( (steps || 1) * this.options.step );
13748                         this._stop();
13749                 }
13750         },
13751
13752         stepDown: modifier(function( steps ) {
13753                 this._stepDown( steps );
13754         }),
13755         _stepDown: function( steps ) {
13756                 if ( this._start() ) {
13757                         this._spin( (steps || 1) * -this.options.step );
13758                         this._stop();
13759                 }
13760         },
13761
13762         pageUp: modifier(function( pages ) {
13763                 this._stepUp( (pages || 1) * this.options.page );
13764         }),
13765
13766         pageDown: modifier(function( pages ) {
13767                 this._stepDown( (pages || 1) * this.options.page );
13768         }),
13769
13770         value: function( newVal ) {
13771                 if ( !arguments.length ) {
13772                         return this._parse( this.element.val() );
13773                 }
13774                 modifier( this._value ).call( this, newVal );
13775         },
13776
13777         widget: function() {
13778                 return this.uiSpinner;
13779         }
13780 });
13781
13782 }( jQuery ) );
13783
13784 (function( $, undefined ) {
13785
13786 var tabId = 0,
13787         rhash = /#.*$/;
13788
13789 function getNextTabId() {
13790         return ++tabId;
13791 }
13792
13793 function isLocal( anchor ) {
13794         return anchor.hash.length > 1 &&
13795                 decodeURIComponent( anchor.href.replace( rhash, "" ) ) ===
13796                         decodeURIComponent( location.href.replace( rhash, "" ) );
13797 }
13798
13799 $.widget( "ui.tabs", {
13800         version: "1.10.3",
13801         delay: 300,
13802         options: {
13803                 active: null,
13804                 collapsible: false,
13805                 event: "click",
13806                 heightStyle: "content",
13807                 hide: null,
13808                 show: null,
13809
13810                 // callbacks
13811                 activate: null,
13812                 beforeActivate: null,
13813                 beforeLoad: null,
13814                 load: null
13815         },
13816
13817         _create: function() {
13818                 var that = this,
13819                         options = this.options;
13820
13821                 this.running = false;
13822
13823                 this.element
13824                         .addClass( "ui-tabs ui-widget ui-widget-content ui-corner-all" )
13825                         .toggleClass( "ui-tabs-collapsible", options.collapsible )
13826                         // Prevent users from focusing disabled tabs via click
13827                         .delegate( ".ui-tabs-nav > li", "mousedown" + this.eventNamespace, function( event ) {
13828                                 if ( $( this ).is( ".ui-state-disabled" ) ) {
13829                                         event.preventDefault();
13830                                 }
13831                         })
13832                         // support: IE <9
13833                         // Preventing the default action in mousedown doesn't prevent IE
13834                         // from focusing the element, so if the anchor gets focused, blur.
13835                         // We don't have to worry about focusing the previously focused
13836                         // element since clicking on a non-focusable element should focus
13837                         // the body anyway.
13838                         .delegate( ".ui-tabs-anchor", "focus" + this.eventNamespace, function() {
13839                                 if ( $( this ).closest( "li" ).is( ".ui-state-disabled" ) ) {
13840                                         this.blur();
13841                                 }
13842                         });
13843
13844                 this._processTabs();
13845                 options.active = this._initialActive();
13846
13847                 // Take disabling tabs via class attribute from HTML
13848                 // into account and update option properly.
13849                 if ( $.isArray( options.disabled ) ) {
13850                         options.disabled = $.unique( options.disabled.concat(
13851                                 $.map( this.tabs.filter( ".ui-state-disabled" ), function( li ) {
13852                                         return that.tabs.index( li );
13853                                 })
13854                         ) ).sort();
13855                 }
13856
13857                 // check for length avoids error when initializing empty list
13858                 if ( this.options.active !== false && this.anchors.length ) {
13859                         this.active = this._findActive( options.active );
13860                 } else {
13861                         this.active = $();
13862                 }
13863
13864                 this._refresh();
13865
13866                 if ( this.active.length ) {
13867                         this.load( options.active );
13868                 }
13869         },
13870
13871         _initialActive: function() {
13872                 var active = this.options.active,
13873                         collapsible = this.options.collapsible,
13874                         locationHash = location.hash.substring( 1 );
13875
13876                 if ( active === null ) {
13877                         // check the fragment identifier in the URL
13878                         if ( locationHash ) {
13879                                 this.tabs.each(function( i, tab ) {
13880                                         if ( $( tab ).attr( "aria-controls" ) === locationHash ) {
13881                                                 active = i;
13882                                                 return false;
13883                                         }
13884                                 });
13885                         }
13886
13887                         // check for a tab marked active via a class
13888                         if ( active === null ) {
13889                                 active = this.tabs.index( this.tabs.filter( ".ui-tabs-active" ) );
13890                         }
13891
13892                         // no active tab, set to false
13893                         if ( active === null || active === -1 ) {
13894                                 active = this.tabs.length ? 0 : false;
13895                         }
13896                 }
13897
13898                 // handle numbers: negative, out of range
13899                 if ( active !== false ) {
13900                         active = this.tabs.index( this.tabs.eq( active ) );
13901                         if ( active === -1 ) {
13902                                 active = collapsible ? false : 0;
13903                         }
13904                 }
13905
13906                 // don't allow collapsible: false and active: false
13907                 if ( !collapsible && active === false && this.anchors.length ) {
13908                         active = 0;
13909                 }
13910
13911                 return active;
13912         },
13913
13914         _getCreateEventData: function() {
13915                 return {
13916                         tab: this.active,
13917                         panel: !this.active.length ? $() : this._getPanelForTab( this.active )
13918                 };
13919         },
13920
13921         _tabKeydown: function( event ) {
13922                 /*jshint maxcomplexity:15*/
13923                 var focusedTab = $( this.document[0].activeElement ).closest( "li" ),
13924                         selectedIndex = this.tabs.index( focusedTab ),
13925                         goingForward = true;
13926
13927                 if ( this._handlePageNav( event ) ) {
13928                         return;
13929                 }
13930
13931                 switch ( event.keyCode ) {
13932                         case $.ui.keyCode.RIGHT:
13933                         case $.ui.keyCode.DOWN:
13934                                 selectedIndex++;
13935                                 break;
13936                         case $.ui.keyCode.UP:
13937                         case $.ui.keyCode.LEFT:
13938                                 goingForward = false;
13939                                 selectedIndex--;
13940                                 break;
13941                         case $.ui.keyCode.END:
13942                                 selectedIndex = this.anchors.length - 1;
13943                                 break;
13944                         case $.ui.keyCode.HOME:
13945                                 selectedIndex = 0;
13946                                 break;
13947                         case $.ui.keyCode.SPACE:
13948                                 // Activate only, no collapsing
13949                                 event.preventDefault();
13950                                 clearTimeout( this.activating );
13951                                 this._activate( selectedIndex );
13952                                 return;
13953                         case $.ui.keyCode.ENTER:
13954                                 // Toggle (cancel delayed activation, allow collapsing)
13955                                 event.preventDefault();
13956                                 clearTimeout( this.activating );
13957                                 // Determine if we should collapse or activate
13958                                 this._activate( selectedIndex === this.options.active ? false : selectedIndex );
13959                                 return;
13960                         default:
13961                                 return;
13962                 }
13963
13964                 // Focus the appropriate tab, based on which key was pressed
13965                 event.preventDefault();
13966                 clearTimeout( this.activating );
13967                 selectedIndex = this._focusNextTab( selectedIndex, goingForward );
13968
13969                 // Navigating with control key will prevent automatic activation
13970                 if ( !event.ctrlKey ) {
13971                         // Update aria-selected immediately so that AT think the tab is already selected.
13972                         // Otherwise AT may confuse the user by stating that they need to activate the tab,
13973                         // but the tab will already be activated by the time the announcement finishes.
13974                         focusedTab.attr( "aria-selected", "false" );
13975                         this.tabs.eq( selectedIndex ).attr( "aria-selected", "true" );
13976
13977                         this.activating = this._delay(function() {
13978                                 this.option( "active", selectedIndex );
13979                         }, this.delay );
13980                 }
13981         },
13982
13983         _panelKeydown: function( event ) {
13984                 if ( this._handlePageNav( event ) ) {
13985                         return;
13986                 }
13987
13988                 // Ctrl+up moves focus to the current tab
13989                 if ( event.ctrlKey && event.keyCode === $.ui.keyCode.UP ) {
13990                         event.preventDefault();
13991                         this.active.focus();
13992                 }
13993         },
13994
13995         // Alt+page up/down moves focus to the previous/next tab (and activates)
13996         _handlePageNav: function( event ) {
13997                 if ( event.altKey && event.keyCode === $.ui.keyCode.PAGE_UP ) {
13998                         this._activate( this._focusNextTab( this.options.active - 1, false ) );
13999                         return true;
14000                 }
14001                 if ( event.altKey && event.keyCode === $.ui.keyCode.PAGE_DOWN ) {
14002                         this._activate( this._focusNextTab( this.options.active + 1, true ) );
14003                         return true;
14004                 }
14005         },
14006
14007         _findNextTab: function( index, goingForward ) {
14008                 var lastTabIndex = this.tabs.length - 1;
14009
14010                 function constrain() {
14011                         if ( index > lastTabIndex ) {
14012                                 index = 0;
14013                         }
14014                         if ( index < 0 ) {
14015                                 index = lastTabIndex;
14016                         }
14017                         return index;
14018                 }
14019
14020                 while ( $.inArray( constrain(), this.options.disabled ) !== -1 ) {
14021                         index = goingForward ? index + 1 : index - 1;
14022                 }
14023
14024                 return index;
14025         },
14026
14027         _focusNextTab: function( index, goingForward ) {
14028                 index = this._findNextTab( index, goingForward );
14029                 this.tabs.eq( index ).focus();
14030                 return index;
14031         },
14032
14033         _setOption: function( key, value ) {
14034                 if ( key === "active" ) {
14035                         // _activate() will handle invalid values and update this.options
14036                         this._activate( value );
14037                         return;
14038                 }
14039
14040                 if ( key === "disabled" ) {
14041                         // don't use the widget factory's disabled handling
14042                         this._setupDisabled( value );
14043                         return;
14044                 }
14045
14046                 this._super( key, value);
14047
14048                 if ( key === "collapsible" ) {
14049                         this.element.toggleClass( "ui-tabs-collapsible", value );
14050                         // Setting collapsible: false while collapsed; open first panel
14051                         if ( !value && this.options.active === false ) {
14052                                 this._activate( 0 );
14053                         }
14054                 }
14055
14056                 if ( key === "event" ) {
14057                         this._setupEvents( value );
14058                 }
14059
14060                 if ( key === "heightStyle" ) {
14061                         this._setupHeightStyle( value );
14062                 }
14063         },
14064
14065         _tabId: function( tab ) {
14066                 return tab.attr( "aria-controls" ) || "ui-tabs-" + getNextTabId();
14067         },
14068
14069         _sanitizeSelector: function( hash ) {
14070                 return hash ? hash.replace( /[!"$%&'()*+,.\/:;<=>?@\[\]\^`{|}~]/g, "\\$&" ) : "";
14071         },
14072
14073         refresh: function() {
14074                 var options = this.options,
14075                         lis = this.tablist.children( ":has(a[href])" );
14076
14077                 // get disabled tabs from class attribute from HTML
14078                 // this will get converted to a boolean if needed in _refresh()
14079                 options.disabled = $.map( lis.filter( ".ui-state-disabled" ), function( tab ) {
14080                         return lis.index( tab );
14081                 });
14082
14083                 this._processTabs();
14084
14085                 // was collapsed or no tabs
14086                 if ( options.active === false || !this.anchors.length ) {
14087                         options.active = false;
14088                         this.active = $();
14089                 // was active, but active tab is gone
14090                 } else if ( this.active.length && !$.contains( this.tablist[ 0 ], this.active[ 0 ] ) ) {
14091                         // all remaining tabs are disabled
14092                         if ( this.tabs.length === options.disabled.length ) {
14093                                 options.active = false;
14094                                 this.active = $();
14095                         // activate previous tab
14096                         } else {
14097                                 this._activate( this._findNextTab( Math.max( 0, options.active - 1 ), false ) );
14098                         }
14099                 // was active, active tab still exists
14100                 } else {
14101                         // make sure active index is correct
14102                         options.active = this.tabs.index( this.active );
14103                 }
14104
14105                 this._refresh();
14106         },
14107
14108         _refresh: function() {
14109                 this._setupDisabled( this.options.disabled );
14110                 this._setupEvents( this.options.event );
14111                 this._setupHeightStyle( this.options.heightStyle );
14112
14113                 this.tabs.not( this.active ).attr({
14114                         "aria-selected": "false",
14115                         tabIndex: -1
14116                 });
14117                 this.panels.not( this._getPanelForTab( this.active ) )
14118                         .hide()
14119                         .attr({
14120                                 "aria-expanded": "false",
14121                                 "aria-hidden": "true"
14122                         });
14123
14124                 // Make sure one tab is in the tab order
14125                 if ( !this.active.length ) {
14126                         this.tabs.eq( 0 ).attr( "tabIndex", 0 );
14127                 } else {
14128                         this.active
14129                                 .addClass( "ui-tabs-active ui-state-active" )
14130                                 .attr({
14131                                         "aria-selected": "true",
14132                                         tabIndex: 0
14133                                 });
14134                         this._getPanelForTab( this.active )
14135                                 .show()
14136                                 .attr({
14137                                         "aria-expanded": "true",
14138                                         "aria-hidden": "false"
14139                                 });
14140                 }
14141         },
14142
14143         _processTabs: function() {
14144                 var that = this;
14145
14146                 this.tablist = this._getList()
14147                         .addClass( "ui-tabs-nav ui-helper-reset ui-helper-clearfix ui-widget-header ui-corner-all" )
14148                         .attr( "role", "tablist" );
14149
14150                 this.tabs = this.tablist.find( "> li:has(a[href])" )
14151                         .addClass( "ui-state-default ui-corner-top" )
14152                         .attr({
14153                                 role: "tab",
14154                                 tabIndex: -1
14155                         });
14156
14157                 this.anchors = this.tabs.map(function() {
14158                                 return $( "a", this )[ 0 ];
14159                         })
14160                         .addClass( "ui-tabs-anchor" )
14161                         .attr({
14162                                 role: "presentation",
14163                                 tabIndex: -1
14164                         });
14165
14166                 this.panels = $();
14167
14168                 this.anchors.each(function( i, anchor ) {
14169                         var selector, panel, panelId,
14170                                 anchorId = $( anchor ).uniqueId().attr( "id" ),
14171                                 tab = $( anchor ).closest( "li" ),
14172                                 originalAriaControls = tab.attr( "aria-controls" );
14173
14174                         // inline tab
14175                         if ( isLocal( anchor ) ) {
14176                                 selector = anchor.hash;
14177                                 panel = that.element.find( that._sanitizeSelector( selector ) );
14178                         // remote tab
14179                         } else {
14180                                 panelId = that._tabId( tab );
14181                                 selector = "#" + panelId;
14182                                 panel = that.element.find( selector );
14183                                 if ( !panel.length ) {
14184                                         panel = that._createPanel( panelId );
14185                                         panel.insertAfter( that.panels[ i - 1 ] || that.tablist );
14186                                 }
14187                                 panel.attr( "aria-live", "polite" );
14188                         }
14189
14190                         if ( panel.length) {
14191                                 that.panels = that.panels.add( panel );
14192                         }
14193                         if ( originalAriaControls ) {
14194                                 tab.data( "ui-tabs-aria-controls", originalAriaControls );
14195                         }
14196                         tab.attr({
14197                                 "aria-controls": selector.substring( 1 ),
14198                                 "aria-labelledby": anchorId
14199                         });
14200                         panel.attr( "aria-labelledby", anchorId );
14201                 });
14202
14203                 this.panels
14204                         .addClass( "ui-tabs-panel ui-widget-content ui-corner-bottom" )
14205                         .attr( "role", "tabpanel" );
14206         },
14207
14208         // allow overriding how to find the list for rare usage scenarios (#7715)
14209         _getList: function() {
14210                 return this.element.find( "ol,ul" ).eq( 0 );
14211         },
14212
14213         _createPanel: function( id ) {
14214                 return $( "<div>" )
14215                         .attr( "id", id )
14216                         .addClass( "ui-tabs-panel ui-widget-content ui-corner-bottom" )
14217                         .data( "ui-tabs-destroy", true );
14218         },
14219
14220         _setupDisabled: function( disabled ) {
14221                 if ( $.isArray( disabled ) ) {
14222                         if ( !disabled.length ) {
14223                                 disabled = false;
14224                         } else if ( disabled.length === this.anchors.length ) {
14225                                 disabled = true;
14226                         }
14227                 }
14228
14229                 // disable tabs
14230                 for ( var i = 0, li; ( li = this.tabs[ i ] ); i++ ) {
14231                         if ( disabled === true || $.inArray( i, disabled ) !== -1 ) {
14232                                 $( li )
14233                                         .addClass( "ui-state-disabled" )
14234                                         .attr( "aria-disabled", "true" );
14235                         } else {
14236                                 $( li )
14237                                         .removeClass( "ui-state-disabled" )
14238                                         .removeAttr( "aria-disabled" );
14239                         }
14240                 }
14241
14242                 this.options.disabled = disabled;
14243         },
14244
14245         _setupEvents: function( event ) {
14246                 var events = {
14247                         click: function( event ) {
14248                                 event.preventDefault();
14249                         }
14250                 };
14251                 if ( event ) {
14252                         $.each( event.split(" "), function( index, eventName ) {
14253                                 events[ eventName ] = "_eventHandler";
14254                         });
14255                 }
14256
14257                 this._off( this.anchors.add( this.tabs ).add( this.panels ) );
14258                 this._on( this.anchors, events );
14259                 this._on( this.tabs, { keydown: "_tabKeydown" } );
14260                 this._on( this.panels, { keydown: "_panelKeydown" } );
14261
14262                 this._focusable( this.tabs );
14263                 this._hoverable( this.tabs );
14264         },
14265
14266         _setupHeightStyle: function( heightStyle ) {
14267                 var maxHeight,
14268                         parent = this.element.parent();
14269
14270                 if ( heightStyle === "fill" ) {
14271                         maxHeight = parent.height();
14272                         maxHeight -= this.element.outerHeight() - this.element.height();
14273
14274                         this.element.siblings( ":visible" ).each(function() {
14275                                 var elem = $( this ),
14276                                         position = elem.css( "position" );
14277
14278                                 if ( position === "absolute" || position === "fixed" ) {
14279                                         return;
14280                                 }
14281                                 maxHeight -= elem.outerHeight( true );
14282                         });
14283
14284                         this.element.children().not( this.panels ).each(function() {
14285                                 maxHeight -= $( this ).outerHeight( true );
14286                         });
14287
14288                         this.panels.each(function() {
14289                                 $( this ).height( Math.max( 0, maxHeight -
14290                                         $( this ).innerHeight() + $( this ).height() ) );
14291                         })
14292                         .css( "overflow", "auto" );
14293                 } else if ( heightStyle === "auto" ) {
14294                         maxHeight = 0;
14295                         this.panels.each(function() {
14296                                 maxHeight = Math.max( maxHeight, $( this ).height( "" ).height() );
14297                         }).height( maxHeight );
14298                 }
14299         },
14300
14301         _eventHandler: function( event ) {
14302                 var options = this.options,
14303                         active = this.active,
14304                         anchor = $( event.currentTarget ),
14305                         tab = anchor.closest( "li" ),
14306                         clickedIsActive = tab[ 0 ] === active[ 0 ],
14307                         collapsing = clickedIsActive && options.collapsible,
14308                         toShow = collapsing ? $() : this._getPanelForTab( tab ),
14309                         toHide = !active.length ? $() : this._getPanelForTab( active ),
14310                         eventData = {
14311                                 oldTab: active,
14312                                 oldPanel: toHide,
14313                                 newTab: collapsing ? $() : tab,
14314                                 newPanel: toShow
14315                         };
14316
14317                 event.preventDefault();
14318
14319                 if ( tab.hasClass( "ui-state-disabled" ) ||
14320                                 // tab is already loading
14321                                 tab.hasClass( "ui-tabs-loading" ) ||
14322                                 // can't switch durning an animation
14323                                 this.running ||
14324                                 // click on active header, but not collapsible
14325                                 ( clickedIsActive && !options.collapsible ) ||
14326                                 // allow canceling activation
14327                                 ( this._trigger( "beforeActivate", event, eventData ) === false ) ) {
14328                         return;
14329                 }
14330
14331                 options.active = collapsing ? false : this.tabs.index( tab );
14332
14333                 this.active = clickedIsActive ? $() : tab;
14334                 if ( this.xhr ) {
14335                         this.xhr.abort();
14336                 }
14337
14338                 if ( !toHide.length && !toShow.length ) {
14339                         $.error( "jQuery UI Tabs: Mismatching fragment identifier." );
14340                 }
14341
14342                 if ( toShow.length ) {
14343                         this.load( this.tabs.index( tab ), event );
14344                 }
14345                 this._toggle( event, eventData );
14346         },
14347
14348         // handles show/hide for selecting tabs
14349         _toggle: function( event, eventData ) {
14350                 var that = this,
14351                         toShow = eventData.newPanel,
14352                         toHide = eventData.oldPanel;
14353
14354                 this.running = true;
14355
14356                 function complete() {
14357                         that.running = false;
14358                         that._trigger( "activate", event, eventData );
14359                 }
14360
14361                 function show() {
14362                         eventData.newTab.closest( "li" ).addClass( "ui-tabs-active ui-state-active" );
14363
14364                         if ( toShow.length && that.options.show ) {
14365                                 that._show( toShow, that.options.show, complete );
14366                         } else {
14367                                 toShow.show();
14368                                 complete();
14369                         }
14370                 }
14371
14372                 // start out by hiding, then showing, then completing
14373                 if ( toHide.length && this.options.hide ) {
14374                         this._hide( toHide, this.options.hide, function() {
14375                                 eventData.oldTab.closest( "li" ).removeClass( "ui-tabs-active ui-state-active" );
14376                                 show();
14377                         });
14378                 } else {
14379                         eventData.oldTab.closest( "li" ).removeClass( "ui-tabs-active ui-state-active" );
14380                         toHide.hide();
14381                         show();
14382                 }
14383
14384                 toHide.attr({
14385                         "aria-expanded": "false",
14386                         "aria-hidden": "true"
14387                 });
14388                 eventData.oldTab.attr( "aria-selected", "false" );
14389                 // If we're switching tabs, remove the old tab from the tab order.
14390                 // If we're opening from collapsed state, remove the previous tab from the tab order.
14391                 // If we're collapsing, then keep the collapsing tab in the tab order.
14392                 if ( toShow.length && toHide.length ) {
14393                         eventData.oldTab.attr( "tabIndex", -1 );
14394                 } else if ( toShow.length ) {
14395                         this.tabs.filter(function() {
14396                                 return $( this ).attr( "tabIndex" ) === 0;
14397                         })
14398                         .attr( "tabIndex", -1 );
14399                 }
14400
14401                 toShow.attr({
14402                         "aria-expanded": "true",
14403                         "aria-hidden": "false"
14404                 });
14405                 eventData.newTab.attr({
14406                         "aria-selected": "true",
14407                         tabIndex: 0
14408                 });
14409         },
14410
14411         _activate: function( index ) {
14412                 var anchor,
14413                         active = this._findActive( index );
14414
14415                 // trying to activate the already active panel
14416                 if ( active[ 0 ] === this.active[ 0 ] ) {
14417                         return;
14418                 }
14419
14420                 // trying to collapse, simulate a click on the current active header
14421                 if ( !active.length ) {
14422                         active = this.active;
14423                 }
14424
14425                 anchor = active.find( ".ui-tabs-anchor" )[ 0 ];
14426                 this._eventHandler({
14427                         target: anchor,
14428                         currentTarget: anchor,
14429                         preventDefault: $.noop
14430                 });
14431         },
14432
14433         _findActive: function( index ) {
14434                 return index === false ? $() : this.tabs.eq( index );
14435         },
14436
14437         _getIndex: function( index ) {
14438                 // meta-function to give users option to provide a href string instead of a numerical index.
14439                 if ( typeof index === "string" ) {
14440                         index = this.anchors.index( this.anchors.filter( "[href$='" + index + "']" ) );
14441                 }
14442
14443                 return index;
14444         },
14445
14446         _destroy: function() {
14447                 if ( this.xhr ) {
14448                         this.xhr.abort();
14449                 }
14450
14451                 this.element.removeClass( "ui-tabs ui-widget ui-widget-content ui-corner-all ui-tabs-collapsible" );
14452
14453                 this.tablist
14454                         .removeClass( "ui-tabs-nav ui-helper-reset ui-helper-clearfix ui-widget-header ui-corner-all" )
14455                         .removeAttr( "role" );
14456
14457                 this.anchors
14458                         .removeClass( "ui-tabs-anchor" )
14459                         .removeAttr( "role" )
14460                         .removeAttr( "tabIndex" )
14461                         .removeUniqueId();
14462
14463                 this.tabs.add( this.panels ).each(function() {
14464                         if ( $.data( this, "ui-tabs-destroy" ) ) {
14465                                 $( this ).remove();
14466                         } else {
14467                                 $( this )
14468                                         .removeClass( "ui-state-default ui-state-active ui-state-disabled " +
14469                                                 "ui-corner-top ui-corner-bottom ui-widget-content ui-tabs-active ui-tabs-panel" )
14470                                         .removeAttr( "tabIndex" )
14471                                         .removeAttr( "aria-live" )
14472                                         .removeAttr( "aria-busy" )
14473                                         .removeAttr( "aria-selected" )
14474                                         .removeAttr( "aria-labelledby" )
14475                                         .removeAttr( "aria-hidden" )
14476                                         .removeAttr( "aria-expanded" )
14477                                         .removeAttr( "role" );
14478                         }
14479                 });
14480
14481                 this.tabs.each(function() {
14482                         var li = $( this ),
14483                                 prev = li.data( "ui-tabs-aria-controls" );
14484                         if ( prev ) {
14485                                 li
14486                                         .attr( "aria-controls", prev )
14487                                         .removeData( "ui-tabs-aria-controls" );
14488                         } else {
14489                                 li.removeAttr( "aria-controls" );
14490                         }
14491                 });
14492
14493                 this.panels.show();
14494
14495                 if ( this.options.heightStyle !== "content" ) {
14496                         this.panels.css( "height", "" );
14497                 }
14498         },
14499
14500         enable: function( index ) {
14501                 var disabled = this.options.disabled;
14502                 if ( disabled === false ) {
14503                         return;
14504                 }
14505
14506                 if ( index === undefined ) {
14507                         disabled = false;
14508                 } else {
14509                         index = this._getIndex( index );
14510                         if ( $.isArray( disabled ) ) {
14511                                 disabled = $.map( disabled, function( num ) {
14512                                         return num !== index ? num : null;
14513                                 });
14514                         } else {
14515                                 disabled = $.map( this.tabs, function( li, num ) {
14516                                         return num !== index ? num : null;
14517                                 });
14518                         }
14519                 }
14520                 this._setupDisabled( disabled );
14521         },
14522
14523         disable: function( index ) {
14524                 var disabled = this.options.disabled;
14525                 if ( disabled === true ) {
14526                         return;
14527                 }
14528
14529                 if ( index === undefined ) {
14530                         disabled = true;
14531                 } else {
14532                         index = this._getIndex( index );
14533                         if ( $.inArray( index, disabled ) !== -1 ) {
14534                                 return;
14535                         }
14536                         if ( $.isArray( disabled ) ) {
14537                                 disabled = $.merge( [ index ], disabled ).sort();
14538                         } else {
14539                                 disabled = [ index ];
14540                         }
14541                 }
14542                 this._setupDisabled( disabled );
14543         },
14544
14545         load: function( index, event ) {
14546                 index = this._getIndex( index );
14547                 var that = this,
14548                         tab = this.tabs.eq( index ),
14549                         anchor = tab.find( ".ui-tabs-anchor" ),
14550                         panel = this._getPanelForTab( tab ),
14551                         eventData = {
14552                                 tab: tab,
14553                                 panel: panel
14554                         };
14555
14556                 // not remote
14557                 if ( isLocal( anchor[ 0 ] ) ) {
14558                         return;
14559                 }
14560
14561                 this.xhr = $.ajax( this._ajaxSettings( anchor, event, eventData ) );
14562
14563                 // support: jQuery <1.8
14564                 // jQuery <1.8 returns false if the request is canceled in beforeSend,
14565                 // but as of 1.8, $.ajax() always returns a jqXHR object.
14566                 if ( this.xhr && this.xhr.statusText !== "canceled" ) {
14567                         tab.addClass( "ui-tabs-loading" );
14568                         panel.attr( "aria-busy", "true" );
14569
14570                         this.xhr
14571                                 .success(function( response ) {
14572                                         // support: jQuery <1.8
14573                                         // http://bugs.jquery.com/ticket/11778
14574                                         setTimeout(function() {
14575                                                 panel.html( response );
14576                                                 that._trigger( "load", event, eventData );
14577                                         }, 1 );
14578                                 })
14579                                 .complete(function( jqXHR, status ) {
14580                                         // support: jQuery <1.8
14581                                         // http://bugs.jquery.com/ticket/11778
14582                                         setTimeout(function() {
14583                                                 if ( status === "abort" ) {
14584                                                         that.panels.stop( false, true );
14585                                                 }
14586
14587                                                 tab.removeClass( "ui-tabs-loading" );
14588                                                 panel.removeAttr( "aria-busy" );
14589
14590                                                 if ( jqXHR === that.xhr ) {
14591                                                         delete that.xhr;
14592                                                 }
14593                                         }, 1 );
14594                                 });
14595                 }
14596         },
14597
14598         _ajaxSettings: function( anchor, event, eventData ) {
14599                 var that = this;
14600                 return {
14601                         url: anchor.attr( "href" ),
14602                         beforeSend: function( jqXHR, settings ) {
14603                                 return that._trigger( "beforeLoad", event,
14604                                         $.extend( { jqXHR : jqXHR, ajaxSettings: settings }, eventData ) );
14605                         }
14606                 };
14607         },
14608
14609         _getPanelForTab: function( tab ) {
14610                 var id = $( tab ).attr( "aria-controls" );
14611                 return this.element.find( this._sanitizeSelector( "#" + id ) );
14612         }
14613 });
14614
14615 })( jQuery );
14616
14617 (function( $ ) {
14618
14619 var increments = 0;
14620
14621 function addDescribedBy( elem, id ) {
14622         var describedby = (elem.attr( "aria-describedby" ) || "").split( /\s+/ );
14623         describedby.push( id );
14624         elem
14625                 .data( "ui-tooltip-id", id )
14626                 .attr( "aria-describedby", $.trim( describedby.join( " " ) ) );
14627 }
14628
14629 function removeDescribedBy( elem ) {
14630         var id = elem.data( "ui-tooltip-id" ),
14631                 describedby = (elem.attr( "aria-describedby" ) || "").split( /\s+/ ),
14632                 index = $.inArray( id, describedby );
14633         if ( index !== -1 ) {
14634                 describedby.splice( index, 1 );
14635         }
14636
14637         elem.removeData( "ui-tooltip-id" );
14638         describedby = $.trim( describedby.join( " " ) );
14639         if ( describedby ) {
14640                 elem.attr( "aria-describedby", describedby );
14641         } else {
14642                 elem.removeAttr( "aria-describedby" );
14643         }
14644 }
14645
14646 $.widget( "ui.tooltip", {
14647         version: "1.10.3",
14648         options: {
14649                 content: function() {
14650                         // support: IE<9, Opera in jQuery <1.7
14651                         // .text() can't accept undefined, so coerce to a string
14652                         var title = $( this ).attr( "title" ) || "";
14653                         // Escape title, since we're going from an attribute to raw HTML
14654                         return $( "<a>" ).text( title ).html();
14655                 },
14656                 hide: true,
14657                 // Disabled elements have inconsistent behavior across browsers (#8661)
14658                 items: "[title]:not([disabled])",
14659                 position: {
14660                         my: "left top+15",
14661                         at: "left bottom",
14662                         collision: "flipfit flip"
14663                 },
14664                 show: true,
14665                 tooltipClass: null,
14666                 track: false,
14667
14668                 // callbacks
14669                 close: null,
14670                 open: null
14671         },
14672
14673         _create: function() {
14674                 this._on({
14675                         mouseover: "open",
14676                         focusin: "open"
14677                 });
14678
14679                 // IDs of generated tooltips, needed for destroy
14680                 this.tooltips = {};
14681                 // IDs of parent tooltips where we removed the title attribute
14682                 this.parents = {};
14683
14684                 if ( this.options.disabled ) {
14685                         this._disable();
14686                 }
14687         },
14688
14689         _setOption: function( key, value ) {
14690                 var that = this;
14691
14692                 if ( key === "disabled" ) {
14693                         this[ value ? "_disable" : "_enable" ]();
14694                         this.options[ key ] = value;
14695                         // disable element style changes
14696                         return;
14697                 }
14698
14699                 this._super( key, value );
14700
14701                 if ( key === "content" ) {
14702                         $.each( this.tooltips, function( id, element ) {
14703                                 that._updateContent( element );
14704                         });
14705                 }
14706         },
14707
14708         _disable: function() {
14709                 var that = this;
14710
14711                 // close open tooltips
14712                 $.each( this.tooltips, function( id, element ) {
14713                         var event = $.Event( "blur" );
14714                         event.target = event.currentTarget = element[0];
14715                         that.close( event, true );
14716                 });
14717
14718                 // remove title attributes to prevent native tooltips
14719                 this.element.find( this.options.items ).addBack().each(function() {
14720                         var element = $( this );
14721                         if ( element.is( "[title]" ) ) {
14722                                 element
14723                                         .data( "ui-tooltip-title", element.attr( "title" ) )
14724                                         .attr( "title", "" );
14725                         }
14726                 });
14727         },
14728
14729         _enable: function() {
14730                 // restore title attributes
14731                 this.element.find( this.options.items ).addBack().each(function() {
14732                         var element = $( this );
14733                         if ( element.data( "ui-tooltip-title" ) ) {
14734                                 element.attr( "title", element.data( "ui-tooltip-title" ) );
14735                         }
14736                 });
14737         },
14738
14739         open: function( event ) {
14740                 var that = this,
14741                         target = $( event ? event.target : this.element )
14742                                 // we need closest here due to mouseover bubbling,
14743                                 // but always pointing at the same event target
14744                                 .closest( this.options.items );
14745
14746                 // No element to show a tooltip for or the tooltip is already open
14747                 if ( !target.length || target.data( "ui-tooltip-id" ) ) {
14748                         return;
14749                 }
14750
14751                 if ( target.attr( "title" ) ) {
14752                         target.data( "ui-tooltip-title", target.attr( "title" ) );
14753                 }
14754
14755                 target.data( "ui-tooltip-open", true );
14756
14757                 // kill parent tooltips, custom or native, for hover
14758                 if ( event && event.type === "mouseover" ) {
14759                         target.parents().each(function() {
14760                                 var parent = $( this ),
14761                                         blurEvent;
14762                                 if ( parent.data( "ui-tooltip-open" ) ) {
14763                                         blurEvent = $.Event( "blur" );
14764                                         blurEvent.target = blurEvent.currentTarget = this;
14765                                         that.close( blurEvent, true );
14766                                 }
14767                                 if ( parent.attr( "title" ) ) {
14768                                         parent.uniqueId();
14769                                         that.parents[ this.id ] = {
14770                                                 element: this,
14771                                                 title: parent.attr( "title" )
14772                                         };
14773                                         parent.attr( "title", "" );
14774                                 }
14775                         });
14776                 }
14777
14778                 this._updateContent( target, event );
14779         },
14780
14781         _updateContent: function( target, event ) {
14782                 var content,
14783                         contentOption = this.options.content,
14784                         that = this,
14785                         eventType = event ? event.type : null;
14786
14787                 if ( typeof contentOption === "string" ) {
14788                         return this._open( event, target, contentOption );
14789                 }
14790
14791                 content = contentOption.call( target[0], function( response ) {
14792                         // ignore async response if tooltip was closed already
14793                         if ( !target.data( "ui-tooltip-open" ) ) {
14794                                 return;
14795                         }
14796                         // IE may instantly serve a cached response for ajax requests
14797                         // delay this call to _open so the other call to _open runs first
14798                         that._delay(function() {
14799                                 // jQuery creates a special event for focusin when it doesn't
14800                                 // exist natively. To improve performance, the native event
14801                                 // object is reused and the type is changed. Therefore, we can't
14802                                 // rely on the type being correct after the event finished
14803                                 // bubbling, so we set it back to the previous value. (#8740)
14804                                 if ( event ) {
14805                                         event.type = eventType;
14806                                 }
14807                                 this._open( event, target, response );
14808                         });
14809                 });
14810                 if ( content ) {
14811                         this._open( event, target, content );
14812                 }
14813         },
14814
14815         _open: function( event, target, content ) {
14816                 var tooltip, events, delayedShow,
14817                         positionOption = $.extend( {}, this.options.position );
14818
14819                 if ( !content ) {
14820                         return;
14821                 }
14822
14823                 // Content can be updated multiple times. If the tooltip already
14824                 // exists, then just update the content and bail.
14825                 tooltip = this._find( target );
14826                 if ( tooltip.length ) {
14827                         tooltip.find( ".ui-tooltip-content" ).html( content );
14828                         return;
14829                 }
14830
14831                 // if we have a title, clear it to prevent the native tooltip
14832                 // we have to check first to avoid defining a title if none exists
14833                 // (we don't want to cause an element to start matching [title])
14834                 //
14835                 // We use removeAttr only for key events, to allow IE to export the correct
14836                 // accessible attributes. For mouse events, set to empty string to avoid
14837                 // native tooltip showing up (happens only when removing inside mouseover).
14838                 if ( target.is( "[title]" ) ) {
14839                         if ( event && event.type === "mouseover" ) {
14840                                 target.attr( "title", "" );
14841                         } else {
14842                                 target.removeAttr( "title" );
14843                         }
14844                 }
14845
14846                 tooltip = this._tooltip( target );
14847                 addDescribedBy( target, tooltip.attr( "id" ) );
14848                 tooltip.find( ".ui-tooltip-content" ).html( content );
14849
14850                 function position( event ) {
14851                         positionOption.of = event;
14852                         if ( tooltip.is( ":hidden" ) ) {
14853                                 return;
14854                         }
14855                         tooltip.position( positionOption );
14856                 }
14857                 if ( this.options.track && event && /^mouse/.test( event.type ) ) {
14858                         this._on( this.document, {
14859                                 mousemove: position
14860                         });
14861                         // trigger once to override element-relative positioning
14862                         position( event );
14863                 } else {
14864                         tooltip.position( $.extend({
14865                                 of: target
14866                         }, this.options.position ) );
14867                 }
14868
14869                 tooltip.hide();
14870
14871                 this._show( tooltip, this.options.show );
14872                 // Handle tracking tooltips that are shown with a delay (#8644). As soon
14873                 // as the tooltip is visible, position the tooltip using the most recent
14874                 // event.
14875                 if ( this.options.show && this.options.show.delay ) {
14876                         delayedShow = this.delayedShow = setInterval(function() {
14877                                 if ( tooltip.is( ":visible" ) ) {
14878                                         position( positionOption.of );
14879                                         clearInterval( delayedShow );
14880                                 }
14881                         }, $.fx.interval );
14882                 }
14883
14884                 this._trigger( "open", event, { tooltip: tooltip } );
14885
14886                 events = {
14887                         keyup: function( event ) {
14888                                 if ( event.keyCode === $.ui.keyCode.ESCAPE ) {
14889                                         var fakeEvent = $.Event(event);
14890                                         fakeEvent.currentTarget = target[0];
14891                                         this.close( fakeEvent, true );
14892                                 }
14893                         },
14894                         remove: function() {
14895                                 this._removeTooltip( tooltip );
14896                         }
14897                 };
14898                 if ( !event || event.type === "mouseover" ) {
14899                         events.mouseleave = "close";
14900                 }
14901                 if ( !event || event.type === "focusin" ) {
14902                         events.focusout = "close";
14903                 }
14904                 this._on( true, target, events );
14905         },
14906
14907         close: function( event ) {
14908                 var that = this,
14909                         target = $( event ? event.currentTarget : this.element ),
14910                         tooltip = this._find( target );
14911
14912                 // disabling closes the tooltip, so we need to track when we're closing
14913                 // to avoid an infinite loop in case the tooltip becomes disabled on close
14914                 if ( this.closing ) {
14915                         return;
14916                 }
14917
14918                 // Clear the interval for delayed tracking tooltips
14919                 clearInterval( this.delayedShow );
14920
14921                 // only set title if we had one before (see comment in _open())
14922                 if ( target.data( "ui-tooltip-title" ) ) {
14923                         target.attr( "title", target.data( "ui-tooltip-title" ) );
14924                 }
14925
14926                 removeDescribedBy( target );
14927
14928                 tooltip.stop( true );
14929                 this._hide( tooltip, this.options.hide, function() {
14930                         that._removeTooltip( $( this ) );
14931                 });
14932
14933                 target.removeData( "ui-tooltip-open" );
14934                 this._off( target, "mouseleave focusout keyup" );
14935                 // Remove 'remove' binding only on delegated targets
14936                 if ( target[0] !== this.element[0] ) {
14937                         this._off( target, "remove" );
14938                 }
14939                 this._off( this.document, "mousemove" );
14940
14941                 if ( event && event.type === "mouseleave" ) {
14942                         $.each( this.parents, function( id, parent ) {
14943                                 $( parent.element ).attr( "title", parent.title );
14944                                 delete that.parents[ id ];
14945                         });
14946                 }
14947
14948                 this.closing = true;
14949                 this._trigger( "close", event, { tooltip: tooltip } );
14950                 this.closing = false;
14951         },
14952
14953         _tooltip: function( element ) {
14954                 var id = "ui-tooltip-" + increments++,
14955                         tooltip = $( "<div>" )
14956                                 .attr({
14957                                         id: id,
14958                                         role: "tooltip"
14959                                 })
14960                                 .addClass( "ui-tooltip ui-widget ui-corner-all ui-widget-content " +
14961                                         ( this.options.tooltipClass || "" ) );
14962                 $( "<div>" )
14963                         .addClass( "ui-tooltip-content" )
14964                         .appendTo( tooltip );
14965                 tooltip.appendTo( this.document[0].body );
14966                 this.tooltips[ id ] = element;
14967                 return tooltip;
14968         },
14969
14970         _find: function( target ) {
14971                 var id = target.data( "ui-tooltip-id" );
14972                 return id ? $( "#" + id ) : $();
14973         },
14974
14975         _removeTooltip: function( tooltip ) {
14976                 tooltip.remove();
14977                 delete this.tooltips[ tooltip.attr( "id" ) ];
14978         },
14979
14980         _destroy: function() {
14981                 var that = this;
14982
14983                 // close open tooltips
14984                 $.each( this.tooltips, function( id, element ) {
14985                         // Delegate to close method to handle common cleanup
14986                         var event = $.Event( "blur" );
14987                         event.target = event.currentTarget = element[0];
14988                         that.close( event, true );
14989
14990                         // Remove immediately; destroying an open tooltip doesn't use the
14991                         // hide animation
14992                         $( "#" + id ).remove();
14993
14994                         // Restore the title
14995                         if ( element.data( "ui-tooltip-title" ) ) {
14996                                 element.attr( "title", element.data( "ui-tooltip-title" ) );
14997                                 element.removeData( "ui-tooltip-title" );
14998                         }
14999                 });
15000         }
15001 });
15002
15003 }( jQuery ) );