prep for intercross wishlist
[sgn.git] / static / css / jquery-ricebase-theme / jquery-ui.js
blob0841d75aff9cc2091aa9157d987d22d4428a9327
1 /*! jQuery UI - v1.11.0 - 2014-06-26
2 * http://jqueryui.com
3 * Includes: core.js, widget.js, mouse.js, position.js, draggable.js, droppable.js, resizable.js, selectable.js, sortable.js, accordion.js, autocomplete.js, button.js, datepicker.js, dialog.js, menu.js, progressbar.js, selectmenu.js, slider.js, spinner.js, tabs.js, tooltip.js, effect.js, effect-blind.js, effect-bounce.js, effect-clip.js, effect-drop.js, effect-explode.js, effect-fade.js, effect-fold.js, effect-highlight.js, effect-puff.js, effect-pulsate.js, effect-scale.js, effect-shake.js, effect-size.js, effect-slide.js, effect-transfer.js
4 * Copyright 2014 jQuery Foundation and other contributors; Licensed MIT */
6 (function( factory ) {
7         if ( typeof define === "function" && define.amd ) {
9                 // AMD. Register as an anonymous module.
10                 define([ "jquery" ], factory );
11         } else {
13                 // Browser globals
14                 factory( jQuery );
15         }
16 }(function( $ ) {
17 /*!
18  * jQuery UI Core 1.11.0
19  * http://jqueryui.com
20  *
21  * Copyright 2014 jQuery Foundation and other contributors
22  * Released under the MIT license.
23  * http://jquery.org/license
24  *
25  * http://api.jqueryui.com/category/ui-core/
26  */
29 // $.ui might exist from components with no dependencies, e.g., $.ui.position
30 $.ui = $.ui || {};
32 $.extend( $.ui, {
33         version: "1.11.0",
35         keyCode: {
36                 BACKSPACE: 8,
37                 COMMA: 188,
38                 DELETE: 46,
39                 DOWN: 40,
40                 END: 35,
41                 ENTER: 13,
42                 ESCAPE: 27,
43                 HOME: 36,
44                 LEFT: 37,
45                 PAGE_DOWN: 34,
46                 PAGE_UP: 33,
47                 PERIOD: 190,
48                 RIGHT: 39,
49                 SPACE: 32,
50                 TAB: 9,
51                 UP: 38
52         }
53 });
55 // plugins
56 $.fn.extend({
57         scrollParent: function() {
58                 var position = this.css( "position" ),
59                         excludeStaticParent = position === "absolute",
60                         scrollParent = this.parents().filter( function() {
61                                 var parent = $( this );
62                                 if ( excludeStaticParent && parent.css( "position" ) === "static" ) {
63                                         return false;
64                                 }
65                                 return (/(auto|scroll)/).test( parent.css( "overflow" ) + parent.css( "overflow-y" ) + parent.css( "overflow-x" ) );
66                         }).eq( 0 );
68                 return position === "fixed" || !scrollParent.length ? $( this[ 0 ].ownerDocument || document ) : scrollParent;
69         },
71         uniqueId: (function() {
72                 var uuid = 0;
74                 return function() {
75                         return this.each(function() {
76                                 if ( !this.id ) {
77                                         this.id = "ui-id-" + ( ++uuid );
78                                 }
79                         });
80                 };
81         })(),
83         removeUniqueId: function() {
84                 return this.each(function() {
85                         if ( /^ui-id-\d+$/.test( this.id ) ) {
86                                 $( this ).removeAttr( "id" );
87                         }
88                 });
89         }
90 });
92 // selectors
93 function focusable( element, isTabIndexNotNaN ) {
94         var map, mapName, img,
95                 nodeName = element.nodeName.toLowerCase();
96         if ( "area" === nodeName ) {
97                 map = element.parentNode;
98                 mapName = map.name;
99                 if ( !element.href || !mapName || map.nodeName.toLowerCase() !== "map" ) {
100                         return false;
101                 }
102                 img = $( "img[usemap=#" + mapName + "]" )[0];
103                 return !!img && visible( img );
104         }
105         return ( /input|select|textarea|button|object/.test( nodeName ) ?
106                 !element.disabled :
107                 "a" === nodeName ?
108                         element.href || isTabIndexNotNaN :
109                         isTabIndexNotNaN) &&
110                 // the element and all of its ancestors must be visible
111                 visible( element );
114 function visible( element ) {
115         return $.expr.filters.visible( element ) &&
116                 !$( element ).parents().addBack().filter(function() {
117                         return $.css( this, "visibility" ) === "hidden";
118                 }).length;
121 $.extend( $.expr[ ":" ], {
122         data: $.expr.createPseudo ?
123                 $.expr.createPseudo(function( dataName ) {
124                         return function( elem ) {
125                                 return !!$.data( elem, dataName );
126                         };
127                 }) :
128                 // support: jQuery <1.8
129                 function( elem, i, match ) {
130                         return !!$.data( elem, match[ 3 ] );
131                 },
133         focusable: function( element ) {
134                 return focusable( element, !isNaN( $.attr( element, "tabindex" ) ) );
135         },
137         tabbable: function( element ) {
138                 var tabIndex = $.attr( element, "tabindex" ),
139                         isTabIndexNaN = isNaN( tabIndex );
140                 return ( isTabIndexNaN || tabIndex >= 0 ) && focusable( element, !isTabIndexNaN );
141         }
144 // support: jQuery <1.8
145 if ( !$( "<a>" ).outerWidth( 1 ).jquery ) {
146         $.each( [ "Width", "Height" ], function( i, name ) {
147                 var side = name === "Width" ? [ "Left", "Right" ] : [ "Top", "Bottom" ],
148                         type = name.toLowerCase(),
149                         orig = {
150                                 innerWidth: $.fn.innerWidth,
151                                 innerHeight: $.fn.innerHeight,
152                                 outerWidth: $.fn.outerWidth,
153                                 outerHeight: $.fn.outerHeight
154                         };
156                 function reduce( elem, size, border, margin ) {
157                         $.each( side, function() {
158                                 size -= parseFloat( $.css( elem, "padding" + this ) ) || 0;
159                                 if ( border ) {
160                                         size -= parseFloat( $.css( elem, "border" + this + "Width" ) ) || 0;
161                                 }
162                                 if ( margin ) {
163                                         size -= parseFloat( $.css( elem, "margin" + this ) ) || 0;
164                                 }
165                         });
166                         return size;
167                 }
169                 $.fn[ "inner" + name ] = function( size ) {
170                         if ( size === undefined ) {
171                                 return orig[ "inner" + name ].call( this );
172                         }
174                         return this.each(function() {
175                                 $( this ).css( type, reduce( this, size ) + "px" );
176                         });
177                 };
179                 $.fn[ "outer" + name] = function( size, margin ) {
180                         if ( typeof size !== "number" ) {
181                                 return orig[ "outer" + name ].call( this, size );
182                         }
184                         return this.each(function() {
185                                 $( this).css( type, reduce( this, size, true, margin ) + "px" );
186                         });
187                 };
188         });
191 // support: jQuery <1.8
192 if ( !$.fn.addBack ) {
193         $.fn.addBack = function( selector ) {
194                 return this.add( selector == null ?
195                         this.prevObject : this.prevObject.filter( selector )
196                 );
197         };
200 // support: jQuery 1.6.1, 1.6.2 (http://bugs.jquery.com/ticket/9413)
201 if ( $( "<a>" ).data( "a-b", "a" ).removeData( "a-b" ).data( "a-b" ) ) {
202         $.fn.removeData = (function( removeData ) {
203                 return function( key ) {
204                         if ( arguments.length ) {
205                                 return removeData.call( this, $.camelCase( key ) );
206                         } else {
207                                 return removeData.call( this );
208                         }
209                 };
210         })( $.fn.removeData );
213 // deprecated
214 $.ui.ie = !!/msie [\w.]+/.exec( navigator.userAgent.toLowerCase() );
216 $.fn.extend({
217         focus: (function( orig ) {
218                 return function( delay, fn ) {
219                         return typeof delay === "number" ?
220                                 this.each(function() {
221                                         var elem = this;
222                                         setTimeout(function() {
223                                                 $( elem ).focus();
224                                                 if ( fn ) {
225                                                         fn.call( elem );
226                                                 }
227                                         }, delay );
228                                 }) :
229                                 orig.apply( this, arguments );
230                 };
231         })( $.fn.focus ),
233         disableSelection: (function() {
234                 var eventType = "onselectstart" in document.createElement( "div" ) ?
235                         "selectstart" :
236                         "mousedown";
238                 return function() {
239                         return this.bind( eventType + ".ui-disableSelection", function( event ) {
240                                 event.preventDefault();
241                         });
242                 };
243         })(),
245         enableSelection: function() {
246                 return this.unbind( ".ui-disableSelection" );
247         },
249         zIndex: function( zIndex ) {
250                 if ( zIndex !== undefined ) {
251                         return this.css( "zIndex", zIndex );
252                 }
254                 if ( this.length ) {
255                         var elem = $( this[ 0 ] ), position, value;
256                         while ( elem.length && elem[ 0 ] !== document ) {
257                                 // Ignore z-index if position is set to a value where z-index is ignored by the browser
258                                 // This makes behavior of this function consistent across browsers
259                                 // WebKit always returns auto if the element is positioned
260                                 position = elem.css( "position" );
261                                 if ( position === "absolute" || position === "relative" || position === "fixed" ) {
262                                         // IE returns 0 when zIndex is not specified
263                                         // other browsers return a string
264                                         // we ignore the case of nested elements with an explicit value of 0
265                                         // <div style="z-index: -10;"><div style="z-index: 0;"></div></div>
266                                         value = parseInt( elem.css( "zIndex" ), 10 );
267                                         if ( !isNaN( value ) && value !== 0 ) {
268                                                 return value;
269                                         }
270                                 }
271                                 elem = elem.parent();
272                         }
273                 }
275                 return 0;
276         }
279 // $.ui.plugin is deprecated. Use $.widget() extensions instead.
280 $.ui.plugin = {
281         add: function( module, option, set ) {
282                 var i,
283                         proto = $.ui[ module ].prototype;
284                 for ( i in set ) {
285                         proto.plugins[ i ] = proto.plugins[ i ] || [];
286                         proto.plugins[ i ].push( [ option, set[ i ] ] );
287                 }
288         },
289         call: function( instance, name, args, allowDisconnected ) {
290                 var i,
291                         set = instance.plugins[ name ];
293                 if ( !set ) {
294                         return;
295                 }
297                 if ( !allowDisconnected && ( !instance.element[ 0 ].parentNode || instance.element[ 0 ].parentNode.nodeType === 11 ) ) {
298                         return;
299                 }
301                 for ( i = 0; i < set.length; i++ ) {
302                         if ( instance.options[ set[ i ][ 0 ] ] ) {
303                                 set[ i ][ 1 ].apply( instance.element, args );
304                         }
305                 }
306         }
311  * jQuery UI Widget 1.11.0
312  * http://jqueryui.com
314  * Copyright 2014 jQuery Foundation and other contributors
315  * Released under the MIT license.
316  * http://jquery.org/license
318  * http://api.jqueryui.com/jQuery.widget/
319  */
322 var widget_uuid = 0,
323         widget_slice = Array.prototype.slice;
325 $.cleanData = (function( orig ) {
326         return function( elems ) {
327                 for ( var i = 0, elem; (elem = elems[i]) != null; i++ ) {
328                         try {
329                                 $( elem ).triggerHandler( "remove" );
330                         // http://bugs.jquery.com/ticket/8235
331                         } catch( e ) {}
332                 }
333                 orig( elems );
334         };
335 })( $.cleanData );
337 $.widget = function( name, base, prototype ) {
338         var fullName, existingConstructor, constructor, basePrototype,
339                 // proxiedPrototype allows the provided prototype to remain unmodified
340                 // so that it can be used as a mixin for multiple widgets (#8876)
341                 proxiedPrototype = {},
342                 namespace = name.split( "." )[ 0 ];
344         name = name.split( "." )[ 1 ];
345         fullName = namespace + "-" + name;
347         if ( !prototype ) {
348                 prototype = base;
349                 base = $.Widget;
350         }
352         // create selector for plugin
353         $.expr[ ":" ][ fullName.toLowerCase() ] = function( elem ) {
354                 return !!$.data( elem, fullName );
355         };
357         $[ namespace ] = $[ namespace ] || {};
358         existingConstructor = $[ namespace ][ name ];
359         constructor = $[ namespace ][ name ] = function( options, element ) {
360                 // allow instantiation without "new" keyword
361                 if ( !this._createWidget ) {
362                         return new constructor( options, element );
363                 }
365                 // allow instantiation without initializing for simple inheritance
366                 // must use "new" keyword (the code above always passes args)
367                 if ( arguments.length ) {
368                         this._createWidget( options, element );
369                 }
370         };
371         // extend with the existing constructor to carry over any static properties
372         $.extend( constructor, existingConstructor, {
373                 version: prototype.version,
374                 // copy the object used to create the prototype in case we need to
375                 // redefine the widget later
376                 _proto: $.extend( {}, prototype ),
377                 // track widgets that inherit from this widget in case this widget is
378                 // redefined after a widget inherits from it
379                 _childConstructors: []
380         });
382         basePrototype = new base();
383         // we need to make the options hash a property directly on the new instance
384         // otherwise we'll modify the options hash on the prototype that we're
385         // inheriting from
386         basePrototype.options = $.widget.extend( {}, basePrototype.options );
387         $.each( prototype, function( prop, value ) {
388                 if ( !$.isFunction( value ) ) {
389                         proxiedPrototype[ prop ] = value;
390                         return;
391                 }
392                 proxiedPrototype[ prop ] = (function() {
393                         var _super = function() {
394                                         return base.prototype[ prop ].apply( this, arguments );
395                                 },
396                                 _superApply = function( args ) {
397                                         return base.prototype[ prop ].apply( this, args );
398                                 };
399                         return function() {
400                                 var __super = this._super,
401                                         __superApply = this._superApply,
402                                         returnValue;
404                                 this._super = _super;
405                                 this._superApply = _superApply;
407                                 returnValue = value.apply( this, arguments );
409                                 this._super = __super;
410                                 this._superApply = __superApply;
412                                 return returnValue;
413                         };
414                 })();
415         });
416         constructor.prototype = $.widget.extend( basePrototype, {
417                 // TODO: remove support for widgetEventPrefix
418                 // always use the name + a colon as the prefix, e.g., draggable:start
419                 // don't prefix for widgets that aren't DOM-based
420                 widgetEventPrefix: existingConstructor ? (basePrototype.widgetEventPrefix || name) : name
421         }, proxiedPrototype, {
422                 constructor: constructor,
423                 namespace: namespace,
424                 widgetName: name,
425                 widgetFullName: fullName
426         });
428         // If this widget is being redefined then we need to find all widgets that
429         // are inheriting from it and redefine all of them so that they inherit from
430         // the new version of this widget. We're essentially trying to replace one
431         // level in the prototype chain.
432         if ( existingConstructor ) {
433                 $.each( existingConstructor._childConstructors, function( i, child ) {
434                         var childPrototype = child.prototype;
436                         // redefine the child widget using the same prototype that was
437                         // originally used, but inherit from the new version of the base
438                         $.widget( childPrototype.namespace + "." + childPrototype.widgetName, constructor, child._proto );
439                 });
440                 // remove the list of existing child constructors from the old constructor
441                 // so the old child constructors can be garbage collected
442                 delete existingConstructor._childConstructors;
443         } else {
444                 base._childConstructors.push( constructor );
445         }
447         $.widget.bridge( name, constructor );
449         return constructor;
452 $.widget.extend = function( target ) {
453         var input = widget_slice.call( arguments, 1 ),
454                 inputIndex = 0,
455                 inputLength = input.length,
456                 key,
457                 value;
458         for ( ; inputIndex < inputLength; inputIndex++ ) {
459                 for ( key in input[ inputIndex ] ) {
460                         value = input[ inputIndex ][ key ];
461                         if ( input[ inputIndex ].hasOwnProperty( key ) && value !== undefined ) {
462                                 // Clone objects
463                                 if ( $.isPlainObject( value ) ) {
464                                         target[ key ] = $.isPlainObject( target[ key ] ) ?
465                                                 $.widget.extend( {}, target[ key ], value ) :
466                                                 // Don't extend strings, arrays, etc. with objects
467                                                 $.widget.extend( {}, value );
468                                 // Copy everything else by reference
469                                 } else {
470                                         target[ key ] = value;
471                                 }
472                         }
473                 }
474         }
475         return target;
478 $.widget.bridge = function( name, object ) {
479         var fullName = object.prototype.widgetFullName || name;
480         $.fn[ name ] = function( options ) {
481                 var isMethodCall = typeof options === "string",
482                         args = widget_slice.call( arguments, 1 ),
483                         returnValue = this;
485                 // allow multiple hashes to be passed on init
486                 options = !isMethodCall && args.length ?
487                         $.widget.extend.apply( null, [ options ].concat(args) ) :
488                         options;
490                 if ( isMethodCall ) {
491                         this.each(function() {
492                                 var methodValue,
493                                         instance = $.data( this, fullName );
494                                 if ( options === "instance" ) {
495                                         returnValue = instance;
496                                         return false;
497                                 }
498                                 if ( !instance ) {
499                                         return $.error( "cannot call methods on " + name + " prior to initialization; " +
500                                                 "attempted to call method '" + options + "'" );
501                                 }
502                                 if ( !$.isFunction( instance[options] ) || options.charAt( 0 ) === "_" ) {
503                                         return $.error( "no such method '" + options + "' for " + name + " widget instance" );
504                                 }
505                                 methodValue = instance[ options ].apply( instance, args );
506                                 if ( methodValue !== instance && methodValue !== undefined ) {
507                                         returnValue = methodValue && methodValue.jquery ?
508                                                 returnValue.pushStack( methodValue.get() ) :
509                                                 methodValue;
510                                         return false;
511                                 }
512                         });
513                 } else {
514                         this.each(function() {
515                                 var instance = $.data( this, fullName );
516                                 if ( instance ) {
517                                         instance.option( options || {} );
518                                         if ( instance._init ) {
519                                                 instance._init();
520                                         }
521                                 } else {
522                                         $.data( this, fullName, new object( options, this ) );
523                                 }
524                         });
525                 }
527                 return returnValue;
528         };
531 $.Widget = function( /* options, element */ ) {};
532 $.Widget._childConstructors = [];
534 $.Widget.prototype = {
535         widgetName: "widget",
536         widgetEventPrefix: "",
537         defaultElement: "<div>",
538         options: {
539                 disabled: false,
541                 // callbacks
542                 create: null
543         },
544         _createWidget: function( options, element ) {
545                 element = $( element || this.defaultElement || this )[ 0 ];
546                 this.element = $( element );
547                 this.uuid = widget_uuid++;
548                 this.eventNamespace = "." + this.widgetName + this.uuid;
549                 this.options = $.widget.extend( {},
550                         this.options,
551                         this._getCreateOptions(),
552                         options );
554                 this.bindings = $();
555                 this.hoverable = $();
556                 this.focusable = $();
558                 if ( element !== this ) {
559                         $.data( element, this.widgetFullName, this );
560                         this._on( true, this.element, {
561                                 remove: function( event ) {
562                                         if ( event.target === element ) {
563                                                 this.destroy();
564                                         }
565                                 }
566                         });
567                         this.document = $( element.style ?
568                                 // element within the document
569                                 element.ownerDocument :
570                                 // element is window or document
571                                 element.document || element );
572                         this.window = $( this.document[0].defaultView || this.document[0].parentWindow );
573                 }
575                 this._create();
576                 this._trigger( "create", null, this._getCreateEventData() );
577                 this._init();
578         },
579         _getCreateOptions: $.noop,
580         _getCreateEventData: $.noop,
581         _create: $.noop,
582         _init: $.noop,
584         destroy: function() {
585                 this._destroy();
586                 // we can probably remove the unbind calls in 2.0
587                 // all event bindings should go through this._on()
588                 this.element
589                         .unbind( this.eventNamespace )
590                         .removeData( this.widgetFullName )
591                         // support: jquery <1.6.3
592                         // http://bugs.jquery.com/ticket/9413
593                         .removeData( $.camelCase( this.widgetFullName ) );
594                 this.widget()
595                         .unbind( this.eventNamespace )
596                         .removeAttr( "aria-disabled" )
597                         .removeClass(
598                                 this.widgetFullName + "-disabled " +
599                                 "ui-state-disabled" );
601                 // clean up events and states
602                 this.bindings.unbind( this.eventNamespace );
603                 this.hoverable.removeClass( "ui-state-hover" );
604                 this.focusable.removeClass( "ui-state-focus" );
605         },
606         _destroy: $.noop,
608         widget: function() {
609                 return this.element;
610         },
612         option: function( key, value ) {
613                 var options = key,
614                         parts,
615                         curOption,
616                         i;
618                 if ( arguments.length === 0 ) {
619                         // don't return a reference to the internal hash
620                         return $.widget.extend( {}, this.options );
621                 }
623                 if ( typeof key === "string" ) {
624                         // handle nested keys, e.g., "foo.bar" => { foo: { bar: ___ } }
625                         options = {};
626                         parts = key.split( "." );
627                         key = parts.shift();
628                         if ( parts.length ) {
629                                 curOption = options[ key ] = $.widget.extend( {}, this.options[ key ] );
630                                 for ( i = 0; i < parts.length - 1; i++ ) {
631                                         curOption[ parts[ i ] ] = curOption[ parts[ i ] ] || {};
632                                         curOption = curOption[ parts[ i ] ];
633                                 }
634                                 key = parts.pop();
635                                 if ( arguments.length === 1 ) {
636                                         return curOption[ key ] === undefined ? null : curOption[ key ];
637                                 }
638                                 curOption[ key ] = value;
639                         } else {
640                                 if ( arguments.length === 1 ) {
641                                         return this.options[ key ] === undefined ? null : this.options[ key ];
642                                 }
643                                 options[ key ] = value;
644                         }
645                 }
647                 this._setOptions( options );
649                 return this;
650         },
651         _setOptions: function( options ) {
652                 var key;
654                 for ( key in options ) {
655                         this._setOption( key, options[ key ] );
656                 }
658                 return this;
659         },
660         _setOption: function( key, value ) {
661                 this.options[ key ] = value;
663                 if ( key === "disabled" ) {
664                         this.widget()
665                                 .toggleClass( this.widgetFullName + "-disabled", !!value );
667                         // If the widget is becoming disabled, then nothing is interactive
668                         if ( value ) {
669                                 this.hoverable.removeClass( "ui-state-hover" );
670                                 this.focusable.removeClass( "ui-state-focus" );
671                         }
672                 }
674                 return this;
675         },
677         enable: function() {
678                 return this._setOptions({ disabled: false });
679         },
680         disable: function() {
681                 return this._setOptions({ disabled: true });
682         },
684         _on: function( suppressDisabledCheck, element, handlers ) {
685                 var delegateElement,
686                         instance = this;
688                 // no suppressDisabledCheck flag, shuffle arguments
689                 if ( typeof suppressDisabledCheck !== "boolean" ) {
690                         handlers = element;
691                         element = suppressDisabledCheck;
692                         suppressDisabledCheck = false;
693                 }
695                 // no element argument, shuffle and use this.element
696                 if ( !handlers ) {
697                         handlers = element;
698                         element = this.element;
699                         delegateElement = this.widget();
700                 } else {
701                         element = delegateElement = $( element );
702                         this.bindings = this.bindings.add( element );
703                 }
705                 $.each( handlers, function( event, handler ) {
706                         function handlerProxy() {
707                                 // allow widgets to customize the disabled handling
708                                 // - disabled as an array instead of boolean
709                                 // - disabled class as method for disabling individual parts
710                                 if ( !suppressDisabledCheck &&
711                                                 ( instance.options.disabled === true ||
712                                                         $( this ).hasClass( "ui-state-disabled" ) ) ) {
713                                         return;
714                                 }
715                                 return ( typeof handler === "string" ? instance[ handler ] : handler )
716                                         .apply( instance, arguments );
717                         }
719                         // copy the guid so direct unbinding works
720                         if ( typeof handler !== "string" ) {
721                                 handlerProxy.guid = handler.guid =
722                                         handler.guid || handlerProxy.guid || $.guid++;
723                         }
725                         var match = event.match( /^([\w:-]*)\s*(.*)$/ ),
726                                 eventName = match[1] + instance.eventNamespace,
727                                 selector = match[2];
728                         if ( selector ) {
729                                 delegateElement.delegate( selector, eventName, handlerProxy );
730                         } else {
731                                 element.bind( eventName, handlerProxy );
732                         }
733                 });
734         },
736         _off: function( element, eventName ) {
737                 eventName = (eventName || "").split( " " ).join( this.eventNamespace + " " ) + this.eventNamespace;
738                 element.unbind( eventName ).undelegate( eventName );
739         },
741         _delay: function( handler, delay ) {
742                 function handlerProxy() {
743                         return ( typeof handler === "string" ? instance[ handler ] : handler )
744                                 .apply( instance, arguments );
745                 }
746                 var instance = this;
747                 return setTimeout( handlerProxy, delay || 0 );
748         },
750         _hoverable: function( element ) {
751                 this.hoverable = this.hoverable.add( element );
752                 this._on( element, {
753                         mouseenter: function( event ) {
754                                 $( event.currentTarget ).addClass( "ui-state-hover" );
755                         },
756                         mouseleave: function( event ) {
757                                 $( event.currentTarget ).removeClass( "ui-state-hover" );
758                         }
759                 });
760         },
762         _focusable: function( element ) {
763                 this.focusable = this.focusable.add( element );
764                 this._on( element, {
765                         focusin: function( event ) {
766                                 $( event.currentTarget ).addClass( "ui-state-focus" );
767                         },
768                         focusout: function( event ) {
769                                 $( event.currentTarget ).removeClass( "ui-state-focus" );
770                         }
771                 });
772         },
774         _trigger: function( type, event, data ) {
775                 var prop, orig,
776                         callback = this.options[ type ];
778                 data = data || {};
779                 event = $.Event( event );
780                 event.type = ( type === this.widgetEventPrefix ?
781                         type :
782                         this.widgetEventPrefix + type ).toLowerCase();
783                 // the original event may come from any element
784                 // so we need to reset the target on the new event
785                 event.target = this.element[ 0 ];
787                 // copy original event properties over to the new event
788                 orig = event.originalEvent;
789                 if ( orig ) {
790                         for ( prop in orig ) {
791                                 if ( !( prop in event ) ) {
792                                         event[ prop ] = orig[ prop ];
793                                 }
794                         }
795                 }
797                 this.element.trigger( event, data );
798                 return !( $.isFunction( callback ) &&
799                         callback.apply( this.element[0], [ event ].concat( data ) ) === false ||
800                         event.isDefaultPrevented() );
801         }
804 $.each( { show: "fadeIn", hide: "fadeOut" }, function( method, defaultEffect ) {
805         $.Widget.prototype[ "_" + method ] = function( element, options, callback ) {
806                 if ( typeof options === "string" ) {
807                         options = { effect: options };
808                 }
809                 var hasOptions,
810                         effectName = !options ?
811                                 method :
812                                 options === true || typeof options === "number" ?
813                                         defaultEffect :
814                                         options.effect || defaultEffect;
815                 options = options || {};
816                 if ( typeof options === "number" ) {
817                         options = { duration: options };
818                 }
819                 hasOptions = !$.isEmptyObject( options );
820                 options.complete = callback;
821                 if ( options.delay ) {
822                         element.delay( options.delay );
823                 }
824                 if ( hasOptions && $.effects && $.effects.effect[ effectName ] ) {
825                         element[ method ]( options );
826                 } else if ( effectName !== method && element[ effectName ] ) {
827                         element[ effectName ]( options.duration, options.easing, callback );
828                 } else {
829                         element.queue(function( next ) {
830                                 $( this )[ method ]();
831                                 if ( callback ) {
832                                         callback.call( element[ 0 ] );
833                                 }
834                                 next();
835                         });
836                 }
837         };
840 var widget = $.widget;
844  * jQuery UI Mouse 1.11.0
845  * http://jqueryui.com
847  * Copyright 2014 jQuery Foundation and other contributors
848  * Released under the MIT license.
849  * http://jquery.org/license
851  * http://api.jqueryui.com/mouse/
852  */
855 var mouseHandled = false;
856 $( document ).mouseup( function() {
857         mouseHandled = false;
860 var mouse = $.widget("ui.mouse", {
861         version: "1.11.0",
862         options: {
863                 cancel: "input,textarea,button,select,option",
864                 distance: 1,
865                 delay: 0
866         },
867         _mouseInit: function() {
868                 var that = this;
870                 this.element
871                         .bind("mousedown." + this.widgetName, function(event) {
872                                 return that._mouseDown(event);
873                         })
874                         .bind("click." + this.widgetName, function(event) {
875                                 if (true === $.data(event.target, that.widgetName + ".preventClickEvent")) {
876                                         $.removeData(event.target, that.widgetName + ".preventClickEvent");
877                                         event.stopImmediatePropagation();
878                                         return false;
879                                 }
880                         });
882                 this.started = false;
883         },
885         // TODO: make sure destroying one instance of mouse doesn't mess with
886         // other instances of mouse
887         _mouseDestroy: function() {
888                 this.element.unbind("." + this.widgetName);
889                 if ( this._mouseMoveDelegate ) {
890                         this.document
891                                 .unbind("mousemove." + this.widgetName, this._mouseMoveDelegate)
892                                 .unbind("mouseup." + this.widgetName, this._mouseUpDelegate);
893                 }
894         },
896         _mouseDown: function(event) {
897                 // don't let more than one widget handle mouseStart
898                 if ( mouseHandled ) {
899                         return;
900                 }
902                 // we may have missed mouseup (out of window)
903                 (this._mouseStarted && this._mouseUp(event));
905                 this._mouseDownEvent = event;
907                 var that = this,
908                         btnIsLeft = (event.which === 1),
909                         // event.target.nodeName works around a bug in IE 8 with
910                         // disabled inputs (#7620)
911                         elIsCancel = (typeof this.options.cancel === "string" && event.target.nodeName ? $(event.target).closest(this.options.cancel).length : false);
912                 if (!btnIsLeft || elIsCancel || !this._mouseCapture(event)) {
913                         return true;
914                 }
916                 this.mouseDelayMet = !this.options.delay;
917                 if (!this.mouseDelayMet) {
918                         this._mouseDelayTimer = setTimeout(function() {
919                                 that.mouseDelayMet = true;
920                         }, this.options.delay);
921                 }
923                 if (this._mouseDistanceMet(event) && this._mouseDelayMet(event)) {
924                         this._mouseStarted = (this._mouseStart(event) !== false);
925                         if (!this._mouseStarted) {
926                                 event.preventDefault();
927                                 return true;
928                         }
929                 }
931                 // Click event may never have fired (Gecko & Opera)
932                 if (true === $.data(event.target, this.widgetName + ".preventClickEvent")) {
933                         $.removeData(event.target, this.widgetName + ".preventClickEvent");
934                 }
936                 // these delegates are required to keep context
937                 this._mouseMoveDelegate = function(event) {
938                         return that._mouseMove(event);
939                 };
940                 this._mouseUpDelegate = function(event) {
941                         return that._mouseUp(event);
942                 };
944                 this.document
945                         .bind( "mousemove." + this.widgetName, this._mouseMoveDelegate )
946                         .bind( "mouseup." + this.widgetName, this._mouseUpDelegate );
948                 event.preventDefault();
950                 mouseHandled = true;
951                 return true;
952         },
954         _mouseMove: function(event) {
955                 // IE mouseup check - mouseup happened when mouse was out of window
956                 if ($.ui.ie && ( !document.documentMode || document.documentMode < 9 ) && !event.button) {
957                         return this._mouseUp(event);
959                 // Iframe mouseup check - mouseup occurred in another document
960                 } else if ( !event.which ) {
961                         return this._mouseUp( event );
962                 }
964                 if (this._mouseStarted) {
965                         this._mouseDrag(event);
966                         return event.preventDefault();
967                 }
969                 if (this._mouseDistanceMet(event) && this._mouseDelayMet(event)) {
970                         this._mouseStarted =
971                                 (this._mouseStart(this._mouseDownEvent, event) !== false);
972                         (this._mouseStarted ? this._mouseDrag(event) : this._mouseUp(event));
973                 }
975                 return !this._mouseStarted;
976         },
978         _mouseUp: function(event) {
979                 this.document
980                         .unbind( "mousemove." + this.widgetName, this._mouseMoveDelegate )
981                         .unbind( "mouseup." + this.widgetName, this._mouseUpDelegate );
983                 if (this._mouseStarted) {
984                         this._mouseStarted = false;
986                         if (event.target === this._mouseDownEvent.target) {
987                                 $.data(event.target, this.widgetName + ".preventClickEvent", true);
988                         }
990                         this._mouseStop(event);
991                 }
993                 mouseHandled = false;
994                 return false;
995         },
997         _mouseDistanceMet: function(event) {
998                 return (Math.max(
999                                 Math.abs(this._mouseDownEvent.pageX - event.pageX),
1000                                 Math.abs(this._mouseDownEvent.pageY - event.pageY)
1001                         ) >= this.options.distance
1002                 );
1003         },
1005         _mouseDelayMet: function(/* event */) {
1006                 return this.mouseDelayMet;
1007         },
1009         // These are placeholder methods, to be overriden by extending plugin
1010         _mouseStart: function(/* event */) {},
1011         _mouseDrag: function(/* event */) {},
1012         _mouseStop: function(/* event */) {},
1013         _mouseCapture: function(/* event */) { return true; }
1018  * jQuery UI Position 1.11.0
1019  * http://jqueryui.com
1021  * Copyright 2014 jQuery Foundation and other contributors
1022  * Released under the MIT license.
1023  * http://jquery.org/license
1025  * http://api.jqueryui.com/position/
1026  */
1028 (function() {
1030 $.ui = $.ui || {};
1032 var cachedScrollbarWidth, supportsOffsetFractions,
1033         max = Math.max,
1034         abs = Math.abs,
1035         round = Math.round,
1036         rhorizontal = /left|center|right/,
1037         rvertical = /top|center|bottom/,
1038         roffset = /[\+\-]\d+(\.[\d]+)?%?/,
1039         rposition = /^\w+/,
1040         rpercent = /%$/,
1041         _position = $.fn.position;
1043 function getOffsets( offsets, width, height ) {
1044         return [
1045                 parseFloat( offsets[ 0 ] ) * ( rpercent.test( offsets[ 0 ] ) ? width / 100 : 1 ),
1046                 parseFloat( offsets[ 1 ] ) * ( rpercent.test( offsets[ 1 ] ) ? height / 100 : 1 )
1047         ];
1050 function parseCss( element, property ) {
1051         return parseInt( $.css( element, property ), 10 ) || 0;
1054 function getDimensions( elem ) {
1055         var raw = elem[0];
1056         if ( raw.nodeType === 9 ) {
1057                 return {
1058                         width: elem.width(),
1059                         height: elem.height(),
1060                         offset: { top: 0, left: 0 }
1061                 };
1062         }
1063         if ( $.isWindow( raw ) ) {
1064                 return {
1065                         width: elem.width(),
1066                         height: elem.height(),
1067                         offset: { top: elem.scrollTop(), left: elem.scrollLeft() }
1068                 };
1069         }
1070         if ( raw.preventDefault ) {
1071                 return {
1072                         width: 0,
1073                         height: 0,
1074                         offset: { top: raw.pageY, left: raw.pageX }
1075                 };
1076         }
1077         return {
1078                 width: elem.outerWidth(),
1079                 height: elem.outerHeight(),
1080                 offset: elem.offset()
1081         };
1084 $.position = {
1085         scrollbarWidth: function() {
1086                 if ( cachedScrollbarWidth !== undefined ) {
1087                         return cachedScrollbarWidth;
1088                 }
1089                 var w1, w2,
1090                         div = $( "<div style='display:block;position:absolute;width:50px;height:50px;overflow:hidden;'><div style='height:100px;width:auto;'></div></div>" ),
1091                         innerDiv = div.children()[0];
1093                 $( "body" ).append( div );
1094                 w1 = innerDiv.offsetWidth;
1095                 div.css( "overflow", "scroll" );
1097                 w2 = innerDiv.offsetWidth;
1099                 if ( w1 === w2 ) {
1100                         w2 = div[0].clientWidth;
1101                 }
1103                 div.remove();
1105                 return (cachedScrollbarWidth = w1 - w2);
1106         },
1107         getScrollInfo: function( within ) {
1108                 var overflowX = within.isWindow || within.isDocument ? "" :
1109                                 within.element.css( "overflow-x" ),
1110                         overflowY = within.isWindow || within.isDocument ? "" :
1111                                 within.element.css( "overflow-y" ),
1112                         hasOverflowX = overflowX === "scroll" ||
1113                                 ( overflowX === "auto" && within.width < within.element[0].scrollWidth ),
1114                         hasOverflowY = overflowY === "scroll" ||
1115                                 ( overflowY === "auto" && within.height < within.element[0].scrollHeight );
1116                 return {
1117                         width: hasOverflowY ? $.position.scrollbarWidth() : 0,
1118                         height: hasOverflowX ? $.position.scrollbarWidth() : 0
1119                 };
1120         },
1121         getWithinInfo: function( element ) {
1122                 var withinElement = $( element || window ),
1123                         isWindow = $.isWindow( withinElement[0] ),
1124                         isDocument = !!withinElement[ 0 ] && withinElement[ 0 ].nodeType === 9;
1125                 return {
1126                         element: withinElement,
1127                         isWindow: isWindow,
1128                         isDocument: isDocument,
1129                         offset: withinElement.offset() || { left: 0, top: 0 },
1130                         scrollLeft: withinElement.scrollLeft(),
1131                         scrollTop: withinElement.scrollTop(),
1132                         width: isWindow ? withinElement.width() : withinElement.outerWidth(),
1133                         height: isWindow ? withinElement.height() : withinElement.outerHeight()
1134                 };
1135         }
1138 $.fn.position = function( options ) {
1139         if ( !options || !options.of ) {
1140                 return _position.apply( this, arguments );
1141         }
1143         // make a copy, we don't want to modify arguments
1144         options = $.extend( {}, options );
1146         var atOffset, targetWidth, targetHeight, targetOffset, basePosition, dimensions,
1147                 target = $( options.of ),
1148                 within = $.position.getWithinInfo( options.within ),
1149                 scrollInfo = $.position.getScrollInfo( within ),
1150                 collision = ( options.collision || "flip" ).split( " " ),
1151                 offsets = {};
1153         dimensions = getDimensions( target );
1154         if ( target[0].preventDefault ) {
1155                 // force left top to allow flipping
1156                 options.at = "left top";
1157         }
1158         targetWidth = dimensions.width;
1159         targetHeight = dimensions.height;
1160         targetOffset = dimensions.offset;
1161         // clone to reuse original targetOffset later
1162         basePosition = $.extend( {}, targetOffset );
1164         // force my and at to have valid horizontal and vertical positions
1165         // if a value is missing or invalid, it will be converted to center
1166         $.each( [ "my", "at" ], function() {
1167                 var pos = ( options[ this ] || "" ).split( " " ),
1168                         horizontalOffset,
1169                         verticalOffset;
1171                 if ( pos.length === 1) {
1172                         pos = rhorizontal.test( pos[ 0 ] ) ?
1173                                 pos.concat( [ "center" ] ) :
1174                                 rvertical.test( pos[ 0 ] ) ?
1175                                         [ "center" ].concat( pos ) :
1176                                         [ "center", "center" ];
1177                 }
1178                 pos[ 0 ] = rhorizontal.test( pos[ 0 ] ) ? pos[ 0 ] : "center";
1179                 pos[ 1 ] = rvertical.test( pos[ 1 ] ) ? pos[ 1 ] : "center";
1181                 // calculate offsets
1182                 horizontalOffset = roffset.exec( pos[ 0 ] );
1183                 verticalOffset = roffset.exec( pos[ 1 ] );
1184                 offsets[ this ] = [
1185                         horizontalOffset ? horizontalOffset[ 0 ] : 0,
1186                         verticalOffset ? verticalOffset[ 0 ] : 0
1187                 ];
1189                 // reduce to just the positions without the offsets
1190                 options[ this ] = [
1191                         rposition.exec( pos[ 0 ] )[ 0 ],
1192                         rposition.exec( pos[ 1 ] )[ 0 ]
1193                 ];
1194         });
1196         // normalize collision option
1197         if ( collision.length === 1 ) {
1198                 collision[ 1 ] = collision[ 0 ];
1199         }
1201         if ( options.at[ 0 ] === "right" ) {
1202                 basePosition.left += targetWidth;
1203         } else if ( options.at[ 0 ] === "center" ) {
1204                 basePosition.left += targetWidth / 2;
1205         }
1207         if ( options.at[ 1 ] === "bottom" ) {
1208                 basePosition.top += targetHeight;
1209         } else if ( options.at[ 1 ] === "center" ) {
1210                 basePosition.top += targetHeight / 2;
1211         }
1213         atOffset = getOffsets( offsets.at, targetWidth, targetHeight );
1214         basePosition.left += atOffset[ 0 ];
1215         basePosition.top += atOffset[ 1 ];
1217         return this.each(function() {
1218                 var collisionPosition, using,
1219                         elem = $( this ),
1220                         elemWidth = elem.outerWidth(),
1221                         elemHeight = elem.outerHeight(),
1222                         marginLeft = parseCss( this, "marginLeft" ),
1223                         marginTop = parseCss( this, "marginTop" ),
1224                         collisionWidth = elemWidth + marginLeft + parseCss( this, "marginRight" ) + scrollInfo.width,
1225                         collisionHeight = elemHeight + marginTop + parseCss( this, "marginBottom" ) + scrollInfo.height,
1226                         position = $.extend( {}, basePosition ),
1227                         myOffset = getOffsets( offsets.my, elem.outerWidth(), elem.outerHeight() );
1229                 if ( options.my[ 0 ] === "right" ) {
1230                         position.left -= elemWidth;
1231                 } else if ( options.my[ 0 ] === "center" ) {
1232                         position.left -= elemWidth / 2;
1233                 }
1235                 if ( options.my[ 1 ] === "bottom" ) {
1236                         position.top -= elemHeight;
1237                 } else if ( options.my[ 1 ] === "center" ) {
1238                         position.top -= elemHeight / 2;
1239                 }
1241                 position.left += myOffset[ 0 ];
1242                 position.top += myOffset[ 1 ];
1244                 // if the browser doesn't support fractions, then round for consistent results
1245                 if ( !supportsOffsetFractions ) {
1246                         position.left = round( position.left );
1247                         position.top = round( position.top );
1248                 }
1250                 collisionPosition = {
1251                         marginLeft: marginLeft,
1252                         marginTop: marginTop
1253                 };
1255                 $.each( [ "left", "top" ], function( i, dir ) {
1256                         if ( $.ui.position[ collision[ i ] ] ) {
1257                                 $.ui.position[ collision[ i ] ][ dir ]( position, {
1258                                         targetWidth: targetWidth,
1259                                         targetHeight: targetHeight,
1260                                         elemWidth: elemWidth,
1261                                         elemHeight: elemHeight,
1262                                         collisionPosition: collisionPosition,
1263                                         collisionWidth: collisionWidth,
1264                                         collisionHeight: collisionHeight,
1265                                         offset: [ atOffset[ 0 ] + myOffset[ 0 ], atOffset [ 1 ] + myOffset[ 1 ] ],
1266                                         my: options.my,
1267                                         at: options.at,
1268                                         within: within,
1269                                         elem: elem
1270                                 });
1271                         }
1272                 });
1274                 if ( options.using ) {
1275                         // adds feedback as second argument to using callback, if present
1276                         using = function( props ) {
1277                                 var left = targetOffset.left - position.left,
1278                                         right = left + targetWidth - elemWidth,
1279                                         top = targetOffset.top - position.top,
1280                                         bottom = top + targetHeight - elemHeight,
1281                                         feedback = {
1282                                                 target: {
1283                                                         element: target,
1284                                                         left: targetOffset.left,
1285                                                         top: targetOffset.top,
1286                                                         width: targetWidth,
1287                                                         height: targetHeight
1288                                                 },
1289                                                 element: {
1290                                                         element: elem,
1291                                                         left: position.left,
1292                                                         top: position.top,
1293                                                         width: elemWidth,
1294                                                         height: elemHeight
1295                                                 },
1296                                                 horizontal: right < 0 ? "left" : left > 0 ? "right" : "center",
1297                                                 vertical: bottom < 0 ? "top" : top > 0 ? "bottom" : "middle"
1298                                         };
1299                                 if ( targetWidth < elemWidth && abs( left + right ) < targetWidth ) {
1300                                         feedback.horizontal = "center";
1301                                 }
1302                                 if ( targetHeight < elemHeight && abs( top + bottom ) < targetHeight ) {
1303                                         feedback.vertical = "middle";
1304                                 }
1305                                 if ( max( abs( left ), abs( right ) ) > max( abs( top ), abs( bottom ) ) ) {
1306                                         feedback.important = "horizontal";
1307                                 } else {
1308                                         feedback.important = "vertical";
1309                                 }
1310                                 options.using.call( this, props, feedback );
1311                         };
1312                 }
1314                 elem.offset( $.extend( position, { using: using } ) );
1315         });
1318 $.ui.position = {
1319         fit: {
1320                 left: function( position, data ) {
1321                         var within = data.within,
1322                                 withinOffset = within.isWindow ? within.scrollLeft : within.offset.left,
1323                                 outerWidth = within.width,
1324                                 collisionPosLeft = position.left - data.collisionPosition.marginLeft,
1325                                 overLeft = withinOffset - collisionPosLeft,
1326                                 overRight = collisionPosLeft + data.collisionWidth - outerWidth - withinOffset,
1327                                 newOverRight;
1329                         // element is wider than within
1330                         if ( data.collisionWidth > outerWidth ) {
1331                                 // element is initially over the left side of within
1332                                 if ( overLeft > 0 && overRight <= 0 ) {
1333                                         newOverRight = position.left + overLeft + data.collisionWidth - outerWidth - withinOffset;
1334                                         position.left += overLeft - newOverRight;
1335                                 // element is initially over right side of within
1336                                 } else if ( overRight > 0 && overLeft <= 0 ) {
1337                                         position.left = withinOffset;
1338                                 // element is initially over both left and right sides of within
1339                                 } else {
1340                                         if ( overLeft > overRight ) {
1341                                                 position.left = withinOffset + outerWidth - data.collisionWidth;
1342                                         } else {
1343                                                 position.left = withinOffset;
1344                                         }
1345                                 }
1346                         // too far left -> align with left edge
1347                         } else if ( overLeft > 0 ) {
1348                                 position.left += overLeft;
1349                         // too far right -> align with right edge
1350                         } else if ( overRight > 0 ) {
1351                                 position.left -= overRight;
1352                         // adjust based on position and margin
1353                         } else {
1354                                 position.left = max( position.left - collisionPosLeft, position.left );
1355                         }
1356                 },
1357                 top: function( position, data ) {
1358                         var within = data.within,
1359                                 withinOffset = within.isWindow ? within.scrollTop : within.offset.top,
1360                                 outerHeight = data.within.height,
1361                                 collisionPosTop = position.top - data.collisionPosition.marginTop,
1362                                 overTop = withinOffset - collisionPosTop,
1363                                 overBottom = collisionPosTop + data.collisionHeight - outerHeight - withinOffset,
1364                                 newOverBottom;
1366                         // element is taller than within
1367                         if ( data.collisionHeight > outerHeight ) {
1368                                 // element is initially over the top of within
1369                                 if ( overTop > 0 && overBottom <= 0 ) {
1370                                         newOverBottom = position.top + overTop + data.collisionHeight - outerHeight - withinOffset;
1371                                         position.top += overTop - newOverBottom;
1372                                 // element is initially over bottom of within
1373                                 } else if ( overBottom > 0 && overTop <= 0 ) {
1374                                         position.top = withinOffset;
1375                                 // element is initially over both top and bottom of within
1376                                 } else {
1377                                         if ( overTop > overBottom ) {
1378                                                 position.top = withinOffset + outerHeight - data.collisionHeight;
1379                                         } else {
1380                                                 position.top = withinOffset;
1381                                         }
1382                                 }
1383                         // too far up -> align with top
1384                         } else if ( overTop > 0 ) {
1385                                 position.top += overTop;
1386                         // too far down -> align with bottom edge
1387                         } else if ( overBottom > 0 ) {
1388                                 position.top -= overBottom;
1389                         // adjust based on position and margin
1390                         } else {
1391                                 position.top = max( position.top - collisionPosTop, position.top );
1392                         }
1393                 }
1394         },
1395         flip: {
1396                 left: function( position, data ) {
1397                         var within = data.within,
1398                                 withinOffset = within.offset.left + within.scrollLeft,
1399                                 outerWidth = within.width,
1400                                 offsetLeft = within.isWindow ? within.scrollLeft : within.offset.left,
1401                                 collisionPosLeft = position.left - data.collisionPosition.marginLeft,
1402                                 overLeft = collisionPosLeft - offsetLeft,
1403                                 overRight = collisionPosLeft + data.collisionWidth - outerWidth - offsetLeft,
1404                                 myOffset = data.my[ 0 ] === "left" ?
1405                                         -data.elemWidth :
1406                                         data.my[ 0 ] === "right" ?
1407                                                 data.elemWidth :
1408                                                 0,
1409                                 atOffset = data.at[ 0 ] === "left" ?
1410                                         data.targetWidth :
1411                                         data.at[ 0 ] === "right" ?
1412                                                 -data.targetWidth :
1413                                                 0,
1414                                 offset = -2 * data.offset[ 0 ],
1415                                 newOverRight,
1416                                 newOverLeft;
1418                         if ( overLeft < 0 ) {
1419                                 newOverRight = position.left + myOffset + atOffset + offset + data.collisionWidth - outerWidth - withinOffset;
1420                                 if ( newOverRight < 0 || newOverRight < abs( overLeft ) ) {
1421                                         position.left += myOffset + atOffset + offset;
1422                                 }
1423                         } else if ( overRight > 0 ) {
1424                                 newOverLeft = position.left - data.collisionPosition.marginLeft + myOffset + atOffset + offset - offsetLeft;
1425                                 if ( newOverLeft > 0 || abs( newOverLeft ) < overRight ) {
1426                                         position.left += myOffset + atOffset + offset;
1427                                 }
1428                         }
1429                 },
1430                 top: function( position, data ) {
1431                         var within = data.within,
1432                                 withinOffset = within.offset.top + within.scrollTop,
1433                                 outerHeight = within.height,
1434                                 offsetTop = within.isWindow ? within.scrollTop : within.offset.top,
1435                                 collisionPosTop = position.top - data.collisionPosition.marginTop,
1436                                 overTop = collisionPosTop - offsetTop,
1437                                 overBottom = collisionPosTop + data.collisionHeight - outerHeight - offsetTop,
1438                                 top = data.my[ 1 ] === "top",
1439                                 myOffset = top ?
1440                                         -data.elemHeight :
1441                                         data.my[ 1 ] === "bottom" ?
1442                                                 data.elemHeight :
1443                                                 0,
1444                                 atOffset = data.at[ 1 ] === "top" ?
1445                                         data.targetHeight :
1446                                         data.at[ 1 ] === "bottom" ?
1447                                                 -data.targetHeight :
1448                                                 0,
1449                                 offset = -2 * data.offset[ 1 ],
1450                                 newOverTop,
1451                                 newOverBottom;
1452                         if ( overTop < 0 ) {
1453                                 newOverBottom = position.top + myOffset + atOffset + offset + data.collisionHeight - outerHeight - withinOffset;
1454                                 if ( ( position.top + myOffset + atOffset + offset) > overTop && ( newOverBottom < 0 || newOverBottom < abs( overTop ) ) ) {
1455                                         position.top += myOffset + atOffset + offset;
1456                                 }
1457                         } else if ( overBottom > 0 ) {
1458                                 newOverTop = position.top - data.collisionPosition.marginTop + myOffset + atOffset + offset - offsetTop;
1459                                 if ( ( position.top + myOffset + atOffset + offset) > overBottom && ( newOverTop > 0 || abs( newOverTop ) < overBottom ) ) {
1460                                         position.top += myOffset + atOffset + offset;
1461                                 }
1462                         }
1463                 }
1464         },
1465         flipfit: {
1466                 left: function() {
1467                         $.ui.position.flip.left.apply( this, arguments );
1468                         $.ui.position.fit.left.apply( this, arguments );
1469                 },
1470                 top: function() {
1471                         $.ui.position.flip.top.apply( this, arguments );
1472                         $.ui.position.fit.top.apply( this, arguments );
1473                 }
1474         }
1477 // fraction support test
1478 (function() {
1479         var testElement, testElementParent, testElementStyle, offsetLeft, i,
1480                 body = document.getElementsByTagName( "body" )[ 0 ],
1481                 div = document.createElement( "div" );
1483         //Create a "fake body" for testing based on method used in jQuery.support
1484         testElement = document.createElement( body ? "div" : "body" );
1485         testElementStyle = {
1486                 visibility: "hidden",
1487                 width: 0,
1488                 height: 0,
1489                 border: 0,
1490                 margin: 0,
1491                 background: "none"
1492         };
1493         if ( body ) {
1494                 $.extend( testElementStyle, {
1495                         position: "absolute",
1496                         left: "-1000px",
1497                         top: "-1000px"
1498                 });
1499         }
1500         for ( i in testElementStyle ) {
1501                 testElement.style[ i ] = testElementStyle[ i ];
1502         }
1503         testElement.appendChild( div );
1504         testElementParent = body || document.documentElement;
1505         testElementParent.insertBefore( testElement, testElementParent.firstChild );
1507         div.style.cssText = "position: absolute; left: 10.7432222px;";
1509         offsetLeft = $( div ).offset().left;
1510         supportsOffsetFractions = offsetLeft > 10 && offsetLeft < 11;
1512         testElement.innerHTML = "";
1513         testElementParent.removeChild( testElement );
1514 })();
1516 })();
1518 var position = $.ui.position;
1522  * jQuery UI Draggable 1.11.0
1523  * http://jqueryui.com
1525  * Copyright 2014 jQuery Foundation and other contributors
1526  * Released under the MIT license.
1527  * http://jquery.org/license
1529  * http://api.jqueryui.com/draggable/
1530  */
1533 $.widget("ui.draggable", $.ui.mouse, {
1534         version: "1.11.0",
1535         widgetEventPrefix: "drag",
1536         options: {
1537                 addClasses: true,
1538                 appendTo: "parent",
1539                 axis: false,
1540                 connectToSortable: false,
1541                 containment: false,
1542                 cursor: "auto",
1543                 cursorAt: false,
1544                 grid: false,
1545                 handle: false,
1546                 helper: "original",
1547                 iframeFix: false,
1548                 opacity: false,
1549                 refreshPositions: false,
1550                 revert: false,
1551                 revertDuration: 500,
1552                 scope: "default",
1553                 scroll: true,
1554                 scrollSensitivity: 20,
1555                 scrollSpeed: 20,
1556                 snap: false,
1557                 snapMode: "both",
1558                 snapTolerance: 20,
1559                 stack: false,
1560                 zIndex: false,
1562                 // callbacks
1563                 drag: null,
1564                 start: null,
1565                 stop: null
1566         },
1567         _create: function() {
1569                 if (this.options.helper === "original" && !(/^(?:r|a|f)/).test(this.element.css("position"))) {
1570                         this.element[0].style.position = "relative";
1571                 }
1572                 if (this.options.addClasses){
1573                         this.element.addClass("ui-draggable");
1574                 }
1575                 if (this.options.disabled){
1576                         this.element.addClass("ui-draggable-disabled");
1577                 }
1578                 this._setHandleClassName();
1580                 this._mouseInit();
1581         },
1583         _setOption: function( key, value ) {
1584                 this._super( key, value );
1585                 if ( key === "handle" ) {
1586                         this._setHandleClassName();
1587                 }
1588         },
1590         _destroy: function() {
1591                 if ( ( this.helper || this.element ).is( ".ui-draggable-dragging" ) ) {
1592                         this.destroyOnClear = true;
1593                         return;
1594                 }
1595                 this.element.removeClass( "ui-draggable ui-draggable-dragging ui-draggable-disabled" );
1596                 this._removeHandleClassName();
1597                 this._mouseDestroy();
1598         },
1600         _mouseCapture: function(event) {
1602                 var document = this.document[ 0 ],
1603                         o = this.options;
1605                 // support: IE9
1606                 // IE9 throws an "Unspecified error" accessing document.activeElement from an <iframe>
1607                 try {
1608                         // Support: IE9+
1609                         // If the <body> is blurred, IE will switch windows, see #9520
1610                         if ( document.activeElement && document.activeElement.nodeName.toLowerCase() !== "body" ) {
1611                                 // Blur any element that currently has focus, see #4261
1612                                 $( document.activeElement ).blur();
1613                         }
1614                 } catch ( error ) {}
1616                 // among others, prevent a drag on a resizable-handle
1617                 if (this.helper || o.disabled || $(event.target).closest(".ui-resizable-handle").length > 0) {
1618                         return false;
1619                 }
1621                 //Quit if we're not on a valid handle
1622                 this.handle = this._getHandle(event);
1623                 if (!this.handle) {
1624                         return false;
1625                 }
1627                 $(o.iframeFix === true ? "iframe" : o.iframeFix).each(function() {
1628                         $("<div class='ui-draggable-iframeFix' style='background: #fff;'></div>")
1629                         .css({
1630                                 width: this.offsetWidth + "px", height: this.offsetHeight + "px",
1631                                 position: "absolute", opacity: "0.001", zIndex: 1000
1632                         })
1633                         .css($(this).offset())
1634                         .appendTo("body");
1635                 });
1637                 return true;
1639         },
1641         _mouseStart: function(event) {
1643                 var o = this.options;
1645                 //Create and append the visible helper
1646                 this.helper = this._createHelper(event);
1648                 this.helper.addClass("ui-draggable-dragging");
1650                 //Cache the helper size
1651                 this._cacheHelperProportions();
1653                 //If ddmanager is used for droppables, set the global draggable
1654                 if ($.ui.ddmanager) {
1655                         $.ui.ddmanager.current = this;
1656                 }
1658                 /*
1659                  * - Position generation -
1660                  * This block generates everything position related - it's the core of draggables.
1661                  */
1663                 //Cache the margins of the original element
1664                 this._cacheMargins();
1666                 //Store the helper's css position
1667                 this.cssPosition = this.helper.css( "position" );
1668                 this.scrollParent = this.helper.scrollParent();
1669                 this.offsetParent = this.helper.offsetParent();
1670                 this.offsetParentCssPosition = this.offsetParent.css( "position" );
1672                 //The element's absolute position on the page minus margins
1673                 this.offset = this.positionAbs = this.element.offset();
1674                 this.offset = {
1675                         top: this.offset.top - this.margins.top,
1676                         left: this.offset.left - this.margins.left
1677                 };
1679                 //Reset scroll cache
1680                 this.offset.scroll = false;
1682                 $.extend(this.offset, {
1683                         click: { //Where the click happened, relative to the element
1684                                 left: event.pageX - this.offset.left,
1685                                 top: event.pageY - this.offset.top
1686                         },
1687                         parent: this._getParentOffset(),
1688                         relative: this._getRelativeOffset() //This is a relative to absolute position minus the actual position calculation - only used for relative positioned helper
1689                 });
1691                 //Generate the original position
1692                 this.originalPosition = this.position = this._generatePosition( event, false );
1693                 this.originalPageX = event.pageX;
1694                 this.originalPageY = event.pageY;
1696                 //Adjust the mouse offset relative to the helper if "cursorAt" is supplied
1697                 (o.cursorAt && this._adjustOffsetFromHelper(o.cursorAt));
1699                 //Set a containment if given in the options
1700                 this._setContainment();
1702                 //Trigger event + callbacks
1703                 if (this._trigger("start", event) === false) {
1704                         this._clear();
1705                         return false;
1706                 }
1708                 //Recache the helper size
1709                 this._cacheHelperProportions();
1711                 //Prepare the droppable offsets
1712                 if ($.ui.ddmanager && !o.dropBehaviour) {
1713                         $.ui.ddmanager.prepareOffsets(this, event);
1714                 }
1716                 this._mouseDrag(event, true); //Execute the drag once - this causes the helper not to be visible before getting its correct position
1718                 //If the ddmanager is used for droppables, inform the manager that dragging has started (see #5003)
1719                 if ( $.ui.ddmanager ) {
1720                         $.ui.ddmanager.dragStart(this, event);
1721                 }
1723                 return true;
1724         },
1726         _mouseDrag: function(event, noPropagation) {
1727                 // reset any necessary cached properties (see #5009)
1728                 if ( this.offsetParentCssPosition === "fixed" ) {
1729                         this.offset.parent = this._getParentOffset();
1730                 }
1732                 //Compute the helpers position
1733                 this.position = this._generatePosition( event, true );
1734                 this.positionAbs = this._convertPositionTo("absolute");
1736                 //Call plugins and callbacks and use the resulting position if something is returned
1737                 if (!noPropagation) {
1738                         var ui = this._uiHash();
1739                         if (this._trigger("drag", event, ui) === false) {
1740                                 this._mouseUp({});
1741                                 return false;
1742                         }
1743                         this.position = ui.position;
1744                 }
1746                 this.helper[ 0 ].style.left = this.position.left + "px";
1747                 this.helper[ 0 ].style.top = this.position.top + "px";
1749                 if ($.ui.ddmanager) {
1750                         $.ui.ddmanager.drag(this, event);
1751                 }
1753                 return false;
1754         },
1756         _mouseStop: function(event) {
1758                 //If we are using droppables, inform the manager about the drop
1759                 var that = this,
1760                         dropped = false;
1761                 if ($.ui.ddmanager && !this.options.dropBehaviour) {
1762                         dropped = $.ui.ddmanager.drop(this, event);
1763                 }
1765                 //if a drop comes from outside (a sortable)
1766                 if (this.dropped) {
1767                         dropped = this.dropped;
1768                         this.dropped = false;
1769                 }
1771                 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))) {
1772                         $(this.helper).animate(this.originalPosition, parseInt(this.options.revertDuration, 10), function() {
1773                                 if (that._trigger("stop", event) !== false) {
1774                                         that._clear();
1775                                 }
1776                         });
1777                 } else {
1778                         if (this._trigger("stop", event) !== false) {
1779                                 this._clear();
1780                         }
1781                 }
1783                 return false;
1784         },
1786         _mouseUp: function(event) {
1787                 //Remove frame helpers
1788                 $("div.ui-draggable-iframeFix").each(function() {
1789                         this.parentNode.removeChild(this);
1790                 });
1792                 //If the ddmanager is used for droppables, inform the manager that dragging has stopped (see #5003)
1793                 if ( $.ui.ddmanager ) {
1794                         $.ui.ddmanager.dragStop(this, event);
1795                 }
1797                 // The interaction is over; whether or not the click resulted in a drag, focus the element
1798                 this.element.focus();
1800                 return $.ui.mouse.prototype._mouseUp.call(this, event);
1801         },
1803         cancel: function() {
1805                 if (this.helper.is(".ui-draggable-dragging")) {
1806                         this._mouseUp({});
1807                 } else {
1808                         this._clear();
1809                 }
1811                 return this;
1813         },
1815         _getHandle: function(event) {
1816                 return this.options.handle ?
1817                         !!$( event.target ).closest( this.element.find( this.options.handle ) ).length :
1818                         true;
1819         },
1821         _setHandleClassName: function() {
1822                 this._removeHandleClassName();
1823                 $( this.options.handle || this.element ).addClass( "ui-draggable-handle" );
1824         },
1826         _removeHandleClassName: function() {
1827                 this.element.find( ".ui-draggable-handle" )
1828                         .addBack()
1829                         .removeClass( "ui-draggable-handle" );
1830         },
1832         _createHelper: function(event) {
1834                 var o = this.options,
1835                         helper = $.isFunction(o.helper) ? $(o.helper.apply(this.element[ 0 ], [ event ])) : (o.helper === "clone" ? this.element.clone().removeAttr("id") : this.element);
1837                 if (!helper.parents("body").length) {
1838                         helper.appendTo((o.appendTo === "parent" ? this.element[0].parentNode : o.appendTo));
1839                 }
1841                 if (helper[0] !== this.element[0] && !(/(fixed|absolute)/).test(helper.css("position"))) {
1842                         helper.css("position", "absolute");
1843                 }
1845                 return helper;
1847         },
1849         _adjustOffsetFromHelper: function(obj) {
1850                 if (typeof obj === "string") {
1851                         obj = obj.split(" ");
1852                 }
1853                 if ($.isArray(obj)) {
1854                         obj = { left: +obj[0], top: +obj[1] || 0 };
1855                 }
1856                 if ("left" in obj) {
1857                         this.offset.click.left = obj.left + this.margins.left;
1858                 }
1859                 if ("right" in obj) {
1860                         this.offset.click.left = this.helperProportions.width - obj.right + this.margins.left;
1861                 }
1862                 if ("top" in obj) {
1863                         this.offset.click.top = obj.top + this.margins.top;
1864                 }
1865                 if ("bottom" in obj) {
1866                         this.offset.click.top = this.helperProportions.height - obj.bottom + this.margins.top;
1867                 }
1868         },
1870         _isRootNode: function( element ) {
1871                 return ( /(html|body)/i ).test( element.tagName ) || element === this.document[ 0 ];
1872         },
1874         _getParentOffset: function() {
1876                 //Get the offsetParent and cache its position
1877                 var po = this.offsetParent.offset(),
1878                         document = this.document[ 0 ];
1880                 // This is a special case where we need to modify a offset calculated on start, since the following happened:
1881                 // 1. The position of the helper is absolute, so it's position is calculated based on the next positioned parent
1882                 // 2. The actual offset parent is a child of the scroll parent, and the scroll parent isn't the document, which means that
1883                 //    the scroll is included in the initial calculation of the offset of the parent, and never recalculated upon drag
1884                 if (this.cssPosition === "absolute" && this.scrollParent[0] !== document && $.contains(this.scrollParent[0], this.offsetParent[0])) {
1885                         po.left += this.scrollParent.scrollLeft();
1886                         po.top += this.scrollParent.scrollTop();
1887                 }
1889                 if ( this._isRootNode( this.offsetParent[ 0 ] ) ) {
1890                         po = { top: 0, left: 0 };
1891                 }
1893                 return {
1894                         top: po.top + (parseInt(this.offsetParent.css("borderTopWidth"),10) || 0),
1895                         left: po.left + (parseInt(this.offsetParent.css("borderLeftWidth"),10) || 0)
1896                 };
1898         },
1900         _getRelativeOffset: function() {
1901                 if ( this.cssPosition !== "relative" ) {
1902                         return { top: 0, left: 0 };
1903                 }
1905                 var p = this.element.position(),
1906                         scrollIsRootNode = this._isRootNode( this.scrollParent[ 0 ] );
1908                 return {
1909                         top: p.top - ( parseInt(this.helper.css( "top" ), 10) || 0 ) + ( !scrollIsRootNode ? this.scrollParent.scrollTop() : 0 ),
1910                         left: p.left - ( parseInt(this.helper.css( "left" ), 10) || 0 ) + ( !scrollIsRootNode ? this.scrollParent.scrollLeft() : 0 )
1911                 };
1913         },
1915         _cacheMargins: function() {
1916                 this.margins = {
1917                         left: (parseInt(this.element.css("marginLeft"),10) || 0),
1918                         top: (parseInt(this.element.css("marginTop"),10) || 0),
1919                         right: (parseInt(this.element.css("marginRight"),10) || 0),
1920                         bottom: (parseInt(this.element.css("marginBottom"),10) || 0)
1921                 };
1922         },
1924         _cacheHelperProportions: function() {
1925                 this.helperProportions = {
1926                         width: this.helper.outerWidth(),
1927                         height: this.helper.outerHeight()
1928                 };
1929         },
1931         _setContainment: function() {
1933                 var over, c, ce,
1934                         o = this.options,
1935                         document = this.document[ 0 ];
1937                 this.relative_container = null;
1939                 if ( !o.containment ) {
1940                         this.containment = null;
1941                         return;
1942                 }
1944                 if ( o.containment === "window" ) {
1945                         this.containment = [
1946                                 $( window ).scrollLeft() - this.offset.relative.left - this.offset.parent.left,
1947                                 $( window ).scrollTop() - this.offset.relative.top - this.offset.parent.top,
1948                                 $( window ).scrollLeft() + $( window ).width() - this.helperProportions.width - this.margins.left,
1949                                 $( window ).scrollTop() + ( $( window ).height() || document.body.parentNode.scrollHeight ) - this.helperProportions.height - this.margins.top
1950                         ];
1951                         return;
1952                 }
1954                 if ( o.containment === "document") {
1955                         this.containment = [
1956                                 0,
1957                                 0,
1958                                 $( document ).width() - this.helperProportions.width - this.margins.left,
1959                                 ( $( document ).height() || document.body.parentNode.scrollHeight ) - this.helperProportions.height - this.margins.top
1960                         ];
1961                         return;
1962                 }
1964                 if ( o.containment.constructor === Array ) {
1965                         this.containment = o.containment;
1966                         return;
1967                 }
1969                 if ( o.containment === "parent" ) {
1970                         o.containment = this.helper[ 0 ].parentNode;
1971                 }
1973                 c = $( o.containment );
1974                 ce = c[ 0 ];
1976                 if ( !ce ) {
1977                         return;
1978                 }
1980                 over = c.css( "overflow" ) !== "hidden";
1982                 this.containment = [
1983                         ( parseInt( c.css( "borderLeftWidth" ), 10 ) || 0 ) + ( parseInt( c.css( "paddingLeft" ), 10 ) || 0 ),
1984                         ( parseInt( c.css( "borderTopWidth" ), 10 ) || 0 ) + ( parseInt( c.css( "paddingTop" ), 10 ) || 0 ),
1985                         ( 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,
1986                         ( 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
1987                 ];
1988                 this.relative_container = c;
1989         },
1991         _convertPositionTo: function(d, pos) {
1993                 if (!pos) {
1994                         pos = this.position;
1995                 }
1997                 var mod = d === "absolute" ? 1 : -1,
1998                         scrollIsRootNode = this._isRootNode( this.scrollParent[ 0 ] );
2000                 return {
2001                         top: (
2002                                 pos.top +                                                                                                                               // The absolute mouse position
2003                                 this.offset.relative.top * mod +                                                                                // Only for relative positioned nodes: Relative offset from element to offset parent
2004                                 this.offset.parent.top * mod -                                                                          // The offsetParent's offset without borders (offset + border)
2005                                 ( ( this.cssPosition === "fixed" ? -this.offset.scroll.top : ( scrollIsRootNode ? 0 : this.offset.scroll.top ) ) * mod)
2006                         ),
2007                         left: (
2008                                 pos.left +                                                                                                                              // The absolute mouse position
2009                                 this.offset.relative.left * mod +                                                                               // Only for relative positioned nodes: Relative offset from element to offset parent
2010                                 this.offset.parent.left * mod   -                                                                               // The offsetParent's offset without borders (offset + border)
2011                                 ( ( this.cssPosition === "fixed" ? -this.offset.scroll.left : ( scrollIsRootNode ? 0 : this.offset.scroll.left ) ) * mod)
2012                         )
2013                 };
2015         },
2017         _generatePosition: function( event, constrainPosition ) {
2019                 var containment, co, top, left,
2020                         o = this.options,
2021                         scrollIsRootNode = this._isRootNode( this.scrollParent[ 0 ] ),
2022                         pageX = event.pageX,
2023                         pageY = event.pageY;
2025                 // Cache the scroll
2026                 if ( !scrollIsRootNode || !this.offset.scroll ) {
2027                         this.offset.scroll = {
2028                                 top: this.scrollParent.scrollTop(),
2029                                 left: this.scrollParent.scrollLeft()
2030                         };
2031                 }
2033                 /*
2034                  * - Position constraining -
2035                  * Constrain the position to a mix of grid, containment.
2036                  */
2038                 // If we are not dragging yet, we won't check for options
2039                 if ( constrainPosition ) {
2040                         if ( this.containment ) {
2041                                 if ( this.relative_container ){
2042                                         co = this.relative_container.offset();
2043                                         containment = [
2044                                                 this.containment[ 0 ] + co.left,
2045                                                 this.containment[ 1 ] + co.top,
2046                                                 this.containment[ 2 ] + co.left,
2047                                                 this.containment[ 3 ] + co.top
2048                                         ];
2049                                 } else {
2050                                         containment = this.containment;
2051                                 }
2053                                 if (event.pageX - this.offset.click.left < containment[0]) {
2054                                         pageX = containment[0] + this.offset.click.left;
2055                                 }
2056                                 if (event.pageY - this.offset.click.top < containment[1]) {
2057                                         pageY = containment[1] + this.offset.click.top;
2058                                 }
2059                                 if (event.pageX - this.offset.click.left > containment[2]) {
2060                                         pageX = containment[2] + this.offset.click.left;
2061                                 }
2062                                 if (event.pageY - this.offset.click.top > containment[3]) {
2063                                         pageY = containment[3] + this.offset.click.top;
2064                                 }
2065                         }
2067                         if (o.grid) {
2068                                 //Check for grid elements set to 0 to prevent divide by 0 error causing invalid argument errors in IE (see ticket #6950)
2069                                 top = o.grid[1] ? this.originalPageY + Math.round((pageY - this.originalPageY) / o.grid[1]) * o.grid[1] : this.originalPageY;
2070                                 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;
2072                                 left = o.grid[0] ? this.originalPageX + Math.round((pageX - this.originalPageX) / o.grid[0]) * o.grid[0] : this.originalPageX;
2073                                 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;
2074                         }
2076                         if ( o.axis === "y" ) {
2077                                 pageX = this.originalPageX;
2078                         }
2080                         if ( o.axis === "x" ) {
2081                                 pageY = this.originalPageY;
2082                         }
2083                 }
2085                 return {
2086                         top: (
2087                                 pageY -                                                                                                                                 // The absolute mouse position
2088                                 this.offset.click.top   -                                                                                               // Click offset (relative to the element)
2089                                 this.offset.relative.top -                                                                                              // Only for relative positioned nodes: Relative offset from element to offset parent
2090                                 this.offset.parent.top +                                                                                                // The offsetParent's offset without borders (offset + border)
2091                                 ( this.cssPosition === "fixed" ? -this.offset.scroll.top : ( scrollIsRootNode ? 0 : this.offset.scroll.top ) )
2092                         ),
2093                         left: (
2094                                 pageX -                                                                                                                                 // The absolute mouse position
2095                                 this.offset.click.left -                                                                                                // Click offset (relative to the element)
2096                                 this.offset.relative.left -                                                                                             // Only for relative positioned nodes: Relative offset from element to offset parent
2097                                 this.offset.parent.left +                                                                                               // The offsetParent's offset without borders (offset + border)
2098                                 ( this.cssPosition === "fixed" ? -this.offset.scroll.left : ( scrollIsRootNode ? 0 : this.offset.scroll.left ) )
2099                         )
2100                 };
2102         },
2104         _clear: function() {
2105                 this.helper.removeClass("ui-draggable-dragging");
2106                 if (this.helper[0] !== this.element[0] && !this.cancelHelperRemoval) {
2107                         this.helper.remove();
2108                 }
2109                 this.helper = null;
2110                 this.cancelHelperRemoval = false;
2111                 if ( this.destroyOnClear ) {
2112                         this.destroy();
2113                 }
2114         },
2116         // From now on bulk stuff - mainly helpers
2118         _trigger: function(type, event, ui) {
2119                 ui = ui || this._uiHash();
2120                 $.ui.plugin.call( this, type, [ event, ui, this ], true );
2121                 //The absolute position has to be recalculated after plugins
2122                 if (type === "drag") {
2123                         this.positionAbs = this._convertPositionTo("absolute");
2124                 }
2125                 return $.Widget.prototype._trigger.call(this, type, event, ui);
2126         },
2128         plugins: {},
2130         _uiHash: function() {
2131                 return {
2132                         helper: this.helper,
2133                         position: this.position,
2134                         originalPosition: this.originalPosition,
2135                         offset: this.positionAbs
2136                 };
2137         }
2141 $.ui.plugin.add("draggable", "connectToSortable", {
2142         start: function( event, ui, inst ) {
2144                 var o = inst.options,
2145                         uiSortable = $.extend({}, ui, { item: inst.element });
2146                 inst.sortables = [];
2147                 $(o.connectToSortable).each(function() {
2148                         var sortable = $( this ).sortable( "instance" );
2149                         if (sortable && !sortable.options.disabled) {
2150                                 inst.sortables.push({
2151                                         instance: sortable,
2152                                         shouldRevert: sortable.options.revert
2153                                 });
2154                                 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).
2155                                 sortable._trigger("activate", event, uiSortable);
2156                         }
2157                 });
2159         },
2160         stop: function( event, ui, inst ) {
2162                 //If we are still over the sortable, we fake the stop event of the sortable, but also remove helper
2163                 var uiSortable = $.extend( {}, ui, {
2164                         item: inst.element
2165                 });
2167                 $.each(inst.sortables, function() {
2168                         if (this.instance.isOver) {
2170                                 this.instance.isOver = 0;
2172                                 inst.cancelHelperRemoval = true; //Don't remove the helper in the draggable instance
2173                                 this.instance.cancelHelperRemoval = false; //Remove it in the sortable instance (so sortable plugins like revert still work)
2175                                 //The sortable revert is supported, and we have to set a temporary dropped variable on the draggable to support revert: "valid/invalid"
2176                                 if (this.shouldRevert) {
2177                                         this.instance.options.revert = this.shouldRevert;
2178                                 }
2180                                 //Trigger the stop of the sortable
2181                                 this.instance._mouseStop(event);
2183                                 this.instance.options.helper = this.instance.options._helper;
2185                                 //If the helper has been the original item, restore properties in the sortable
2186                                 if (inst.options.helper === "original") {
2187                                         this.instance.currentItem.css({ top: "auto", left: "auto" });
2188                                 }
2190                         } else {
2191                                 this.instance.cancelHelperRemoval = false; //Remove the helper in the sortable instance
2192                                 this.instance._trigger("deactivate", event, uiSortable);
2193                         }
2195                 });
2197         },
2198         drag: function( event, ui, inst ) {
2200                 var that = this;
2202                 $.each(inst.sortables, function() {
2204                         var innermostIntersecting = false,
2205                                 thisSortable = this;
2207                         //Copy over some variables to allow calling the sortable's native _intersectsWith
2208                         this.instance.positionAbs = inst.positionAbs;
2209                         this.instance.helperProportions = inst.helperProportions;
2210                         this.instance.offset.click = inst.offset.click;
2212                         if (this.instance._intersectsWith(this.instance.containerCache)) {
2213                                 innermostIntersecting = true;
2214                                 $.each(inst.sortables, function() {
2215                                         this.instance.positionAbs = inst.positionAbs;
2216                                         this.instance.helperProportions = inst.helperProportions;
2217                                         this.instance.offset.click = inst.offset.click;
2218                                         if (this !== thisSortable &&
2219                                                 this.instance._intersectsWith(this.instance.containerCache) &&
2220                                                 $.contains(thisSortable.instance.element[0], this.instance.element[0])
2221                                         ) {
2222                                                 innermostIntersecting = false;
2223                                         }
2224                                         return innermostIntersecting;
2225                                 });
2226                         }
2228                         if (innermostIntersecting) {
2229                                 //If it intersects, we use a little isOver variable and set it once, so our move-in stuff gets fired only once
2230                                 if (!this.instance.isOver) {
2232                                         this.instance.isOver = 1;
2233                                         //Now we fake the start of dragging for the sortable instance,
2234                                         //by cloning the list group item, appending it to the sortable and using it as inst.currentItem
2235                                         //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)
2236                                         this.instance.currentItem = $(that).clone().removeAttr("id").appendTo(this.instance.element).data("ui-sortable-item", true);
2237                                         this.instance.options._helper = this.instance.options.helper; //Store helper option to later restore it
2238                                         this.instance.options.helper = function() { return ui.helper[0]; };
2240                                         event.target = this.instance.currentItem[0];
2241                                         this.instance._mouseCapture(event, true);
2242                                         this.instance._mouseStart(event, true, true);
2244                                         //Because the browser event is way off the new appended portlet, we modify a couple of variables to reflect the changes
2245                                         this.instance.offset.click.top = inst.offset.click.top;
2246                                         this.instance.offset.click.left = inst.offset.click.left;
2247                                         this.instance.offset.parent.left -= inst.offset.parent.left - this.instance.offset.parent.left;
2248                                         this.instance.offset.parent.top -= inst.offset.parent.top - this.instance.offset.parent.top;
2250                                         inst._trigger("toSortable", event);
2251                                         inst.dropped = this.instance.element; //draggable revert needs that
2252                                         //hack so receive/update callbacks work (mostly)
2253                                         inst.currentItem = inst.element;
2254                                         this.instance.fromOutside = inst;
2256                                 }
2258                                 //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
2259                                 if (this.instance.currentItem) {
2260                                         this.instance._mouseDrag(event);
2261                                 }
2263                         } else {
2265                                 //If it doesn't intersect with the sortable, and it intersected before,
2266                                 //we fake the drag stop of the sortable, but make sure it doesn't remove the helper by using cancelHelperRemoval
2267                                 if (this.instance.isOver) {
2269                                         this.instance.isOver = 0;
2270                                         this.instance.cancelHelperRemoval = true;
2272                                         //Prevent reverting on this forced stop
2273                                         this.instance.options.revert = false;
2275                                         // The out event needs to be triggered independently
2276                                         this.instance._trigger("out", event, this.instance._uiHash(this.instance));
2278                                         this.instance._mouseStop(event, true);
2279                                         this.instance.options.helper = this.instance.options._helper;
2281                                         //Now we remove our currentItem, the list group clone again, and the placeholder, and animate the helper back to it's original size
2282                                         this.instance.currentItem.remove();
2283                                         if (this.instance.placeholder) {
2284                                                 this.instance.placeholder.remove();
2285                                         }
2287                                         inst._trigger("fromSortable", event);
2288                                         inst.dropped = false; //draggable revert needs that
2289                                 }
2291                         }
2293                 });
2295         }
2298 $.ui.plugin.add("draggable", "cursor", {
2299         start: function( event, ui, instance ) {
2300                 var t = $( "body" ),
2301                         o = instance.options;
2303                 if (t.css("cursor")) {
2304                         o._cursor = t.css("cursor");
2305                 }
2306                 t.css("cursor", o.cursor);
2307         },
2308         stop: function( event, ui, instance ) {
2309                 var o = instance.options;
2310                 if (o._cursor) {
2311                         $("body").css("cursor", o._cursor);
2312                 }
2313         }
2316 $.ui.plugin.add("draggable", "opacity", {
2317         start: function( event, ui, instance ) {
2318                 var t = $( ui.helper ),
2319                         o = instance.options;
2320                 if (t.css("opacity")) {
2321                         o._opacity = t.css("opacity");
2322                 }
2323                 t.css("opacity", o.opacity);
2324         },
2325         stop: function( event, ui, instance ) {
2326                 var o = instance.options;
2327                 if (o._opacity) {
2328                         $(ui.helper).css("opacity", o._opacity);
2329                 }
2330         }
2333 $.ui.plugin.add("draggable", "scroll", {
2334         start: function( event, ui, i ) {
2335                 if ( i.scrollParent[ 0 ] !== i.document[ 0 ] && i.scrollParent[ 0 ].tagName !== "HTML" ) {
2336                         i.overflowOffset = i.scrollParent.offset();
2337                 }
2338         },
2339         drag: function( event, ui, i  ) {
2341                 var o = i.options,
2342                         scrolled = false,
2343                         document = i.document[ 0 ];
2345                 if ( i.scrollParent[ 0 ] !== document && i.scrollParent[ 0 ].tagName !== "HTML" ) {
2346                         if (!o.axis || o.axis !== "x") {
2347                                 if ((i.overflowOffset.top + i.scrollParent[0].offsetHeight) - event.pageY < o.scrollSensitivity) {
2348                                         i.scrollParent[0].scrollTop = scrolled = i.scrollParent[0].scrollTop + o.scrollSpeed;
2349                                 } else if (event.pageY - i.overflowOffset.top < o.scrollSensitivity) {
2350                                         i.scrollParent[0].scrollTop = scrolled = i.scrollParent[0].scrollTop - o.scrollSpeed;
2351                                 }
2352                         }
2354                         if (!o.axis || o.axis !== "y") {
2355                                 if ((i.overflowOffset.left + i.scrollParent[0].offsetWidth) - event.pageX < o.scrollSensitivity) {
2356                                         i.scrollParent[0].scrollLeft = scrolled = i.scrollParent[0].scrollLeft + o.scrollSpeed;
2357                                 } else if (event.pageX - i.overflowOffset.left < o.scrollSensitivity) {
2358                                         i.scrollParent[0].scrollLeft = scrolled = i.scrollParent[0].scrollLeft - o.scrollSpeed;
2359                                 }
2360                         }
2362                 } else {
2364                         if (!o.axis || o.axis !== "x") {
2365                                 if (event.pageY - $(document).scrollTop() < o.scrollSensitivity) {
2366                                         scrolled = $(document).scrollTop($(document).scrollTop() - o.scrollSpeed);
2367                                 } else if ($(window).height() - (event.pageY - $(document).scrollTop()) < o.scrollSensitivity) {
2368                                         scrolled = $(document).scrollTop($(document).scrollTop() + o.scrollSpeed);
2369                                 }
2370                         }
2372                         if (!o.axis || o.axis !== "y") {
2373                                 if (event.pageX - $(document).scrollLeft() < o.scrollSensitivity) {
2374                                         scrolled = $(document).scrollLeft($(document).scrollLeft() - o.scrollSpeed);
2375                                 } else if ($(window).width() - (event.pageX - $(document).scrollLeft()) < o.scrollSensitivity) {
2376                                         scrolled = $(document).scrollLeft($(document).scrollLeft() + o.scrollSpeed);
2377                                 }
2378                         }
2380                 }
2382                 if (scrolled !== false && $.ui.ddmanager && !o.dropBehaviour) {
2383                         $.ui.ddmanager.prepareOffsets(i, event);
2384                 }
2386         }
2389 $.ui.plugin.add("draggable", "snap", {
2390         start: function( event, ui, i ) {
2392                 var o = i.options;
2394                 i.snapElements = [];
2396                 $(o.snap.constructor !== String ? ( o.snap.items || ":data(ui-draggable)" ) : o.snap).each(function() {
2397                         var $t = $(this),
2398                                 $o = $t.offset();
2399                         if (this !== i.element[0]) {
2400                                 i.snapElements.push({
2401                                         item: this,
2402                                         width: $t.outerWidth(), height: $t.outerHeight(),
2403                                         top: $o.top, left: $o.left
2404                                 });
2405                         }
2406                 });
2408         },
2409         drag: function( event, ui, inst ) {
2411                 var ts, bs, ls, rs, l, r, t, b, i, first,
2412                         o = inst.options,
2413                         d = o.snapTolerance,
2414                         x1 = ui.offset.left, x2 = x1 + inst.helperProportions.width,
2415                         y1 = ui.offset.top, y2 = y1 + inst.helperProportions.height;
2417                 for (i = inst.snapElements.length - 1; i >= 0; i--){
2419                         l = inst.snapElements[i].left;
2420                         r = l + inst.snapElements[i].width;
2421                         t = inst.snapElements[i].top;
2422                         b = t + inst.snapElements[i].height;
2424                         if ( x2 < l - d || x1 > r + d || y2 < t - d || y1 > b + d || !$.contains( inst.snapElements[ i ].item.ownerDocument, inst.snapElements[ i ].item ) ) {
2425                                 if (inst.snapElements[i].snapping) {
2426                                         (inst.options.snap.release && inst.options.snap.release.call(inst.element, event, $.extend(inst._uiHash(), { snapItem: inst.snapElements[i].item })));
2427                                 }
2428                                 inst.snapElements[i].snapping = false;
2429                                 continue;
2430                         }
2432                         if (o.snapMode !== "inner") {
2433                                 ts = Math.abs(t - y2) <= d;
2434                                 bs = Math.abs(b - y1) <= d;
2435                                 ls = Math.abs(l - x2) <= d;
2436                                 rs = Math.abs(r - x1) <= d;
2437                                 if (ts) {
2438                                         ui.position.top = inst._convertPositionTo("relative", { top: t - inst.helperProportions.height, left: 0 }).top - inst.margins.top;
2439                                 }
2440                                 if (bs) {
2441                                         ui.position.top = inst._convertPositionTo("relative", { top: b, left: 0 }).top - inst.margins.top;
2442                                 }
2443                                 if (ls) {
2444                                         ui.position.left = inst._convertPositionTo("relative", { top: 0, left: l - inst.helperProportions.width }).left - inst.margins.left;
2445                                 }
2446                                 if (rs) {
2447                                         ui.position.left = inst._convertPositionTo("relative", { top: 0, left: r }).left - inst.margins.left;
2448                                 }
2449                         }
2451                         first = (ts || bs || ls || rs);
2453                         if (o.snapMode !== "outer") {
2454                                 ts = Math.abs(t - y1) <= d;
2455                                 bs = Math.abs(b - y2) <= d;
2456                                 ls = Math.abs(l - x1) <= d;
2457                                 rs = Math.abs(r - x2) <= d;
2458                                 if (ts) {
2459                                         ui.position.top = inst._convertPositionTo("relative", { top: t, left: 0 }).top - inst.margins.top;
2460                                 }
2461                                 if (bs) {
2462                                         ui.position.top = inst._convertPositionTo("relative", { top: b - inst.helperProportions.height, left: 0 }).top - inst.margins.top;
2463                                 }
2464                                 if (ls) {
2465                                         ui.position.left = inst._convertPositionTo("relative", { top: 0, left: l }).left - inst.margins.left;
2466                                 }
2467                                 if (rs) {
2468                                         ui.position.left = inst._convertPositionTo("relative", { top: 0, left: r - inst.helperProportions.width }).left - inst.margins.left;
2469                                 }
2470                         }
2472                         if (!inst.snapElements[i].snapping && (ts || bs || ls || rs || first)) {
2473                                 (inst.options.snap.snap && inst.options.snap.snap.call(inst.element, event, $.extend(inst._uiHash(), { snapItem: inst.snapElements[i].item })));
2474                         }
2475                         inst.snapElements[i].snapping = (ts || bs || ls || rs || first);
2477                 }
2479         }
2482 $.ui.plugin.add("draggable", "stack", {
2483         start: function( event, ui, instance ) {
2484                 var min,
2485                         o = instance.options,
2486                         group = $.makeArray($(o.stack)).sort(function(a,b) {
2487                                 return (parseInt($(a).css("zIndex"),10) || 0) - (parseInt($(b).css("zIndex"),10) || 0);
2488                         });
2490                 if (!group.length) { return; }
2492                 min = parseInt($(group[0]).css("zIndex"), 10) || 0;
2493                 $(group).each(function(i) {
2494                         $(this).css("zIndex", min + i);
2495                 });
2496                 this.css("zIndex", (min + group.length));
2497         }
2500 $.ui.plugin.add("draggable", "zIndex", {
2501         start: function( event, ui, instance ) {
2502                 var t = $( ui.helper ),
2503                         o = instance.options;
2505                 if (t.css("zIndex")) {
2506                         o._zIndex = t.css("zIndex");
2507                 }
2508                 t.css("zIndex", o.zIndex);
2509         },
2510         stop: function( event, ui, instance ) {
2511                 var o = instance.options;
2513                 if (o._zIndex) {
2514                         $(ui.helper).css("zIndex", o._zIndex);
2515                 }
2516         }
2519 var draggable = $.ui.draggable;
2523  * jQuery UI Droppable 1.11.0
2524  * http://jqueryui.com
2526  * Copyright 2014 jQuery Foundation and other contributors
2527  * Released under the MIT license.
2528  * http://jquery.org/license
2530  * http://api.jqueryui.com/droppable/
2531  */
2534 $.widget( "ui.droppable", {
2535         version: "1.11.0",
2536         widgetEventPrefix: "drop",
2537         options: {
2538                 accept: "*",
2539                 activeClass: false,
2540                 addClasses: true,
2541                 greedy: false,
2542                 hoverClass: false,
2543                 scope: "default",
2544                 tolerance: "intersect",
2546                 // callbacks
2547                 activate: null,
2548                 deactivate: null,
2549                 drop: null,
2550                 out: null,
2551                 over: null
2552         },
2553         _create: function() {
2555                 var proportions,
2556                         o = this.options,
2557                         accept = o.accept;
2559                 this.isover = false;
2560                 this.isout = true;
2562                 this.accept = $.isFunction( accept ) ? accept : function( d ) {
2563                         return d.is( accept );
2564                 };
2566                 this.proportions = function( /* valueToWrite */ ) {
2567                         if ( arguments.length ) {
2568                                 // Store the droppable's proportions
2569                                 proportions = arguments[ 0 ];
2570                         } else {
2571                                 // Retrieve or derive the droppable's proportions
2572                                 return proportions ?
2573                                         proportions :
2574                                         proportions = {
2575                                                 width: this.element[ 0 ].offsetWidth,
2576                                                 height: this.element[ 0 ].offsetHeight
2577                                         };
2578                         }
2579                 };
2581                 this._addToManager( o.scope );
2583                 o.addClasses && this.element.addClass( "ui-droppable" );
2585         },
2587         _addToManager: function( scope ) {
2588                 // Add the reference and positions to the manager
2589                 $.ui.ddmanager.droppables[ scope ] = $.ui.ddmanager.droppables[ scope ] || [];
2590                 $.ui.ddmanager.droppables[ scope ].push( this );
2591         },
2593         _splice: function( drop ) {
2594                 var i = 0;
2595                 for ( ; i < drop.length; i++ ) {
2596                         if ( drop[ i ] === this ) {
2597                                 drop.splice( i, 1 );
2598                         }
2599                 }
2600         },
2602         _destroy: function() {
2603                 var drop = $.ui.ddmanager.droppables[ this.options.scope ];
2605                 this._splice( drop );
2607                 this.element.removeClass( "ui-droppable ui-droppable-disabled" );
2608         },
2610         _setOption: function( key, value ) {
2612                 if ( key === "accept" ) {
2613                         this.accept = $.isFunction( value ) ? value : function( d ) {
2614                                 return d.is( value );
2615                         };
2616                 } else if ( key === "scope" ) {
2617                         var drop = $.ui.ddmanager.droppables[ this.options.scope ];
2619                         this._splice( drop );
2620                         this._addToManager( value );
2621                 }
2623                 this._super( key, value );
2624         },
2626         _activate: function( event ) {
2627                 var draggable = $.ui.ddmanager.current;
2628                 if ( this.options.activeClass ) {
2629                         this.element.addClass( this.options.activeClass );
2630                 }
2631                 if ( draggable ){
2632                         this._trigger( "activate", event, this.ui( draggable ) );
2633                 }
2634         },
2636         _deactivate: function( event ) {
2637                 var draggable = $.ui.ddmanager.current;
2638                 if ( this.options.activeClass ) {
2639                         this.element.removeClass( this.options.activeClass );
2640                 }
2641                 if ( draggable ){
2642                         this._trigger( "deactivate", event, this.ui( draggable ) );
2643                 }
2644         },
2646         _over: function( event ) {
2648                 var draggable = $.ui.ddmanager.current;
2650                 // Bail if draggable and droppable are same element
2651                 if ( !draggable || ( draggable.currentItem || draggable.element )[ 0 ] === this.element[ 0 ] ) {
2652                         return;
2653                 }
2655                 if ( this.accept.call( this.element[ 0 ], ( draggable.currentItem || draggable.element ) ) ) {
2656                         if ( this.options.hoverClass ) {
2657                                 this.element.addClass( this.options.hoverClass );
2658                         }
2659                         this._trigger( "over", event, this.ui( draggable ) );
2660                 }
2662         },
2664         _out: function( event ) {
2666                 var draggable = $.ui.ddmanager.current;
2668                 // Bail if draggable and droppable are same element
2669                 if ( !draggable || ( draggable.currentItem || draggable.element )[ 0 ] === this.element[ 0 ] ) {
2670                         return;
2671                 }
2673                 if ( this.accept.call( this.element[ 0 ], ( draggable.currentItem || draggable.element ) ) ) {
2674                         if ( this.options.hoverClass ) {
2675                                 this.element.removeClass( this.options.hoverClass );
2676                         }
2677                         this._trigger( "out", event, this.ui( draggable ) );
2678                 }
2680         },
2682         _drop: function( event, custom ) {
2684                 var draggable = custom || $.ui.ddmanager.current,
2685                         childrenIntersection = false;
2687                 // Bail if draggable and droppable are same element
2688                 if ( !draggable || ( draggable.currentItem || draggable.element )[ 0 ] === this.element[ 0 ] ) {
2689                         return false;
2690                 }
2692                 this.element.find( ":data(ui-droppable)" ).not( ".ui-draggable-dragging" ).each(function() {
2693                         var inst = $( this ).droppable( "instance" );
2694                         if (
2695                                 inst.options.greedy &&
2696                                 !inst.options.disabled &&
2697                                 inst.options.scope === draggable.options.scope &&
2698                                 inst.accept.call( inst.element[ 0 ], ( draggable.currentItem || draggable.element ) ) &&
2699                                 $.ui.intersect( draggable, $.extend( inst, { offset: inst.element.offset() } ), inst.options.tolerance )
2700                         ) { childrenIntersection = true; return false; }
2701                 });
2702                 if ( childrenIntersection ) {
2703                         return false;
2704                 }
2706                 if ( this.accept.call( this.element[ 0 ], ( draggable.currentItem || draggable.element ) ) ) {
2707                         if ( this.options.activeClass ) {
2708                                 this.element.removeClass( this.options.activeClass );
2709                         }
2710                         if ( this.options.hoverClass ) {
2711                                 this.element.removeClass( this.options.hoverClass );
2712                         }
2713                         this._trigger( "drop", event, this.ui( draggable ) );
2714                         return this.element;
2715                 }
2717                 return false;
2719         },
2721         ui: function( c ) {
2722                 return {
2723                         draggable: ( c.currentItem || c.element ),
2724                         helper: c.helper,
2725                         position: c.position,
2726                         offset: c.positionAbs
2727                 };
2728         }
2732 $.ui.intersect = (function() {
2733         function isOverAxis( x, reference, size ) {
2734                 return ( x >= reference ) && ( x < ( reference + size ) );
2735         }
2737         return function( draggable, droppable, toleranceMode ) {
2739                 if ( !droppable.offset ) {
2740                         return false;
2741                 }
2743                 var draggableLeft, draggableTop,
2744                         x1 = ( draggable.positionAbs || draggable.position.absolute ).left,
2745                         y1 = ( draggable.positionAbs || draggable.position.absolute ).top,
2746                         x2 = x1 + draggable.helperProportions.width,
2747                         y2 = y1 + draggable.helperProportions.height,
2748                         l = droppable.offset.left,
2749                         t = droppable.offset.top,
2750                         r = l + droppable.proportions().width,
2751                         b = t + droppable.proportions().height;
2753                 switch ( toleranceMode ) {
2754                 case "fit":
2755                         return ( l <= x1 && x2 <= r && t <= y1 && y2 <= b );
2756                 case "intersect":
2757                         return ( l < x1 + ( draggable.helperProportions.width / 2 ) && // Right Half
2758                                 x2 - ( draggable.helperProportions.width / 2 ) < r && // Left Half
2759                                 t < y1 + ( draggable.helperProportions.height / 2 ) && // Bottom Half
2760                                 y2 - ( draggable.helperProportions.height / 2 ) < b ); // Top Half
2761                 case "pointer":
2762                         draggableLeft = ( ( draggable.positionAbs || draggable.position.absolute ).left + ( draggable.clickOffset || draggable.offset.click ).left );
2763                         draggableTop = ( ( draggable.positionAbs || draggable.position.absolute ).top + ( draggable.clickOffset || draggable.offset.click ).top );
2764                         return isOverAxis( draggableTop, t, droppable.proportions().height ) && isOverAxis( draggableLeft, l, droppable.proportions().width );
2765                 case "touch":
2766                         return (
2767                                 ( y1 >= t && y1 <= b ) || // Top edge touching
2768                                 ( y2 >= t && y2 <= b ) || // Bottom edge touching
2769                                 ( y1 < t && y2 > b ) // Surrounded vertically
2770                         ) && (
2771                                 ( x1 >= l && x1 <= r ) || // Left edge touching
2772                                 ( x2 >= l && x2 <= r ) || // Right edge touching
2773                                 ( x1 < l && x2 > r ) // Surrounded horizontally
2774                         );
2775                 default:
2776                         return false;
2777                 }
2778         };
2779 })();
2782         This manager tracks offsets of draggables and droppables
2784 $.ui.ddmanager = {
2785         current: null,
2786         droppables: { "default": [] },
2787         prepareOffsets: function( t, event ) {
2789                 var i, j,
2790                         m = $.ui.ddmanager.droppables[ t.options.scope ] || [],
2791                         type = event ? event.type : null, // workaround for #2317
2792                         list = ( t.currentItem || t.element ).find( ":data(ui-droppable)" ).addBack();
2794                 droppablesLoop: for ( i = 0; i < m.length; i++ ) {
2796                         // No disabled and non-accepted
2797                         if ( m[ i ].options.disabled || ( t && !m[ i ].accept.call( m[ i ].element[ 0 ], ( t.currentItem || t.element ) ) ) ) {
2798                                 continue;
2799                         }
2801                         // Filter out elements in the current dragged item
2802                         for ( j = 0; j < list.length; j++ ) {
2803                                 if ( list[ j ] === m[ i ].element[ 0 ] ) {
2804                                         m[ i ].proportions().height = 0;
2805                                         continue droppablesLoop;
2806                                 }
2807                         }
2809                         m[ i ].visible = m[ i ].element.css( "display" ) !== "none";
2810                         if ( !m[ i ].visible ) {
2811                                 continue;
2812                         }
2814                         // Activate the droppable if used directly from draggables
2815                         if ( type === "mousedown" ) {
2816                                 m[ i ]._activate.call( m[ i ], event );
2817                         }
2819                         m[ i ].offset = m[ i ].element.offset();
2820                         m[ i ].proportions({ width: m[ i ].element[ 0 ].offsetWidth, height: m[ i ].element[ 0 ].offsetHeight });
2822                 }
2824         },
2825         drop: function( draggable, event ) {
2827                 var dropped = false;
2828                 // Create a copy of the droppables in case the list changes during the drop (#9116)
2829                 $.each( ( $.ui.ddmanager.droppables[ draggable.options.scope ] || [] ).slice(), function() {
2831                         if ( !this.options ) {
2832                                 return;
2833                         }
2834                         if ( !this.options.disabled && this.visible && $.ui.intersect( draggable, this, this.options.tolerance ) ) {
2835                                 dropped = this._drop.call( this, event ) || dropped;
2836                         }
2838                         if ( !this.options.disabled && this.visible && this.accept.call( this.element[ 0 ], ( draggable.currentItem || draggable.element ) ) ) {
2839                                 this.isout = true;
2840                                 this.isover = false;
2841                                 this._deactivate.call( this, event );
2842                         }
2844                 });
2845                 return dropped;
2847         },
2848         dragStart: function( draggable, event ) {
2849                 // Listen for scrolling so that if the dragging causes scrolling the position of the droppables can be recalculated (see #5003)
2850                 draggable.element.parentsUntil( "body" ).bind( "scroll.droppable", function() {
2851                         if ( !draggable.options.refreshPositions ) {
2852                                 $.ui.ddmanager.prepareOffsets( draggable, event );
2853                         }
2854                 });
2855         },
2856         drag: function( draggable, event ) {
2858                 // If you have a highly dynamic page, you might try this option. It renders positions every time you move the mouse.
2859                 if ( draggable.options.refreshPositions ) {
2860                         $.ui.ddmanager.prepareOffsets( draggable, event );
2861                 }
2863                 // Run through all droppables and check their positions based on specific tolerance options
2864                 $.each( $.ui.ddmanager.droppables[ draggable.options.scope ] || [], function() {
2866                         if ( this.options.disabled || this.greedyChild || !this.visible ) {
2867                                 return;
2868                         }
2870                         var parentInstance, scope, parent,
2871                                 intersects = $.ui.intersect( draggable, this, this.options.tolerance ),
2872                                 c = !intersects && this.isover ? "isout" : ( intersects && !this.isover ? "isover" : null );
2873                         if ( !c ) {
2874                                 return;
2875                         }
2877                         if ( this.options.greedy ) {
2878                                 // find droppable parents with same scope
2879                                 scope = this.options.scope;
2880                                 parent = this.element.parents( ":data(ui-droppable)" ).filter(function() {
2881                                         return $( this ).droppable( "instance" ).options.scope === scope;
2882                                 });
2884                                 if ( parent.length ) {
2885                                         parentInstance = $( parent[ 0 ] ).droppable( "instance" );
2886                                         parentInstance.greedyChild = ( c === "isover" );
2887                                 }
2888                         }
2890                         // we just moved into a greedy child
2891                         if ( parentInstance && c === "isover" ) {
2892                                 parentInstance.isover = false;
2893                                 parentInstance.isout = true;
2894                                 parentInstance._out.call( parentInstance, event );
2895                         }
2897                         this[ c ] = true;
2898                         this[c === "isout" ? "isover" : "isout"] = false;
2899                         this[c === "isover" ? "_over" : "_out"].call( this, event );
2901                         // we just moved out of a greedy child
2902                         if ( parentInstance && c === "isout" ) {
2903                                 parentInstance.isout = false;
2904                                 parentInstance.isover = true;
2905                                 parentInstance._over.call( parentInstance, event );
2906                         }
2907                 });
2909         },
2910         dragStop: function( draggable, event ) {
2911                 draggable.element.parentsUntil( "body" ).unbind( "scroll.droppable" );
2912                 // Call prepareOffsets one final time since IE does not fire return scroll events when overflow was caused by drag (see #5003)
2913                 if ( !draggable.options.refreshPositions ) {
2914                         $.ui.ddmanager.prepareOffsets( draggable, event );
2915                 }
2916         }
2919 var droppable = $.ui.droppable;
2923  * jQuery UI Resizable 1.11.0
2924  * http://jqueryui.com
2926  * Copyright 2014 jQuery Foundation and other contributors
2927  * Released under the MIT license.
2928  * http://jquery.org/license
2930  * http://api.jqueryui.com/resizable/
2931  */
2934 $.widget("ui.resizable", $.ui.mouse, {
2935         version: "1.11.0",
2936         widgetEventPrefix: "resize",
2937         options: {
2938                 alsoResize: false,
2939                 animate: false,
2940                 animateDuration: "slow",
2941                 animateEasing: "swing",
2942                 aspectRatio: false,
2943                 autoHide: false,
2944                 containment: false,
2945                 ghost: false,
2946                 grid: false,
2947                 handles: "e,s,se",
2948                 helper: false,
2949                 maxHeight: null,
2950                 maxWidth: null,
2951                 minHeight: 10,
2952                 minWidth: 10,
2953                 // See #7960
2954                 zIndex: 90,
2956                 // callbacks
2957                 resize: null,
2958                 start: null,
2959                 stop: null
2960         },
2962         _num: function( value ) {
2963                 return parseInt( value, 10 ) || 0;
2964         },
2966         _isNumber: function( value ) {
2967                 return !isNaN( parseInt( value , 10 ) );
2968         },
2970         _hasScroll: function( el, a ) {
2972                 if ( $( el ).css( "overflow" ) === "hidden") {
2973                         return false;
2974                 }
2976                 var scroll = ( a && a === "left" ) ? "scrollLeft" : "scrollTop",
2977                         has = false;
2979                 if ( el[ scroll ] > 0 ) {
2980                         return true;
2981                 }
2983                 // TODO: determine which cases actually cause this to happen
2984                 // if the element doesn't have the scroll set, see if it's possible to
2985                 // set the scroll
2986                 el[ scroll ] = 1;
2987                 has = ( el[ scroll ] > 0 );
2988                 el[ scroll ] = 0;
2989                 return has;
2990         },
2992         _create: function() {
2994                 var n, i, handle, axis, hname,
2995                         that = this,
2996                         o = this.options;
2997                 this.element.addClass("ui-resizable");
2999                 $.extend(this, {
3000                         _aspectRatio: !!(o.aspectRatio),
3001                         aspectRatio: o.aspectRatio,
3002                         originalElement: this.element,
3003                         _proportionallyResizeElements: [],
3004                         _helper: o.helper || o.ghost || o.animate ? o.helper || "ui-resizable-helper" : null
3005                 });
3007                 // Wrap the element if it cannot hold child nodes
3008                 if(this.element[0].nodeName.match(/canvas|textarea|input|select|button|img/i)) {
3010                         this.element.wrap(
3011                                 $("<div class='ui-wrapper' style='overflow: hidden;'></div>").css({
3012                                         position: this.element.css("position"),
3013                                         width: this.element.outerWidth(),
3014                                         height: this.element.outerHeight(),
3015                                         top: this.element.css("top"),
3016                                         left: this.element.css("left")
3017                                 })
3018                         );
3020                         this.element = this.element.parent().data(
3021                                 "ui-resizable", this.element.resizable( "instance" )
3022                         );
3024                         this.elementIsWrapper = true;
3026                         this.element.css({ marginLeft: this.originalElement.css("marginLeft"), marginTop: this.originalElement.css("marginTop"), marginRight: this.originalElement.css("marginRight"), marginBottom: this.originalElement.css("marginBottom") });
3027                         this.originalElement.css({ marginLeft: 0, marginTop: 0, marginRight: 0, marginBottom: 0});
3028                         // support: Safari
3029                         // Prevent Safari textarea resize
3030                         this.originalResizeStyle = this.originalElement.css("resize");
3031                         this.originalElement.css("resize", "none");
3033                         this._proportionallyResizeElements.push(this.originalElement.css({ position: "static", zoom: 1, display: "block" }));
3035                         // support: IE9
3036                         // avoid IE jump (hard set the margin)
3037                         this.originalElement.css({ margin: this.originalElement.css("margin") });
3039                         this._proportionallyResize();
3040                 }
3042                 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" });
3043                 if(this.handles.constructor === String) {
3045                         if ( this.handles === "all") {
3046                                 this.handles = "n,e,s,w,se,sw,ne,nw";
3047                         }
3049                         n = this.handles.split(",");
3050                         this.handles = {};
3052                         for(i = 0; i < n.length; i++) {
3054                                 handle = $.trim(n[i]);
3055                                 hname = "ui-resizable-"+handle;
3056                                 axis = $("<div class='ui-resizable-handle " + hname + "'></div>");
3058                                 axis.css({ zIndex: o.zIndex });
3060                                 // TODO : What's going on here?
3061                                 if ("se" === handle) {
3062                                         axis.addClass("ui-icon ui-icon-gripsmall-diagonal-se");
3063                                 }
3065                                 this.handles[handle] = ".ui-resizable-"+handle;
3066                                 this.element.append(axis);
3067                         }
3069                 }
3071                 this._renderAxis = function(target) {
3073                         var i, axis, padPos, padWrapper;
3075                         target = target || this.element;
3077                         for(i in this.handles) {
3079                                 if(this.handles[i].constructor === String) {
3080                                         this.handles[i] = this.element.children( this.handles[ i ] ).first().show();
3081                                 }
3083                                 if (this.elementIsWrapper && this.originalElement[0].nodeName.match(/textarea|input|select|button/i)) {
3085                                         axis = $(this.handles[i], this.element);
3087                                         padWrapper = /sw|ne|nw|se|n|s/.test(i) ? axis.outerHeight() : axis.outerWidth();
3089                                         padPos = [ "padding",
3090                                                 /ne|nw|n/.test(i) ? "Top" :
3091                                                 /se|sw|s/.test(i) ? "Bottom" :
3092                                                 /^e$/.test(i) ? "Right" : "Left" ].join("");
3094                                         target.css(padPos, padWrapper);
3096                                         this._proportionallyResize();
3098                                 }
3100                                 // TODO: What's that good for? There's not anything to be executed left
3101                                 if(!$(this.handles[i]).length) {
3102                                         continue;
3103                                 }
3104                         }
3105                 };
3107                 // TODO: make renderAxis a prototype function
3108                 this._renderAxis(this.element);
3110                 this._handles = $(".ui-resizable-handle", this.element)
3111                         .disableSelection();
3113                 this._handles.mouseover(function() {
3114                         if (!that.resizing) {
3115                                 if (this.className) {
3116                                         axis = this.className.match(/ui-resizable-(se|sw|ne|nw|n|e|s|w)/i);
3117                                 }
3118                                 that.axis = axis && axis[1] ? axis[1] : "se";
3119                         }
3120                 });
3122                 if (o.autoHide) {
3123                         this._handles.hide();
3124                         $(this.element)
3125                                 .addClass("ui-resizable-autohide")
3126                                 .mouseenter(function() {
3127                                         if (o.disabled) {
3128                                                 return;
3129                                         }
3130                                         $(this).removeClass("ui-resizable-autohide");
3131                                         that._handles.show();
3132                                 })
3133                                 .mouseleave(function(){
3134                                         if (o.disabled) {
3135                                                 return;
3136                                         }
3137                                         if (!that.resizing) {
3138                                                 $(this).addClass("ui-resizable-autohide");
3139                                                 that._handles.hide();
3140                                         }
3141                                 });
3142                 }
3144                 this._mouseInit();
3146         },
3148         _destroy: function() {
3150                 this._mouseDestroy();
3152                 var wrapper,
3153                         _destroy = function(exp) {
3154                                 $(exp).removeClass("ui-resizable ui-resizable-disabled ui-resizable-resizing")
3155                                         .removeData("resizable").removeData("ui-resizable").unbind(".resizable").find(".ui-resizable-handle").remove();
3156                         };
3158                 // TODO: Unwrap at same DOM position
3159                 if (this.elementIsWrapper) {
3160                         _destroy(this.element);
3161                         wrapper = this.element;
3162                         this.originalElement.css({
3163                                 position: wrapper.css("position"),
3164                                 width: wrapper.outerWidth(),
3165                                 height: wrapper.outerHeight(),
3166                                 top: wrapper.css("top"),
3167                                 left: wrapper.css("left")
3168                         }).insertAfter( wrapper );
3169                         wrapper.remove();
3170                 }
3172                 this.originalElement.css("resize", this.originalResizeStyle);
3173                 _destroy(this.originalElement);
3175                 return this;
3176         },
3178         _mouseCapture: function(event) {
3179                 var i, handle,
3180                         capture = false;
3182                 for (i in this.handles) {
3183                         handle = $(this.handles[i])[0];
3184                         if (handle === event.target || $.contains(handle, event.target)) {
3185                                 capture = true;
3186                         }
3187                 }
3189                 return !this.options.disabled && capture;
3190         },
3192         _mouseStart: function(event) {
3194                 var curleft, curtop, cursor,
3195                         o = this.options,
3196                         el = this.element;
3198                 this.resizing = true;
3200                 this._renderProxy();
3202                 curleft = this._num(this.helper.css("left"));
3203                 curtop = this._num(this.helper.css("top"));
3205                 if (o.containment) {
3206                         curleft += $(o.containment).scrollLeft() || 0;
3207                         curtop += $(o.containment).scrollTop() || 0;
3208                 }
3210                 this.offset = this.helper.offset();
3211                 this.position = { left: curleft, top: curtop };
3212                 this.size = this._helper ? { width: this.helper.width(), height: this.helper.height() } : { width: el.width(), height: el.height() };
3213                 this.originalSize = this._helper ? { width: el.outerWidth(), height: el.outerHeight() } : { width: el.width(), height: el.height() };
3214                 this.originalPosition = { left: curleft, top: curtop };
3215                 this.sizeDiff = { width: el.outerWidth() - el.width(), height: el.outerHeight() - el.height() };
3216                 this.originalMousePosition = { left: event.pageX, top: event.pageY };
3218                 this.aspectRatio = (typeof o.aspectRatio === "number") ? o.aspectRatio : ((this.originalSize.width / this.originalSize.height) || 1);
3220                 cursor = $(".ui-resizable-" + this.axis).css("cursor");
3221                 $("body").css("cursor", cursor === "auto" ? this.axis + "-resize" : cursor);
3223                 el.addClass("ui-resizable-resizing");
3224                 this._propagate("start", event);
3225                 return true;
3226         },
3228         _mouseDrag: function(event) {
3230                 var data,
3231                         el = this.helper, props = {},
3232                         smp = this.originalMousePosition,
3233                         a = this.axis,
3234                         dx = (event.pageX-smp.left)||0,
3235                         dy = (event.pageY-smp.top)||0,
3236                         trigger = this._change[a];
3238                 this.prevPosition = {
3239                         top: this.position.top,
3240                         left: this.position.left
3241                 };
3242                 this.prevSize = {
3243                         width: this.size.width,
3244                         height: this.size.height
3245                 };
3247                 if (!trigger) {
3248                         return false;
3249                 }
3251                 data = trigger.apply(this, [event, dx, dy]);
3253                 this._updateVirtualBoundaries(event.shiftKey);
3254                 if (this._aspectRatio || event.shiftKey) {
3255                         data = this._updateRatio(data, event);
3256                 }
3258                 data = this._respectSize(data, event);
3260                 this._updateCache(data);
3262                 this._propagate("resize", event);
3264                 if ( this.position.top !== this.prevPosition.top ) {
3265                         props.top = this.position.top + "px";
3266                 }
3267                 if ( this.position.left !== this.prevPosition.left ) {
3268                         props.left = this.position.left + "px";
3269                 }
3270                 if ( this.size.width !== this.prevSize.width ) {
3271                         props.width = this.size.width + "px";
3272                 }
3273                 if ( this.size.height !== this.prevSize.height ) {
3274                         props.height = this.size.height + "px";
3275                 }
3276                 el.css( props );
3278                 if ( !this._helper && this._proportionallyResizeElements.length ) {
3279                         this._proportionallyResize();
3280                 }
3282                 if ( !$.isEmptyObject( props ) ) {
3283                         this._trigger( "resize", event, this.ui() );
3284                 }
3286                 return false;
3287         },
3289         _mouseStop: function(event) {
3291                 this.resizing = false;
3292                 var pr, ista, soffseth, soffsetw, s, left, top,
3293                         o = this.options, that = this;
3295                 if(this._helper) {
3297                         pr = this._proportionallyResizeElements;
3298                         ista = pr.length && (/textarea/i).test(pr[0].nodeName);
3299                         soffseth = ista && this._hasScroll(pr[0], "left") /* TODO - jump height */ ? 0 : that.sizeDiff.height;
3300                         soffsetw = ista ? 0 : that.sizeDiff.width;
3302                         s = { width: (that.helper.width()  - soffsetw), height: (that.helper.height() - soffseth) };
3303                         left = (parseInt(that.element.css("left"), 10) + (that.position.left - that.originalPosition.left)) || null;
3304                         top = (parseInt(that.element.css("top"), 10) + (that.position.top - that.originalPosition.top)) || null;
3306                         if (!o.animate) {
3307                                 this.element.css($.extend(s, { top: top, left: left }));
3308                         }
3310                         that.helper.height(that.size.height);
3311                         that.helper.width(that.size.width);
3313                         if (this._helper && !o.animate) {
3314                                 this._proportionallyResize();
3315                         }
3316                 }
3318                 $("body").css("cursor", "auto");
3320                 this.element.removeClass("ui-resizable-resizing");
3322                 this._propagate("stop", event);
3324                 if (this._helper) {
3325                         this.helper.remove();
3326                 }
3328                 return false;
3330         },
3332         _updateVirtualBoundaries: function(forceAspectRatio) {
3333                 var pMinWidth, pMaxWidth, pMinHeight, pMaxHeight, b,
3334                         o = this.options;
3336                 b = {
3337                         minWidth: this._isNumber(o.minWidth) ? o.minWidth : 0,
3338                         maxWidth: this._isNumber(o.maxWidth) ? o.maxWidth : Infinity,
3339                         minHeight: this._isNumber(o.minHeight) ? o.minHeight : 0,
3340                         maxHeight: this._isNumber(o.maxHeight) ? o.maxHeight : Infinity
3341                 };
3343                 if(this._aspectRatio || forceAspectRatio) {
3344                         pMinWidth = b.minHeight * this.aspectRatio;
3345                         pMinHeight = b.minWidth / this.aspectRatio;
3346                         pMaxWidth = b.maxHeight * this.aspectRatio;
3347                         pMaxHeight = b.maxWidth / this.aspectRatio;
3349                         if(pMinWidth > b.minWidth) {
3350                                 b.minWidth = pMinWidth;
3351                         }
3352                         if(pMinHeight > b.minHeight) {
3353                                 b.minHeight = pMinHeight;
3354                         }
3355                         if(pMaxWidth < b.maxWidth) {
3356                                 b.maxWidth = pMaxWidth;
3357                         }
3358                         if(pMaxHeight < b.maxHeight) {
3359                                 b.maxHeight = pMaxHeight;
3360                         }
3361                 }
3362                 this._vBoundaries = b;
3363         },
3365         _updateCache: function(data) {
3366                 this.offset = this.helper.offset();
3367                 if (this._isNumber(data.left)) {
3368                         this.position.left = data.left;
3369                 }
3370                 if (this._isNumber(data.top)) {
3371                         this.position.top = data.top;
3372                 }
3373                 if (this._isNumber(data.height)) {
3374                         this.size.height = data.height;
3375                 }
3376                 if (this._isNumber(data.width)) {
3377                         this.size.width = data.width;
3378                 }
3379         },
3381         _updateRatio: function( data ) {
3383                 var cpos = this.position,
3384                         csize = this.size,
3385                         a = this.axis;
3387                 if (this._isNumber(data.height)) {
3388                         data.width = (data.height * this.aspectRatio);
3389                 } else if (this._isNumber(data.width)) {
3390                         data.height = (data.width / this.aspectRatio);
3391                 }
3393                 if (a === "sw") {
3394                         data.left = cpos.left + (csize.width - data.width);
3395                         data.top = null;
3396                 }
3397                 if (a === "nw") {
3398                         data.top = cpos.top + (csize.height - data.height);
3399                         data.left = cpos.left + (csize.width - data.width);
3400                 }
3402                 return data;
3403         },
3405         _respectSize: function( data ) {
3407                 var o = this._vBoundaries,
3408                         a = this.axis,
3409                         ismaxw = this._isNumber(data.width) && o.maxWidth && (o.maxWidth < data.width), ismaxh = this._isNumber(data.height) && o.maxHeight && (o.maxHeight < data.height),
3410                         isminw = this._isNumber(data.width) && o.minWidth && (o.minWidth > data.width), isminh = this._isNumber(data.height) && o.minHeight && (o.minHeight > data.height),
3411                         dw = this.originalPosition.left + this.originalSize.width,
3412                         dh = this.position.top + this.size.height,
3413                         cw = /sw|nw|w/.test(a), ch = /nw|ne|n/.test(a);
3414                 if (isminw) {
3415                         data.width = o.minWidth;
3416                 }
3417                 if (isminh) {
3418                         data.height = o.minHeight;
3419                 }
3420                 if (ismaxw) {
3421                         data.width = o.maxWidth;
3422                 }
3423                 if (ismaxh) {
3424                         data.height = o.maxHeight;
3425                 }
3427                 if (isminw && cw) {
3428                         data.left = dw - o.minWidth;
3429                 }
3430                 if (ismaxw && cw) {
3431                         data.left = dw - o.maxWidth;
3432                 }
3433                 if (isminh && ch) {
3434                         data.top = dh - o.minHeight;
3435                 }
3436                 if (ismaxh && ch) {
3437                         data.top = dh - o.maxHeight;
3438                 }
3440                 // Fixing jump error on top/left - bug #2330
3441                 if (!data.width && !data.height && !data.left && data.top) {
3442                         data.top = null;
3443                 } else if (!data.width && !data.height && !data.top && data.left) {
3444                         data.left = null;
3445                 }
3447                 return data;
3448         },
3450         _proportionallyResize: function() {
3452                 if (!this._proportionallyResizeElements.length) {
3453                         return;
3454                 }
3456                 var i, j, borders, paddings, prel,
3457                         element = this.helper || this.element;
3459                 for ( i=0; i < this._proportionallyResizeElements.length; i++) {
3461                         prel = this._proportionallyResizeElements[i];
3463                         if (!this.borderDif) {
3464                                 this.borderDif = [];
3465                                 borders = [prel.css("borderTopWidth"), prel.css("borderRightWidth"), prel.css("borderBottomWidth"), prel.css("borderLeftWidth")];
3466                                 paddings = [prel.css("paddingTop"), prel.css("paddingRight"), prel.css("paddingBottom"), prel.css("paddingLeft")];
3468                                 for ( j = 0; j < borders.length; j++ ) {
3469                                         this.borderDif[ j ] = ( parseInt( borders[ j ], 10 ) || 0 ) + ( parseInt( paddings[ j ], 10 ) || 0 );
3470                                 }
3471                         }
3473                         prel.css({
3474                                 height: (element.height() - this.borderDif[0] - this.borderDif[2]) || 0,
3475                                 width: (element.width() - this.borderDif[1] - this.borderDif[3]) || 0
3476                         });
3478                 }
3480         },
3482         _renderProxy: function() {
3484                 var el = this.element, o = this.options;
3485                 this.elementOffset = el.offset();
3487                 if(this._helper) {
3489                         this.helper = this.helper || $("<div style='overflow:hidden;'></div>");
3491                         this.helper.addClass(this._helper).css({
3492                                 width: this.element.outerWidth() - 1,
3493                                 height: this.element.outerHeight() - 1,
3494                                 position: "absolute",
3495                                 left: this.elementOffset.left +"px",
3496                                 top: this.elementOffset.top +"px",
3497                                 zIndex: ++o.zIndex //TODO: Don't modify option
3498                         });
3500                         this.helper
3501                                 .appendTo("body")
3502                                 .disableSelection();
3504                 } else {
3505                         this.helper = this.element;
3506                 }
3508         },
3510         _change: {
3511                 e: function(event, dx) {
3512                         return { width: this.originalSize.width + dx };
3513                 },
3514                 w: function(event, dx) {
3515                         var cs = this.originalSize, sp = this.originalPosition;
3516                         return { left: sp.left + dx, width: cs.width - dx };
3517                 },
3518                 n: function(event, dx, dy) {
3519                         var cs = this.originalSize, sp = this.originalPosition;
3520                         return { top: sp.top + dy, height: cs.height - dy };
3521                 },
3522                 s: function(event, dx, dy) {
3523                         return { height: this.originalSize.height + dy };
3524                 },
3525                 se: function(event, dx, dy) {
3526                         return $.extend(this._change.s.apply(this, arguments), this._change.e.apply(this, [event, dx, dy]));
3527                 },
3528                 sw: function(event, dx, dy) {
3529                         return $.extend(this._change.s.apply(this, arguments), this._change.w.apply(this, [event, dx, dy]));
3530                 },
3531                 ne: function(event, dx, dy) {
3532                         return $.extend(this._change.n.apply(this, arguments), this._change.e.apply(this, [event, dx, dy]));
3533                 },
3534                 nw: function(event, dx, dy) {
3535                         return $.extend(this._change.n.apply(this, arguments), this._change.w.apply(this, [event, dx, dy]));
3536                 }
3537         },
3539         _propagate: function(n, event) {
3540                 $.ui.plugin.call(this, n, [event, this.ui()]);
3541                 (n !== "resize" && this._trigger(n, event, this.ui()));
3542         },
3544         plugins: {},
3546         ui: function() {
3547                 return {
3548                         originalElement: this.originalElement,
3549                         element: this.element,
3550                         helper: this.helper,
3551                         position: this.position,
3552                         size: this.size,
3553                         originalSize: this.originalSize,
3554                         originalPosition: this.originalPosition,
3555                         prevSize: this.prevSize,
3556                         prevPosition: this.prevPosition
3557                 };
3558         }
3563  * Resizable Extensions
3564  */
3566 $.ui.plugin.add("resizable", "animate", {
3568         stop: function( event ) {
3569                 var that = $(this).resizable( "instance" ),
3570                         o = that.options,
3571                         pr = that._proportionallyResizeElements,
3572                         ista = pr.length && (/textarea/i).test(pr[0].nodeName),
3573                         soffseth = ista && that._hasScroll(pr[0], "left") /* TODO - jump height */ ? 0 : that.sizeDiff.height,
3574                         soffsetw = ista ? 0 : that.sizeDiff.width,
3575                         style = { width: (that.size.width - soffsetw), height: (that.size.height - soffseth) },
3576                         left = (parseInt(that.element.css("left"), 10) + (that.position.left - that.originalPosition.left)) || null,
3577                         top = (parseInt(that.element.css("top"), 10) + (that.position.top - that.originalPosition.top)) || null;
3579                 that.element.animate(
3580                         $.extend(style, top && left ? { top: top, left: left } : {}), {
3581                                 duration: o.animateDuration,
3582                                 easing: o.animateEasing,
3583                                 step: function() {
3585                                         var data = {
3586                                                 width: parseInt(that.element.css("width"), 10),
3587                                                 height: parseInt(that.element.css("height"), 10),
3588                                                 top: parseInt(that.element.css("top"), 10),
3589                                                 left: parseInt(that.element.css("left"), 10)
3590                                         };
3592                                         if (pr && pr.length) {
3593                                                 $(pr[0]).css({ width: data.width, height: data.height });
3594                                         }
3596                                         // propagating resize, and updating values for each animation step
3597                                         that._updateCache(data);
3598                                         that._propagate("resize", event);
3600                                 }
3601                         }
3602                 );
3603         }
3607 $.ui.plugin.add( "resizable", "containment", {
3609         start: function() {
3610                 var element, p, co, ch, cw, width, height,
3611                         that = $( this ).resizable( "instance" ),
3612                         o = that.options,
3613                         el = that.element,
3614                         oc = o.containment,
3615                         ce = ( oc instanceof $ ) ? oc.get( 0 ) : ( /parent/.test( oc ) ) ? el.parent().get( 0 ) : oc;
3617                 if ( !ce ) {
3618                         return;
3619                 }
3621                 that.containerElement = $( ce );
3623                 if ( /document/.test( oc ) || oc === document ) {
3624                         that.containerOffset = {
3625                                 left: 0,
3626                                 top: 0
3627                         };
3628                         that.containerPosition = {
3629                                 left: 0,
3630                                 top: 0
3631                         };
3633                         that.parentData = {
3634                                 element: $( document ),
3635                                 left: 0,
3636                                 top: 0,
3637                                 width: $( document ).width(),
3638                                 height: $( document ).height() || document.body.parentNode.scrollHeight
3639                         };
3640                 } else {
3641                         element = $( ce );
3642                         p = [];
3643                         $([ "Top", "Right", "Left", "Bottom" ]).each(function( i, name ) {
3644                                 p[ i ] = that._num( element.css( "padding" + name ) );
3645                         });
3647                         that.containerOffset = element.offset();
3648                         that.containerPosition = element.position();
3649                         that.containerSize = {
3650                                 height: ( element.innerHeight() - p[ 3 ] ),
3651                                 width: ( element.innerWidth() - p[ 1 ] )
3652                         };
3654                         co = that.containerOffset;
3655                         ch = that.containerSize.height;
3656                         cw = that.containerSize.width;
3657                         width = ( that._hasScroll ( ce, "left" ) ? ce.scrollWidth : cw );
3658                         height = ( that._hasScroll ( ce ) ? ce.scrollHeight : ch ) ;
3660                         that.parentData = {
3661                                 element: ce,
3662                                 left: co.left,
3663                                 top: co.top,
3664                                 width: width,
3665                                 height: height
3666                         };
3667                 }
3668         },
3670         resize: function( event, ui ) {
3671                 var woset, hoset, isParent, isOffsetRelative,
3672                         that = $( this ).resizable( "instance" ),
3673                         o = that.options,
3674                         co = that.containerOffset,
3675                         cp = that.position,
3676                         pRatio = that._aspectRatio || event.shiftKey,
3677                         cop = {
3678                                 top: 0,
3679                                 left: 0
3680                         },
3681                         ce = that.containerElement,
3682                         continueResize = true;
3684                 if ( ce[ 0 ] !== document && ( /static/ ).test( ce.css( "position" ) ) ) {
3685                         cop = co;
3686                 }
3688                 if ( cp.left < ( that._helper ? co.left : 0 ) ) {
3689                         that.size.width = that.size.width + ( that._helper ? ( that.position.left - co.left ) : ( that.position.left - cop.left ) );
3690                         if ( pRatio ) {
3691                                 that.size.height = that.size.width / that.aspectRatio;
3692                                 continueResize = false;
3693                         }
3694                         that.position.left = o.helper ? co.left : 0;
3695                 }
3697                 if ( cp.top < ( that._helper ? co.top : 0 ) ) {
3698                         that.size.height = that.size.height + ( that._helper ? ( that.position.top - co.top ) : that.position.top );
3699                         if ( pRatio ) {
3700                                 that.size.width = that.size.height * that.aspectRatio;
3701                                 continueResize = false;
3702                         }
3703                         that.position.top = that._helper ? co.top : 0;
3704                 }
3706                 that.offset.left = that.parentData.left + that.position.left;
3707                 that.offset.top = that.parentData.top + that.position.top;
3709                 woset = Math.abs( ( that._helper ? that.offset.left - cop.left : ( that.offset.left - co.left ) ) + that.sizeDiff.width );
3710                 hoset = Math.abs( ( that._helper ? that.offset.top - cop.top : ( that.offset.top - co.top ) ) + that.sizeDiff.height );
3712                 isParent = that.containerElement.get( 0 ) === that.element.parent().get( 0 );
3713                 isOffsetRelative = /relative|absolute/.test( that.containerElement.css( "position" ) );
3715                 if ( isParent && isOffsetRelative ) {
3716                         woset -= Math.abs( that.parentData.left );
3717                 }
3719                 if ( woset + that.size.width >= that.parentData.width ) {
3720                         that.size.width = that.parentData.width - woset;
3721                         if ( pRatio ) {
3722                                 that.size.height = that.size.width / that.aspectRatio;
3723                                 continueResize = false;
3724                         }
3725                 }
3727                 if ( hoset + that.size.height >= that.parentData.height ) {
3728                         that.size.height = that.parentData.height - hoset;
3729                         if ( pRatio ) {
3730                                 that.size.width = that.size.height * that.aspectRatio;
3731                                 continueResize = false;
3732                         }
3733                 }
3735                 if ( !continueResize ){
3736                         that.position.left = ui.prevPosition.left;
3737                         that.position.top = ui.prevPosition.top;
3738                         that.size.width = ui.prevSize.width;
3739                         that.size.height = ui.prevSize.height;
3740                 }
3741         },
3743         stop: function(){
3744                 var that = $( this ).resizable( "instance" ),
3745                         o = that.options,
3746                         co = that.containerOffset,
3747                         cop = that.containerPosition,
3748                         ce = that.containerElement,
3749                         helper = $( that.helper ),
3750                         ho = helper.offset(),
3751                         w = helper.outerWidth() - that.sizeDiff.width,
3752                         h = helper.outerHeight() - that.sizeDiff.height;
3754                 if ( that._helper && !o.animate && ( /relative/ ).test( ce.css( "position" ) ) ) {
3755                         $( this ).css({
3756                                 left: ho.left - cop.left - co.left,
3757                                 width: w,
3758                                 height: h
3759                         });
3760                 }
3762                 if ( that._helper && !o.animate && ( /static/ ).test( ce.css( "position" ) ) ) {
3763                         $( this ).css({
3764                                 left: ho.left - cop.left - co.left,
3765                                 width: w,
3766                                 height: h
3767                         });
3768                 }
3769         }
3772 $.ui.plugin.add("resizable", "alsoResize", {
3774         start: function () {
3775                 var that = $(this).resizable( "instance" ),
3776                         o = that.options,
3777                         _store = function (exp) {
3778                                 $(exp).each(function() {
3779                                         var el = $(this);
3780                                         el.data("ui-resizable-alsoresize", {
3781                                                 width: parseInt(el.width(), 10), height: parseInt(el.height(), 10),
3782                                                 left: parseInt(el.css("left"), 10), top: parseInt(el.css("top"), 10)
3783                                         });
3784                                 });
3785                         };
3787                 if (typeof(o.alsoResize) === "object" && !o.alsoResize.parentNode) {
3788                         if (o.alsoResize.length) { o.alsoResize = o.alsoResize[0]; _store(o.alsoResize); }
3789                         else { $.each(o.alsoResize, function (exp) { _store(exp); }); }
3790                 }else{
3791                         _store(o.alsoResize);
3792                 }
3793         },
3795         resize: function (event, ui) {
3796                 var that = $(this).resizable( "instance" ),
3797                         o = that.options,
3798                         os = that.originalSize,
3799                         op = that.originalPosition,
3800                         delta = {
3801                                 height: (that.size.height - os.height) || 0, width: (that.size.width - os.width) || 0,
3802                                 top: (that.position.top - op.top) || 0, left: (that.position.left - op.left) || 0
3803                         },
3805                         _alsoResize = function (exp, c) {
3806                                 $(exp).each(function() {
3807                                         var el = $(this), start = $(this).data("ui-resizable-alsoresize"), style = {},
3808                                                 css = c && c.length ? c : el.parents(ui.originalElement[0]).length ? ["width", "height"] : ["width", "height", "top", "left"];
3810                                         $.each(css, function (i, prop) {
3811                                                 var sum = (start[prop]||0) + (delta[prop]||0);
3812                                                 if (sum && sum >= 0) {
3813                                                         style[prop] = sum || null;
3814                                                 }
3815                                         });
3817                                         el.css(style);
3818                                 });
3819                         };
3821                 if (typeof(o.alsoResize) === "object" && !o.alsoResize.nodeType) {
3822                         $.each(o.alsoResize, function (exp, c) { _alsoResize(exp, c); });
3823                 }else{
3824                         _alsoResize(o.alsoResize);
3825                 }
3826         },
3828         stop: function () {
3829                 $(this).removeData("resizable-alsoresize");
3830         }
3833 $.ui.plugin.add("resizable", "ghost", {
3835         start: function() {
3837                 var that = $(this).resizable( "instance" ), o = that.options, cs = that.size;
3839                 that.ghost = that.originalElement.clone();
3840                 that.ghost
3841                         .css({ opacity: 0.25, display: "block", position: "relative", height: cs.height, width: cs.width, margin: 0, left: 0, top: 0 })
3842                         .addClass("ui-resizable-ghost")
3843                         .addClass(typeof o.ghost === "string" ? o.ghost : "");
3845                 that.ghost.appendTo(that.helper);
3847         },
3849         resize: function(){
3850                 var that = $(this).resizable( "instance" );
3851                 if (that.ghost) {
3852                         that.ghost.css({ position: "relative", height: that.size.height, width: that.size.width });
3853                 }
3854         },
3856         stop: function() {
3857                 var that = $(this).resizable( "instance" );
3858                 if (that.ghost && that.helper) {
3859                         that.helper.get(0).removeChild(that.ghost.get(0));
3860                 }
3861         }
3865 $.ui.plugin.add("resizable", "grid", {
3867         resize: function() {
3868                 var that = $(this).resizable( "instance" ),
3869                         o = that.options,
3870                         cs = that.size,
3871                         os = that.originalSize,
3872                         op = that.originalPosition,
3873                         a = that.axis,
3874                         grid = typeof o.grid === "number" ? [o.grid, o.grid] : o.grid,
3875                         gridX = (grid[0]||1),
3876                         gridY = (grid[1]||1),
3877                         ox = Math.round((cs.width - os.width) / gridX) * gridX,
3878                         oy = Math.round((cs.height - os.height) / gridY) * gridY,
3879                         newWidth = os.width + ox,
3880                         newHeight = os.height + oy,
3881                         isMaxWidth = o.maxWidth && (o.maxWidth < newWidth),
3882                         isMaxHeight = o.maxHeight && (o.maxHeight < newHeight),
3883                         isMinWidth = o.minWidth && (o.minWidth > newWidth),
3884                         isMinHeight = o.minHeight && (o.minHeight > newHeight);
3886                 o.grid = grid;
3888                 if (isMinWidth) {
3889                         newWidth = newWidth + gridX;
3890                 }
3891                 if (isMinHeight) {
3892                         newHeight = newHeight + gridY;
3893                 }
3894                 if (isMaxWidth) {
3895                         newWidth = newWidth - gridX;
3896                 }
3897                 if (isMaxHeight) {
3898                         newHeight = newHeight - gridY;
3899                 }
3901                 if (/^(se|s|e)$/.test(a)) {
3902                         that.size.width = newWidth;
3903                         that.size.height = newHeight;
3904                 } else if (/^(ne)$/.test(a)) {
3905                         that.size.width = newWidth;
3906                         that.size.height = newHeight;
3907                         that.position.top = op.top - oy;
3908                 } else if (/^(sw)$/.test(a)) {
3909                         that.size.width = newWidth;
3910                         that.size.height = newHeight;
3911                         that.position.left = op.left - ox;
3912                 } else {
3913                         if ( newHeight - gridY > 0 ) {
3914                                 that.size.height = newHeight;
3915                                 that.position.top = op.top - oy;
3916                         } else {
3917                                 that.size.height = gridY;
3918                                 that.position.top = op.top + os.height - gridY;
3919                         }
3920                         if ( newWidth - gridX > 0 ) {
3921                                 that.size.width = newWidth;
3922                                 that.position.left = op.left - ox;
3923                         } else {
3924                                 that.size.width = gridX;
3925                                 that.position.left = op.left + os.width - gridX;
3926                         }
3927                 }
3928         }
3932 var resizable = $.ui.resizable;
3936  * jQuery UI Selectable 1.11.0
3937  * http://jqueryui.com
3939  * Copyright 2014 jQuery Foundation and other contributors
3940  * Released under the MIT license.
3941  * http://jquery.org/license
3943  * http://api.jqueryui.com/selectable/
3944  */
3947 var selectable = $.widget("ui.selectable", $.ui.mouse, {
3948         version: "1.11.0",
3949         options: {
3950                 appendTo: "body",
3951                 autoRefresh: true,
3952                 distance: 0,
3953                 filter: "*",
3954                 tolerance: "touch",
3956                 // callbacks
3957                 selected: null,
3958                 selecting: null,
3959                 start: null,
3960                 stop: null,
3961                 unselected: null,
3962                 unselecting: null
3963         },
3964         _create: function() {
3965                 var selectees,
3966                         that = this;
3968                 this.element.addClass("ui-selectable");
3970                 this.dragged = false;
3972                 // cache selectee children based on filter
3973                 this.refresh = function() {
3974                         selectees = $(that.options.filter, that.element[0]);
3975                         selectees.addClass("ui-selectee");
3976                         selectees.each(function() {
3977                                 var $this = $(this),
3978                                         pos = $this.offset();
3979                                 $.data(this, "selectable-item", {
3980                                         element: this,
3981                                         $element: $this,
3982                                         left: pos.left,
3983                                         top: pos.top,
3984                                         right: pos.left + $this.outerWidth(),
3985                                         bottom: pos.top + $this.outerHeight(),
3986                                         startselected: false,
3987                                         selected: $this.hasClass("ui-selected"),
3988                                         selecting: $this.hasClass("ui-selecting"),
3989                                         unselecting: $this.hasClass("ui-unselecting")
3990                                 });
3991                         });
3992                 };
3993                 this.refresh();
3995                 this.selectees = selectees.addClass("ui-selectee");
3997                 this._mouseInit();
3999                 this.helper = $("<div class='ui-selectable-helper'></div>");
4000         },
4002         _destroy: function() {
4003                 this.selectees
4004                         .removeClass("ui-selectee")
4005                         .removeData("selectable-item");
4006                 this.element
4007                         .removeClass("ui-selectable ui-selectable-disabled");
4008                 this._mouseDestroy();
4009         },
4011         _mouseStart: function(event) {
4012                 var that = this,
4013                         options = this.options;
4015                 this.opos = [ event.pageX, event.pageY ];
4017                 if (this.options.disabled) {
4018                         return;
4019                 }
4021                 this.selectees = $(options.filter, this.element[0]);
4023                 this._trigger("start", event);
4025                 $(options.appendTo).append(this.helper);
4026                 // position helper (lasso)
4027                 this.helper.css({
4028                         "left": event.pageX,
4029                         "top": event.pageY,
4030                         "width": 0,
4031                         "height": 0
4032                 });
4034                 if (options.autoRefresh) {
4035                         this.refresh();
4036                 }
4038                 this.selectees.filter(".ui-selected").each(function() {
4039                         var selectee = $.data(this, "selectable-item");
4040                         selectee.startselected = true;
4041                         if (!event.metaKey && !event.ctrlKey) {
4042                                 selectee.$element.removeClass("ui-selected");
4043                                 selectee.selected = false;
4044                                 selectee.$element.addClass("ui-unselecting");
4045                                 selectee.unselecting = true;
4046                                 // selectable UNSELECTING callback
4047                                 that._trigger("unselecting", event, {
4048                                         unselecting: selectee.element
4049                                 });
4050                         }
4051                 });
4053                 $(event.target).parents().addBack().each(function() {
4054                         var doSelect,
4055                                 selectee = $.data(this, "selectable-item");
4056                         if (selectee) {
4057                                 doSelect = (!event.metaKey && !event.ctrlKey) || !selectee.$element.hasClass("ui-selected");
4058                                 selectee.$element
4059                                         .removeClass(doSelect ? "ui-unselecting" : "ui-selected")
4060                                         .addClass(doSelect ? "ui-selecting" : "ui-unselecting");
4061                                 selectee.unselecting = !doSelect;
4062                                 selectee.selecting = doSelect;
4063                                 selectee.selected = doSelect;
4064                                 // selectable (UN)SELECTING callback
4065                                 if (doSelect) {
4066                                         that._trigger("selecting", event, {
4067                                                 selecting: selectee.element
4068                                         });
4069                                 } else {
4070                                         that._trigger("unselecting", event, {
4071                                                 unselecting: selectee.element
4072                                         });
4073                                 }
4074                                 return false;
4075                         }
4076                 });
4078         },
4080         _mouseDrag: function(event) {
4082                 this.dragged = true;
4084                 if (this.options.disabled) {
4085                         return;
4086                 }
4088                 var tmp,
4089                         that = this,
4090                         options = this.options,
4091                         x1 = this.opos[0],
4092                         y1 = this.opos[1],
4093                         x2 = event.pageX,
4094                         y2 = event.pageY;
4096                 if (x1 > x2) { tmp = x2; x2 = x1; x1 = tmp; }
4097                 if (y1 > y2) { tmp = y2; y2 = y1; y1 = tmp; }
4098                 this.helper.css({ left: x1, top: y1, width: x2 - x1, height: y2 - y1 });
4100                 this.selectees.each(function() {
4101                         var selectee = $.data(this, "selectable-item"),
4102                                 hit = false;
4104                         //prevent helper from being selected if appendTo: selectable
4105                         if (!selectee || selectee.element === that.element[0]) {
4106                                 return;
4107                         }
4109                         if (options.tolerance === "touch") {
4110                                 hit = ( !(selectee.left > x2 || selectee.right < x1 || selectee.top > y2 || selectee.bottom < y1) );
4111                         } else if (options.tolerance === "fit") {
4112                                 hit = (selectee.left > x1 && selectee.right < x2 && selectee.top > y1 && selectee.bottom < y2);
4113                         }
4115                         if (hit) {
4116                                 // SELECT
4117                                 if (selectee.selected) {
4118                                         selectee.$element.removeClass("ui-selected");
4119                                         selectee.selected = false;
4120                                 }
4121                                 if (selectee.unselecting) {
4122                                         selectee.$element.removeClass("ui-unselecting");
4123                                         selectee.unselecting = false;
4124                                 }
4125                                 if (!selectee.selecting) {
4126                                         selectee.$element.addClass("ui-selecting");
4127                                         selectee.selecting = true;
4128                                         // selectable SELECTING callback
4129                                         that._trigger("selecting", event, {
4130                                                 selecting: selectee.element
4131                                         });
4132                                 }
4133                         } else {
4134                                 // UNSELECT
4135                                 if (selectee.selecting) {
4136                                         if ((event.metaKey || event.ctrlKey) && selectee.startselected) {
4137                                                 selectee.$element.removeClass("ui-selecting");
4138                                                 selectee.selecting = false;
4139                                                 selectee.$element.addClass("ui-selected");
4140                                                 selectee.selected = true;
4141                                         } else {
4142                                                 selectee.$element.removeClass("ui-selecting");
4143                                                 selectee.selecting = false;
4144                                                 if (selectee.startselected) {
4145                                                         selectee.$element.addClass("ui-unselecting");
4146                                                         selectee.unselecting = true;
4147                                                 }
4148                                                 // selectable UNSELECTING callback
4149                                                 that._trigger("unselecting", event, {
4150                                                         unselecting: selectee.element
4151                                                 });
4152                                         }
4153                                 }
4154                                 if (selectee.selected) {
4155                                         if (!event.metaKey && !event.ctrlKey && !selectee.startselected) {
4156                                                 selectee.$element.removeClass("ui-selected");
4157                                                 selectee.selected = false;
4159                                                 selectee.$element.addClass("ui-unselecting");
4160                                                 selectee.unselecting = true;
4161                                                 // selectable UNSELECTING callback
4162                                                 that._trigger("unselecting", event, {
4163                                                         unselecting: selectee.element
4164                                                 });
4165                                         }
4166                                 }
4167                         }
4168                 });
4170                 return false;
4171         },
4173         _mouseStop: function(event) {
4174                 var that = this;
4176                 this.dragged = false;
4178                 $(".ui-unselecting", this.element[0]).each(function() {
4179                         var selectee = $.data(this, "selectable-item");
4180                         selectee.$element.removeClass("ui-unselecting");
4181                         selectee.unselecting = false;
4182                         selectee.startselected = false;
4183                         that._trigger("unselected", event, {
4184                                 unselected: selectee.element
4185                         });
4186                 });
4187                 $(".ui-selecting", this.element[0]).each(function() {
4188                         var selectee = $.data(this, "selectable-item");
4189                         selectee.$element.removeClass("ui-selecting").addClass("ui-selected");
4190                         selectee.selecting = false;
4191                         selectee.selected = true;
4192                         selectee.startselected = true;
4193                         that._trigger("selected", event, {
4194                                 selected: selectee.element
4195                         });
4196                 });
4197                 this._trigger("stop", event);
4199                 this.helper.remove();
4201                 return false;
4202         }
4208  * jQuery UI Sortable 1.11.0
4209  * http://jqueryui.com
4211  * Copyright 2014 jQuery Foundation and other contributors
4212  * Released under the MIT license.
4213  * http://jquery.org/license
4215  * http://api.jqueryui.com/sortable/
4216  */
4219 var sortable = $.widget("ui.sortable", $.ui.mouse, {
4220         version: "1.11.0",
4221         widgetEventPrefix: "sort",
4222         ready: false,
4223         options: {
4224                 appendTo: "parent",
4225                 axis: false,
4226                 connectWith: false,
4227                 containment: false,
4228                 cursor: "auto",
4229                 cursorAt: false,
4230                 dropOnEmpty: true,
4231                 forcePlaceholderSize: false,
4232                 forceHelperSize: false,
4233                 grid: false,
4234                 handle: false,
4235                 helper: "original",
4236                 items: "> *",
4237                 opacity: false,
4238                 placeholder: false,
4239                 revert: false,
4240                 scroll: true,
4241                 scrollSensitivity: 20,
4242                 scrollSpeed: 20,
4243                 scope: "default",
4244                 tolerance: "intersect",
4245                 zIndex: 1000,
4247                 // callbacks
4248                 activate: null,
4249                 beforeStop: null,
4250                 change: null,
4251                 deactivate: null,
4252                 out: null,
4253                 over: null,
4254                 receive: null,
4255                 remove: null,
4256                 sort: null,
4257                 start: null,
4258                 stop: null,
4259                 update: null
4260         },
4262         _isOverAxis: function( x, reference, size ) {
4263                 return ( x >= reference ) && ( x < ( reference + size ) );
4264         },
4266         _isFloating: function( item ) {
4267                 return (/left|right/).test(item.css("float")) || (/inline|table-cell/).test(item.css("display"));
4268         },
4270         _create: function() {
4272                 var o = this.options;
4273                 this.containerCache = {};
4274                 this.element.addClass("ui-sortable");
4276                 //Get the items
4277                 this.refresh();
4279                 //Let's determine if the items are being displayed horizontally
4280                 this.floating = this.items.length ? o.axis === "x" || this._isFloating(this.items[0].item) : false;
4282                 //Let's determine the parent's offset
4283                 this.offset = this.element.offset();
4285                 //Initialize mouse events for interaction
4286                 this._mouseInit();
4288                 this._setHandleClassName();
4290                 //We're ready to go
4291                 this.ready = true;
4293         },
4295         _setOption: function( key, value ) {
4296                 this._super( key, value );
4298                 if ( key === "handle" ) {
4299                         this._setHandleClassName();
4300                 }
4301         },
4303         _setHandleClassName: function() {
4304                 this.element.find( ".ui-sortable-handle" ).removeClass( "ui-sortable-handle" );
4305                 $.each( this.items, function() {
4306                         ( this.instance.options.handle ?
4307                                 this.item.find( this.instance.options.handle ) : this.item )
4308                                 .addClass( "ui-sortable-handle" );
4309                 });
4310         },
4312         _destroy: function() {
4313                 this.element
4314                         .removeClass( "ui-sortable ui-sortable-disabled" )
4315                         .find( ".ui-sortable-handle" )
4316                                 .removeClass( "ui-sortable-handle" );
4317                 this._mouseDestroy();
4319                 for ( var i = this.items.length - 1; i >= 0; i-- ) {
4320                         this.items[i].item.removeData(this.widgetName + "-item");
4321                 }
4323                 return this;
4324         },
4326         _mouseCapture: function(event, overrideHandle) {
4327                 var currentItem = null,
4328                         validHandle = false,
4329                         that = this;
4331                 if (this.reverting) {
4332                         return false;
4333                 }
4335                 if(this.options.disabled || this.options.type === "static") {
4336                         return false;
4337                 }
4339                 //We have to refresh the items data once first
4340                 this._refreshItems(event);
4342                 //Find out if the clicked node (or one of its parents) is a actual item in this.items
4343                 $(event.target).parents().each(function() {
4344                         if($.data(this, that.widgetName + "-item") === that) {
4345                                 currentItem = $(this);
4346                                 return false;
4347                         }
4348                 });
4349                 if($.data(event.target, that.widgetName + "-item") === that) {
4350                         currentItem = $(event.target);
4351                 }
4353                 if(!currentItem) {
4354                         return false;
4355                 }
4356                 if(this.options.handle && !overrideHandle) {
4357                         $(this.options.handle, currentItem).find("*").addBack().each(function() {
4358                                 if(this === event.target) {
4359                                         validHandle = true;
4360                                 }
4361                         });
4362                         if(!validHandle) {
4363                                 return false;
4364                         }
4365                 }
4367                 this.currentItem = currentItem;
4368                 this._removeCurrentsFromItems();
4369                 return true;
4371         },
4373         _mouseStart: function(event, overrideHandle, noActivation) {
4375                 var i, body,
4376                         o = this.options;
4378                 this.currentContainer = this;
4380                 //We only need to call refreshPositions, because the refreshItems call has been moved to mouseCapture
4381                 this.refreshPositions();
4383                 //Create and append the visible helper
4384                 this.helper = this._createHelper(event);
4386                 //Cache the helper size
4387                 this._cacheHelperProportions();
4389                 /*
4390                  * - Position generation -
4391                  * This block generates everything position related - it's the core of draggables.
4392                  */
4394                 //Cache the margins of the original element
4395                 this._cacheMargins();
4397                 //Get the next scrolling parent
4398                 this.scrollParent = this.helper.scrollParent();
4400                 //The element's absolute position on the page minus margins
4401                 this.offset = this.currentItem.offset();
4402                 this.offset = {
4403                         top: this.offset.top - this.margins.top,
4404                         left: this.offset.left - this.margins.left
4405                 };
4407                 $.extend(this.offset, {
4408                         click: { //Where the click happened, relative to the element
4409                                 left: event.pageX - this.offset.left,
4410                                 top: event.pageY - this.offset.top
4411                         },
4412                         parent: this._getParentOffset(),
4413                         relative: this._getRelativeOffset() //This is a relative to absolute position minus the actual position calculation - only used for relative positioned helper
4414                 });
4416                 // Only after we got the offset, we can change the helper's position to absolute
4417                 // TODO: Still need to figure out a way to make relative sorting possible
4418                 this.helper.css("position", "absolute");
4419                 this.cssPosition = this.helper.css("position");
4421                 //Generate the original position
4422                 this.originalPosition = this._generatePosition(event);
4423                 this.originalPageX = event.pageX;
4424                 this.originalPageY = event.pageY;
4426                 //Adjust the mouse offset relative to the helper if "cursorAt" is supplied
4427                 (o.cursorAt && this._adjustOffsetFromHelper(o.cursorAt));
4429                 //Cache the former DOM position
4430                 this.domPosition = { prev: this.currentItem.prev()[0], parent: this.currentItem.parent()[0] };
4432                 //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
4433                 if(this.helper[0] !== this.currentItem[0]) {
4434                         this.currentItem.hide();
4435                 }
4437                 //Create the placeholder
4438                 this._createPlaceholder();
4440                 //Set a containment if given in the options
4441                 if(o.containment) {
4442                         this._setContainment();
4443                 }
4445                 if( o.cursor && o.cursor !== "auto" ) { // cursor option
4446                         body = this.document.find( "body" );
4448                         // support: IE
4449                         this.storedCursor = body.css( "cursor" );
4450                         body.css( "cursor", o.cursor );
4452                         this.storedStylesheet = $( "<style>*{ cursor: "+o.cursor+" !important; }</style>" ).appendTo( body );
4453                 }
4455                 if(o.opacity) { // opacity option
4456                         if (this.helper.css("opacity")) {
4457                                 this._storedOpacity = this.helper.css("opacity");
4458                         }
4459                         this.helper.css("opacity", o.opacity);
4460                 }
4462                 if(o.zIndex) { // zIndex option
4463                         if (this.helper.css("zIndex")) {
4464                                 this._storedZIndex = this.helper.css("zIndex");
4465                         }
4466                         this.helper.css("zIndex", o.zIndex);
4467                 }
4469                 //Prepare scrolling
4470                 if(this.scrollParent[0] !== document && this.scrollParent[0].tagName !== "HTML") {
4471                         this.overflowOffset = this.scrollParent.offset();
4472                 }
4474                 //Call callbacks
4475                 this._trigger("start", event, this._uiHash());
4477                 //Recache the helper size
4478                 if(!this._preserveHelperProportions) {
4479                         this._cacheHelperProportions();
4480                 }
4483                 //Post "activate" events to possible containers
4484                 if( !noActivation ) {
4485                         for ( i = this.containers.length - 1; i >= 0; i-- ) {
4486                                 this.containers[ i ]._trigger( "activate", event, this._uiHash( this ) );
4487                         }
4488                 }
4490                 //Prepare possible droppables
4491                 if($.ui.ddmanager) {
4492                         $.ui.ddmanager.current = this;
4493                 }
4495                 if ($.ui.ddmanager && !o.dropBehaviour) {
4496                         $.ui.ddmanager.prepareOffsets(this, event);
4497                 }
4499                 this.dragging = true;
4501                 this.helper.addClass("ui-sortable-helper");
4502                 this._mouseDrag(event); //Execute the drag once - this causes the helper not to be visible before getting its correct position
4503                 return true;
4505         },
4507         _mouseDrag: function(event) {
4508                 var i, item, itemElement, intersection,
4509                         o = this.options,
4510                         scrolled = false;
4512                 //Compute the helpers position
4513                 this.position = this._generatePosition(event);
4514                 this.positionAbs = this._convertPositionTo("absolute");
4516                 if (!this.lastPositionAbs) {
4517                         this.lastPositionAbs = this.positionAbs;
4518                 }
4520                 //Do scrolling
4521                 if(this.options.scroll) {
4522                         if(this.scrollParent[0] !== document && this.scrollParent[0].tagName !== "HTML") {
4524                                 if((this.overflowOffset.top + this.scrollParent[0].offsetHeight) - event.pageY < o.scrollSensitivity) {
4525                                         this.scrollParent[0].scrollTop = scrolled = this.scrollParent[0].scrollTop + o.scrollSpeed;
4526                                 } else if(event.pageY - this.overflowOffset.top < o.scrollSensitivity) {
4527                                         this.scrollParent[0].scrollTop = scrolled = this.scrollParent[0].scrollTop - o.scrollSpeed;
4528                                 }
4530                                 if((this.overflowOffset.left + this.scrollParent[0].offsetWidth) - event.pageX < o.scrollSensitivity) {
4531                                         this.scrollParent[0].scrollLeft = scrolled = this.scrollParent[0].scrollLeft + o.scrollSpeed;
4532                                 } else if(event.pageX - this.overflowOffset.left < o.scrollSensitivity) {
4533                                         this.scrollParent[0].scrollLeft = scrolled = this.scrollParent[0].scrollLeft - o.scrollSpeed;
4534                                 }
4536                         } else {
4538                                 if(event.pageY - $(document).scrollTop() < o.scrollSensitivity) {
4539                                         scrolled = $(document).scrollTop($(document).scrollTop() - o.scrollSpeed);
4540                                 } else if($(window).height() - (event.pageY - $(document).scrollTop()) < o.scrollSensitivity) {
4541                                         scrolled = $(document).scrollTop($(document).scrollTop() + o.scrollSpeed);
4542                                 }
4544                                 if(event.pageX - $(document).scrollLeft() < o.scrollSensitivity) {
4545                                         scrolled = $(document).scrollLeft($(document).scrollLeft() - o.scrollSpeed);
4546                                 } else if($(window).width() - (event.pageX - $(document).scrollLeft()) < o.scrollSensitivity) {
4547                                         scrolled = $(document).scrollLeft($(document).scrollLeft() + o.scrollSpeed);
4548                                 }
4550                         }
4552                         if(scrolled !== false && $.ui.ddmanager && !o.dropBehaviour) {
4553                                 $.ui.ddmanager.prepareOffsets(this, event);
4554                         }
4555                 }
4557                 //Regenerate the absolute position used for position checks
4558                 this.positionAbs = this._convertPositionTo("absolute");
4560                 //Set the helper position
4561                 if(!this.options.axis || this.options.axis !== "y") {
4562                         this.helper[0].style.left = this.position.left+"px";
4563                 }
4564                 if(!this.options.axis || this.options.axis !== "x") {
4565                         this.helper[0].style.top = this.position.top+"px";
4566                 }
4568                 //Rearrange
4569                 for (i = this.items.length - 1; i >= 0; i--) {
4571                         //Cache variables and intersection, continue if no intersection
4572                         item = this.items[i];
4573                         itemElement = item.item[0];
4574                         intersection = this._intersectsWithPointer(item);
4575                         if (!intersection) {
4576                                 continue;
4577                         }
4579                         // Only put the placeholder inside the current Container, skip all
4580                         // items from other containers. This works because when moving
4581                         // an item from one container to another the
4582                         // currentContainer is switched before the placeholder is moved.
4583                         //
4584                         // Without this, moving items in "sub-sortables" can cause
4585                         // the placeholder to jitter between the outer and inner container.
4586                         if (item.instance !== this.currentContainer) {
4587                                 continue;
4588                         }
4590                         // cannot intersect with itself
4591                         // no useless actions that have been done before
4592                         // no action if the item moved is the parent of the item checked
4593                         if (itemElement !== this.currentItem[0] &&
4594                                 this.placeholder[intersection === 1 ? "next" : "prev"]()[0] !== itemElement &&
4595                                 !$.contains(this.placeholder[0], itemElement) &&
4596                                 (this.options.type === "semi-dynamic" ? !$.contains(this.element[0], itemElement) : true)
4597                         ) {
4599                                 this.direction = intersection === 1 ? "down" : "up";
4601                                 if (this.options.tolerance === "pointer" || this._intersectsWithSides(item)) {
4602                                         this._rearrange(event, item);
4603                                 } else {
4604                                         break;
4605                                 }
4607                                 this._trigger("change", event, this._uiHash());
4608                                 break;
4609                         }
4610                 }
4612                 //Post events to containers
4613                 this._contactContainers(event);
4615                 //Interconnect with droppables
4616                 if($.ui.ddmanager) {
4617                         $.ui.ddmanager.drag(this, event);
4618                 }
4620                 //Call callbacks
4621                 this._trigger("sort", event, this._uiHash());
4623                 this.lastPositionAbs = this.positionAbs;
4624                 return false;
4626         },
4628         _mouseStop: function(event, noPropagation) {
4630                 if(!event) {
4631                         return;
4632                 }
4634                 //If we are using droppables, inform the manager about the drop
4635                 if ($.ui.ddmanager && !this.options.dropBehaviour) {
4636                         $.ui.ddmanager.drop(this, event);
4637                 }
4639                 if(this.options.revert) {
4640                         var that = this,
4641                                 cur = this.placeholder.offset(),
4642                                 axis = this.options.axis,
4643                                 animation = {};
4645                         if ( !axis || axis === "x" ) {
4646                                 animation.left = cur.left - this.offset.parent.left - this.margins.left + (this.offsetParent[0] === document.body ? 0 : this.offsetParent[0].scrollLeft);
4647                         }
4648                         if ( !axis || axis === "y" ) {
4649                                 animation.top = cur.top - this.offset.parent.top - this.margins.top + (this.offsetParent[0] === document.body ? 0 : this.offsetParent[0].scrollTop);
4650                         }
4651                         this.reverting = true;
4652                         $(this.helper).animate( animation, parseInt(this.options.revert, 10) || 500, function() {
4653                                 that._clear(event);
4654                         });
4655                 } else {
4656                         this._clear(event, noPropagation);
4657                 }
4659                 return false;
4661         },
4663         cancel: function() {
4665                 if(this.dragging) {
4667                         this._mouseUp({ target: null });
4669                         if(this.options.helper === "original") {
4670                                 this.currentItem.css(this._storedCSS).removeClass("ui-sortable-helper");
4671                         } else {
4672                                 this.currentItem.show();
4673                         }
4675                         //Post deactivating events to containers
4676                         for (var i = this.containers.length - 1; i >= 0; i--){
4677                                 this.containers[i]._trigger("deactivate", null, this._uiHash(this));
4678                                 if(this.containers[i].containerCache.over) {
4679                                         this.containers[i]._trigger("out", null, this._uiHash(this));
4680                                         this.containers[i].containerCache.over = 0;
4681                                 }
4682                         }
4684                 }
4686                 if (this.placeholder) {
4687                         //$(this.placeholder[0]).remove(); would have been the jQuery way - unfortunately, it unbinds ALL events from the original node!
4688                         if(this.placeholder[0].parentNode) {
4689                                 this.placeholder[0].parentNode.removeChild(this.placeholder[0]);
4690                         }
4691                         if(this.options.helper !== "original" && this.helper && this.helper[0].parentNode) {
4692                                 this.helper.remove();
4693                         }
4695                         $.extend(this, {
4696                                 helper: null,
4697                                 dragging: false,
4698                                 reverting: false,
4699                                 _noFinalSort: null
4700                         });
4702                         if(this.domPosition.prev) {
4703                                 $(this.domPosition.prev).after(this.currentItem);
4704                         } else {
4705                                 $(this.domPosition.parent).prepend(this.currentItem);
4706                         }
4707                 }
4709                 return this;
4711         },
4713         serialize: function(o) {
4715                 var items = this._getItemsAsjQuery(o && o.connected),
4716                         str = [];
4717                 o = o || {};
4719                 $(items).each(function() {
4720                         var res = ($(o.item || this).attr(o.attribute || "id") || "").match(o.expression || (/(.+)[\-=_](.+)/));
4721                         if (res) {
4722                                 str.push((o.key || res[1]+"[]")+"="+(o.key && o.expression ? res[1] : res[2]));
4723                         }
4724                 });
4726                 if(!str.length && o.key) {
4727                         str.push(o.key + "=");
4728                 }
4730                 return str.join("&");
4732         },
4734         toArray: function(o) {
4736                 var items = this._getItemsAsjQuery(o && o.connected),
4737                         ret = [];
4739                 o = o || {};
4741                 items.each(function() { ret.push($(o.item || this).attr(o.attribute || "id") || ""); });
4742                 return ret;
4744         },
4746         /* Be careful with the following core functions */
4747         _intersectsWith: function(item) {
4749                 var x1 = this.positionAbs.left,
4750                         x2 = x1 + this.helperProportions.width,
4751                         y1 = this.positionAbs.top,
4752                         y2 = y1 + this.helperProportions.height,
4753                         l = item.left,
4754                         r = l + item.width,
4755                         t = item.top,
4756                         b = t + item.height,
4757                         dyClick = this.offset.click.top,
4758                         dxClick = this.offset.click.left,
4759                         isOverElementHeight = ( this.options.axis === "x" ) || ( ( y1 + dyClick ) > t && ( y1 + dyClick ) < b ),
4760                         isOverElementWidth = ( this.options.axis === "y" ) || ( ( x1 + dxClick ) > l && ( x1 + dxClick ) < r ),
4761                         isOverElement = isOverElementHeight && isOverElementWidth;
4763                 if ( this.options.tolerance === "pointer" ||
4764                         this.options.forcePointerForContainers ||
4765                         (this.options.tolerance !== "pointer" && this.helperProportions[this.floating ? "width" : "height"] > item[this.floating ? "width" : "height"])
4766                 ) {
4767                         return isOverElement;
4768                 } else {
4770                         return (l < x1 + (this.helperProportions.width / 2) && // Right Half
4771                                 x2 - (this.helperProportions.width / 2) < r && // Left Half
4772                                 t < y1 + (this.helperProportions.height / 2) && // Bottom Half
4773                                 y2 - (this.helperProportions.height / 2) < b ); // Top Half
4775                 }
4776         },
4778         _intersectsWithPointer: function(item) {
4780                 var isOverElementHeight = (this.options.axis === "x") || this._isOverAxis(this.positionAbs.top + this.offset.click.top, item.top, item.height),
4781                         isOverElementWidth = (this.options.axis === "y") || this._isOverAxis(this.positionAbs.left + this.offset.click.left, item.left, item.width),
4782                         isOverElement = isOverElementHeight && isOverElementWidth,
4783                         verticalDirection = this._getDragVerticalDirection(),
4784                         horizontalDirection = this._getDragHorizontalDirection();
4786                 if (!isOverElement) {
4787                         return false;
4788                 }
4790                 return this.floating ?
4791                         ( ((horizontalDirection && horizontalDirection === "right") || verticalDirection === "down") ? 2 : 1 )
4792                         : ( verticalDirection && (verticalDirection === "down" ? 2 : 1) );
4794         },
4796         _intersectsWithSides: function(item) {
4798                 var isOverBottomHalf = this._isOverAxis(this.positionAbs.top + this.offset.click.top, item.top + (item.height/2), item.height),
4799                         isOverRightHalf = this._isOverAxis(this.positionAbs.left + this.offset.click.left, item.left + (item.width/2), item.width),
4800                         verticalDirection = this._getDragVerticalDirection(),
4801                         horizontalDirection = this._getDragHorizontalDirection();
4803                 if (this.floating && horizontalDirection) {
4804                         return ((horizontalDirection === "right" && isOverRightHalf) || (horizontalDirection === "left" && !isOverRightHalf));
4805                 } else {
4806                         return verticalDirection && ((verticalDirection === "down" && isOverBottomHalf) || (verticalDirection === "up" && !isOverBottomHalf));
4807                 }
4809         },
4811         _getDragVerticalDirection: function() {
4812                 var delta = this.positionAbs.top - this.lastPositionAbs.top;
4813                 return delta !== 0 && (delta > 0 ? "down" : "up");
4814         },
4816         _getDragHorizontalDirection: function() {
4817                 var delta = this.positionAbs.left - this.lastPositionAbs.left;
4818                 return delta !== 0 && (delta > 0 ? "right" : "left");
4819         },
4821         refresh: function(event) {
4822                 this._refreshItems(event);
4823                 this._setHandleClassName();
4824                 this.refreshPositions();
4825                 return this;
4826         },
4828         _connectWith: function() {
4829                 var options = this.options;
4830                 return options.connectWith.constructor === String ? [options.connectWith] : options.connectWith;
4831         },
4833         _getItemsAsjQuery: function(connected) {
4835                 var i, j, cur, inst,
4836                         items = [],
4837                         queries = [],
4838                         connectWith = this._connectWith();
4840                 if(connectWith && connected) {
4841                         for (i = connectWith.length - 1; i >= 0; i--){
4842                                 cur = $(connectWith[i]);
4843                                 for ( j = cur.length - 1; j >= 0; j--){
4844                                         inst = $.data(cur[j], this.widgetFullName);
4845                                         if(inst && inst !== this && !inst.options.disabled) {
4846                                                 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]);
4847                                         }
4848                                 }
4849                         }
4850                 }
4852                 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]);
4854                 function addItems() {
4855                         items.push( this );
4856                 }
4857                 for (i = queries.length - 1; i >= 0; i--){
4858                         queries[i][0].each( addItems );
4859                 }
4861                 return $(items);
4863         },
4865         _removeCurrentsFromItems: function() {
4867                 var list = this.currentItem.find(":data(" + this.widgetName + "-item)");
4869                 this.items = $.grep(this.items, function (item) {
4870                         for (var j=0; j < list.length; j++) {
4871                                 if(list[j] === item.item[0]) {
4872                                         return false;
4873                                 }
4874                         }
4875                         return true;
4876                 });
4878         },
4880         _refreshItems: function(event) {
4882                 this.items = [];
4883                 this.containers = [this];
4885                 var i, j, cur, inst, targetData, _queries, item, queriesLength,
4886                         items = this.items,
4887                         queries = [[$.isFunction(this.options.items) ? this.options.items.call(this.element[0], event, { item: this.currentItem }) : $(this.options.items, this.element), this]],
4888                         connectWith = this._connectWith();
4890                 if(connectWith && this.ready) { //Shouldn't be run the first time through due to massive slow-down
4891                         for (i = connectWith.length - 1; i >= 0; i--){
4892                                 cur = $(connectWith[i]);
4893                                 for (j = cur.length - 1; j >= 0; j--){
4894                                         inst = $.data(cur[j], this.widgetFullName);
4895                                         if(inst && inst !== this && !inst.options.disabled) {
4896                                                 queries.push([$.isFunction(inst.options.items) ? inst.options.items.call(inst.element[0], event, { item: this.currentItem }) : $(inst.options.items, inst.element), inst]);
4897                                                 this.containers.push(inst);
4898                                         }
4899                                 }
4900                         }
4901                 }
4903                 for (i = queries.length - 1; i >= 0; i--) {
4904                         targetData = queries[i][1];
4905                         _queries = queries[i][0];
4907                         for (j=0, queriesLength = _queries.length; j < queriesLength; j++) {
4908                                 item = $(_queries[j]);
4910                                 item.data(this.widgetName + "-item", targetData); // Data for target checking (mouse manager)
4912                                 items.push({
4913                                         item: item,
4914                                         instance: targetData,
4915                                         width: 0, height: 0,
4916                                         left: 0, top: 0
4917                                 });
4918                         }
4919                 }
4921         },
4923         refreshPositions: function(fast) {
4925                 //This has to be redone because due to the item being moved out/into the offsetParent, the offsetParent's position will change
4926                 if(this.offsetParent && this.helper) {
4927                         this.offset.parent = this._getParentOffset();
4928                 }
4930                 var i, item, t, p;
4932                 for (i = this.items.length - 1; i >= 0; i--){
4933                         item = this.items[i];
4935                         //We ignore calculating positions of all connected containers when we're not over them
4936                         if(item.instance !== this.currentContainer && this.currentContainer && item.item[0] !== this.currentItem[0]) {
4937                                 continue;
4938                         }
4940                         t = this.options.toleranceElement ? $(this.options.toleranceElement, item.item) : item.item;
4942                         if (!fast) {
4943                                 item.width = t.outerWidth();
4944                                 item.height = t.outerHeight();
4945                         }
4947                         p = t.offset();
4948                         item.left = p.left;
4949                         item.top = p.top;
4950                 }
4952                 if(this.options.custom && this.options.custom.refreshContainers) {
4953                         this.options.custom.refreshContainers.call(this);
4954                 } else {
4955                         for (i = this.containers.length - 1; i >= 0; i--){
4956                                 p = this.containers[i].element.offset();
4957                                 this.containers[i].containerCache.left = p.left;
4958                                 this.containers[i].containerCache.top = p.top;
4959                                 this.containers[i].containerCache.width = this.containers[i].element.outerWidth();
4960                                 this.containers[i].containerCache.height = this.containers[i].element.outerHeight();
4961                         }
4962                 }
4964                 return this;
4965         },
4967         _createPlaceholder: function(that) {
4968                 that = that || this;
4969                 var className,
4970                         o = that.options;
4972                 if(!o.placeholder || o.placeholder.constructor === String) {
4973                         className = o.placeholder;
4974                         o.placeholder = {
4975                                 element: function() {
4977                                         var nodeName = that.currentItem[0].nodeName.toLowerCase(),
4978                                                 element = $( "<" + nodeName + ">", that.document[0] )
4979                                                         .addClass(className || that.currentItem[0].className+" ui-sortable-placeholder")
4980                                                         .removeClass("ui-sortable-helper");
4982                                         if ( nodeName === "tr" ) {
4983                                                 that.currentItem.children().each(function() {
4984                                                         $( "<td>&#160;</td>", that.document[0] )
4985                                                                 .attr( "colspan", $( this ).attr( "colspan" ) || 1 )
4986                                                                 .appendTo( element );
4987                                                 });
4988                                         } else if ( nodeName === "img" ) {
4989                                                 element.attr( "src", that.currentItem.attr( "src" ) );
4990                                         }
4992                                         if ( !className ) {
4993                                                 element.css( "visibility", "hidden" );
4994                                         }
4996                                         return element;
4997                                 },
4998                                 update: function(container, p) {
5000                                         // 1. If a className is set as 'placeholder option, we don't force sizes - the class is responsible for that
5001                                         // 2. The option 'forcePlaceholderSize can be enabled to force it even if a class name is specified
5002                                         if(className && !o.forcePlaceholderSize) {
5003                                                 return;
5004                                         }
5006                                         //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
5007                                         if(!p.height()) { p.height(that.currentItem.innerHeight() - parseInt(that.currentItem.css("paddingTop")||0, 10) - parseInt(that.currentItem.css("paddingBottom")||0, 10)); }
5008                                         if(!p.width()) { p.width(that.currentItem.innerWidth() - parseInt(that.currentItem.css("paddingLeft")||0, 10) - parseInt(that.currentItem.css("paddingRight")||0, 10)); }
5009                                 }
5010                         };
5011                 }
5013                 //Create the placeholder
5014                 that.placeholder = $(o.placeholder.element.call(that.element, that.currentItem));
5016                 //Append it after the actual current item
5017                 that.currentItem.after(that.placeholder);
5019                 //Update the size of the placeholder (TODO: Logic to fuzzy, see line 316/317)
5020                 o.placeholder.update(that, that.placeholder);
5022         },
5024         _contactContainers: function(event) {
5025                 var i, j, dist, itemWithLeastDistance, posProperty, sizeProperty, cur, nearBottom, floating, axis,
5026                         innermostContainer = null,
5027                         innermostIndex = null;
5029                 // get innermost container that intersects with item
5030                 for (i = this.containers.length - 1; i >= 0; i--) {
5032                         // never consider a container that's located within the item itself
5033                         if($.contains(this.currentItem[0], this.containers[i].element[0])) {
5034                                 continue;
5035                         }
5037                         if(this._intersectsWith(this.containers[i].containerCache)) {
5039                                 // if we've already found a container and it's more "inner" than this, then continue
5040                                 if(innermostContainer && $.contains(this.containers[i].element[0], innermostContainer.element[0])) {
5041                                         continue;
5042                                 }
5044                                 innermostContainer = this.containers[i];
5045                                 innermostIndex = i;
5047                         } else {
5048                                 // container doesn't intersect. trigger "out" event if necessary
5049                                 if(this.containers[i].containerCache.over) {
5050                                         this.containers[i]._trigger("out", event, this._uiHash(this));
5051                                         this.containers[i].containerCache.over = 0;
5052                                 }
5053                         }
5055                 }
5057                 // if no intersecting containers found, return
5058                 if(!innermostContainer) {
5059                         return;
5060                 }
5062                 // move the item into the container if it's not there already
5063                 if(this.containers.length === 1) {
5064                         if (!this.containers[innermostIndex].containerCache.over) {
5065                                 this.containers[innermostIndex]._trigger("over", event, this._uiHash(this));
5066                                 this.containers[innermostIndex].containerCache.over = 1;
5067                         }
5068                 } else {
5070                         //When entering a new container, we will find the item with the least distance and append our item near it
5071                         dist = 10000;
5072                         itemWithLeastDistance = null;
5073                         floating = innermostContainer.floating || this._isFloating(this.currentItem);
5074                         posProperty = floating ? "left" : "top";
5075                         sizeProperty = floating ? "width" : "height";
5076                         axis = floating ? "clientX" : "clientY";
5078                         for (j = this.items.length - 1; j >= 0; j--) {
5079                                 if(!$.contains(this.containers[innermostIndex].element[0], this.items[j].item[0])) {
5080                                         continue;
5081                                 }
5082                                 if(this.items[j].item[0] === this.currentItem[0]) {
5083                                         continue;
5084                                 }
5086                                 cur = this.items[j].item.offset()[posProperty];
5087                                 nearBottom = false;
5088                                 if ( event[ axis ] - cur > this.items[ j ][ sizeProperty ] / 2 ) {
5089                                         nearBottom = true;
5090                                 }
5092                                 if ( Math.abs( event[ axis ] - cur ) < dist ) {
5093                                         dist = Math.abs( event[ axis ] - cur );
5094                                         itemWithLeastDistance = this.items[ j ];
5095                                         this.direction = nearBottom ? "up": "down";
5096                                 }
5097                         }
5099                         //Check if dropOnEmpty is enabled
5100                         if(!itemWithLeastDistance && !this.options.dropOnEmpty) {
5101                                 return;
5102                         }
5104                         if(this.currentContainer === this.containers[innermostIndex]) {
5105                                 return;
5106                         }
5108                         itemWithLeastDistance ? this._rearrange(event, itemWithLeastDistance, null, true) : this._rearrange(event, null, this.containers[innermostIndex].element, true);
5109                         this._trigger("change", event, this._uiHash());
5110                         this.containers[innermostIndex]._trigger("change", event, this._uiHash(this));
5111                         this.currentContainer = this.containers[innermostIndex];
5113                         //Update the placeholder
5114                         this.options.placeholder.update(this.currentContainer, this.placeholder);
5116                         this.containers[innermostIndex]._trigger("over", event, this._uiHash(this));
5117                         this.containers[innermostIndex].containerCache.over = 1;
5118                 }
5121         },
5123         _createHelper: function(event) {
5125                 var o = this.options,
5126                         helper = $.isFunction(o.helper) ? $(o.helper.apply(this.element[0], [event, this.currentItem])) : (o.helper === "clone" ? this.currentItem.clone() : this.currentItem);
5128                 //Add the helper to the DOM if that didn't happen already
5129                 if(!helper.parents("body").length) {
5130                         $(o.appendTo !== "parent" ? o.appendTo : this.currentItem[0].parentNode)[0].appendChild(helper[0]);
5131                 }
5133                 if(helper[0] === this.currentItem[0]) {
5134                         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") };
5135                 }
5137                 if(!helper[0].style.width || o.forceHelperSize) {
5138                         helper.width(this.currentItem.width());
5139                 }
5140                 if(!helper[0].style.height || o.forceHelperSize) {
5141                         helper.height(this.currentItem.height());
5142                 }
5144                 return helper;
5146         },
5148         _adjustOffsetFromHelper: function(obj) {
5149                 if (typeof obj === "string") {
5150                         obj = obj.split(" ");
5151                 }
5152                 if ($.isArray(obj)) {
5153                         obj = {left: +obj[0], top: +obj[1] || 0};
5154                 }
5155                 if ("left" in obj) {
5156                         this.offset.click.left = obj.left + this.margins.left;
5157                 }
5158                 if ("right" in obj) {
5159                         this.offset.click.left = this.helperProportions.width - obj.right + this.margins.left;
5160                 }
5161                 if ("top" in obj) {
5162                         this.offset.click.top = obj.top + this.margins.top;
5163                 }
5164                 if ("bottom" in obj) {
5165                         this.offset.click.top = this.helperProportions.height - obj.bottom + this.margins.top;
5166                 }
5167         },
5169         _getParentOffset: function() {
5172                 //Get the offsetParent and cache its position
5173                 this.offsetParent = this.helper.offsetParent();
5174                 var po = this.offsetParent.offset();
5176                 // This is a special case where we need to modify a offset calculated on start, since the following happened:
5177                 // 1. The position of the helper is absolute, so it's position is calculated based on the next positioned parent
5178                 // 2. The actual offset parent is a child of the scroll parent, and the scroll parent isn't the document, which means that
5179                 //    the scroll is included in the initial calculation of the offset of the parent, and never recalculated upon drag
5180                 if(this.cssPosition === "absolute" && this.scrollParent[0] !== document && $.contains(this.scrollParent[0], this.offsetParent[0])) {
5181                         po.left += this.scrollParent.scrollLeft();
5182                         po.top += this.scrollParent.scrollTop();
5183                 }
5185                 // This needs to be actually done for all browsers, since pageX/pageY includes this information
5186                 // with an ugly IE fix
5187                 if( this.offsetParent[0] === document.body || (this.offsetParent[0].tagName && this.offsetParent[0].tagName.toLowerCase() === "html" && $.ui.ie)) {
5188                         po = { top: 0, left: 0 };
5189                 }
5191                 return {
5192                         top: po.top + (parseInt(this.offsetParent.css("borderTopWidth"),10) || 0),
5193                         left: po.left + (parseInt(this.offsetParent.css("borderLeftWidth"),10) || 0)
5194                 };
5196         },
5198         _getRelativeOffset: function() {
5200                 if(this.cssPosition === "relative") {
5201                         var p = this.currentItem.position();
5202                         return {
5203                                 top: p.top - (parseInt(this.helper.css("top"),10) || 0) + this.scrollParent.scrollTop(),
5204                                 left: p.left - (parseInt(this.helper.css("left"),10) || 0) + this.scrollParent.scrollLeft()
5205                         };
5206                 } else {
5207                         return { top: 0, left: 0 };
5208                 }
5210         },
5212         _cacheMargins: function() {
5213                 this.margins = {
5214                         left: (parseInt(this.currentItem.css("marginLeft"),10) || 0),
5215                         top: (parseInt(this.currentItem.css("marginTop"),10) || 0)
5216                 };
5217         },
5219         _cacheHelperProportions: function() {
5220                 this.helperProportions = {
5221                         width: this.helper.outerWidth(),
5222                         height: this.helper.outerHeight()
5223                 };
5224         },
5226         _setContainment: function() {
5228                 var ce, co, over,
5229                         o = this.options;
5230                 if(o.containment === "parent") {
5231                         o.containment = this.helper[0].parentNode;
5232                 }
5233                 if(o.containment === "document" || o.containment === "window") {
5234                         this.containment = [
5235                                 0 - this.offset.relative.left - this.offset.parent.left,
5236                                 0 - this.offset.relative.top - this.offset.parent.top,
5237                                 $(o.containment === "document" ? document : window).width() - this.helperProportions.width - this.margins.left,
5238                                 ($(o.containment === "document" ? document : window).height() || document.body.parentNode.scrollHeight) - this.helperProportions.height - this.margins.top
5239                         ];
5240                 }
5242                 if(!(/^(document|window|parent)$/).test(o.containment)) {
5243                         ce = $(o.containment)[0];
5244                         co = $(o.containment).offset();
5245                         over = ($(ce).css("overflow") !== "hidden");
5247                         this.containment = [
5248                                 co.left + (parseInt($(ce).css("borderLeftWidth"),10) || 0) + (parseInt($(ce).css("paddingLeft"),10) || 0) - this.margins.left,
5249                                 co.top + (parseInt($(ce).css("borderTopWidth"),10) || 0) + (parseInt($(ce).css("paddingTop"),10) || 0) - this.margins.top,
5250                                 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,
5251                                 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
5252                         ];
5253                 }
5255         },
5257         _convertPositionTo: function(d, pos) {
5259                 if(!pos) {
5260                         pos = this.position;
5261                 }
5262                 var mod = d === "absolute" ? 1 : -1,
5263                         scroll = this.cssPosition === "absolute" && !(this.scrollParent[0] !== document && $.contains(this.scrollParent[0], this.offsetParent[0])) ? this.offsetParent : this.scrollParent,
5264                         scrollIsRootNode = (/(html|body)/i).test(scroll[0].tagName);
5266                 return {
5267                         top: (
5268                                 pos.top +                                                                                                                               // The absolute mouse position
5269                                 this.offset.relative.top * mod +                                                                                // Only for relative positioned nodes: Relative offset from element to offset parent
5270                                 this.offset.parent.top * mod -                                                                                  // The offsetParent's offset without borders (offset + border)
5271                                 ( ( this.cssPosition === "fixed" ? -this.scrollParent.scrollTop() : ( scrollIsRootNode ? 0 : scroll.scrollTop() ) ) * mod)
5272                         ),
5273                         left: (
5274                                 pos.left +                                                                                                                              // The absolute mouse position
5275                                 this.offset.relative.left * mod +                                                                               // Only for relative positioned nodes: Relative offset from element to offset parent
5276                                 this.offset.parent.left * mod   -                                                                               // The offsetParent's offset without borders (offset + border)
5277                                 ( ( this.cssPosition === "fixed" ? -this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 : scroll.scrollLeft() ) * mod)
5278                         )
5279                 };
5281         },
5283         _generatePosition: function(event) {
5285                 var top, left,
5286                         o = this.options,
5287                         pageX = event.pageX,
5288                         pageY = event.pageY,
5289                         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);
5291                 // This is another very weird special case that only happens for relative elements:
5292                 // 1. If the css position is relative
5293                 // 2. and the scroll parent is the document or similar to the offset parent
5294                 // we have to refresh the relative offset during the scroll so there are no jumps
5295                 if(this.cssPosition === "relative" && !(this.scrollParent[0] !== document && this.scrollParent[0] !== this.offsetParent[0])) {
5296                         this.offset.relative = this._getRelativeOffset();
5297                 }
5299                 /*
5300                  * - Position constraining -
5301                  * Constrain the position to a mix of grid, containment.
5302                  */
5304                 if(this.originalPosition) { //If we are not dragging yet, we won't check for options
5306                         if(this.containment) {
5307                                 if(event.pageX - this.offset.click.left < this.containment[0]) {
5308                                         pageX = this.containment[0] + this.offset.click.left;
5309                                 }
5310                                 if(event.pageY - this.offset.click.top < this.containment[1]) {
5311                                         pageY = this.containment[1] + this.offset.click.top;
5312                                 }
5313                                 if(event.pageX - this.offset.click.left > this.containment[2]) {
5314                                         pageX = this.containment[2] + this.offset.click.left;
5315                                 }
5316                                 if(event.pageY - this.offset.click.top > this.containment[3]) {
5317                                         pageY = this.containment[3] + this.offset.click.top;
5318                                 }
5319                         }
5321                         if(o.grid) {
5322                                 top = this.originalPageY + Math.round((pageY - this.originalPageY) / o.grid[1]) * o.grid[1];
5323                                 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;
5325                                 left = this.originalPageX + Math.round((pageX - this.originalPageX) / o.grid[0]) * o.grid[0];
5326                                 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;
5327                         }
5329                 }
5331                 return {
5332                         top: (
5333                                 pageY -                                                                                                                         // The absolute mouse position
5334                                 this.offset.click.top -                                                                                                 // Click offset (relative to the element)
5335                                 this.offset.relative.top        -                                                                                       // Only for relative positioned nodes: Relative offset from element to offset parent
5336                                 this.offset.parent.top +                                                                                                // The offsetParent's offset without borders (offset + border)
5337                                 ( ( this.cssPosition === "fixed" ? -this.scrollParent.scrollTop() : ( scrollIsRootNode ? 0 : scroll.scrollTop() ) ))
5338                         ),
5339                         left: (
5340                                 pageX -                                                                                                                         // The absolute mouse position
5341                                 this.offset.click.left -                                                                                                // Click offset (relative to the element)
5342                                 this.offset.relative.left       -                                                                                       // Only for relative positioned nodes: Relative offset from element to offset parent
5343                                 this.offset.parent.left +                                                                                               // The offsetParent's offset without borders (offset + border)
5344                                 ( ( this.cssPosition === "fixed" ? -this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 : scroll.scrollLeft() ))
5345                         )
5346                 };
5348         },
5350         _rearrange: function(event, i, a, hardRefresh) {
5352                 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));
5354                 //Various things done here to improve the performance:
5355                 // 1. we create a setTimeout, that calls refreshPositions
5356                 // 2. on the instance, we have a counter variable, that get's higher after every append
5357                 // 3. on the local scope, we copy the counter variable, and check in the timeout, if it's still the same
5358                 // 4. this lets only the last addition to the timeout stack through
5359                 this.counter = this.counter ? ++this.counter : 1;
5360                 var counter = this.counter;
5362                 this._delay(function() {
5363                         if(counter === this.counter) {
5364                                 this.refreshPositions(!hardRefresh); //Precompute after each DOM insertion, NOT on mousemove
5365                         }
5366                 });
5368         },
5370         _clear: function(event, noPropagation) {
5372                 this.reverting = false;
5373                 // We delay all events that have to be triggered to after the point where the placeholder has been removed and
5374                 // everything else normalized again
5375                 var i,
5376                         delayedTriggers = [];
5378                 // We first have to update the dom position of the actual currentItem
5379                 // Note: don't do it if the current item is already removed (by a user), or it gets reappended (see #4088)
5380                 if(!this._noFinalSort && this.currentItem.parent().length) {
5381                         this.placeholder.before(this.currentItem);
5382                 }
5383                 this._noFinalSort = null;
5385                 if(this.helper[0] === this.currentItem[0]) {
5386                         for(i in this._storedCSS) {
5387                                 if(this._storedCSS[i] === "auto" || this._storedCSS[i] === "static") {
5388                                         this._storedCSS[i] = "";
5389                                 }
5390                         }
5391                         this.currentItem.css(this._storedCSS).removeClass("ui-sortable-helper");
5392                 } else {
5393                         this.currentItem.show();
5394                 }
5396                 if(this.fromOutside && !noPropagation) {
5397                         delayedTriggers.push(function(event) { this._trigger("receive", event, this._uiHash(this.fromOutside)); });
5398                 }
5399                 if((this.fromOutside || this.domPosition.prev !== this.currentItem.prev().not(".ui-sortable-helper")[0] || this.domPosition.parent !== this.currentItem.parent()[0]) && !noPropagation) {
5400                         delayedTriggers.push(function(event) { this._trigger("update", event, this._uiHash()); }); //Trigger update callback if the DOM position has changed
5401                 }
5403                 // Check if the items Container has Changed and trigger appropriate
5404                 // events.
5405                 if (this !== this.currentContainer) {
5406                         if(!noPropagation) {
5407                                 delayedTriggers.push(function(event) { this._trigger("remove", event, this._uiHash()); });
5408                                 delayedTriggers.push((function(c) { return function(event) { c._trigger("receive", event, this._uiHash(this)); };  }).call(this, this.currentContainer));
5409                                 delayedTriggers.push((function(c) { return function(event) { c._trigger("update", event, this._uiHash(this));  }; }).call(this, this.currentContainer));
5410                         }
5411                 }
5414                 //Post events to containers
5415                 function delayEvent( type, instance, container ) {
5416                         return function( event ) {
5417                                 container._trigger( type, event, instance._uiHash( instance ) );
5418                         };
5419                 }
5420                 for (i = this.containers.length - 1; i >= 0; i--){
5421                         if (!noPropagation) {
5422                                 delayedTriggers.push( delayEvent( "deactivate", this, this.containers[ i ] ) );
5423                         }
5424                         if(this.containers[i].containerCache.over) {
5425                                 delayedTriggers.push( delayEvent( "out", this, this.containers[ i ] ) );
5426                                 this.containers[i].containerCache.over = 0;
5427                         }
5428                 }
5430                 //Do what was originally in plugins
5431                 if ( this.storedCursor ) {
5432                         this.document.find( "body" ).css( "cursor", this.storedCursor );
5433                         this.storedStylesheet.remove();
5434                 }
5435                 if(this._storedOpacity) {
5436                         this.helper.css("opacity", this._storedOpacity);
5437                 }
5438                 if(this._storedZIndex) {
5439                         this.helper.css("zIndex", this._storedZIndex === "auto" ? "" : this._storedZIndex);
5440                 }
5442                 this.dragging = false;
5443                 if(this.cancelHelperRemoval) {
5444                         if(!noPropagation) {
5445                                 this._trigger("beforeStop", event, this._uiHash());
5446                                 for (i=0; i < delayedTriggers.length; i++) {
5447                                         delayedTriggers[i].call(this, event);
5448                                 } //Trigger all delayed events
5449                                 this._trigger("stop", event, this._uiHash());
5450                         }
5452                         this.fromOutside = false;
5453                         return false;
5454                 }
5456                 if(!noPropagation) {
5457                         this._trigger("beforeStop", event, this._uiHash());
5458                 }
5460                 //$(this.placeholder[0]).remove(); would have been the jQuery way - unfortunately, it unbinds ALL events from the original node!
5461                 this.placeholder[0].parentNode.removeChild(this.placeholder[0]);
5463                 if(this.helper[0] !== this.currentItem[0]) {
5464                         this.helper.remove();
5465                 }
5466                 this.helper = null;
5468                 if(!noPropagation) {
5469                         for (i=0; i < delayedTriggers.length; i++) {
5470                                 delayedTriggers[i].call(this, event);
5471                         } //Trigger all delayed events
5472                         this._trigger("stop", event, this._uiHash());
5473                 }
5475                 this.fromOutside = false;
5476                 return true;
5478         },
5480         _trigger: function() {
5481                 if ($.Widget.prototype._trigger.apply(this, arguments) === false) {
5482                         this.cancel();
5483                 }
5484         },
5486         _uiHash: function(_inst) {
5487                 var inst = _inst || this;
5488                 return {
5489                         helper: inst.helper,
5490                         placeholder: inst.placeholder || $([]),
5491                         position: inst.position,
5492                         originalPosition: inst.originalPosition,
5493                         offset: inst.positionAbs,
5494                         item: inst.currentItem,
5495                         sender: _inst ? _inst.element : null
5496                 };
5497         }
5503  * jQuery UI Accordion 1.11.0
5504  * http://jqueryui.com
5506  * Copyright 2014 jQuery Foundation and other contributors
5507  * Released under the MIT license.
5508  * http://jquery.org/license
5510  * http://api.jqueryui.com/accordion/
5511  */
5514 var accordion = $.widget( "ui.accordion", {
5515         version: "1.11.0",
5516         options: {
5517                 active: 0,
5518                 animate: {},
5519                 collapsible: false,
5520                 event: "click",
5521                 header: "> li > :first-child,> :not(li):even",
5522                 heightStyle: "auto",
5523                 icons: {
5524                         activeHeader: "ui-icon-triangle-1-s",
5525                         header: "ui-icon-triangle-1-e"
5526                 },
5528                 // callbacks
5529                 activate: null,
5530                 beforeActivate: null
5531         },
5533         hideProps: {
5534                 borderTopWidth: "hide",
5535                 borderBottomWidth: "hide",
5536                 paddingTop: "hide",
5537                 paddingBottom: "hide",
5538                 height: "hide"
5539         },
5541         showProps: {
5542                 borderTopWidth: "show",
5543                 borderBottomWidth: "show",
5544                 paddingTop: "show",
5545                 paddingBottom: "show",
5546                 height: "show"
5547         },
5549         _create: function() {
5550                 var options = this.options;
5551                 this.prevShow = this.prevHide = $();
5552                 this.element.addClass( "ui-accordion ui-widget ui-helper-reset" )
5553                         // ARIA
5554                         .attr( "role", "tablist" );
5556                 // don't allow collapsible: false and active: false / null
5557                 if ( !options.collapsible && (options.active === false || options.active == null) ) {
5558                         options.active = 0;
5559                 }
5561                 this._processPanels();
5562                 // handle negative values
5563                 if ( options.active < 0 ) {
5564                         options.active += this.headers.length;
5565                 }
5566                 this._refresh();
5567         },
5569         _getCreateEventData: function() {
5570                 return {
5571                         header: this.active,
5572                         panel: !this.active.length ? $() : this.active.next()
5573                 };
5574         },
5576         _createIcons: function() {
5577                 var icons = this.options.icons;
5578                 if ( icons ) {
5579                         $( "<span>" )
5580                                 .addClass( "ui-accordion-header-icon ui-icon " + icons.header )
5581                                 .prependTo( this.headers );
5582                         this.active.children( ".ui-accordion-header-icon" )
5583                                 .removeClass( icons.header )
5584                                 .addClass( icons.activeHeader );
5585                         this.headers.addClass( "ui-accordion-icons" );
5586                 }
5587         },
5589         _destroyIcons: function() {
5590                 this.headers
5591                         .removeClass( "ui-accordion-icons" )
5592                         .children( ".ui-accordion-header-icon" )
5593                                 .remove();
5594         },
5596         _destroy: function() {
5597                 var contents;
5599                 // clean up main element
5600                 this.element
5601                         .removeClass( "ui-accordion ui-widget ui-helper-reset" )
5602                         .removeAttr( "role" );
5604                 // clean up headers
5605                 this.headers
5606                         .removeClass( "ui-accordion-header ui-accordion-header-active ui-state-default " +
5607                                 "ui-corner-all ui-state-active ui-state-disabled ui-corner-top" )
5608                         .removeAttr( "role" )
5609                         .removeAttr( "aria-expanded" )
5610                         .removeAttr( "aria-selected" )
5611                         .removeAttr( "aria-controls" )
5612                         .removeAttr( "tabIndex" )
5613                         .removeUniqueId();
5615                 this._destroyIcons();
5617                 // clean up content panels
5618                 contents = this.headers.next()
5619                         .removeClass( "ui-helper-reset ui-widget-content ui-corner-bottom " +
5620                                 "ui-accordion-content ui-accordion-content-active ui-state-disabled" )
5621                         .css( "display", "" )
5622                         .removeAttr( "role" )
5623                         .removeAttr( "aria-hidden" )
5624                         .removeAttr( "aria-labelledby" )
5625                         .removeUniqueId();
5627                 if ( this.options.heightStyle !== "content" ) {
5628                         contents.css( "height", "" );
5629                 }
5630         },
5632         _setOption: function( key, value ) {
5633                 if ( key === "active" ) {
5634                         // _activate() will handle invalid values and update this.options
5635                         this._activate( value );
5636                         return;
5637                 }
5639                 if ( key === "event" ) {
5640                         if ( this.options.event ) {
5641                                 this._off( this.headers, this.options.event );
5642                         }
5643                         this._setupEvents( value );
5644                 }
5646                 this._super( key, value );
5648                 // setting collapsible: false while collapsed; open first panel
5649                 if ( key === "collapsible" && !value && this.options.active === false ) {
5650                         this._activate( 0 );
5651                 }
5653                 if ( key === "icons" ) {
5654                         this._destroyIcons();
5655                         if ( value ) {
5656                                 this._createIcons();
5657                         }
5658                 }
5660                 // #5332 - opacity doesn't cascade to positioned elements in IE
5661                 // so we need to add the disabled class to the headers and panels
5662                 if ( key === "disabled" ) {
5663                         this.element
5664                                 .toggleClass( "ui-state-disabled", !!value )
5665                                 .attr( "aria-disabled", value );
5666                         this.headers.add( this.headers.next() )
5667                                 .toggleClass( "ui-state-disabled", !!value );
5668                 }
5669         },
5671         _keydown: function( event ) {
5672                 if ( event.altKey || event.ctrlKey ) {
5673                         return;
5674                 }
5676                 var keyCode = $.ui.keyCode,
5677                         length = this.headers.length,
5678                         currentIndex = this.headers.index( event.target ),
5679                         toFocus = false;
5681                 switch ( event.keyCode ) {
5682                         case keyCode.RIGHT:
5683                         case keyCode.DOWN:
5684                                 toFocus = this.headers[ ( currentIndex + 1 ) % length ];
5685                                 break;
5686                         case keyCode.LEFT:
5687                         case keyCode.UP:
5688                                 toFocus = this.headers[ ( currentIndex - 1 + length ) % length ];
5689                                 break;
5690                         case keyCode.SPACE:
5691                         case keyCode.ENTER:
5692                                 this._eventHandler( event );
5693                                 break;
5694                         case keyCode.HOME:
5695                                 toFocus = this.headers[ 0 ];
5696                                 break;
5697                         case keyCode.END:
5698                                 toFocus = this.headers[ length - 1 ];
5699                                 break;
5700                 }
5702                 if ( toFocus ) {
5703                         $( event.target ).attr( "tabIndex", -1 );
5704                         $( toFocus ).attr( "tabIndex", 0 );
5705                         toFocus.focus();
5706                         event.preventDefault();
5707                 }
5708         },
5710         _panelKeyDown: function( event ) {
5711                 if ( event.keyCode === $.ui.keyCode.UP && event.ctrlKey ) {
5712                         $( event.currentTarget ).prev().focus();
5713                 }
5714         },
5716         refresh: function() {
5717                 var options = this.options;
5718                 this._processPanels();
5720                 // was collapsed or no panel
5721                 if ( ( options.active === false && options.collapsible === true ) || !this.headers.length ) {
5722                         options.active = false;
5723                         this.active = $();
5724                 // active false only when collapsible is true
5725                 } else if ( options.active === false ) {
5726                         this._activate( 0 );
5727                 // was active, but active panel is gone
5728                 } else if ( this.active.length && !$.contains( this.element[ 0 ], this.active[ 0 ] ) ) {
5729                         // all remaining panel are disabled
5730                         if ( this.headers.length === this.headers.find(".ui-state-disabled").length ) {
5731                                 options.active = false;
5732                                 this.active = $();
5733                         // activate previous panel
5734                         } else {
5735                                 this._activate( Math.max( 0, options.active - 1 ) );
5736                         }
5737                 // was active, active panel still exists
5738                 } else {
5739                         // make sure active index is correct
5740                         options.active = this.headers.index( this.active );
5741                 }
5743                 this._destroyIcons();
5745                 this._refresh();
5746         },
5748         _processPanels: function() {
5749                 this.headers = this.element.find( this.options.header )
5750                         .addClass( "ui-accordion-header ui-state-default ui-corner-all" );
5752                 this.headers.next()
5753                         .addClass( "ui-accordion-content ui-helper-reset ui-widget-content ui-corner-bottom" )
5754                         .filter( ":not(.ui-accordion-content-active)" )
5755                         .hide();
5756         },
5758         _refresh: function() {
5759                 var maxHeight,
5760                         options = this.options,
5761                         heightStyle = options.heightStyle,
5762                         parent = this.element.parent();
5764                 this.active = this._findActive( options.active )
5765                         .addClass( "ui-accordion-header-active ui-state-active ui-corner-top" )
5766                         .removeClass( "ui-corner-all" );
5767                 this.active.next()
5768                         .addClass( "ui-accordion-content-active" )
5769                         .show();
5771                 this.headers
5772                         .attr( "role", "tab" )
5773                         .each(function() {
5774                                 var header = $( this ),
5775                                         headerId = header.uniqueId().attr( "id" ),
5776                                         panel = header.next(),
5777                                         panelId = panel.uniqueId().attr( "id" );
5778                                 header.attr( "aria-controls", panelId );
5779                                 panel.attr( "aria-labelledby", headerId );
5780                         })
5781                         .next()
5782                                 .attr( "role", "tabpanel" );
5784                 this.headers
5785                         .not( this.active )
5786                         .attr({
5787                                 "aria-selected": "false",
5788                                 "aria-expanded": "false",
5789                                 tabIndex: -1
5790                         })
5791                         .next()
5792                                 .attr({
5793                                         "aria-hidden": "true"
5794                                 })
5795                                 .hide();
5797                 // make sure at least one header is in the tab order
5798                 if ( !this.active.length ) {
5799                         this.headers.eq( 0 ).attr( "tabIndex", 0 );
5800                 } else {
5801                         this.active.attr({
5802                                 "aria-selected": "true",
5803                                 "aria-expanded": "true",
5804                                 tabIndex: 0
5805                         })
5806                         .next()
5807                                 .attr({
5808                                         "aria-hidden": "false"
5809                                 });
5810                 }
5812                 this._createIcons();
5814                 this._setupEvents( options.event );
5816                 if ( heightStyle === "fill" ) {
5817                         maxHeight = parent.height();
5818                         this.element.siblings( ":visible" ).each(function() {
5819                                 var elem = $( this ),
5820                                         position = elem.css( "position" );
5822                                 if ( position === "absolute" || position === "fixed" ) {
5823                                         return;
5824                                 }
5825                                 maxHeight -= elem.outerHeight( true );
5826                         });
5828                         this.headers.each(function() {
5829                                 maxHeight -= $( this ).outerHeight( true );
5830                         });
5832                         this.headers.next()
5833                                 .each(function() {
5834                                         $( this ).height( Math.max( 0, maxHeight -
5835                                                 $( this ).innerHeight() + $( this ).height() ) );
5836                                 })
5837                                 .css( "overflow", "auto" );
5838                 } else if ( heightStyle === "auto" ) {
5839                         maxHeight = 0;
5840                         this.headers.next()
5841                                 .each(function() {
5842                                         maxHeight = Math.max( maxHeight, $( this ).css( "height", "" ).height() );
5843                                 })
5844                                 .height( maxHeight );
5845                 }
5846         },
5848         _activate: function( index ) {
5849                 var active = this._findActive( index )[ 0 ];
5851                 // trying to activate the already active panel
5852                 if ( active === this.active[ 0 ] ) {
5853                         return;
5854                 }
5856                 // trying to collapse, simulate a click on the currently active header
5857                 active = active || this.active[ 0 ];
5859                 this._eventHandler({
5860                         target: active,
5861                         currentTarget: active,
5862                         preventDefault: $.noop
5863                 });
5864         },
5866         _findActive: function( selector ) {
5867                 return typeof selector === "number" ? this.headers.eq( selector ) : $();
5868         },
5870         _setupEvents: function( event ) {
5871                 var events = {
5872                         keydown: "_keydown"
5873                 };
5874                 if ( event ) {
5875                         $.each( event.split( " " ), function( index, eventName ) {
5876                                 events[ eventName ] = "_eventHandler";
5877                         });
5878                 }
5880                 this._off( this.headers.add( this.headers.next() ) );
5881                 this._on( this.headers, events );
5882                 this._on( this.headers.next(), { keydown: "_panelKeyDown" });
5883                 this._hoverable( this.headers );
5884                 this._focusable( this.headers );
5885         },
5887         _eventHandler: function( event ) {
5888                 var options = this.options,
5889                         active = this.active,
5890                         clicked = $( event.currentTarget ),
5891                         clickedIsActive = clicked[ 0 ] === active[ 0 ],
5892                         collapsing = clickedIsActive && options.collapsible,
5893                         toShow = collapsing ? $() : clicked.next(),
5894                         toHide = active.next(),
5895                         eventData = {
5896                                 oldHeader: active,
5897                                 oldPanel: toHide,
5898                                 newHeader: collapsing ? $() : clicked,
5899                                 newPanel: toShow
5900                         };
5902                 event.preventDefault();
5904                 if (
5905                                 // click on active header, but not collapsible
5906                                 ( clickedIsActive && !options.collapsible ) ||
5907                                 // allow canceling activation
5908                                 ( this._trigger( "beforeActivate", event, eventData ) === false ) ) {
5909                         return;
5910                 }
5912                 options.active = collapsing ? false : this.headers.index( clicked );
5914                 // when the call to ._toggle() comes after the class changes
5915                 // it causes a very odd bug in IE 8 (see #6720)
5916                 this.active = clickedIsActive ? $() : clicked;
5917                 this._toggle( eventData );
5919                 // switch classes
5920                 // corner classes on the previously active header stay after the animation
5921                 active.removeClass( "ui-accordion-header-active ui-state-active" );
5922                 if ( options.icons ) {
5923                         active.children( ".ui-accordion-header-icon" )
5924                                 .removeClass( options.icons.activeHeader )
5925                                 .addClass( options.icons.header );
5926                 }
5928                 if ( !clickedIsActive ) {
5929                         clicked
5930                                 .removeClass( "ui-corner-all" )
5931                                 .addClass( "ui-accordion-header-active ui-state-active ui-corner-top" );
5932                         if ( options.icons ) {
5933                                 clicked.children( ".ui-accordion-header-icon" )
5934                                         .removeClass( options.icons.header )
5935                                         .addClass( options.icons.activeHeader );
5936                         }
5938                         clicked
5939                                 .next()
5940                                 .addClass( "ui-accordion-content-active" );
5941                 }
5942         },
5944         _toggle: function( data ) {
5945                 var toShow = data.newPanel,
5946                         toHide = this.prevShow.length ? this.prevShow : data.oldPanel;
5948                 // handle activating a panel during the animation for another activation
5949                 this.prevShow.add( this.prevHide ).stop( true, true );
5950                 this.prevShow = toShow;
5951                 this.prevHide = toHide;
5953                 if ( this.options.animate ) {
5954                         this._animate( toShow, toHide, data );
5955                 } else {
5956                         toHide.hide();
5957                         toShow.show();
5958                         this._toggleComplete( data );
5959                 }
5961                 toHide.attr({
5962                         "aria-hidden": "true"
5963                 });
5964                 toHide.prev().attr( "aria-selected", "false" );
5965                 // if we're switching panels, remove the old header from the tab order
5966                 // if we're opening from collapsed state, remove the previous header from the tab order
5967                 // if we're collapsing, then keep the collapsing header in the tab order
5968                 if ( toShow.length && toHide.length ) {
5969                         toHide.prev().attr({
5970                                 "tabIndex": -1,
5971                                 "aria-expanded": "false"
5972                         });
5973                 } else if ( toShow.length ) {
5974                         this.headers.filter(function() {
5975                                 return $( this ).attr( "tabIndex" ) === 0;
5976                         })
5977                         .attr( "tabIndex", -1 );
5978                 }
5980                 toShow
5981                         .attr( "aria-hidden", "false" )
5982                         .prev()
5983                                 .attr({
5984                                         "aria-selected": "true",
5985                                         tabIndex: 0,
5986                                         "aria-expanded": "true"
5987                                 });
5988         },
5990         _animate: function( toShow, toHide, data ) {
5991                 var total, easing, duration,
5992                         that = this,
5993                         adjust = 0,
5994                         down = toShow.length &&
5995                                 ( !toHide.length || ( toShow.index() < toHide.index() ) ),
5996                         animate = this.options.animate || {},
5997                         options = down && animate.down || animate,
5998                         complete = function() {
5999                                 that._toggleComplete( data );
6000                         };
6002                 if ( typeof options === "number" ) {
6003                         duration = options;
6004                 }
6005                 if ( typeof options === "string" ) {
6006                         easing = options;
6007                 }
6008                 // fall back from options to animation in case of partial down settings
6009                 easing = easing || options.easing || animate.easing;
6010                 duration = duration || options.duration || animate.duration;
6012                 if ( !toHide.length ) {
6013                         return toShow.animate( this.showProps, duration, easing, complete );
6014                 }
6015                 if ( !toShow.length ) {
6016                         return toHide.animate( this.hideProps, duration, easing, complete );
6017                 }
6019                 total = toShow.show().outerHeight();
6020                 toHide.animate( this.hideProps, {
6021                         duration: duration,
6022                         easing: easing,
6023                         step: function( now, fx ) {
6024                                 fx.now = Math.round( now );
6025                         }
6026                 });
6027                 toShow
6028                         .hide()
6029                         .animate( this.showProps, {
6030                                 duration: duration,
6031                                 easing: easing,
6032                                 complete: complete,
6033                                 step: function( now, fx ) {
6034                                         fx.now = Math.round( now );
6035                                         if ( fx.prop !== "height" ) {
6036                                                 adjust += fx.now;
6037                                         } else if ( that.options.heightStyle !== "content" ) {
6038                                                 fx.now = Math.round( total - toHide.outerHeight() - adjust );
6039                                                 adjust = 0;
6040                                         }
6041                                 }
6042                         });
6043         },
6045         _toggleComplete: function( data ) {
6046                 var toHide = data.oldPanel;
6048                 toHide
6049                         .removeClass( "ui-accordion-content-active" )
6050                         .prev()
6051                                 .removeClass( "ui-corner-top" )
6052                                 .addClass( "ui-corner-all" );
6054                 // Work around for rendering bug in IE (#5421)
6055                 if ( toHide.length ) {
6056                         toHide.parent()[ 0 ].className = toHide.parent()[ 0 ].className;
6057                 }
6058                 this._trigger( "activate", null, data );
6059         }
6064  * jQuery UI Menu 1.11.0
6065  * http://jqueryui.com
6067  * Copyright 2014 jQuery Foundation and other contributors
6068  * Released under the MIT license.
6069  * http://jquery.org/license
6071  * http://api.jqueryui.com/menu/
6072  */
6075 var menu = $.widget( "ui.menu", {
6076         version: "1.11.0",
6077         defaultElement: "<ul>",
6078         delay: 300,
6079         options: {
6080                 icons: {
6081                         submenu: "ui-icon-carat-1-e"
6082                 },
6083                 items: "> *",
6084                 menus: "ul",
6085                 position: {
6086                         my: "left-1 top",
6087                         at: "right top"
6088                 },
6089                 role: "menu",
6091                 // callbacks
6092                 blur: null,
6093                 focus: null,
6094                 select: null
6095         },
6097         _create: function() {
6098                 this.activeMenu = this.element;
6100                 // Flag used to prevent firing of the click handler
6101                 // as the event bubbles up through nested menus
6102                 this.mouseHandled = false;
6103                 this.element
6104                         .uniqueId()
6105                         .addClass( "ui-menu ui-widget ui-widget-content" )
6106                         .toggleClass( "ui-menu-icons", !!this.element.find( ".ui-icon" ).length )
6107                         .attr({
6108                                 role: this.options.role,
6109                                 tabIndex: 0
6110                         });
6112                 if ( this.options.disabled ) {
6113                         this.element
6114                                 .addClass( "ui-state-disabled" )
6115                                 .attr( "aria-disabled", "true" );
6116                 }
6118                 this._on({
6119                         // Prevent focus from sticking to links inside menu after clicking
6120                         // them (focus should always stay on UL during navigation).
6121                         "mousedown .ui-menu-item": function( event ) {
6122                                 event.preventDefault();
6123                         },
6124                         "click .ui-menu-item": function( event ) {
6125                                 var target = $( event.target );
6126                                 if ( !this.mouseHandled && target.not( ".ui-state-disabled" ).length ) {
6127                                         this.select( event );
6129                                         // Only set the mouseHandled flag if the event will bubble, see #9469.
6130                                         if ( !event.isPropagationStopped() ) {
6131                                                 this.mouseHandled = true;
6132                                         }
6134                                         // Open submenu on click
6135                                         if ( target.has( ".ui-menu" ).length ) {
6136                                                 this.expand( event );
6137                                         } else if ( !this.element.is( ":focus" ) && $( this.document[ 0 ].activeElement ).closest( ".ui-menu" ).length ) {
6139                                                 // Redirect focus to the menu
6140                                                 this.element.trigger( "focus", [ true ] );
6142                                                 // If the active item is on the top level, let it stay active.
6143                                                 // Otherwise, blur the active item since it is no longer visible.
6144                                                 if ( this.active && this.active.parents( ".ui-menu" ).length === 1 ) {
6145                                                         clearTimeout( this.timer );
6146                                                 }
6147                                         }
6148                                 }
6149                         },
6150                         "mouseenter .ui-menu-item": function( event ) {
6151                                 var target = $( event.currentTarget );
6152                                 // Remove ui-state-active class from siblings of the newly focused menu item
6153                                 // to avoid a jump caused by adjacent elements both having a class with a border
6154                                 target.siblings( ".ui-state-active" ).removeClass( "ui-state-active" );
6155                                 this.focus( event, target );
6156                         },
6157                         mouseleave: "collapseAll",
6158                         "mouseleave .ui-menu": "collapseAll",
6159                         focus: function( event, keepActiveItem ) {
6160                                 // If there's already an active item, keep it active
6161                                 // If not, activate the first item
6162                                 var item = this.active || this.element.find( this.options.items ).eq( 0 );
6164                                 if ( !keepActiveItem ) {
6165                                         this.focus( event, item );
6166                                 }
6167                         },
6168                         blur: function( event ) {
6169                                 this._delay(function() {
6170                                         if ( !$.contains( this.element[0], this.document[0].activeElement ) ) {
6171                                                 this.collapseAll( event );
6172                                         }
6173                                 });
6174                         },
6175                         keydown: "_keydown"
6176                 });
6178                 this.refresh();
6180                 // Clicks outside of a menu collapse any open menus
6181                 this._on( this.document, {
6182                         click: function( event ) {
6183                                 if ( this._closeOnDocumentClick( event ) ) {
6184                                         this.collapseAll( event );
6185                                 }
6187                                 // Reset the mouseHandled flag
6188                                 this.mouseHandled = false;
6189                         }
6190                 });
6191         },
6193         _destroy: function() {
6194                 // Destroy (sub)menus
6195                 this.element
6196                         .removeAttr( "aria-activedescendant" )
6197                         .find( ".ui-menu" ).addBack()
6198                                 .removeClass( "ui-menu ui-widget ui-widget-content ui-menu-icons ui-front" )
6199                                 .removeAttr( "role" )
6200                                 .removeAttr( "tabIndex" )
6201                                 .removeAttr( "aria-labelledby" )
6202                                 .removeAttr( "aria-expanded" )
6203                                 .removeAttr( "aria-hidden" )
6204                                 .removeAttr( "aria-disabled" )
6205                                 .removeUniqueId()
6206                                 .show();
6208                 // Destroy menu items
6209                 this.element.find( ".ui-menu-item" )
6210                         .removeClass( "ui-menu-item" )
6211                         .removeAttr( "role" )
6212                         .removeAttr( "aria-disabled" )
6213                         .removeUniqueId()
6214                         .removeClass( "ui-state-hover" )
6215                         .removeAttr( "tabIndex" )
6216                         .removeAttr( "role" )
6217                         .removeAttr( "aria-haspopup" )
6218                         .children().each( function() {
6219                                 var elem = $( this );
6220                                 if ( elem.data( "ui-menu-submenu-carat" ) ) {
6221                                         elem.remove();
6222                                 }
6223                         });
6225                 // Destroy menu dividers
6226                 this.element.find( ".ui-menu-divider" ).removeClass( "ui-menu-divider ui-widget-content" );
6227         },
6229         _keydown: function( event ) {
6230                 var match, prev, character, skip, regex,
6231                         preventDefault = true;
6233                 function escape( value ) {
6234                         return value.replace( /[\-\[\]{}()*+?.,\\\^$|#\s]/g, "\\$&" );
6235                 }
6237                 switch ( event.keyCode ) {
6238                 case $.ui.keyCode.PAGE_UP:
6239                         this.previousPage( event );
6240                         break;
6241                 case $.ui.keyCode.PAGE_DOWN:
6242                         this.nextPage( event );
6243                         break;
6244                 case $.ui.keyCode.HOME:
6245                         this._move( "first", "first", event );
6246                         break;
6247                 case $.ui.keyCode.END:
6248                         this._move( "last", "last", event );
6249                         break;
6250                 case $.ui.keyCode.UP:
6251                         this.previous( event );
6252                         break;
6253                 case $.ui.keyCode.DOWN:
6254                         this.next( event );
6255                         break;
6256                 case $.ui.keyCode.LEFT:
6257                         this.collapse( event );
6258                         break;
6259                 case $.ui.keyCode.RIGHT:
6260                         if ( this.active && !this.active.is( ".ui-state-disabled" ) ) {
6261                                 this.expand( event );
6262                         }
6263                         break;
6264                 case $.ui.keyCode.ENTER:
6265                 case $.ui.keyCode.SPACE:
6266                         this._activate( event );
6267                         break;
6268                 case $.ui.keyCode.ESCAPE:
6269                         this.collapse( event );
6270                         break;
6271                 default:
6272                         preventDefault = false;
6273                         prev = this.previousFilter || "";
6274                         character = String.fromCharCode( event.keyCode );
6275                         skip = false;
6277                         clearTimeout( this.filterTimer );
6279                         if ( character === prev ) {
6280                                 skip = true;
6281                         } else {
6282                                 character = prev + character;
6283                         }
6285                         regex = new RegExp( "^" + escape( character ), "i" );
6286                         match = this.activeMenu.find( this.options.items ).filter(function() {
6287                                 return regex.test( $( this ).text() );
6288                         });
6289                         match = skip && match.index( this.active.next() ) !== -1 ?
6290                                 this.active.nextAll( ".ui-menu-item" ) :
6291                                 match;
6293                         // If no matches on the current filter, reset to the last character pressed
6294                         // to move down the menu to the first item that starts with that character
6295                         if ( !match.length ) {
6296                                 character = String.fromCharCode( event.keyCode );
6297                                 regex = new RegExp( "^" + escape( character ), "i" );
6298                                 match = this.activeMenu.find( this.options.items ).filter(function() {
6299                                         return regex.test( $( this ).text() );
6300                                 });
6301                         }
6303                         if ( match.length ) {
6304                                 this.focus( event, match );
6305                                 if ( match.length > 1 ) {
6306                                         this.previousFilter = character;
6307                                         this.filterTimer = this._delay(function() {
6308                                                 delete this.previousFilter;
6309                                         }, 1000 );
6310                                 } else {
6311                                         delete this.previousFilter;
6312                                 }
6313                         } else {
6314                                 delete this.previousFilter;
6315                         }
6316                 }
6318                 if ( preventDefault ) {
6319                         event.preventDefault();
6320                 }
6321         },
6323         _activate: function( event ) {
6324                 if ( !this.active.is( ".ui-state-disabled" ) ) {
6325                         if ( this.active.is( "[aria-haspopup='true']" ) ) {
6326                                 this.expand( event );
6327                         } else {
6328                                 this.select( event );
6329                         }
6330                 }
6331         },
6333         refresh: function() {
6334                 var menus, items,
6335                         that = this,
6336                         icon = this.options.icons.submenu,
6337                         submenus = this.element.find( this.options.menus );
6339                 this.element.toggleClass( "ui-menu-icons", !!this.element.find( ".ui-icon" ).length );
6341                 // Initialize nested menus
6342                 submenus.filter( ":not(.ui-menu)" )
6343                         .addClass( "ui-menu ui-widget ui-widget-content ui-front" )
6344                         .hide()
6345                         .attr({
6346                                 role: this.options.role,
6347                                 "aria-hidden": "true",
6348                                 "aria-expanded": "false"
6349                         })
6350                         .each(function() {
6351                                 var menu = $( this ),
6352                                         item = menu.parent(),
6353                                         submenuCarat = $( "<span>" )
6354                                                 .addClass( "ui-menu-icon ui-icon " + icon )
6355                                                 .data( "ui-menu-submenu-carat", true );
6357                                 item
6358                                         .attr( "aria-haspopup", "true" )
6359                                         .prepend( submenuCarat );
6360                                 menu.attr( "aria-labelledby", item.attr( "id" ) );
6361                         });
6363                 menus = submenus.add( this.element );
6364                 items = menus.find( this.options.items );
6366                 // Initialize menu-items containing spaces and/or dashes only as dividers
6367                 items.not( ".ui-menu-item" ).each(function() {
6368                         var item = $( this );
6369                         if ( that._isDivider( item ) ) {
6370                                 item.addClass( "ui-widget-content ui-menu-divider" );
6371                         }
6372                 });
6374                 // Don't refresh list items that are already adapted
6375                 items.not( ".ui-menu-item, .ui-menu-divider" )
6376                         .addClass( "ui-menu-item" )
6377                         .uniqueId()
6378                         .attr({
6379                                 tabIndex: -1,
6380                                 role: this._itemRole()
6381                         });
6383                 // Add aria-disabled attribute to any disabled menu item
6384                 items.filter( ".ui-state-disabled" ).attr( "aria-disabled", "true" );
6386                 // If the active item has been removed, blur the menu
6387                 if ( this.active && !$.contains( this.element[ 0 ], this.active[ 0 ] ) ) {
6388                         this.blur();
6389                 }
6390         },
6392         _itemRole: function() {
6393                 return {
6394                         menu: "menuitem",
6395                         listbox: "option"
6396                 }[ this.options.role ];
6397         },
6399         _setOption: function( key, value ) {
6400                 if ( key === "icons" ) {
6401                         this.element.find( ".ui-menu-icon" )
6402                                 .removeClass( this.options.icons.submenu )
6403                                 .addClass( value.submenu );
6404                 }
6405                 if ( key === "disabled" ) {
6406                         this.element
6407                                 .toggleClass( "ui-state-disabled", !!value )
6408                                 .attr( "aria-disabled", value );
6409                 }
6410                 this._super( key, value );
6411         },
6413         focus: function( event, item ) {
6414                 var nested, focused;
6415                 this.blur( event, event && event.type === "focus" );
6417                 this._scrollIntoView( item );
6419                 this.active = item.first();
6420                 focused = this.active.addClass( "ui-state-focus" ).removeClass( "ui-state-active" );
6421                 // Only update aria-activedescendant if there's a role
6422                 // otherwise we assume focus is managed elsewhere
6423                 if ( this.options.role ) {
6424                         this.element.attr( "aria-activedescendant", focused.attr( "id" ) );
6425                 }
6427                 // Highlight active parent menu item, if any
6428                 this.active
6429                         .parent()
6430                         .closest( ".ui-menu-item" )
6431                         .addClass( "ui-state-active" );
6433                 if ( event && event.type === "keydown" ) {
6434                         this._close();
6435                 } else {
6436                         this.timer = this._delay(function() {
6437                                 this._close();
6438                         }, this.delay );
6439                 }
6441                 nested = item.children( ".ui-menu" );
6442                 if ( nested.length && event && ( /^mouse/.test( event.type ) ) ) {
6443                         this._startOpening(nested);
6444                 }
6445                 this.activeMenu = item.parent();
6447                 this._trigger( "focus", event, { item: item } );
6448         },
6450         _scrollIntoView: function( item ) {
6451                 var borderTop, paddingTop, offset, scroll, elementHeight, itemHeight;
6452                 if ( this._hasScroll() ) {
6453                         borderTop = parseFloat( $.css( this.activeMenu[0], "borderTopWidth" ) ) || 0;
6454                         paddingTop = parseFloat( $.css( this.activeMenu[0], "paddingTop" ) ) || 0;
6455                         offset = item.offset().top - this.activeMenu.offset().top - borderTop - paddingTop;
6456                         scroll = this.activeMenu.scrollTop();
6457                         elementHeight = this.activeMenu.height();
6458                         itemHeight = item.outerHeight();
6460                         if ( offset < 0 ) {
6461                                 this.activeMenu.scrollTop( scroll + offset );
6462                         } else if ( offset + itemHeight > elementHeight ) {
6463                                 this.activeMenu.scrollTop( scroll + offset - elementHeight + itemHeight );
6464                         }
6465                 }
6466         },
6468         blur: function( event, fromFocus ) {
6469                 if ( !fromFocus ) {
6470                         clearTimeout( this.timer );
6471                 }
6473                 if ( !this.active ) {
6474                         return;
6475                 }
6477                 this.active.removeClass( "ui-state-focus" );
6478                 this.active = null;
6480                 this._trigger( "blur", event, { item: this.active } );
6481         },
6483         _startOpening: function( submenu ) {
6484                 clearTimeout( this.timer );
6486                 // Don't open if already open fixes a Firefox bug that caused a .5 pixel
6487                 // shift in the submenu position when mousing over the carat icon
6488                 if ( submenu.attr( "aria-hidden" ) !== "true" ) {
6489                         return;
6490                 }
6492                 this.timer = this._delay(function() {
6493                         this._close();
6494                         this._open( submenu );
6495                 }, this.delay );
6496         },
6498         _open: function( submenu ) {
6499                 var position = $.extend({
6500                         of: this.active
6501                 }, this.options.position );
6503                 clearTimeout( this.timer );
6504                 this.element.find( ".ui-menu" ).not( submenu.parents( ".ui-menu" ) )
6505                         .hide()
6506                         .attr( "aria-hidden", "true" );
6508                 submenu
6509                         .show()
6510                         .removeAttr( "aria-hidden" )
6511                         .attr( "aria-expanded", "true" )
6512                         .position( position );
6513         },
6515         collapseAll: function( event, all ) {
6516                 clearTimeout( this.timer );
6517                 this.timer = this._delay(function() {
6518                         // If we were passed an event, look for the submenu that contains the event
6519                         var currentMenu = all ? this.element :
6520                                 $( event && event.target ).closest( this.element.find( ".ui-menu" ) );
6522                         // If we found no valid submenu ancestor, use the main menu to close all sub menus anyway
6523                         if ( !currentMenu.length ) {
6524                                 currentMenu = this.element;
6525                         }
6527                         this._close( currentMenu );
6529                         this.blur( event );
6530                         this.activeMenu = currentMenu;
6531                 }, this.delay );
6532         },
6534         // With no arguments, closes the currently active menu - if nothing is active
6535         // it closes all menus.  If passed an argument, it will search for menus BELOW
6536         _close: function( startMenu ) {
6537                 if ( !startMenu ) {
6538                         startMenu = this.active ? this.active.parent() : this.element;
6539                 }
6541                 startMenu
6542                         .find( ".ui-menu" )
6543                                 .hide()
6544                                 .attr( "aria-hidden", "true" )
6545                                 .attr( "aria-expanded", "false" )
6546                         .end()
6547                         .find( ".ui-state-active" ).not( ".ui-state-focus" )
6548                                 .removeClass( "ui-state-active" );
6549         },
6551         _closeOnDocumentClick: function( event ) {
6552                 return !$( event.target ).closest( ".ui-menu" ).length;
6553         },
6555         _isDivider: function( item ) {
6557                 // Match hyphen, em dash, en dash
6558                 return !/[^\-\u2014\u2013\s]/.test( item.text() );
6559         },
6561         collapse: function( event ) {
6562                 var newItem = this.active &&
6563                         this.active.parent().closest( ".ui-menu-item", this.element );
6564                 if ( newItem && newItem.length ) {
6565                         this._close();
6566                         this.focus( event, newItem );
6567                 }
6568         },
6570         expand: function( event ) {
6571                 var newItem = this.active &&
6572                         this.active
6573                                 .children( ".ui-menu " )
6574                                 .find( this.options.items )
6575                                 .first();
6577                 if ( newItem && newItem.length ) {
6578                         this._open( newItem.parent() );
6580                         // Delay so Firefox will not hide activedescendant change in expanding submenu from AT
6581                         this._delay(function() {
6582                                 this.focus( event, newItem );
6583                         });
6584                 }
6585         },
6587         next: function( event ) {
6588                 this._move( "next", "first", event );
6589         },
6591         previous: function( event ) {
6592                 this._move( "prev", "last", event );
6593         },
6595         isFirstItem: function() {
6596                 return this.active && !this.active.prevAll( ".ui-menu-item" ).length;
6597         },
6599         isLastItem: function() {
6600                 return this.active && !this.active.nextAll( ".ui-menu-item" ).length;
6601         },
6603         _move: function( direction, filter, event ) {
6604                 var next;
6605                 if ( this.active ) {
6606                         if ( direction === "first" || direction === "last" ) {
6607                                 next = this.active
6608                                         [ direction === "first" ? "prevAll" : "nextAll" ]( ".ui-menu-item" )
6609                                         .eq( -1 );
6610                         } else {
6611                                 next = this.active
6612                                         [ direction + "All" ]( ".ui-menu-item" )
6613                                         .eq( 0 );
6614                         }
6615                 }
6616                 if ( !next || !next.length || !this.active ) {
6617                         next = this.activeMenu.find( this.options.items )[ filter ]();
6618                 }
6620                 this.focus( event, next );
6621         },
6623         nextPage: function( event ) {
6624                 var item, base, height;
6626                 if ( !this.active ) {
6627                         this.next( event );
6628                         return;
6629                 }
6630                 if ( this.isLastItem() ) {
6631                         return;
6632                 }
6633                 if ( this._hasScroll() ) {
6634                         base = this.active.offset().top;
6635                         height = this.element.height();
6636                         this.active.nextAll( ".ui-menu-item" ).each(function() {
6637                                 item = $( this );
6638                                 return item.offset().top - base - height < 0;
6639                         });
6641                         this.focus( event, item );
6642                 } else {
6643                         this.focus( event, this.activeMenu.find( this.options.items )
6644                                 [ !this.active ? "first" : "last" ]() );
6645                 }
6646         },
6648         previousPage: function( event ) {
6649                 var item, base, height;
6650                 if ( !this.active ) {
6651                         this.next( event );
6652                         return;
6653                 }
6654                 if ( this.isFirstItem() ) {
6655                         return;
6656                 }
6657                 if ( this._hasScroll() ) {
6658                         base = this.active.offset().top;
6659                         height = this.element.height();
6660                         this.active.prevAll( ".ui-menu-item" ).each(function() {
6661                                 item = $( this );
6662                                 return item.offset().top - base + height > 0;
6663                         });
6665                         this.focus( event, item );
6666                 } else {
6667                         this.focus( event, this.activeMenu.find( this.options.items ).first() );
6668                 }
6669         },
6671         _hasScroll: function() {
6672                 return this.element.outerHeight() < this.element.prop( "scrollHeight" );
6673         },
6675         select: function( event ) {
6676                 // TODO: It should never be possible to not have an active item at this
6677                 // point, but the tests don't trigger mouseenter before click.
6678                 this.active = this.active || $( event.target ).closest( ".ui-menu-item" );
6679                 var ui = { item: this.active };
6680                 if ( !this.active.has( ".ui-menu" ).length ) {
6681                         this.collapseAll( event, true );
6682                 }
6683                 this._trigger( "select", event, ui );
6684         }
6689  * jQuery UI Autocomplete 1.11.0
6690  * http://jqueryui.com
6692  * Copyright 2014 jQuery Foundation and other contributors
6693  * Released under the MIT license.
6694  * http://jquery.org/license
6696  * http://api.jqueryui.com/autocomplete/
6697  */
6700 $.widget( "ui.autocomplete", {
6701         version: "1.11.0",
6702         defaultElement: "<input>",
6703         options: {
6704                 appendTo: null,
6705                 autoFocus: false,
6706                 delay: 300,
6707                 minLength: 1,
6708                 position: {
6709                         my: "left top",
6710                         at: "left bottom",
6711                         collision: "none"
6712                 },
6713                 source: null,
6715                 // callbacks
6716                 change: null,
6717                 close: null,
6718                 focus: null,
6719                 open: null,
6720                 response: null,
6721                 search: null,
6722                 select: null
6723         },
6725         requestIndex: 0,
6726         pending: 0,
6728         _create: function() {
6729                 // Some browsers only repeat keydown events, not keypress events,
6730                 // so we use the suppressKeyPress flag to determine if we've already
6731                 // handled the keydown event. #7269
6732                 // Unfortunately the code for & in keypress is the same as the up arrow,
6733                 // so we use the suppressKeyPressRepeat flag to avoid handling keypress
6734                 // events when we know the keydown event was used to modify the
6735                 // search term. #7799
6736                 var suppressKeyPress, suppressKeyPressRepeat, suppressInput,
6737                         nodeName = this.element[ 0 ].nodeName.toLowerCase(),
6738                         isTextarea = nodeName === "textarea",
6739                         isInput = nodeName === "input";
6741                 this.isMultiLine =
6742                         // Textareas are always multi-line
6743                         isTextarea ? true :
6744                         // Inputs are always single-line, even if inside a contentEditable element
6745                         // IE also treats inputs as contentEditable
6746                         isInput ? false :
6747                         // All other element types are determined by whether or not they're contentEditable
6748                         this.element.prop( "isContentEditable" );
6750                 this.valueMethod = this.element[ isTextarea || isInput ? "val" : "text" ];
6751                 this.isNewMenu = true;
6753                 this.element
6754                         .addClass( "ui-autocomplete-input" )
6755                         .attr( "autocomplete", "off" );
6757                 this._on( this.element, {
6758                         keydown: function( event ) {
6759                                 if ( this.element.prop( "readOnly" ) ) {
6760                                         suppressKeyPress = true;
6761                                         suppressInput = true;
6762                                         suppressKeyPressRepeat = true;
6763                                         return;
6764                                 }
6766                                 suppressKeyPress = false;
6767                                 suppressInput = false;
6768                                 suppressKeyPressRepeat = false;
6769                                 var keyCode = $.ui.keyCode;
6770                                 switch ( event.keyCode ) {
6771                                 case keyCode.PAGE_UP:
6772                                         suppressKeyPress = true;
6773                                         this._move( "previousPage", event );
6774                                         break;
6775                                 case keyCode.PAGE_DOWN:
6776                                         suppressKeyPress = true;
6777                                         this._move( "nextPage", event );
6778                                         break;
6779                                 case keyCode.UP:
6780                                         suppressKeyPress = true;
6781                                         this._keyEvent( "previous", event );
6782                                         break;
6783                                 case keyCode.DOWN:
6784                                         suppressKeyPress = true;
6785                                         this._keyEvent( "next", event );
6786                                         break;
6787                                 case keyCode.ENTER:
6788                                         // when menu is open and has focus
6789                                         if ( this.menu.active ) {
6790                                                 // #6055 - Opera still allows the keypress to occur
6791                                                 // which causes forms to submit
6792                                                 suppressKeyPress = true;
6793                                                 event.preventDefault();
6794                                                 this.menu.select( event );
6795                                         }
6796                                         break;
6797                                 case keyCode.TAB:
6798                                         if ( this.menu.active ) {
6799                                                 this.menu.select( event );
6800                                         }
6801                                         break;
6802                                 case keyCode.ESCAPE:
6803                                         if ( this.menu.element.is( ":visible" ) ) {
6804                                                 this._value( this.term );
6805                                                 this.close( event );
6806                                                 // Different browsers have different default behavior for escape
6807                                                 // Single press can mean undo or clear
6808                                                 // Double press in IE means clear the whole form
6809                                                 event.preventDefault();
6810                                         }
6811                                         break;
6812                                 default:
6813                                         suppressKeyPressRepeat = true;
6814                                         // search timeout should be triggered before the input value is changed
6815                                         this._searchTimeout( event );
6816                                         break;
6817                                 }
6818                         },
6819                         keypress: function( event ) {
6820                                 if ( suppressKeyPress ) {
6821                                         suppressKeyPress = false;
6822                                         if ( !this.isMultiLine || this.menu.element.is( ":visible" ) ) {
6823                                                 event.preventDefault();
6824                                         }
6825                                         return;
6826                                 }
6827                                 if ( suppressKeyPressRepeat ) {
6828                                         return;
6829                                 }
6831                                 // replicate some key handlers to allow them to repeat in Firefox and Opera
6832                                 var keyCode = $.ui.keyCode;
6833                                 switch ( event.keyCode ) {
6834                                 case keyCode.PAGE_UP:
6835                                         this._move( "previousPage", event );
6836                                         break;
6837                                 case keyCode.PAGE_DOWN:
6838                                         this._move( "nextPage", event );
6839                                         break;
6840                                 case keyCode.UP:
6841                                         this._keyEvent( "previous", event );
6842                                         break;
6843                                 case keyCode.DOWN:
6844                                         this._keyEvent( "next", event );
6845                                         break;
6846                                 }
6847                         },
6848                         input: function( event ) {
6849                                 if ( suppressInput ) {
6850                                         suppressInput = false;
6851                                         event.preventDefault();
6852                                         return;
6853                                 }
6854                                 this._searchTimeout( event );
6855                         },
6856                         focus: function() {
6857                                 this.selectedItem = null;
6858                                 this.previous = this._value();
6859                         },
6860                         blur: function( event ) {
6861                                 if ( this.cancelBlur ) {
6862                                         delete this.cancelBlur;
6863                                         return;
6864                                 }
6866                                 clearTimeout( this.searching );
6867                                 this.close( event );
6868                                 this._change( event );
6869                         }
6870                 });
6872                 this._initSource();
6873                 this.menu = $( "<ul>" )
6874                         .addClass( "ui-autocomplete ui-front" )
6875                         .appendTo( this._appendTo() )
6876                         .menu({
6877                                 // disable ARIA support, the live region takes care of that
6878                                 role: null
6879                         })
6880                         .hide()
6881                         .menu( "instance" );
6883                 this._on( this.menu.element, {
6884                         mousedown: function( event ) {
6885                                 // prevent moving focus out of the text field
6886                                 event.preventDefault();
6888                                 // IE doesn't prevent moving focus even with event.preventDefault()
6889                                 // so we set a flag to know when we should ignore the blur event
6890                                 this.cancelBlur = true;
6891                                 this._delay(function() {
6892                                         delete this.cancelBlur;
6893                                 });
6895                                 // clicking on the scrollbar causes focus to shift to the body
6896                                 // but we can't detect a mouseup or a click immediately afterward
6897                                 // so we have to track the next mousedown and close the menu if
6898                                 // the user clicks somewhere outside of the autocomplete
6899                                 var menuElement = this.menu.element[ 0 ];
6900                                 if ( !$( event.target ).closest( ".ui-menu-item" ).length ) {
6901                                         this._delay(function() {
6902                                                 var that = this;
6903                                                 this.document.one( "mousedown", function( event ) {
6904                                                         if ( event.target !== that.element[ 0 ] &&
6905                                                                         event.target !== menuElement &&
6906                                                                         !$.contains( menuElement, event.target ) ) {
6907                                                                 that.close();
6908                                                         }
6909                                                 });
6910                                         });
6911                                 }
6912                         },
6913                         menufocus: function( event, ui ) {
6914                                 var label, item;
6915                                 // support: Firefox
6916                                 // Prevent accidental activation of menu items in Firefox (#7024 #9118)
6917                                 if ( this.isNewMenu ) {
6918                                         this.isNewMenu = false;
6919                                         if ( event.originalEvent && /^mouse/.test( event.originalEvent.type ) ) {
6920                                                 this.menu.blur();
6922                                                 this.document.one( "mousemove", function() {
6923                                                         $( event.target ).trigger( event.originalEvent );
6924                                                 });
6926                                                 return;
6927                                         }
6928                                 }
6930                                 item = ui.item.data( "ui-autocomplete-item" );
6931                                 if ( false !== this._trigger( "focus", event, { item: item } ) ) {
6932                                         // use value to match what will end up in the input, if it was a key event
6933                                         if ( event.originalEvent && /^key/.test( event.originalEvent.type ) ) {
6934                                                 this._value( item.value );
6935                                         }
6936                                 }
6938                                 // Announce the value in the liveRegion
6939                                 label = ui.item.attr( "aria-label" ) || item.value;
6940                                 if ( label && jQuery.trim( label ).length ) {
6941                                         this.liveRegion.children().hide();
6942                                         $( "<div>" ).text( label ).appendTo( this.liveRegion );
6943                                 }
6944                         },
6945                         menuselect: function( event, ui ) {
6946                                 var item = ui.item.data( "ui-autocomplete-item" ),
6947                                         previous = this.previous;
6949                                 // only trigger when focus was lost (click on menu)
6950                                 if ( this.element[ 0 ] !== this.document[ 0 ].activeElement ) {
6951                                         this.element.focus();
6952                                         this.previous = previous;
6953                                         // #6109 - IE triggers two focus events and the second
6954                                         // is asynchronous, so we need to reset the previous
6955                                         // term synchronously and asynchronously :-(
6956                                         this._delay(function() {
6957                                                 this.previous = previous;
6958                                                 this.selectedItem = item;
6959                                         });
6960                                 }
6962                                 if ( false !== this._trigger( "select", event, { item: item } ) ) {
6963                                         this._value( item.value );
6964                                 }
6965                                 // reset the term after the select event
6966                                 // this allows custom select handling to work properly
6967                                 this.term = this._value();
6969                                 this.close( event );
6970                                 this.selectedItem = item;
6971                         }
6972                 });
6974                 this.liveRegion = $( "<span>", {
6975                                 role: "status",
6976                                 "aria-live": "assertive",
6977                                 "aria-relevant": "additions"
6978                         })
6979                         .addClass( "ui-helper-hidden-accessible" )
6980                         .appendTo( this.document[ 0 ].body );
6982                 // turning off autocomplete prevents the browser from remembering the
6983                 // value when navigating through history, so we re-enable autocomplete
6984                 // if the page is unloaded before the widget is destroyed. #7790
6985                 this._on( this.window, {
6986                         beforeunload: function() {
6987                                 this.element.removeAttr( "autocomplete" );
6988                         }
6989                 });
6990         },
6992         _destroy: function() {
6993                 clearTimeout( this.searching );
6994                 this.element
6995                         .removeClass( "ui-autocomplete-input" )
6996                         .removeAttr( "autocomplete" );
6997                 this.menu.element.remove();
6998                 this.liveRegion.remove();
6999         },
7001         _setOption: function( key, value ) {
7002                 this._super( key, value );
7003                 if ( key === "source" ) {
7004                         this._initSource();
7005                 }
7006                 if ( key === "appendTo" ) {
7007                         this.menu.element.appendTo( this._appendTo() );
7008                 }
7009                 if ( key === "disabled" && value && this.xhr ) {
7010                         this.xhr.abort();
7011                 }
7012         },
7014         _appendTo: function() {
7015                 var element = this.options.appendTo;
7017                 if ( element ) {
7018                         element = element.jquery || element.nodeType ?
7019                                 $( element ) :
7020                                 this.document.find( element ).eq( 0 );
7021                 }
7023                 if ( !element || !element[ 0 ] ) {
7024                         element = this.element.closest( ".ui-front" );
7025                 }
7027                 if ( !element.length ) {
7028                         element = this.document[ 0 ].body;
7029                 }
7031                 return element;
7032         },
7034         _initSource: function() {
7035                 var array, url,
7036                         that = this;
7037                 if ( $.isArray( this.options.source ) ) {
7038                         array = this.options.source;
7039                         this.source = function( request, response ) {
7040                                 response( $.ui.autocomplete.filter( array, request.term ) );
7041                         };
7042                 } else if ( typeof this.options.source === "string" ) {
7043                         url = this.options.source;
7044                         this.source = function( request, response ) {
7045                                 if ( that.xhr ) {
7046                                         that.xhr.abort();
7047                                 }
7048                                 that.xhr = $.ajax({
7049                                         url: url,
7050                                         data: request,
7051                                         dataType: "json",
7052                                         success: function( data ) {
7053                                                 response( data );
7054                                         },
7055                                         error: function() {
7056                                                 response([]);
7057                                         }
7058                                 });
7059                         };
7060                 } else {
7061                         this.source = this.options.source;
7062                 }
7063         },
7065         _searchTimeout: function( event ) {
7066                 clearTimeout( this.searching );
7067                 this.searching = this._delay(function() {
7069                         // Search if the value has changed, or if the user retypes the same value (see #7434)
7070                         var equalValues = this.term === this._value(),
7071                                 menuVisible = this.menu.element.is( ":visible" ),
7072                                 modifierKey = event.altKey || event.ctrlKey || event.metaKey || event.shiftKey;
7074                         if ( !equalValues || ( equalValues && !menuVisible && !modifierKey ) ) {
7075                                 this.selectedItem = null;
7076                                 this.search( null, event );
7077                         }
7078                 }, this.options.delay );
7079         },
7081         search: function( value, event ) {
7082                 value = value != null ? value : this._value();
7084                 // always save the actual value, not the one passed as an argument
7085                 this.term = this._value();
7087                 if ( value.length < this.options.minLength ) {
7088                         return this.close( event );
7089                 }
7091                 if ( this._trigger( "search", event ) === false ) {
7092                         return;
7093                 }
7095                 return this._search( value );
7096         },
7098         _search: function( value ) {
7099                 this.pending++;
7100                 this.element.addClass( "ui-autocomplete-loading" );
7101                 this.cancelSearch = false;
7103                 this.source( { term: value }, this._response() );
7104         },
7106         _response: function() {
7107                 var index = ++this.requestIndex;
7109                 return $.proxy(function( content ) {
7110                         if ( index === this.requestIndex ) {
7111                                 this.__response( content );
7112                         }
7114                         this.pending--;
7115                         if ( !this.pending ) {
7116                                 this.element.removeClass( "ui-autocomplete-loading" );
7117                         }
7118                 }, this );
7119         },
7121         __response: function( content ) {
7122                 if ( content ) {
7123                         content = this._normalize( content );
7124                 }
7125                 this._trigger( "response", null, { content: content } );
7126                 if ( !this.options.disabled && content && content.length && !this.cancelSearch ) {
7127                         this._suggest( content );
7128                         this._trigger( "open" );
7129                 } else {
7130                         // use ._close() instead of .close() so we don't cancel future searches
7131                         this._close();
7132                 }
7133         },
7135         close: function( event ) {
7136                 this.cancelSearch = true;
7137                 this._close( event );
7138         },
7140         _close: function( event ) {
7141                 if ( this.menu.element.is( ":visible" ) ) {
7142                         this.menu.element.hide();
7143                         this.menu.blur();
7144                         this.isNewMenu = true;
7145                         this._trigger( "close", event );
7146                 }
7147         },
7149         _change: function( event ) {
7150                 if ( this.previous !== this._value() ) {
7151                         this._trigger( "change", event, { item: this.selectedItem } );
7152                 }
7153         },
7155         _normalize: function( items ) {
7156                 // assume all items have the right format when the first item is complete
7157                 if ( items.length && items[ 0 ].label && items[ 0 ].value ) {
7158                         return items;
7159                 }
7160                 return $.map( items, function( item ) {
7161                         if ( typeof item === "string" ) {
7162                                 return {
7163                                         label: item,
7164                                         value: item
7165                                 };
7166                         }
7167                         return $.extend( {}, item, {
7168                                 label: item.label || item.value,
7169                                 value: item.value || item.label
7170                         });
7171                 });
7172         },
7174         _suggest: function( items ) {
7175                 var ul = this.menu.element.empty();
7176                 this._renderMenu( ul, items );
7177                 this.isNewMenu = true;
7178                 this.menu.refresh();
7180                 // size and position menu
7181                 ul.show();
7182                 this._resizeMenu();
7183                 ul.position( $.extend({
7184                         of: this.element
7185                 }, this.options.position ) );
7187                 if ( this.options.autoFocus ) {
7188                         this.menu.next();
7189                 }
7190         },
7192         _resizeMenu: function() {
7193                 var ul = this.menu.element;
7194                 ul.outerWidth( Math.max(
7195                         // Firefox wraps long text (possibly a rounding bug)
7196                         // so we add 1px to avoid the wrapping (#7513)
7197                         ul.width( "" ).outerWidth() + 1,
7198                         this.element.outerWidth()
7199                 ) );
7200         },
7202         _renderMenu: function( ul, items ) {
7203                 var that = this;
7204                 $.each( items, function( index, item ) {
7205                         that._renderItemData( ul, item );
7206                 });
7207         },
7209         _renderItemData: function( ul, item ) {
7210                 return this._renderItem( ul, item ).data( "ui-autocomplete-item", item );
7211         },
7213         _renderItem: function( ul, item ) {
7214                 return $( "<li>" ).text( item.label ).appendTo( ul );
7215         },
7217         _move: function( direction, event ) {
7218                 if ( !this.menu.element.is( ":visible" ) ) {
7219                         this.search( null, event );
7220                         return;
7221                 }
7222                 if ( this.menu.isFirstItem() && /^previous/.test( direction ) ||
7223                                 this.menu.isLastItem() && /^next/.test( direction ) ) {
7225                         if ( !this.isMultiLine ) {
7226                                 this._value( this.term );
7227                         }
7229                         this.menu.blur();
7230                         return;
7231                 }
7232                 this.menu[ direction ]( event );
7233         },
7235         widget: function() {
7236                 return this.menu.element;
7237         },
7239         _value: function() {
7240                 return this.valueMethod.apply( this.element, arguments );
7241         },
7243         _keyEvent: function( keyEvent, event ) {
7244                 if ( !this.isMultiLine || this.menu.element.is( ":visible" ) ) {
7245                         this._move( keyEvent, event );
7247                         // prevents moving cursor to beginning/end of the text field in some browsers
7248                         event.preventDefault();
7249                 }
7250         }
7253 $.extend( $.ui.autocomplete, {
7254         escapeRegex: function( value ) {
7255                 return value.replace( /[\-\[\]{}()*+?.,\\\^$|#\s]/g, "\\$&" );
7256         },
7257         filter: function( array, term ) {
7258                 var matcher = new RegExp( $.ui.autocomplete.escapeRegex( term ), "i" );
7259                 return $.grep( array, function( value ) {
7260                         return matcher.test( value.label || value.value || value );
7261                 });
7262         }
7265 // live region extension, adding a `messages` option
7266 // NOTE: This is an experimental API. We are still investigating
7267 // a full solution for string manipulation and internationalization.
7268 $.widget( "ui.autocomplete", $.ui.autocomplete, {
7269         options: {
7270                 messages: {
7271                         noResults: "No search results.",
7272                         results: function( amount ) {
7273                                 return amount + ( amount > 1 ? " results are" : " result is" ) +
7274                                         " available, use up and down arrow keys to navigate.";
7275                         }
7276                 }
7277         },
7279         __response: function( content ) {
7280                 var message;
7281                 this._superApply( arguments );
7282                 if ( this.options.disabled || this.cancelSearch ) {
7283                         return;
7284                 }
7285                 if ( content && content.length ) {
7286                         message = this.options.messages.results( content.length );
7287                 } else {
7288                         message = this.options.messages.noResults;
7289                 }
7290                 this.liveRegion.children().hide();
7291                 $( "<div>" ).text( message ).appendTo( this.liveRegion );
7292         }
7295 var autocomplete = $.ui.autocomplete;
7299  * jQuery UI Button 1.11.0
7300  * http://jqueryui.com
7302  * Copyright 2014 jQuery Foundation and other contributors
7303  * Released under the MIT license.
7304  * http://jquery.org/license
7306  * http://api.jqueryui.com/button/
7307  */
7310 var lastActive,
7311         baseClasses = "ui-button ui-widget ui-state-default ui-corner-all",
7312         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",
7313         formResetHandler = function() {
7314                 var form = $( this );
7315                 setTimeout(function() {
7316                         form.find( ":ui-button" ).button( "refresh" );
7317                 }, 1 );
7318         },
7319         radioGroup = function( radio ) {
7320                 var name = radio.name,
7321                         form = radio.form,
7322                         radios = $( [] );
7323                 if ( name ) {
7324                         name = name.replace( /'/g, "\\'" );
7325                         if ( form ) {
7326                                 radios = $( form ).find( "[name='" + name + "'][type=radio]" );
7327                         } else {
7328                                 radios = $( "[name='" + name + "'][type=radio]", radio.ownerDocument )
7329                                         .filter(function() {
7330                                                 return !this.form;
7331                                         });
7332                         }
7333                 }
7334                 return radios;
7335         };
7337 $.widget( "ui.button", {
7338         version: "1.11.0",
7339         defaultElement: "<button>",
7340         options: {
7341                 disabled: null,
7342                 text: true,
7343                 label: null,
7344                 icons: {
7345                         primary: null,
7346                         secondary: null
7347                 }
7348         },
7349         _create: function() {
7350                 this.element.closest( "form" )
7351                         .unbind( "reset" + this.eventNamespace )
7352                         .bind( "reset" + this.eventNamespace, formResetHandler );
7354                 if ( typeof this.options.disabled !== "boolean" ) {
7355                         this.options.disabled = !!this.element.prop( "disabled" );
7356                 } else {
7357                         this.element.prop( "disabled", this.options.disabled );
7358                 }
7360                 this._determineButtonType();
7361                 this.hasTitle = !!this.buttonElement.attr( "title" );
7363                 var that = this,
7364                         options = this.options,
7365                         toggleButton = this.type === "checkbox" || this.type === "radio",
7366                         activeClass = !toggleButton ? "ui-state-active" : "";
7368                 if ( options.label === null ) {
7369                         options.label = (this.type === "input" ? this.buttonElement.val() : this.buttonElement.html());
7370                 }
7372                 this._hoverable( this.buttonElement );
7374                 this.buttonElement
7375                         .addClass( baseClasses )
7376                         .attr( "role", "button" )
7377                         .bind( "mouseenter" + this.eventNamespace, function() {
7378                                 if ( options.disabled ) {
7379                                         return;
7380                                 }
7381                                 if ( this === lastActive ) {
7382                                         $( this ).addClass( "ui-state-active" );
7383                                 }
7384                         })
7385                         .bind( "mouseleave" + this.eventNamespace, function() {
7386                                 if ( options.disabled ) {
7387                                         return;
7388                                 }
7389                                 $( this ).removeClass( activeClass );
7390                         })
7391                         .bind( "click" + this.eventNamespace, function( event ) {
7392                                 if ( options.disabled ) {
7393                                         event.preventDefault();
7394                                         event.stopImmediatePropagation();
7395                                 }
7396                         });
7398                 // Can't use _focusable() because the element that receives focus
7399                 // and the element that gets the ui-state-focus class are different
7400                 this._on({
7401                         focus: function() {
7402                                 this.buttonElement.addClass( "ui-state-focus" );
7403                         },
7404                         blur: function() {
7405                                 this.buttonElement.removeClass( "ui-state-focus" );
7406                         }
7407                 });
7409                 if ( toggleButton ) {
7410                         this.element.bind( "change" + this.eventNamespace, function() {
7411                                 that.refresh();
7412                         });
7413                 }
7415                 if ( this.type === "checkbox" ) {
7416                         this.buttonElement.bind( "click" + this.eventNamespace, function() {
7417                                 if ( options.disabled ) {
7418                                         return false;
7419                                 }
7420                         });
7421                 } else if ( this.type === "radio" ) {
7422                         this.buttonElement.bind( "click" + this.eventNamespace, function() {
7423                                 if ( options.disabled ) {
7424                                         return false;
7425                                 }
7426                                 $( this ).addClass( "ui-state-active" );
7427                                 that.buttonElement.attr( "aria-pressed", "true" );
7429                                 var radio = that.element[ 0 ];
7430                                 radioGroup( radio )
7431                                         .not( radio )
7432                                         .map(function() {
7433                                                 return $( this ).button( "widget" )[ 0 ];
7434                                         })
7435                                         .removeClass( "ui-state-active" )
7436                                         .attr( "aria-pressed", "false" );
7437                         });
7438                 } else {
7439                         this.buttonElement
7440                                 .bind( "mousedown" + this.eventNamespace, function() {
7441                                         if ( options.disabled ) {
7442                                                 return false;
7443                                         }
7444                                         $( this ).addClass( "ui-state-active" );
7445                                         lastActive = this;
7446                                         that.document.one( "mouseup", function() {
7447                                                 lastActive = null;
7448                                         });
7449                                 })
7450                                 .bind( "mouseup" + this.eventNamespace, function() {
7451                                         if ( options.disabled ) {
7452                                                 return false;
7453                                         }
7454                                         $( this ).removeClass( "ui-state-active" );
7455                                 })
7456                                 .bind( "keydown" + this.eventNamespace, function(event) {
7457                                         if ( options.disabled ) {
7458                                                 return false;
7459                                         }
7460                                         if ( event.keyCode === $.ui.keyCode.SPACE || event.keyCode === $.ui.keyCode.ENTER ) {
7461                                                 $( this ).addClass( "ui-state-active" );
7462                                         }
7463                                 })
7464                                 // see #8559, we bind to blur here in case the button element loses
7465                                 // focus between keydown and keyup, it would be left in an "active" state
7466                                 .bind( "keyup" + this.eventNamespace + " blur" + this.eventNamespace, function() {
7467                                         $( this ).removeClass( "ui-state-active" );
7468                                 });
7470                         if ( this.buttonElement.is("a") ) {
7471                                 this.buttonElement.keyup(function(event) {
7472                                         if ( event.keyCode === $.ui.keyCode.SPACE ) {
7473                                                 // TODO pass through original event correctly (just as 2nd argument doesn't work)
7474                                                 $( this ).click();
7475                                         }
7476                                 });
7477                         }
7478                 }
7480                 this._setOption( "disabled", options.disabled );
7481                 this._resetButton();
7482         },
7484         _determineButtonType: function() {
7485                 var ancestor, labelSelector, checked;
7487                 if ( this.element.is("[type=checkbox]") ) {
7488                         this.type = "checkbox";
7489                 } else if ( this.element.is("[type=radio]") ) {
7490                         this.type = "radio";
7491                 } else if ( this.element.is("input") ) {
7492                         this.type = "input";
7493                 } else {
7494                         this.type = "button";
7495                 }
7497                 if ( this.type === "checkbox" || this.type === "radio" ) {
7498                         // we don't search against the document in case the element
7499                         // is disconnected from the DOM
7500                         ancestor = this.element.parents().last();
7501                         labelSelector = "label[for='" + this.element.attr("id") + "']";
7502                         this.buttonElement = ancestor.find( labelSelector );
7503                         if ( !this.buttonElement.length ) {
7504                                 ancestor = ancestor.length ? ancestor.siblings() : this.element.siblings();
7505                                 this.buttonElement = ancestor.filter( labelSelector );
7506                                 if ( !this.buttonElement.length ) {
7507                                         this.buttonElement = ancestor.find( labelSelector );
7508                                 }
7509                         }
7510                         this.element.addClass( "ui-helper-hidden-accessible" );
7512                         checked = this.element.is( ":checked" );
7513                         if ( checked ) {
7514                                 this.buttonElement.addClass( "ui-state-active" );
7515                         }
7516                         this.buttonElement.prop( "aria-pressed", checked );
7517                 } else {
7518                         this.buttonElement = this.element;
7519                 }
7520         },
7522         widget: function() {
7523                 return this.buttonElement;
7524         },
7526         _destroy: function() {
7527                 this.element
7528                         .removeClass( "ui-helper-hidden-accessible" );
7529                 this.buttonElement
7530                         .removeClass( baseClasses + " ui-state-active " + typeClasses )
7531                         .removeAttr( "role" )
7532                         .removeAttr( "aria-pressed" )
7533                         .html( this.buttonElement.find(".ui-button-text").html() );
7535                 if ( !this.hasTitle ) {
7536                         this.buttonElement.removeAttr( "title" );
7537                 }
7538         },
7540         _setOption: function( key, value ) {
7541                 this._super( key, value );
7542                 if ( key === "disabled" ) {
7543                         this.widget().toggleClass( "ui-state-disabled", !!value );
7544                         this.element.prop( "disabled", !!value );
7545                         if ( value ) {
7546                                 if ( this.type === "checkbox" || this.type === "radio" ) {
7547                                         this.buttonElement.removeClass( "ui-state-focus" );
7548                                 } else {
7549                                         this.buttonElement.removeClass( "ui-state-focus ui-state-active" );
7550                                 }
7551                         }
7552                         return;
7553                 }
7554                 this._resetButton();
7555         },
7557         refresh: function() {
7558                 //See #8237 & #8828
7559                 var isDisabled = this.element.is( "input, button" ) ? this.element.is( ":disabled" ) : this.element.hasClass( "ui-button-disabled" );
7561                 if ( isDisabled !== this.options.disabled ) {
7562                         this._setOption( "disabled", isDisabled );
7563                 }
7564                 if ( this.type === "radio" ) {
7565                         radioGroup( this.element[0] ).each(function() {
7566                                 if ( $( this ).is( ":checked" ) ) {
7567                                         $( this ).button( "widget" )
7568                                                 .addClass( "ui-state-active" )
7569                                                 .attr( "aria-pressed", "true" );
7570                                 } else {
7571                                         $( this ).button( "widget" )
7572                                                 .removeClass( "ui-state-active" )
7573                                                 .attr( "aria-pressed", "false" );
7574                                 }
7575                         });
7576                 } else if ( this.type === "checkbox" ) {
7577                         if ( this.element.is( ":checked" ) ) {
7578                                 this.buttonElement
7579                                         .addClass( "ui-state-active" )
7580                                         .attr( "aria-pressed", "true" );
7581                         } else {
7582                                 this.buttonElement
7583                                         .removeClass( "ui-state-active" )
7584                                         .attr( "aria-pressed", "false" );
7585                         }
7586                 }
7587         },
7589         _resetButton: function() {
7590                 if ( this.type === "input" ) {
7591                         if ( this.options.label ) {
7592                                 this.element.val( this.options.label );
7593                         }
7594                         return;
7595                 }
7596                 var buttonElement = this.buttonElement.removeClass( typeClasses ),
7597                         buttonText = $( "<span></span>", this.document[0] )
7598                                 .addClass( "ui-button-text" )
7599                                 .html( this.options.label )
7600                                 .appendTo( buttonElement.empty() )
7601                                 .text(),
7602                         icons = this.options.icons,
7603                         multipleIcons = icons.primary && icons.secondary,
7604                         buttonClasses = [];
7606                 if ( icons.primary || icons.secondary ) {
7607                         if ( this.options.text ) {
7608                                 buttonClasses.push( "ui-button-text-icon" + ( multipleIcons ? "s" : ( icons.primary ? "-primary" : "-secondary" ) ) );
7609                         }
7611                         if ( icons.primary ) {
7612                                 buttonElement.prepend( "<span class='ui-button-icon-primary ui-icon " + icons.primary + "'></span>" );
7613                         }
7615                         if ( icons.secondary ) {
7616                                 buttonElement.append( "<span class='ui-button-icon-secondary ui-icon " + icons.secondary + "'></span>" );
7617                         }
7619                         if ( !this.options.text ) {
7620                                 buttonClasses.push( multipleIcons ? "ui-button-icons-only" : "ui-button-icon-only" );
7622                                 if ( !this.hasTitle ) {
7623                                         buttonElement.attr( "title", $.trim( buttonText ) );
7624                                 }
7625                         }
7626                 } else {
7627                         buttonClasses.push( "ui-button-text-only" );
7628                 }
7629                 buttonElement.addClass( buttonClasses.join( " " ) );
7630         }
7633 $.widget( "ui.buttonset", {
7634         version: "1.11.0",
7635         options: {
7636                 items: "button, input[type=button], input[type=submit], input[type=reset], input[type=checkbox], input[type=radio], a, :data(ui-button)"
7637         },
7639         _create: function() {
7640                 this.element.addClass( "ui-buttonset" );
7641         },
7643         _init: function() {
7644                 this.refresh();
7645         },
7647         _setOption: function( key, value ) {
7648                 if ( key === "disabled" ) {
7649                         this.buttons.button( "option", key, value );
7650                 }
7652                 this._super( key, value );
7653         },
7655         refresh: function() {
7656                 var rtl = this.element.css( "direction" ) === "rtl",
7657                         allButtons = this.element.find( this.options.items ),
7658                         existingButtons = allButtons.filter( ":ui-button" );
7660                 // Initialize new buttons
7661                 allButtons.not( ":ui-button" ).button();
7663                 // Refresh existing buttons
7664                 existingButtons.button( "refresh" );
7666                 this.buttons = allButtons
7667                         .map(function() {
7668                                 return $( this ).button( "widget" )[ 0 ];
7669                         })
7670                                 .removeClass( "ui-corner-all ui-corner-left ui-corner-right" )
7671                                 .filter( ":first" )
7672                                         .addClass( rtl ? "ui-corner-right" : "ui-corner-left" )
7673                                 .end()
7674                                 .filter( ":last" )
7675                                         .addClass( rtl ? "ui-corner-left" : "ui-corner-right" )
7676                                 .end()
7677                         .end();
7678         },
7680         _destroy: function() {
7681                 this.element.removeClass( "ui-buttonset" );
7682                 this.buttons
7683                         .map(function() {
7684                                 return $( this ).button( "widget" )[ 0 ];
7685                         })
7686                                 .removeClass( "ui-corner-left ui-corner-right" )
7687                         .end()
7688                         .button( "destroy" );
7689         }
7692 var button = $.ui.button;
7696  * jQuery UI Datepicker 1.11.0
7697  * http://jqueryui.com
7699  * Copyright 2014 jQuery Foundation and other contributors
7700  * Released under the MIT license.
7701  * http://jquery.org/license
7703  * http://api.jqueryui.com/datepicker/
7704  */
7707 $.extend($.ui, { datepicker: { version: "1.11.0" } });
7709 var datepicker_instActive;
7711 function datepicker_getZindex( elem ) {
7712         var position, value;
7713         while ( elem.length && elem[ 0 ] !== document ) {
7714                 // Ignore z-index if position is set to a value where z-index is ignored by the browser
7715                 // This makes behavior of this function consistent across browsers
7716                 // WebKit always returns auto if the element is positioned
7717                 position = elem.css( "position" );
7718                 if ( position === "absolute" || position === "relative" || position === "fixed" ) {
7719                         // IE returns 0 when zIndex is not specified
7720                         // other browsers return a string
7721                         // we ignore the case of nested elements with an explicit value of 0
7722                         // <div style="z-index: -10;"><div style="z-index: 0;"></div></div>
7723                         value = parseInt( elem.css( "zIndex" ), 10 );
7724                         if ( !isNaN( value ) && value !== 0 ) {
7725                                 return value;
7726                         }
7727                 }
7728                 elem = elem.parent();
7729         }
7731         return 0;
7733 /* Date picker manager.
7734    Use the singleton instance of this class, $.datepicker, to interact with the date picker.
7735    Settings for (groups of) date pickers are maintained in an instance object,
7736    allowing multiple different settings on the same page. */
7738 function Datepicker() {
7739         this._curInst = null; // The current instance in use
7740         this._keyEvent = false; // If the last event was a key event
7741         this._disabledInputs = []; // List of date picker inputs that have been disabled
7742         this._datepickerShowing = false; // True if the popup picker is showing , false if not
7743         this._inDialog = false; // True if showing within a "dialog", false if not
7744         this._mainDivId = "ui-datepicker-div"; // The ID of the main datepicker division
7745         this._inlineClass = "ui-datepicker-inline"; // The name of the inline marker class
7746         this._appendClass = "ui-datepicker-append"; // The name of the append marker class
7747         this._triggerClass = "ui-datepicker-trigger"; // The name of the trigger marker class
7748         this._dialogClass = "ui-datepicker-dialog"; // The name of the dialog marker class
7749         this._disableClass = "ui-datepicker-disabled"; // The name of the disabled covering marker class
7750         this._unselectableClass = "ui-datepicker-unselectable"; // The name of the unselectable cell marker class
7751         this._currentClass = "ui-datepicker-current-day"; // The name of the current day marker class
7752         this._dayOverClass = "ui-datepicker-days-cell-over"; // The name of the day hover marker class
7753         this.regional = []; // Available regional settings, indexed by language code
7754         this.regional[""] = { // Default regional settings
7755                 closeText: "Done", // Display text for close link
7756                 prevText: "Prev", // Display text for previous month link
7757                 nextText: "Next", // Display text for next month link
7758                 currentText: "Today", // Display text for current month link
7759                 monthNames: ["January","February","March","April","May","June",
7760                         "July","August","September","October","November","December"], // Names of months for drop-down and formatting
7761                 monthNamesShort: ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"], // For formatting
7762                 dayNames: ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"], // For formatting
7763                 dayNamesShort: ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"], // For formatting
7764                 dayNamesMin: ["Su","Mo","Tu","We","Th","Fr","Sa"], // Column headings for days starting at Sunday
7765                 weekHeader: "Wk", // Column header for week of the year
7766                 dateFormat: "mm/dd/yy", // See format options on parseDate
7767                 firstDay: 0, // The first day of the week, Sun = 0, Mon = 1, ...
7768                 isRTL: false, // True if right-to-left language, false if left-to-right
7769                 showMonthAfterYear: false, // True if the year select precedes month, false for month then year
7770                 yearSuffix: "" // Additional text to append to the year in the month headers
7771         };
7772         this._defaults = { // Global defaults for all the date picker instances
7773                 showOn: "focus", // "focus" for popup on focus,
7774                         // "button" for trigger button, or "both" for either
7775                 showAnim: "fadeIn", // Name of jQuery animation for popup
7776                 showOptions: {}, // Options for enhanced animations
7777                 defaultDate: null, // Used when field is blank: actual date,
7778                         // +/-number for offset from today, null for today
7779                 appendText: "", // Display text following the input box, e.g. showing the format
7780                 buttonText: "...", // Text for trigger button
7781                 buttonImage: "", // URL for trigger button image
7782                 buttonImageOnly: false, // True if the image appears alone, false if it appears on a button
7783                 hideIfNoPrevNext: false, // True to hide next/previous month links
7784                         // if not applicable, false to just disable them
7785                 navigationAsDateFormat: false, // True if date formatting applied to prev/today/next links
7786                 gotoCurrent: false, // True if today link goes back to current selection instead
7787                 changeMonth: false, // True if month can be selected directly, false if only prev/next
7788                 changeYear: false, // True if year can be selected directly, false if only prev/next
7789                 yearRange: "c-10:c+10", // Range of years to display in drop-down,
7790                         // either relative to today's year (-nn:+nn), relative to currently displayed year
7791                         // (c-nn:c+nn), absolute (nnnn:nnnn), or a combination of the above (nnnn:-n)
7792                 showOtherMonths: false, // True to show dates in other months, false to leave blank
7793                 selectOtherMonths: false, // True to allow selection of dates in other months, false for unselectable
7794                 showWeek: false, // True to show week of the year, false to not show it
7795                 calculateWeek: this.iso8601Week, // How to calculate the week of the year,
7796                         // takes a Date and returns the number of the week for it
7797                 shortYearCutoff: "+10", // Short year values < this are in the current century,
7798                         // > this are in the previous century,
7799                         // string value starting with "+" for current year + value
7800                 minDate: null, // The earliest selectable date, or null for no limit
7801                 maxDate: null, // The latest selectable date, or null for no limit
7802                 duration: "fast", // Duration of display/closure
7803                 beforeShowDay: null, // Function that takes a date and returns an array with
7804                         // [0] = true if selectable, false if not, [1] = custom CSS class name(s) or "",
7805                         // [2] = cell title (optional), e.g. $.datepicker.noWeekends
7806                 beforeShow: null, // Function that takes an input field and
7807                         // returns a set of custom settings for the date picker
7808                 onSelect: null, // Define a callback function when a date is selected
7809                 onChangeMonthYear: null, // Define a callback function when the month or year is changed
7810                 onClose: null, // Define a callback function when the datepicker is closed
7811                 numberOfMonths: 1, // Number of months to show at a time
7812                 showCurrentAtPos: 0, // The position in multipe months at which to show the current month (starting at 0)
7813                 stepMonths: 1, // Number of months to step back/forward
7814                 stepBigMonths: 12, // Number of months to step back/forward for the big links
7815                 altField: "", // Selector for an alternate field to store selected dates into
7816                 altFormat: "", // The date format to use for the alternate field
7817                 constrainInput: true, // The input is constrained by the current date format
7818                 showButtonPanel: false, // True to show button panel, false to not show it
7819                 autoSize: false, // True to size the input for the date format, false to leave as is
7820                 disabled: false // The initial disabled state
7821         };
7822         $.extend(this._defaults, this.regional[""]);
7823         this.regional.en = $.extend( true, {}, this.regional[ "" ]);
7824         this.regional[ "en-US" ] = $.extend( true, {}, this.regional.en );
7825         this.dpDiv = datepicker_bindHover($("<div id='" + this._mainDivId + "' class='ui-datepicker ui-widget ui-widget-content ui-helper-clearfix ui-corner-all'></div>"));
7828 $.extend(Datepicker.prototype, {
7829         /* Class name added to elements to indicate already configured with a date picker. */
7830         markerClassName: "hasDatepicker",
7832         //Keep track of the maximum number of rows displayed (see #7043)
7833         maxRows: 4,
7835         // TODO rename to "widget" when switching to widget factory
7836         _widgetDatepicker: function() {
7837                 return this.dpDiv;
7838         },
7840         /* Override the default settings for all instances of the date picker.
7841          * @param  settings  object - the new settings to use as defaults (anonymous object)
7842          * @return the manager object
7843          */
7844         setDefaults: function(settings) {
7845                 datepicker_extendRemove(this._defaults, settings || {});
7846                 return this;
7847         },
7849         /* Attach the date picker to a jQuery selection.
7850          * @param  target       element - the target input field or division or span
7851          * @param  settings  object - the new settings to use for this date picker instance (anonymous)
7852          */
7853         _attachDatepicker: function(target, settings) {
7854                 var nodeName, inline, inst;
7855                 nodeName = target.nodeName.toLowerCase();
7856                 inline = (nodeName === "div" || nodeName === "span");
7857                 if (!target.id) {
7858                         this.uuid += 1;
7859                         target.id = "dp" + this.uuid;
7860                 }
7861                 inst = this._newInst($(target), inline);
7862                 inst.settings = $.extend({}, settings || {});
7863                 if (nodeName === "input") {
7864                         this._connectDatepicker(target, inst);
7865                 } else if (inline) {
7866                         this._inlineDatepicker(target, inst);
7867                 }
7868         },
7870         /* Create a new instance object. */
7871         _newInst: function(target, inline) {
7872                 var id = target[0].id.replace(/([^A-Za-z0-9_\-])/g, "\\\\$1"); // escape jQuery meta chars
7873                 return {id: id, input: target, // associated target
7874                         selectedDay: 0, selectedMonth: 0, selectedYear: 0, // current selection
7875                         drawMonth: 0, drawYear: 0, // month being drawn
7876                         inline: inline, // is datepicker inline or not
7877                         dpDiv: (!inline ? this.dpDiv : // presentation div
7878                         datepicker_bindHover($("<div class='" + this._inlineClass + " ui-datepicker ui-widget ui-widget-content ui-helper-clearfix ui-corner-all'></div>")))};
7879         },
7881         /* Attach the date picker to an input field. */
7882         _connectDatepicker: function(target, inst) {
7883                 var input = $(target);
7884                 inst.append = $([]);
7885                 inst.trigger = $([]);
7886                 if (input.hasClass(this.markerClassName)) {
7887                         return;
7888                 }
7889                 this._attachments(input, inst);
7890                 input.addClass(this.markerClassName).keydown(this._doKeyDown).
7891                         keypress(this._doKeyPress).keyup(this._doKeyUp);
7892                 this._autoSize(inst);
7893                 $.data(target, "datepicker", inst);
7894                 //If disabled option is true, disable the datepicker once it has been attached to the input (see ticket #5665)
7895                 if( inst.settings.disabled ) {
7896                         this._disableDatepicker( target );
7897                 }
7898         },
7900         /* Make attachments based on settings. */
7901         _attachments: function(input, inst) {
7902                 var showOn, buttonText, buttonImage,
7903                         appendText = this._get(inst, "appendText"),
7904                         isRTL = this._get(inst, "isRTL");
7906                 if (inst.append) {
7907                         inst.append.remove();
7908                 }
7909                 if (appendText) {
7910                         inst.append = $("<span class='" + this._appendClass + "'>" + appendText + "</span>");
7911                         input[isRTL ? "before" : "after"](inst.append);
7912                 }
7914                 input.unbind("focus", this._showDatepicker);
7916                 if (inst.trigger) {
7917                         inst.trigger.remove();
7918                 }
7920                 showOn = this._get(inst, "showOn");
7921                 if (showOn === "focus" || showOn === "both") { // pop-up date picker when in the marked field
7922                         input.focus(this._showDatepicker);
7923                 }
7924                 if (showOn === "button" || showOn === "both") { // pop-up date picker when button clicked
7925                         buttonText = this._get(inst, "buttonText");
7926                         buttonImage = this._get(inst, "buttonImage");
7927                         inst.trigger = $(this._get(inst, "buttonImageOnly") ?
7928                                 $("<img/>").addClass(this._triggerClass).
7929                                         attr({ src: buttonImage, alt: buttonText, title: buttonText }) :
7930                                 $("<button type='button'></button>").addClass(this._triggerClass).
7931                                         html(!buttonImage ? buttonText : $("<img/>").attr(
7932                                         { src:buttonImage, alt:buttonText, title:buttonText })));
7933                         input[isRTL ? "before" : "after"](inst.trigger);
7934                         inst.trigger.click(function() {
7935                                 if ($.datepicker._datepickerShowing && $.datepicker._lastInput === input[0]) {
7936                                         $.datepicker._hideDatepicker();
7937                                 } else if ($.datepicker._datepickerShowing && $.datepicker._lastInput !== input[0]) {
7938                                         $.datepicker._hideDatepicker();
7939                                         $.datepicker._showDatepicker(input[0]);
7940                                 } else {
7941                                         $.datepicker._showDatepicker(input[0]);
7942                                 }
7943                                 return false;
7944                         });
7945                 }
7946         },
7948         /* Apply the maximum length for the date format. */
7949         _autoSize: function(inst) {
7950                 if (this._get(inst, "autoSize") && !inst.inline) {
7951                         var findMax, max, maxI, i,
7952                                 date = new Date(2009, 12 - 1, 20), // Ensure double digits
7953                                 dateFormat = this._get(inst, "dateFormat");
7955                         if (dateFormat.match(/[DM]/)) {
7956                                 findMax = function(names) {
7957                                         max = 0;
7958                                         maxI = 0;
7959                                         for (i = 0; i < names.length; i++) {
7960                                                 if (names[i].length > max) {
7961                                                         max = names[i].length;
7962                                                         maxI = i;
7963                                                 }
7964                                         }
7965                                         return maxI;
7966                                 };
7967                                 date.setMonth(findMax(this._get(inst, (dateFormat.match(/MM/) ?
7968                                         "monthNames" : "monthNamesShort"))));
7969                                 date.setDate(findMax(this._get(inst, (dateFormat.match(/DD/) ?
7970                                         "dayNames" : "dayNamesShort"))) + 20 - date.getDay());
7971                         }
7972                         inst.input.attr("size", this._formatDate(inst, date).length);
7973                 }
7974         },
7976         /* Attach an inline date picker to a div. */
7977         _inlineDatepicker: function(target, inst) {
7978                 var divSpan = $(target);
7979                 if (divSpan.hasClass(this.markerClassName)) {
7980                         return;
7981                 }
7982                 divSpan.addClass(this.markerClassName).append(inst.dpDiv);
7983                 $.data(target, "datepicker", inst);
7984                 this._setDate(inst, this._getDefaultDate(inst), true);
7985                 this._updateDatepicker(inst);
7986                 this._updateAlternate(inst);
7987                 //If disabled option is true, disable the datepicker before showing it (see ticket #5665)
7988                 if( inst.settings.disabled ) {
7989                         this._disableDatepicker( target );
7990                 }
7991                 // Set display:block in place of inst.dpDiv.show() which won't work on disconnected elements
7992                 // http://bugs.jqueryui.com/ticket/7552 - A Datepicker created on a detached div has zero height
7993                 inst.dpDiv.css( "display", "block" );
7994         },
7996         /* Pop-up the date picker in a "dialog" box.
7997          * @param  input element - ignored
7998          * @param  date string or Date - the initial date to display
7999          * @param  onSelect  function - the function to call when a date is selected
8000          * @param  settings  object - update the dialog date picker instance's settings (anonymous object)
8001          * @param  pos int[2] - coordinates for the dialog's position within the screen or
8002          *                                      event - with x/y coordinates or
8003          *                                      leave empty for default (screen centre)
8004          * @return the manager object
8005          */
8006         _dialogDatepicker: function(input, date, onSelect, settings, pos) {
8007                 var id, browserWidth, browserHeight, scrollX, scrollY,
8008                         inst = this._dialogInst; // internal instance
8010                 if (!inst) {
8011                         this.uuid += 1;
8012                         id = "dp" + this.uuid;
8013                         this._dialogInput = $("<input type='text' id='" + id +
8014                                 "' style='position: absolute; top: -100px; width: 0px;'/>");
8015                         this._dialogInput.keydown(this._doKeyDown);
8016                         $("body").append(this._dialogInput);
8017                         inst = this._dialogInst = this._newInst(this._dialogInput, false);
8018                         inst.settings = {};
8019                         $.data(this._dialogInput[0], "datepicker", inst);
8020                 }
8021                 datepicker_extendRemove(inst.settings, settings || {});
8022                 date = (date && date.constructor === Date ? this._formatDate(inst, date) : date);
8023                 this._dialogInput.val(date);
8025                 this._pos = (pos ? (pos.length ? pos : [pos.pageX, pos.pageY]) : null);
8026                 if (!this._pos) {
8027                         browserWidth = document.documentElement.clientWidth;
8028                         browserHeight = document.documentElement.clientHeight;
8029                         scrollX = document.documentElement.scrollLeft || document.body.scrollLeft;
8030                         scrollY = document.documentElement.scrollTop || document.body.scrollTop;
8031                         this._pos = // should use actual width/height below
8032                                 [(browserWidth / 2) - 100 + scrollX, (browserHeight / 2) - 150 + scrollY];
8033                 }
8035                 // move input on screen for focus, but hidden behind dialog
8036                 this._dialogInput.css("left", (this._pos[0] + 20) + "px").css("top", this._pos[1] + "px");
8037                 inst.settings.onSelect = onSelect;
8038                 this._inDialog = true;
8039                 this.dpDiv.addClass(this._dialogClass);
8040                 this._showDatepicker(this._dialogInput[0]);
8041                 if ($.blockUI) {
8042                         $.blockUI(this.dpDiv);
8043                 }
8044                 $.data(this._dialogInput[0], "datepicker", inst);
8045                 return this;
8046         },
8048         /* Detach a datepicker from its control.
8049          * @param  target       element - the target input field or division or span
8050          */
8051         _destroyDatepicker: function(target) {
8052                 var nodeName,
8053                         $target = $(target),
8054                         inst = $.data(target, "datepicker");
8056                 if (!$target.hasClass(this.markerClassName)) {
8057                         return;
8058                 }
8060                 nodeName = target.nodeName.toLowerCase();
8061                 $.removeData(target, "datepicker");
8062                 if (nodeName === "input") {
8063                         inst.append.remove();
8064                         inst.trigger.remove();
8065                         $target.removeClass(this.markerClassName).
8066                                 unbind("focus", this._showDatepicker).
8067                                 unbind("keydown", this._doKeyDown).
8068                                 unbind("keypress", this._doKeyPress).
8069                                 unbind("keyup", this._doKeyUp);
8070                 } else if (nodeName === "div" || nodeName === "span") {
8071                         $target.removeClass(this.markerClassName).empty();
8072                 }
8073         },
8075         /* Enable the date picker to a jQuery selection.
8076          * @param  target       element - the target input field or division or span
8077          */
8078         _enableDatepicker: function(target) {
8079                 var nodeName, inline,
8080                         $target = $(target),
8081                         inst = $.data(target, "datepicker");
8083                 if (!$target.hasClass(this.markerClassName)) {
8084                         return;
8085                 }
8087                 nodeName = target.nodeName.toLowerCase();
8088                 if (nodeName === "input") {
8089                         target.disabled = false;
8090                         inst.trigger.filter("button").
8091                                 each(function() { this.disabled = false; }).end().
8092                                 filter("img").css({opacity: "1.0", cursor: ""});
8093                 } else if (nodeName === "div" || nodeName === "span") {
8094                         inline = $target.children("." + this._inlineClass);
8095                         inline.children().removeClass("ui-state-disabled");
8096                         inline.find("select.ui-datepicker-month, select.ui-datepicker-year").
8097                                 prop("disabled", false);
8098                 }
8099                 this._disabledInputs = $.map(this._disabledInputs,
8100                         function(value) { return (value === target ? null : value); }); // delete entry
8101         },
8103         /* Disable the date picker to a jQuery selection.
8104          * @param  target       element - the target input field or division or span
8105          */
8106         _disableDatepicker: function(target) {
8107                 var nodeName, inline,
8108                         $target = $(target),
8109                         inst = $.data(target, "datepicker");
8111                 if (!$target.hasClass(this.markerClassName)) {
8112                         return;
8113                 }
8115                 nodeName = target.nodeName.toLowerCase();
8116                 if (nodeName === "input") {
8117                         target.disabled = true;
8118                         inst.trigger.filter("button").
8119                                 each(function() { this.disabled = true; }).end().
8120                                 filter("img").css({opacity: "0.5", cursor: "default"});
8121                 } else if (nodeName === "div" || nodeName === "span") {
8122                         inline = $target.children("." + this._inlineClass);
8123                         inline.children().addClass("ui-state-disabled");
8124                         inline.find("select.ui-datepicker-month, select.ui-datepicker-year").
8125                                 prop("disabled", true);
8126                 }
8127                 this._disabledInputs = $.map(this._disabledInputs,
8128                         function(value) { return (value === target ? null : value); }); // delete entry
8129                 this._disabledInputs[this._disabledInputs.length] = target;
8130         },
8132         /* Is the first field in a jQuery collection disabled as a datepicker?
8133          * @param  target       element - the target input field or division or span
8134          * @return boolean - true if disabled, false if enabled
8135          */
8136         _isDisabledDatepicker: function(target) {
8137                 if (!target) {
8138                         return false;
8139                 }
8140                 for (var i = 0; i < this._disabledInputs.length; i++) {
8141                         if (this._disabledInputs[i] === target) {
8142                                 return true;
8143                         }
8144                 }
8145                 return false;
8146         },
8148         /* Retrieve the instance data for the target control.
8149          * @param  target  element - the target input field or division or span
8150          * @return  object - the associated instance data
8151          * @throws  error if a jQuery problem getting data
8152          */
8153         _getInst: function(target) {
8154                 try {
8155                         return $.data(target, "datepicker");
8156                 }
8157                 catch (err) {
8158                         throw "Missing instance data for this datepicker";
8159                 }
8160         },
8162         /* Update or retrieve the settings for a date picker attached to an input field or division.
8163          * @param  target  element - the target input field or division or span
8164          * @param  name object - the new settings to update or
8165          *                              string - the name of the setting to change or retrieve,
8166          *                              when retrieving also "all" for all instance settings or
8167          *                              "defaults" for all global defaults
8168          * @param  value   any - the new value for the setting
8169          *                              (omit if above is an object or to retrieve a value)
8170          */
8171         _optionDatepicker: function(target, name, value) {
8172                 var settings, date, minDate, maxDate,
8173                         inst = this._getInst(target);
8175                 if (arguments.length === 2 && typeof name === "string") {
8176                         return (name === "defaults" ? $.extend({}, $.datepicker._defaults) :
8177                                 (inst ? (name === "all" ? $.extend({}, inst.settings) :
8178                                 this._get(inst, name)) : null));
8179                 }
8181                 settings = name || {};
8182                 if (typeof name === "string") {
8183                         settings = {};
8184                         settings[name] = value;
8185                 }
8187                 if (inst) {
8188                         if (this._curInst === inst) {
8189                                 this._hideDatepicker();
8190                         }
8192                         date = this._getDateDatepicker(target, true);
8193                         minDate = this._getMinMaxDate(inst, "min");
8194                         maxDate = this._getMinMaxDate(inst, "max");
8195                         datepicker_extendRemove(inst.settings, settings);
8196                         // reformat the old minDate/maxDate values if dateFormat changes and a new minDate/maxDate isn't provided
8197                         if (minDate !== null && settings.dateFormat !== undefined && settings.minDate === undefined) {
8198                                 inst.settings.minDate = this._formatDate(inst, minDate);
8199                         }
8200                         if (maxDate !== null && settings.dateFormat !== undefined && settings.maxDate === undefined) {
8201                                 inst.settings.maxDate = this._formatDate(inst, maxDate);
8202                         }
8203                         if ( "disabled" in settings ) {
8204                                 if ( settings.disabled ) {
8205                                         this._disableDatepicker(target);
8206                                 } else {
8207                                         this._enableDatepicker(target);
8208                                 }
8209                         }
8210                         this._attachments($(target), inst);
8211                         this._autoSize(inst);
8212                         this._setDate(inst, date);
8213                         this._updateAlternate(inst);
8214                         this._updateDatepicker(inst);
8215                 }
8216         },
8218         // change method deprecated
8219         _changeDatepicker: function(target, name, value) {
8220                 this._optionDatepicker(target, name, value);
8221         },
8223         /* Redraw the date picker attached to an input field or division.
8224          * @param  target  element - the target input field or division or span
8225          */
8226         _refreshDatepicker: function(target) {
8227                 var inst = this._getInst(target);
8228                 if (inst) {
8229                         this._updateDatepicker(inst);
8230                 }
8231         },
8233         /* Set the dates for a jQuery selection.
8234          * @param  target element - the target input field or division or span
8235          * @param  date Date - the new date
8236          */
8237         _setDateDatepicker: function(target, date) {
8238                 var inst = this._getInst(target);
8239                 if (inst) {
8240                         this._setDate(inst, date);
8241                         this._updateDatepicker(inst);
8242                         this._updateAlternate(inst);
8243                 }
8244         },
8246         /* Get the date(s) for the first entry in a jQuery selection.
8247          * @param  target element - the target input field or division or span
8248          * @param  noDefault boolean - true if no default date is to be used
8249          * @return Date - the current date
8250          */
8251         _getDateDatepicker: function(target, noDefault) {
8252                 var inst = this._getInst(target);
8253                 if (inst && !inst.inline) {
8254                         this._setDateFromField(inst, noDefault);
8255                 }
8256                 return (inst ? this._getDate(inst) : null);
8257         },
8259         /* Handle keystrokes. */
8260         _doKeyDown: function(event) {
8261                 var onSelect, dateStr, sel,
8262                         inst = $.datepicker._getInst(event.target),
8263                         handled = true,
8264                         isRTL = inst.dpDiv.is(".ui-datepicker-rtl");
8266                 inst._keyEvent = true;
8267                 if ($.datepicker._datepickerShowing) {
8268                         switch (event.keyCode) {
8269                                 case 9: $.datepicker._hideDatepicker();
8270                                                 handled = false;
8271                                                 break; // hide on tab out
8272                                 case 13: sel = $("td." + $.datepicker._dayOverClass + ":not(." +
8273                                                                         $.datepicker._currentClass + ")", inst.dpDiv);
8274                                                 if (sel[0]) {
8275                                                         $.datepicker._selectDay(event.target, inst.selectedMonth, inst.selectedYear, sel[0]);
8276                                                 }
8278                                                 onSelect = $.datepicker._get(inst, "onSelect");
8279                                                 if (onSelect) {
8280                                                         dateStr = $.datepicker._formatDate(inst);
8282                                                         // trigger custom callback
8283                                                         onSelect.apply((inst.input ? inst.input[0] : null), [dateStr, inst]);
8284                                                 } else {
8285                                                         $.datepicker._hideDatepicker();
8286                                                 }
8288                                                 return false; // don't submit the form
8289                                 case 27: $.datepicker._hideDatepicker();
8290                                                 break; // hide on escape
8291                                 case 33: $.datepicker._adjustDate(event.target, (event.ctrlKey ?
8292                                                         -$.datepicker._get(inst, "stepBigMonths") :
8293                                                         -$.datepicker._get(inst, "stepMonths")), "M");
8294                                                 break; // previous month/year on page up/+ ctrl
8295                                 case 34: $.datepicker._adjustDate(event.target, (event.ctrlKey ?
8296                                                         +$.datepicker._get(inst, "stepBigMonths") :
8297                                                         +$.datepicker._get(inst, "stepMonths")), "M");
8298                                                 break; // next month/year on page down/+ ctrl
8299                                 case 35: if (event.ctrlKey || event.metaKey) {
8300                                                         $.datepicker._clearDate(event.target);
8301                                                 }
8302                                                 handled = event.ctrlKey || event.metaKey;
8303                                                 break; // clear on ctrl or command +end
8304                                 case 36: if (event.ctrlKey || event.metaKey) {
8305                                                         $.datepicker._gotoToday(event.target);
8306                                                 }
8307                                                 handled = event.ctrlKey || event.metaKey;
8308                                                 break; // current on ctrl or command +home
8309                                 case 37: if (event.ctrlKey || event.metaKey) {
8310                                                         $.datepicker._adjustDate(event.target, (isRTL ? +1 : -1), "D");
8311                                                 }
8312                                                 handled = event.ctrlKey || event.metaKey;
8313                                                 // -1 day on ctrl or command +left
8314                                                 if (event.originalEvent.altKey) {
8315                                                         $.datepicker._adjustDate(event.target, (event.ctrlKey ?
8316                                                                 -$.datepicker._get(inst, "stepBigMonths") :
8317                                                                 -$.datepicker._get(inst, "stepMonths")), "M");
8318                                                 }
8319                                                 // next month/year on alt +left on Mac
8320                                                 break;
8321                                 case 38: if (event.ctrlKey || event.metaKey) {
8322                                                         $.datepicker._adjustDate(event.target, -7, "D");
8323                                                 }
8324                                                 handled = event.ctrlKey || event.metaKey;
8325                                                 break; // -1 week on ctrl or command +up
8326                                 case 39: if (event.ctrlKey || event.metaKey) {
8327                                                         $.datepicker._adjustDate(event.target, (isRTL ? -1 : +1), "D");
8328                                                 }
8329                                                 handled = event.ctrlKey || event.metaKey;
8330                                                 // +1 day on ctrl or command +right
8331                                                 if (event.originalEvent.altKey) {
8332                                                         $.datepicker._adjustDate(event.target, (event.ctrlKey ?
8333                                                                 +$.datepicker._get(inst, "stepBigMonths") :
8334                                                                 +$.datepicker._get(inst, "stepMonths")), "M");
8335                                                 }
8336                                                 // next month/year on alt +right
8337                                                 break;
8338                                 case 40: if (event.ctrlKey || event.metaKey) {
8339                                                         $.datepicker._adjustDate(event.target, +7, "D");
8340                                                 }
8341                                                 handled = event.ctrlKey || event.metaKey;
8342                                                 break; // +1 week on ctrl or command +down
8343                                 default: handled = false;
8344                         }
8345                 } else if (event.keyCode === 36 && event.ctrlKey) { // display the date picker on ctrl+home
8346                         $.datepicker._showDatepicker(this);
8347                 } else {
8348                         handled = false;
8349                 }
8351                 if (handled) {
8352                         event.preventDefault();
8353                         event.stopPropagation();
8354                 }
8355         },
8357         /* Filter entered characters - based on date format. */
8358         _doKeyPress: function(event) {
8359                 var chars, chr,
8360                         inst = $.datepicker._getInst(event.target);
8362                 if ($.datepicker._get(inst, "constrainInput")) {
8363                         chars = $.datepicker._possibleChars($.datepicker._get(inst, "dateFormat"));
8364                         chr = String.fromCharCode(event.charCode == null ? event.keyCode : event.charCode);
8365                         return event.ctrlKey || event.metaKey || (chr < " " || !chars || chars.indexOf(chr) > -1);
8366                 }
8367         },
8369         /* Synchronise manual entry and field/alternate field. */
8370         _doKeyUp: function(event) {
8371                 var date,
8372                         inst = $.datepicker._getInst(event.target);
8374                 if (inst.input.val() !== inst.lastVal) {
8375                         try {
8376                                 date = $.datepicker.parseDate($.datepicker._get(inst, "dateFormat"),
8377                                         (inst.input ? inst.input.val() : null),
8378                                         $.datepicker._getFormatConfig(inst));
8380                                 if (date) { // only if valid
8381                                         $.datepicker._setDateFromField(inst);
8382                                         $.datepicker._updateAlternate(inst);
8383                                         $.datepicker._updateDatepicker(inst);
8384                                 }
8385                         }
8386                         catch (err) {
8387                         }
8388                 }
8389                 return true;
8390         },
8392         /* Pop-up the date picker for a given input field.
8393          * If false returned from beforeShow event handler do not show.
8394          * @param  input  element - the input field attached to the date picker or
8395          *                                      event - if triggered by focus
8396          */
8397         _showDatepicker: function(input) {
8398                 input = input.target || input;
8399                 if (input.nodeName.toLowerCase() !== "input") { // find from button/image trigger
8400                         input = $("input", input.parentNode)[0];
8401                 }
8403                 if ($.datepicker._isDisabledDatepicker(input) || $.datepicker._lastInput === input) { // already here
8404                         return;
8405                 }
8407                 var inst, beforeShow, beforeShowSettings, isFixed,
8408                         offset, showAnim, duration;
8410                 inst = $.datepicker._getInst(input);
8411                 if ($.datepicker._curInst && $.datepicker._curInst !== inst) {
8412                         $.datepicker._curInst.dpDiv.stop(true, true);
8413                         if ( inst && $.datepicker._datepickerShowing ) {
8414                                 $.datepicker._hideDatepicker( $.datepicker._curInst.input[0] );
8415                         }
8416                 }
8418                 beforeShow = $.datepicker._get(inst, "beforeShow");
8419                 beforeShowSettings = beforeShow ? beforeShow.apply(input, [input, inst]) : {};
8420                 if(beforeShowSettings === false){
8421                         return;
8422                 }
8423                 datepicker_extendRemove(inst.settings, beforeShowSettings);
8425                 inst.lastVal = null;
8426                 $.datepicker._lastInput = input;
8427                 $.datepicker._setDateFromField(inst);
8429                 if ($.datepicker._inDialog) { // hide cursor
8430                         input.value = "";
8431                 }
8432                 if (!$.datepicker._pos) { // position below input
8433                         $.datepicker._pos = $.datepicker._findPos(input);
8434                         $.datepicker._pos[1] += input.offsetHeight; // add the height
8435                 }
8437                 isFixed = false;
8438                 $(input).parents().each(function() {
8439                         isFixed |= $(this).css("position") === "fixed";
8440                         return !isFixed;
8441                 });
8443                 offset = {left: $.datepicker._pos[0], top: $.datepicker._pos[1]};
8444                 $.datepicker._pos = null;
8445                 //to avoid flashes on Firefox
8446                 inst.dpDiv.empty();
8447                 // determine sizing offscreen
8448                 inst.dpDiv.css({position: "absolute", display: "block", top: "-1000px"});
8449                 $.datepicker._updateDatepicker(inst);
8450                 // fix width for dynamic number of date pickers
8451                 // and adjust position before showing
8452                 offset = $.datepicker._checkOffset(inst, offset, isFixed);
8453                 inst.dpDiv.css({position: ($.datepicker._inDialog && $.blockUI ?
8454                         "static" : (isFixed ? "fixed" : "absolute")), display: "none",
8455                         left: offset.left + "px", top: offset.top + "px"});
8457                 if (!inst.inline) {
8458                         showAnim = $.datepicker._get(inst, "showAnim");
8459                         duration = $.datepicker._get(inst, "duration");
8460                         inst.dpDiv.css( "z-index", datepicker_getZindex( $( input ) ) + 1 );
8461                         $.datepicker._datepickerShowing = true;
8463                         if ( $.effects && $.effects.effect[ showAnim ] ) {
8464                                 inst.dpDiv.show(showAnim, $.datepicker._get(inst, "showOptions"), duration);
8465                         } else {
8466                                 inst.dpDiv[showAnim || "show"](showAnim ? duration : null);
8467                         }
8469                         if ( $.datepicker._shouldFocusInput( inst ) ) {
8470                                 inst.input.focus();
8471                         }
8473                         $.datepicker._curInst = inst;
8474                 }
8475         },
8477         /* Generate the date picker content. */
8478         _updateDatepicker: function(inst) {
8479                 this.maxRows = 4; //Reset the max number of rows being displayed (see #7043)
8480                 datepicker_instActive = inst; // for delegate hover events
8481                 inst.dpDiv.empty().append(this._generateHTML(inst));
8482                 this._attachHandlers(inst);
8483                 inst.dpDiv.find("." + this._dayOverClass + " a");
8485                 var origyearshtml,
8486                         numMonths = this._getNumberOfMonths(inst),
8487                         cols = numMonths[1],
8488                         width = 17;
8490                 inst.dpDiv.removeClass("ui-datepicker-multi-2 ui-datepicker-multi-3 ui-datepicker-multi-4").width("");
8491                 if (cols > 1) {
8492                         inst.dpDiv.addClass("ui-datepicker-multi-" + cols).css("width", (width * cols) + "em");
8493                 }
8494                 inst.dpDiv[(numMonths[0] !== 1 || numMonths[1] !== 1 ? "add" : "remove") +
8495                         "Class"]("ui-datepicker-multi");
8496                 inst.dpDiv[(this._get(inst, "isRTL") ? "add" : "remove") +
8497                         "Class"]("ui-datepicker-rtl");
8499                 if (inst === $.datepicker._curInst && $.datepicker._datepickerShowing && $.datepicker._shouldFocusInput( inst ) ) {
8500                         inst.input.focus();
8501                 }
8503                 // deffered render of the years select (to avoid flashes on Firefox)
8504                 if( inst.yearshtml ){
8505                         origyearshtml = inst.yearshtml;
8506                         setTimeout(function(){
8507                                 //assure that inst.yearshtml didn't change.
8508                                 if( origyearshtml === inst.yearshtml && inst.yearshtml ){
8509                                         inst.dpDiv.find("select.ui-datepicker-year:first").replaceWith(inst.yearshtml);
8510                                 }
8511                                 origyearshtml = inst.yearshtml = null;
8512                         }, 0);
8513                 }
8514         },
8516         // #6694 - don't focus the input if it's already focused
8517         // this breaks the change event in IE
8518         // Support: IE and jQuery <1.9
8519         _shouldFocusInput: function( inst ) {
8520                 return inst.input && inst.input.is( ":visible" ) && !inst.input.is( ":disabled" ) && !inst.input.is( ":focus" );
8521         },
8523         /* Check positioning to remain on screen. */
8524         _checkOffset: function(inst, offset, isFixed) {
8525                 var dpWidth = inst.dpDiv.outerWidth(),
8526                         dpHeight = inst.dpDiv.outerHeight(),
8527                         inputWidth = inst.input ? inst.input.outerWidth() : 0,
8528                         inputHeight = inst.input ? inst.input.outerHeight() : 0,
8529                         viewWidth = document.documentElement.clientWidth + (isFixed ? 0 : $(document).scrollLeft()),
8530                         viewHeight = document.documentElement.clientHeight + (isFixed ? 0 : $(document).scrollTop());
8532                 offset.left -= (this._get(inst, "isRTL") ? (dpWidth - inputWidth) : 0);
8533                 offset.left -= (isFixed && offset.left === inst.input.offset().left) ? $(document).scrollLeft() : 0;
8534                 offset.top -= (isFixed && offset.top === (inst.input.offset().top + inputHeight)) ? $(document).scrollTop() : 0;
8536                 // now check if datepicker is showing outside window viewport - move to a better place if so.
8537                 offset.left -= Math.min(offset.left, (offset.left + dpWidth > viewWidth && viewWidth > dpWidth) ?
8538                         Math.abs(offset.left + dpWidth - viewWidth) : 0);
8539                 offset.top -= Math.min(offset.top, (offset.top + dpHeight > viewHeight && viewHeight > dpHeight) ?
8540                         Math.abs(dpHeight + inputHeight) : 0);
8542                 return offset;
8543         },
8545         /* Find an object's position on the screen. */
8546         _findPos: function(obj) {
8547                 var position,
8548                         inst = this._getInst(obj),
8549                         isRTL = this._get(inst, "isRTL");
8551                 while (obj && (obj.type === "hidden" || obj.nodeType !== 1 || $.expr.filters.hidden(obj))) {
8552                         obj = obj[isRTL ? "previousSibling" : "nextSibling"];
8553                 }
8555                 position = $(obj).offset();
8556                 return [position.left, position.top];
8557         },
8559         /* Hide the date picker from view.
8560          * @param  input  element - the input field attached to the date picker
8561          */
8562         _hideDatepicker: function(input) {
8563                 var showAnim, duration, postProcess, onClose,
8564                         inst = this._curInst;
8566                 if (!inst || (input && inst !== $.data(input, "datepicker"))) {
8567                         return;
8568                 }
8570                 if (this._datepickerShowing) {
8571                         showAnim = this._get(inst, "showAnim");
8572                         duration = this._get(inst, "duration");
8573                         postProcess = function() {
8574                                 $.datepicker._tidyDialog(inst);
8575                         };
8577                         // DEPRECATED: after BC for 1.8.x $.effects[ showAnim ] is not needed
8578                         if ( $.effects && ( $.effects.effect[ showAnim ] || $.effects[ showAnim ] ) ) {
8579                                 inst.dpDiv.hide(showAnim, $.datepicker._get(inst, "showOptions"), duration, postProcess);
8580                         } else {
8581                                 inst.dpDiv[(showAnim === "slideDown" ? "slideUp" :
8582                                         (showAnim === "fadeIn" ? "fadeOut" : "hide"))]((showAnim ? duration : null), postProcess);
8583                         }
8585                         if (!showAnim) {
8586                                 postProcess();
8587                         }
8588                         this._datepickerShowing = false;
8590                         onClose = this._get(inst, "onClose");
8591                         if (onClose) {
8592                                 onClose.apply((inst.input ? inst.input[0] : null), [(inst.input ? inst.input.val() : ""), inst]);
8593                         }
8595                         this._lastInput = null;
8596                         if (this._inDialog) {
8597                                 this._dialogInput.css({ position: "absolute", left: "0", top: "-100px" });
8598                                 if ($.blockUI) {
8599                                         $.unblockUI();
8600                                         $("body").append(this.dpDiv);
8601                                 }
8602                         }
8603                         this._inDialog = false;
8604                 }
8605         },
8607         /* Tidy up after a dialog display. */
8608         _tidyDialog: function(inst) {
8609                 inst.dpDiv.removeClass(this._dialogClass).unbind(".ui-datepicker-calendar");
8610         },
8612         /* Close date picker if clicked elsewhere. */
8613         _checkExternalClick: function(event) {
8614                 if (!$.datepicker._curInst) {
8615                         return;
8616                 }
8618                 var $target = $(event.target),
8619                         inst = $.datepicker._getInst($target[0]);
8621                 if ( ( ( $target[0].id !== $.datepicker._mainDivId &&
8622                                 $target.parents("#" + $.datepicker._mainDivId).length === 0 &&
8623                                 !$target.hasClass($.datepicker.markerClassName) &&
8624                                 !$target.closest("." + $.datepicker._triggerClass).length &&
8625                                 $.datepicker._datepickerShowing && !($.datepicker._inDialog && $.blockUI) ) ) ||
8626                         ( $target.hasClass($.datepicker.markerClassName) && $.datepicker._curInst !== inst ) ) {
8627                                 $.datepicker._hideDatepicker();
8628                 }
8629         },
8631         /* Adjust one of the date sub-fields. */
8632         _adjustDate: function(id, offset, period) {
8633                 var target = $(id),
8634                         inst = this._getInst(target[0]);
8636                 if (this._isDisabledDatepicker(target[0])) {
8637                         return;
8638                 }
8639                 this._adjustInstDate(inst, offset +
8640                         (period === "M" ? this._get(inst, "showCurrentAtPos") : 0), // undo positioning
8641                         period);
8642                 this._updateDatepicker(inst);
8643         },
8645         /* Action for current link. */
8646         _gotoToday: function(id) {
8647                 var date,
8648                         target = $(id),
8649                         inst = this._getInst(target[0]);
8651                 if (this._get(inst, "gotoCurrent") && inst.currentDay) {
8652                         inst.selectedDay = inst.currentDay;
8653                         inst.drawMonth = inst.selectedMonth = inst.currentMonth;
8654                         inst.drawYear = inst.selectedYear = inst.currentYear;
8655                 } else {
8656                         date = new Date();
8657                         inst.selectedDay = date.getDate();
8658                         inst.drawMonth = inst.selectedMonth = date.getMonth();
8659                         inst.drawYear = inst.selectedYear = date.getFullYear();
8660                 }
8661                 this._notifyChange(inst);
8662                 this._adjustDate(target);
8663         },
8665         /* Action for selecting a new month/year. */
8666         _selectMonthYear: function(id, select, period) {
8667                 var target = $(id),
8668                         inst = this._getInst(target[0]);
8670                 inst["selected" + (period === "M" ? "Month" : "Year")] =
8671                 inst["draw" + (period === "M" ? "Month" : "Year")] =
8672                         parseInt(select.options[select.selectedIndex].value,10);
8674                 this._notifyChange(inst);
8675                 this._adjustDate(target);
8676         },
8678         /* Action for selecting a day. */
8679         _selectDay: function(id, month, year, td) {
8680                 var inst,
8681                         target = $(id);
8683                 if ($(td).hasClass(this._unselectableClass) || this._isDisabledDatepicker(target[0])) {
8684                         return;
8685                 }
8687                 inst = this._getInst(target[0]);
8688                 inst.selectedDay = inst.currentDay = $("a", td).html();
8689                 inst.selectedMonth = inst.currentMonth = month;
8690                 inst.selectedYear = inst.currentYear = year;
8691                 this._selectDate(id, this._formatDate(inst,
8692                         inst.currentDay, inst.currentMonth, inst.currentYear));
8693         },
8695         /* Erase the input field and hide the date picker. */
8696         _clearDate: function(id) {
8697                 var target = $(id);
8698                 this._selectDate(target, "");
8699         },
8701         /* Update the input field with the selected date. */
8702         _selectDate: function(id, dateStr) {
8703                 var onSelect,
8704                         target = $(id),
8705                         inst = this._getInst(target[0]);
8707                 dateStr = (dateStr != null ? dateStr : this._formatDate(inst));
8708                 if (inst.input) {
8709                         inst.input.val(dateStr);
8710                 }
8711                 this._updateAlternate(inst);
8713                 onSelect = this._get(inst, "onSelect");
8714                 if (onSelect) {
8715                         onSelect.apply((inst.input ? inst.input[0] : null), [dateStr, inst]);  // trigger custom callback
8716                 } else if (inst.input) {
8717                         inst.input.trigger("change"); // fire the change event
8718                 }
8720                 if (inst.inline){
8721                         this._updateDatepicker(inst);
8722                 } else {
8723                         this._hideDatepicker();
8724                         this._lastInput = inst.input[0];
8725                         if (typeof(inst.input[0]) !== "object") {
8726                                 inst.input.focus(); // restore focus
8727                         }
8728                         this._lastInput = null;
8729                 }
8730         },
8732         /* Update any alternate field to synchronise with the main field. */
8733         _updateAlternate: function(inst) {
8734                 var altFormat, date, dateStr,
8735                         altField = this._get(inst, "altField");
8737                 if (altField) { // update alternate field too
8738                         altFormat = this._get(inst, "altFormat") || this._get(inst, "dateFormat");
8739                         date = this._getDate(inst);
8740                         dateStr = this.formatDate(altFormat, date, this._getFormatConfig(inst));
8741                         $(altField).each(function() { $(this).val(dateStr); });
8742                 }
8743         },
8745         /* Set as beforeShowDay function to prevent selection of weekends.
8746          * @param  date  Date - the date to customise
8747          * @return [boolean, string] - is this date selectable?, what is its CSS class?
8748          */
8749         noWeekends: function(date) {
8750                 var day = date.getDay();
8751                 return [(day > 0 && day < 6), ""];
8752         },
8754         /* Set as calculateWeek to determine the week of the year based on the ISO 8601 definition.
8755          * @param  date  Date - the date to get the week for
8756          * @return  number - the number of the week within the year that contains this date
8757          */
8758         iso8601Week: function(date) {
8759                 var time,
8760                         checkDate = new Date(date.getTime());
8762                 // Find Thursday of this week starting on Monday
8763                 checkDate.setDate(checkDate.getDate() + 4 - (checkDate.getDay() || 7));
8765                 time = checkDate.getTime();
8766                 checkDate.setMonth(0); // Compare with Jan 1
8767                 checkDate.setDate(1);
8768                 return Math.floor(Math.round((time - checkDate) / 86400000) / 7) + 1;
8769         },
8771         /* Parse a string value into a date object.
8772          * See formatDate below for the possible formats.
8773          *
8774          * @param  format string - the expected format of the date
8775          * @param  value string - the date in the above format
8776          * @param  settings Object - attributes include:
8777          *                                      shortYearCutoff  number - the cutoff year for determining the century (optional)
8778          *                                      dayNamesShort   string[7] - abbreviated names of the days from Sunday (optional)
8779          *                                      dayNames                string[7] - names of the days from Sunday (optional)
8780          *                                      monthNamesShort string[12] - abbreviated names of the months (optional)
8781          *                                      monthNames              string[12] - names of the months (optional)
8782          * @return  Date - the extracted date value or null if value is blank
8783          */
8784         parseDate: function (format, value, settings) {
8785                 if (format == null || value == null) {
8786                         throw "Invalid arguments";
8787                 }
8789                 value = (typeof value === "object" ? value.toString() : value + "");
8790                 if (value === "") {
8791                         return null;
8792                 }
8794                 var iFormat, dim, extra,
8795                         iValue = 0,
8796                         shortYearCutoffTemp = (settings ? settings.shortYearCutoff : null) || this._defaults.shortYearCutoff,
8797                         shortYearCutoff = (typeof shortYearCutoffTemp !== "string" ? shortYearCutoffTemp :
8798                                 new Date().getFullYear() % 100 + parseInt(shortYearCutoffTemp, 10)),
8799                         dayNamesShort = (settings ? settings.dayNamesShort : null) || this._defaults.dayNamesShort,
8800                         dayNames = (settings ? settings.dayNames : null) || this._defaults.dayNames,
8801                         monthNamesShort = (settings ? settings.monthNamesShort : null) || this._defaults.monthNamesShort,
8802                         monthNames = (settings ? settings.monthNames : null) || this._defaults.monthNames,
8803                         year = -1,
8804                         month = -1,
8805                         day = -1,
8806                         doy = -1,
8807                         literal = false,
8808                         date,
8809                         // Check whether a format character is doubled
8810                         lookAhead = function(match) {
8811                                 var matches = (iFormat + 1 < format.length && format.charAt(iFormat + 1) === match);
8812                                 if (matches) {
8813                                         iFormat++;
8814                                 }
8815                                 return matches;
8816                         },
8817                         // Extract a number from the string value
8818                         getNumber = function(match) {
8819                                 var isDoubled = lookAhead(match),
8820                                         size = (match === "@" ? 14 : (match === "!" ? 20 :
8821                                         (match === "y" && isDoubled ? 4 : (match === "o" ? 3 : 2)))),
8822                                         digits = new RegExp("^\\d{1," + size + "}"),
8823                                         num = value.substring(iValue).match(digits);
8824                                 if (!num) {
8825                                         throw "Missing number at position " + iValue;
8826                                 }
8827                                 iValue += num[0].length;
8828                                 return parseInt(num[0], 10);
8829                         },
8830                         // Extract a name from the string value and convert to an index
8831                         getName = function(match, shortNames, longNames) {
8832                                 var index = -1,
8833                                         names = $.map(lookAhead(match) ? longNames : shortNames, function (v, k) {
8834                                                 return [ [k, v] ];
8835                                         }).sort(function (a, b) {
8836                                                 return -(a[1].length - b[1].length);
8837                                         });
8839                                 $.each(names, function (i, pair) {
8840                                         var name = pair[1];
8841                                         if (value.substr(iValue, name.length).toLowerCase() === name.toLowerCase()) {
8842                                                 index = pair[0];
8843                                                 iValue += name.length;
8844                                                 return false;
8845                                         }
8846                                 });
8847                                 if (index !== -1) {
8848                                         return index + 1;
8849                                 } else {
8850                                         throw "Unknown name at position " + iValue;
8851                                 }
8852                         },
8853                         // Confirm that a literal character matches the string value
8854                         checkLiteral = function() {
8855                                 if (value.charAt(iValue) !== format.charAt(iFormat)) {
8856                                         throw "Unexpected literal at position " + iValue;
8857                                 }
8858                                 iValue++;
8859                         };
8861                 for (iFormat = 0; iFormat < format.length; iFormat++) {
8862                         if (literal) {
8863                                 if (format.charAt(iFormat) === "'" && !lookAhead("'")) {
8864                                         literal = false;
8865                                 } else {
8866                                         checkLiteral();
8867                                 }
8868                         } else {
8869                                 switch (format.charAt(iFormat)) {
8870                                         case "d":
8871                                                 day = getNumber("d");
8872                                                 break;
8873                                         case "D":
8874                                                 getName("D", dayNamesShort, dayNames);
8875                                                 break;
8876                                         case "o":
8877                                                 doy = getNumber("o");
8878                                                 break;
8879                                         case "m":
8880                                                 month = getNumber("m");
8881                                                 break;
8882                                         case "M":
8883                                                 month = getName("M", monthNamesShort, monthNames);
8884                                                 break;
8885                                         case "y":
8886                                                 year = getNumber("y");
8887                                                 break;
8888                                         case "@":
8889                                                 date = new Date(getNumber("@"));
8890                                                 year = date.getFullYear();
8891                                                 month = date.getMonth() + 1;
8892                                                 day = date.getDate();
8893                                                 break;
8894                                         case "!":
8895                                                 date = new Date((getNumber("!") - this._ticksTo1970) / 10000);
8896                                                 year = date.getFullYear();
8897                                                 month = date.getMonth() + 1;
8898                                                 day = date.getDate();
8899                                                 break;
8900                                         case "'":
8901                                                 if (lookAhead("'")){
8902                                                         checkLiteral();
8903                                                 } else {
8904                                                         literal = true;
8905                                                 }
8906                                                 break;
8907                                         default:
8908                                                 checkLiteral();
8909                                 }
8910                         }
8911                 }
8913                 if (iValue < value.length){
8914                         extra = value.substr(iValue);
8915                         if (!/^\s+/.test(extra)) {
8916                                 throw "Extra/unparsed characters found in date: " + extra;
8917                         }
8918                 }
8920                 if (year === -1) {
8921                         year = new Date().getFullYear();
8922                 } else if (year < 100) {
8923                         year += new Date().getFullYear() - new Date().getFullYear() % 100 +
8924                                 (year <= shortYearCutoff ? 0 : -100);
8925                 }
8927                 if (doy > -1) {
8928                         month = 1;
8929                         day = doy;
8930                         do {
8931                                 dim = this._getDaysInMonth(year, month - 1);
8932                                 if (day <= dim) {
8933                                         break;
8934                                 }
8935                                 month++;
8936                                 day -= dim;
8937                         } while (true);
8938                 }
8940                 date = this._daylightSavingAdjust(new Date(year, month - 1, day));
8941                 if (date.getFullYear() !== year || date.getMonth() + 1 !== month || date.getDate() !== day) {
8942                         throw "Invalid date"; // E.g. 31/02/00
8943                 }
8944                 return date;
8945         },
8947         /* Standard date formats. */
8948         ATOM: "yy-mm-dd", // RFC 3339 (ISO 8601)
8949         COOKIE: "D, dd M yy",
8950         ISO_8601: "yy-mm-dd",
8951         RFC_822: "D, d M y",
8952         RFC_850: "DD, dd-M-y",
8953         RFC_1036: "D, d M y",
8954         RFC_1123: "D, d M yy",
8955         RFC_2822: "D, d M yy",
8956         RSS: "D, d M y", // RFC 822
8957         TICKS: "!",
8958         TIMESTAMP: "@",
8959         W3C: "yy-mm-dd", // ISO 8601
8961         _ticksTo1970: (((1970 - 1) * 365 + Math.floor(1970 / 4) - Math.floor(1970 / 100) +
8962                 Math.floor(1970 / 400)) * 24 * 60 * 60 * 10000000),
8964         /* Format a date object into a string value.
8965          * The format can be combinations of the following:
8966          * d  - day of month (no leading zero)
8967          * dd - day of month (two digit)
8968          * o  - day of year (no leading zeros)
8969          * oo - day of year (three digit)
8970          * D  - day name short
8971          * DD - day name long
8972          * m  - month of year (no leading zero)
8973          * mm - month of year (two digit)
8974          * M  - month name short
8975          * MM - month name long
8976          * y  - year (two digit)
8977          * yy - year (four digit)
8978          * @ - Unix timestamp (ms since 01/01/1970)
8979          * ! - Windows ticks (100ns since 01/01/0001)
8980          * "..." - literal text
8981          * '' - single quote
8982          *
8983          * @param  format string - the desired format of the date
8984          * @param  date Date - the date value to format
8985          * @param  settings Object - attributes include:
8986          *                                      dayNamesShort   string[7] - abbreviated names of the days from Sunday (optional)
8987          *                                      dayNames                string[7] - names of the days from Sunday (optional)
8988          *                                      monthNamesShort string[12] - abbreviated names of the months (optional)
8989          *                                      monthNames              string[12] - names of the months (optional)
8990          * @return  string - the date in the above format
8991          */
8992         formatDate: function (format, date, settings) {
8993                 if (!date) {
8994                         return "";
8995                 }
8997                 var iFormat,
8998                         dayNamesShort = (settings ? settings.dayNamesShort : null) || this._defaults.dayNamesShort,
8999                         dayNames = (settings ? settings.dayNames : null) || this._defaults.dayNames,
9000                         monthNamesShort = (settings ? settings.monthNamesShort : null) || this._defaults.monthNamesShort,
9001                         monthNames = (settings ? settings.monthNames : null) || this._defaults.monthNames,
9002                         // Check whether a format character is doubled
9003                         lookAhead = function(match) {
9004                                 var matches = (iFormat + 1 < format.length && format.charAt(iFormat + 1) === match);
9005                                 if (matches) {
9006                                         iFormat++;
9007                                 }
9008                                 return matches;
9009                         },
9010                         // Format a number, with leading zero if necessary
9011                         formatNumber = function(match, value, len) {
9012                                 var num = "" + value;
9013                                 if (lookAhead(match)) {
9014                                         while (num.length < len) {
9015                                                 num = "0" + num;
9016                                         }
9017                                 }
9018                                 return num;
9019                         },
9020                         // Format a name, short or long as requested
9021                         formatName = function(match, value, shortNames, longNames) {
9022                                 return (lookAhead(match) ? longNames[value] : shortNames[value]);
9023                         },
9024                         output = "",
9025                         literal = false;
9027                 if (date) {
9028                         for (iFormat = 0; iFormat < format.length; iFormat++) {
9029                                 if (literal) {
9030                                         if (format.charAt(iFormat) === "'" && !lookAhead("'")) {
9031                                                 literal = false;
9032                                         } else {
9033                                                 output += format.charAt(iFormat);
9034                                         }
9035                                 } else {
9036                                         switch (format.charAt(iFormat)) {
9037                                                 case "d":
9038                                                         output += formatNumber("d", date.getDate(), 2);
9039                                                         break;
9040                                                 case "D":
9041                                                         output += formatName("D", date.getDay(), dayNamesShort, dayNames);
9042                                                         break;
9043                                                 case "o":
9044                                                         output += formatNumber("o",
9045                                                                 Math.round((new Date(date.getFullYear(), date.getMonth(), date.getDate()).getTime() - new Date(date.getFullYear(), 0, 0).getTime()) / 86400000), 3);
9046                                                         break;
9047                                                 case "m":
9048                                                         output += formatNumber("m", date.getMonth() + 1, 2);
9049                                                         break;
9050                                                 case "M":
9051                                                         output += formatName("M", date.getMonth(), monthNamesShort, monthNames);
9052                                                         break;
9053                                                 case "y":
9054                                                         output += (lookAhead("y") ? date.getFullYear() :
9055                                                                 (date.getYear() % 100 < 10 ? "0" : "") + date.getYear() % 100);
9056                                                         break;
9057                                                 case "@":
9058                                                         output += date.getTime();
9059                                                         break;
9060                                                 case "!":
9061                                                         output += date.getTime() * 10000 + this._ticksTo1970;
9062                                                         break;
9063                                                 case "'":
9064                                                         if (lookAhead("'")) {
9065                                                                 output += "'";
9066                                                         } else {
9067                                                                 literal = true;
9068                                                         }
9069                                                         break;
9070                                                 default:
9071                                                         output += format.charAt(iFormat);
9072                                         }
9073                                 }
9074                         }
9075                 }
9076                 return output;
9077         },
9079         /* Extract all possible characters from the date format. */
9080         _possibleChars: function (format) {
9081                 var iFormat,
9082                         chars = "",
9083                         literal = false,
9084                         // Check whether a format character is doubled
9085                         lookAhead = function(match) {
9086                                 var matches = (iFormat + 1 < format.length && format.charAt(iFormat + 1) === match);
9087                                 if (matches) {
9088                                         iFormat++;
9089                                 }
9090                                 return matches;
9091                         };
9093                 for (iFormat = 0; iFormat < format.length; iFormat++) {
9094                         if (literal) {
9095                                 if (format.charAt(iFormat) === "'" && !lookAhead("'")) {
9096                                         literal = false;
9097                                 } else {
9098                                         chars += format.charAt(iFormat);
9099                                 }
9100                         } else {
9101                                 switch (format.charAt(iFormat)) {
9102                                         case "d": case "m": case "y": case "@":
9103                                                 chars += "0123456789";
9104                                                 break;
9105                                         case "D": case "M":
9106                                                 return null; // Accept anything
9107                                         case "'":
9108                                                 if (lookAhead("'")) {
9109                                                         chars += "'";
9110                                                 } else {
9111                                                         literal = true;
9112                                                 }
9113                                                 break;
9114                                         default:
9115                                                 chars += format.charAt(iFormat);
9116                                 }
9117                         }
9118                 }
9119                 return chars;
9120         },
9122         /* Get a setting value, defaulting if necessary. */
9123         _get: function(inst, name) {
9124                 return inst.settings[name] !== undefined ?
9125                         inst.settings[name] : this._defaults[name];
9126         },
9128         /* Parse existing date and initialise date picker. */
9129         _setDateFromField: function(inst, noDefault) {
9130                 if (inst.input.val() === inst.lastVal) {
9131                         return;
9132                 }
9134                 var dateFormat = this._get(inst, "dateFormat"),
9135                         dates = inst.lastVal = inst.input ? inst.input.val() : null,
9136                         defaultDate = this._getDefaultDate(inst),
9137                         date = defaultDate,
9138                         settings = this._getFormatConfig(inst);
9140                 try {
9141                         date = this.parseDate(dateFormat, dates, settings) || defaultDate;
9142                 } catch (event) {
9143                         dates = (noDefault ? "" : dates);
9144                 }
9145                 inst.selectedDay = date.getDate();
9146                 inst.drawMonth = inst.selectedMonth = date.getMonth();
9147                 inst.drawYear = inst.selectedYear = date.getFullYear();
9148                 inst.currentDay = (dates ? date.getDate() : 0);
9149                 inst.currentMonth = (dates ? date.getMonth() : 0);
9150                 inst.currentYear = (dates ? date.getFullYear() : 0);
9151                 this._adjustInstDate(inst);
9152         },
9154         /* Retrieve the default date shown on opening. */
9155         _getDefaultDate: function(inst) {
9156                 return this._restrictMinMax(inst,
9157                         this._determineDate(inst, this._get(inst, "defaultDate"), new Date()));
9158         },
9160         /* A date may be specified as an exact value or a relative one. */
9161         _determineDate: function(inst, date, defaultDate) {
9162                 var offsetNumeric = function(offset) {
9163                                 var date = new Date();
9164                                 date.setDate(date.getDate() + offset);
9165                                 return date;
9166                         },
9167                         offsetString = function(offset) {
9168                                 try {
9169                                         return $.datepicker.parseDate($.datepicker._get(inst, "dateFormat"),
9170                                                 offset, $.datepicker._getFormatConfig(inst));
9171                                 }
9172                                 catch (e) {
9173                                         // Ignore
9174                                 }
9176                                 var date = (offset.toLowerCase().match(/^c/) ?
9177                                         $.datepicker._getDate(inst) : null) || new Date(),
9178                                         year = date.getFullYear(),
9179                                         month = date.getMonth(),
9180                                         day = date.getDate(),
9181                                         pattern = /([+\-]?[0-9]+)\s*(d|D|w|W|m|M|y|Y)?/g,
9182                                         matches = pattern.exec(offset);
9184                                 while (matches) {
9185                                         switch (matches[2] || "d") {
9186                                                 case "d" : case "D" :
9187                                                         day += parseInt(matches[1],10); break;
9188                                                 case "w" : case "W" :
9189                                                         day += parseInt(matches[1],10) * 7; break;
9190                                                 case "m" : case "M" :
9191                                                         month += parseInt(matches[1],10);
9192                                                         day = Math.min(day, $.datepicker._getDaysInMonth(year, month));
9193                                                         break;
9194                                                 case "y": case "Y" :
9195                                                         year += parseInt(matches[1],10);
9196                                                         day = Math.min(day, $.datepicker._getDaysInMonth(year, month));
9197                                                         break;
9198                                         }
9199                                         matches = pattern.exec(offset);
9200                                 }
9201                                 return new Date(year, month, day);
9202                         },
9203                         newDate = (date == null || date === "" ? defaultDate : (typeof date === "string" ? offsetString(date) :
9204                                 (typeof date === "number" ? (isNaN(date) ? defaultDate : offsetNumeric(date)) : new Date(date.getTime()))));
9206                 newDate = (newDate && newDate.toString() === "Invalid Date" ? defaultDate : newDate);
9207                 if (newDate) {
9208                         newDate.setHours(0);
9209                         newDate.setMinutes(0);
9210                         newDate.setSeconds(0);
9211                         newDate.setMilliseconds(0);
9212                 }
9213                 return this._daylightSavingAdjust(newDate);
9214         },
9216         /* Handle switch to/from daylight saving.
9217          * Hours may be non-zero on daylight saving cut-over:
9218          * > 12 when midnight changeover, but then cannot generate
9219          * midnight datetime, so jump to 1AM, otherwise reset.
9220          * @param  date  (Date) the date to check
9221          * @return  (Date) the corrected date
9222          */
9223         _daylightSavingAdjust: function(date) {
9224                 if (!date) {
9225                         return null;
9226                 }
9227                 date.setHours(date.getHours() > 12 ? date.getHours() + 2 : 0);
9228                 return date;
9229         },
9231         /* Set the date(s) directly. */
9232         _setDate: function(inst, date, noChange) {
9233                 var clear = !date,
9234                         origMonth = inst.selectedMonth,
9235                         origYear = inst.selectedYear,
9236                         newDate = this._restrictMinMax(inst, this._determineDate(inst, date, new Date()));
9238                 inst.selectedDay = inst.currentDay = newDate.getDate();
9239                 inst.drawMonth = inst.selectedMonth = inst.currentMonth = newDate.getMonth();
9240                 inst.drawYear = inst.selectedYear = inst.currentYear = newDate.getFullYear();
9241                 if ((origMonth !== inst.selectedMonth || origYear !== inst.selectedYear) && !noChange) {
9242                         this._notifyChange(inst);
9243                 }
9244                 this._adjustInstDate(inst);
9245                 if (inst.input) {
9246                         inst.input.val(clear ? "" : this._formatDate(inst));
9247                 }
9248         },
9250         /* Retrieve the date(s) directly. */
9251         _getDate: function(inst) {
9252                 var startDate = (!inst.currentYear || (inst.input && inst.input.val() === "") ? null :
9253                         this._daylightSavingAdjust(new Date(
9254                         inst.currentYear, inst.currentMonth, inst.currentDay)));
9255                         return startDate;
9256         },
9258         /* Attach the onxxx handlers.  These are declared statically so
9259          * they work with static code transformers like Caja.
9260          */
9261         _attachHandlers: function(inst) {
9262                 var stepMonths = this._get(inst, "stepMonths"),
9263                         id = "#" + inst.id.replace( /\\\\/g, "\\" );
9264                 inst.dpDiv.find("[data-handler]").map(function () {
9265                         var handler = {
9266                                 prev: function () {
9267                                         $.datepicker._adjustDate(id, -stepMonths, "M");
9268                                 },
9269                                 next: function () {
9270                                         $.datepicker._adjustDate(id, +stepMonths, "M");
9271                                 },
9272                                 hide: function () {
9273                                         $.datepicker._hideDatepicker();
9274                                 },
9275                                 today: function () {
9276                                         $.datepicker._gotoToday(id);
9277                                 },
9278                                 selectDay: function () {
9279                                         $.datepicker._selectDay(id, +this.getAttribute("data-month"), +this.getAttribute("data-year"), this);
9280                                         return false;
9281                                 },
9282                                 selectMonth: function () {
9283                                         $.datepicker._selectMonthYear(id, this, "M");
9284                                         return false;
9285                                 },
9286                                 selectYear: function () {
9287                                         $.datepicker._selectMonthYear(id, this, "Y");
9288                                         return false;
9289                                 }
9290                         };
9291                         $(this).bind(this.getAttribute("data-event"), handler[this.getAttribute("data-handler")]);
9292                 });
9293         },
9295         /* Generate the HTML for the current state of the date picker. */
9296         _generateHTML: function(inst) {
9297                 var maxDraw, prevText, prev, nextText, next, currentText, gotoDate,
9298                         controls, buttonPanel, firstDay, showWeek, dayNames, dayNamesMin,
9299                         monthNames, monthNamesShort, beforeShowDay, showOtherMonths,
9300                         selectOtherMonths, defaultDate, html, dow, row, group, col, selectedDate,
9301                         cornerClass, calender, thead, day, daysInMonth, leadDays, curRows, numRows,
9302                         printDate, dRow, tbody, daySettings, otherMonth, unselectable,
9303                         tempDate = new Date(),
9304                         today = this._daylightSavingAdjust(
9305                                 new Date(tempDate.getFullYear(), tempDate.getMonth(), tempDate.getDate())), // clear time
9306                         isRTL = this._get(inst, "isRTL"),
9307                         showButtonPanel = this._get(inst, "showButtonPanel"),
9308                         hideIfNoPrevNext = this._get(inst, "hideIfNoPrevNext"),
9309                         navigationAsDateFormat = this._get(inst, "navigationAsDateFormat"),
9310                         numMonths = this._getNumberOfMonths(inst),
9311                         showCurrentAtPos = this._get(inst, "showCurrentAtPos"),
9312                         stepMonths = this._get(inst, "stepMonths"),
9313                         isMultiMonth = (numMonths[0] !== 1 || numMonths[1] !== 1),
9314                         currentDate = this._daylightSavingAdjust((!inst.currentDay ? new Date(9999, 9, 9) :
9315                                 new Date(inst.currentYear, inst.currentMonth, inst.currentDay))),
9316                         minDate = this._getMinMaxDate(inst, "min"),
9317                         maxDate = this._getMinMaxDate(inst, "max"),
9318                         drawMonth = inst.drawMonth - showCurrentAtPos,
9319                         drawYear = inst.drawYear;
9321                 if (drawMonth < 0) {
9322                         drawMonth += 12;
9323                         drawYear--;
9324                 }
9325                 if (maxDate) {
9326                         maxDraw = this._daylightSavingAdjust(new Date(maxDate.getFullYear(),
9327                                 maxDate.getMonth() - (numMonths[0] * numMonths[1]) + 1, maxDate.getDate()));
9328                         maxDraw = (minDate && maxDraw < minDate ? minDate : maxDraw);
9329                         while (this._daylightSavingAdjust(new Date(drawYear, drawMonth, 1)) > maxDraw) {
9330                                 drawMonth--;
9331                                 if (drawMonth < 0) {
9332                                         drawMonth = 11;
9333                                         drawYear--;
9334                                 }
9335                         }
9336                 }
9337                 inst.drawMonth = drawMonth;
9338                 inst.drawYear = drawYear;
9340                 prevText = this._get(inst, "prevText");
9341                 prevText = (!navigationAsDateFormat ? prevText : this.formatDate(prevText,
9342                         this._daylightSavingAdjust(new Date(drawYear, drawMonth - stepMonths, 1)),
9343                         this._getFormatConfig(inst)));
9345                 prev = (this._canAdjustMonth(inst, -1, drawYear, drawMonth) ?
9346                         "<a class='ui-datepicker-prev ui-corner-all' data-handler='prev' data-event='click'" +
9347                         " title='" + prevText + "'><span class='ui-icon ui-icon-circle-triangle-" + ( isRTL ? "e" : "w") + "'>" + prevText + "</span></a>" :
9348                         (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>"));
9350                 nextText = this._get(inst, "nextText");
9351                 nextText = (!navigationAsDateFormat ? nextText : this.formatDate(nextText,
9352                         this._daylightSavingAdjust(new Date(drawYear, drawMonth + stepMonths, 1)),
9353                         this._getFormatConfig(inst)));
9355                 next = (this._canAdjustMonth(inst, +1, drawYear, drawMonth) ?
9356                         "<a class='ui-datepicker-next ui-corner-all' data-handler='next' data-event='click'" +
9357                         " title='" + nextText + "'><span class='ui-icon ui-icon-circle-triangle-" + ( isRTL ? "w" : "e") + "'>" + nextText + "</span></a>" :
9358                         (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>"));
9360                 currentText = this._get(inst, "currentText");
9361                 gotoDate = (this._get(inst, "gotoCurrent") && inst.currentDay ? currentDate : today);
9362                 currentText = (!navigationAsDateFormat ? currentText :
9363                         this.formatDate(currentText, gotoDate, this._getFormatConfig(inst)));
9365                 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'>" +
9366                         this._get(inst, "closeText") + "</button>" : "");
9368                 buttonPanel = (showButtonPanel) ? "<div class='ui-datepicker-buttonpane ui-widget-content'>" + (isRTL ? controls : "") +
9369                         (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'" +
9370                         ">" + currentText + "</button>" : "") + (isRTL ? "" : controls) + "</div>" : "";
9372                 firstDay = parseInt(this._get(inst, "firstDay"),10);
9373                 firstDay = (isNaN(firstDay) ? 0 : firstDay);
9375                 showWeek = this._get(inst, "showWeek");
9376                 dayNames = this._get(inst, "dayNames");
9377                 dayNamesMin = this._get(inst, "dayNamesMin");
9378                 monthNames = this._get(inst, "monthNames");
9379                 monthNamesShort = this._get(inst, "monthNamesShort");
9380                 beforeShowDay = this._get(inst, "beforeShowDay");
9381                 showOtherMonths = this._get(inst, "showOtherMonths");
9382                 selectOtherMonths = this._get(inst, "selectOtherMonths");
9383                 defaultDate = this._getDefaultDate(inst);
9384                 html = "";
9385                 dow;
9386                 for (row = 0; row < numMonths[0]; row++) {
9387                         group = "";
9388                         this.maxRows = 4;
9389                         for (col = 0; col < numMonths[1]; col++) {
9390                                 selectedDate = this._daylightSavingAdjust(new Date(drawYear, drawMonth, inst.selectedDay));
9391                                 cornerClass = " ui-corner-all";
9392                                 calender = "";
9393                                 if (isMultiMonth) {
9394                                         calender += "<div class='ui-datepicker-group";
9395                                         if (numMonths[1] > 1) {
9396                                                 switch (col) {
9397                                                         case 0: calender += " ui-datepicker-group-first";
9398                                                                 cornerClass = " ui-corner-" + (isRTL ? "right" : "left"); break;
9399                                                         case numMonths[1]-1: calender += " ui-datepicker-group-last";
9400                                                                 cornerClass = " ui-corner-" + (isRTL ? "left" : "right"); break;
9401                                                         default: calender += " ui-datepicker-group-middle"; cornerClass = ""; break;
9402                                                 }
9403                                         }
9404                                         calender += "'>";
9405                                 }
9406                                 calender += "<div class='ui-datepicker-header ui-widget-header ui-helper-clearfix" + cornerClass + "'>" +
9407                                         (/all|left/.test(cornerClass) && row === 0 ? (isRTL ? next : prev) : "") +
9408                                         (/all|right/.test(cornerClass) && row === 0 ? (isRTL ? prev : next) : "") +
9409                                         this._generateMonthYearHeader(inst, drawMonth, drawYear, minDate, maxDate,
9410                                         row > 0 || col > 0, monthNames, monthNamesShort) + // draw month headers
9411                                         "</div><table class='ui-datepicker-calendar'><thead>" +
9412                                         "<tr>";
9413                                 thead = (showWeek ? "<th class='ui-datepicker-week-col'>" + this._get(inst, "weekHeader") + "</th>" : "");
9414                                 for (dow = 0; dow < 7; dow++) { // days of the week
9415                                         day = (dow + firstDay) % 7;
9416                                         thead += "<th scope='col'" + ((dow + firstDay + 6) % 7 >= 5 ? " class='ui-datepicker-week-end'" : "") + ">" +
9417                                                 "<span title='" + dayNames[day] + "'>" + dayNamesMin[day] + "</span></th>";
9418                                 }
9419                                 calender += thead + "</tr></thead><tbody>";
9420                                 daysInMonth = this._getDaysInMonth(drawYear, drawMonth);
9421                                 if (drawYear === inst.selectedYear && drawMonth === inst.selectedMonth) {
9422                                         inst.selectedDay = Math.min(inst.selectedDay, daysInMonth);
9423                                 }
9424                                 leadDays = (this._getFirstDayOfMonth(drawYear, drawMonth) - firstDay + 7) % 7;
9425                                 curRows = Math.ceil((leadDays + daysInMonth) / 7); // calculate the number of rows to generate
9426                                 numRows = (isMultiMonth ? this.maxRows > curRows ? this.maxRows : curRows : curRows); //If multiple months, use the higher number of rows (see #7043)
9427                                 this.maxRows = numRows;
9428                                 printDate = this._daylightSavingAdjust(new Date(drawYear, drawMonth, 1 - leadDays));
9429                                 for (dRow = 0; dRow < numRows; dRow++) { // create date picker rows
9430                                         calender += "<tr>";
9431                                         tbody = (!showWeek ? "" : "<td class='ui-datepicker-week-col'>" +
9432                                                 this._get(inst, "calculateWeek")(printDate) + "</td>");
9433                                         for (dow = 0; dow < 7; dow++) { // create date picker days
9434                                                 daySettings = (beforeShowDay ?
9435                                                         beforeShowDay.apply((inst.input ? inst.input[0] : null), [printDate]) : [true, ""]);
9436                                                 otherMonth = (printDate.getMonth() !== drawMonth);
9437                                                 unselectable = (otherMonth && !selectOtherMonths) || !daySettings[0] ||
9438                                                         (minDate && printDate < minDate) || (maxDate && printDate > maxDate);
9439                                                 tbody += "<td class='" +
9440                                                         ((dow + firstDay + 6) % 7 >= 5 ? " ui-datepicker-week-end" : "") + // highlight weekends
9441                                                         (otherMonth ? " ui-datepicker-other-month" : "") + // highlight days from other months
9442                                                         ((printDate.getTime() === selectedDate.getTime() && drawMonth === inst.selectedMonth && inst._keyEvent) || // user pressed key
9443                                                         (defaultDate.getTime() === printDate.getTime() && defaultDate.getTime() === selectedDate.getTime()) ?
9444                                                         // or defaultDate is current printedDate and defaultDate is selectedDate
9445                                                         " " + this._dayOverClass : "") + // highlight selected day
9446                                                         (unselectable ? " " + this._unselectableClass + " ui-state-disabled": "") +  // highlight unselectable days
9447                                                         (otherMonth && !showOtherMonths ? "" : " " + daySettings[1] + // highlight custom dates
9448                                                         (printDate.getTime() === currentDate.getTime() ? " " + this._currentClass : "") + // highlight selected day
9449                                                         (printDate.getTime() === today.getTime() ? " ui-datepicker-today" : "")) + "'" + // highlight today (if different)
9450                                                         ((!otherMonth || showOtherMonths) && daySettings[2] ? " title='" + daySettings[2].replace(/'/g, "&#39;") + "'" : "") + // cell title
9451                                                         (unselectable ? "" : " data-handler='selectDay' data-event='click' data-month='" + printDate.getMonth() + "' data-year='" + printDate.getFullYear() + "'") + ">" + // actions
9452                                                         (otherMonth && !showOtherMonths ? "&#xa0;" : // display for other months
9453                                                         (unselectable ? "<span class='ui-state-default'>" + printDate.getDate() + "</span>" : "<a class='ui-state-default" +
9454                                                         (printDate.getTime() === today.getTime() ? " ui-state-highlight" : "") +
9455                                                         (printDate.getTime() === currentDate.getTime() ? " ui-state-active" : "") + // highlight selected day
9456                                                         (otherMonth ? " ui-priority-secondary" : "") + // distinguish dates from other months
9457                                                         "' href='#'>" + printDate.getDate() + "</a>")) + "</td>"; // display selectable date
9458                                                 printDate.setDate(printDate.getDate() + 1);
9459                                                 printDate = this._daylightSavingAdjust(printDate);
9460                                         }
9461                                         calender += tbody + "</tr>";
9462                                 }
9463                                 drawMonth++;
9464                                 if (drawMonth > 11) {
9465                                         drawMonth = 0;
9466                                         drawYear++;
9467                                 }
9468                                 calender += "</tbody></table>" + (isMultiMonth ? "</div>" +
9469                                                         ((numMonths[0] > 0 && col === numMonths[1]-1) ? "<div class='ui-datepicker-row-break'></div>" : "") : "");
9470                                 group += calender;
9471                         }
9472                         html += group;
9473                 }
9474                 html += buttonPanel;
9475                 inst._keyEvent = false;
9476                 return html;
9477         },
9479         /* Generate the month and year header. */
9480         _generateMonthYearHeader: function(inst, drawMonth, drawYear, minDate, maxDate,
9481                         secondary, monthNames, monthNamesShort) {
9483                 var inMinYear, inMaxYear, month, years, thisYear, determineYear, year, endYear,
9484                         changeMonth = this._get(inst, "changeMonth"),
9485                         changeYear = this._get(inst, "changeYear"),
9486                         showMonthAfterYear = this._get(inst, "showMonthAfterYear"),
9487                         html = "<div class='ui-datepicker-title'>",
9488                         monthHtml = "";
9490                 // month selection
9491                 if (secondary || !changeMonth) {
9492                         monthHtml += "<span class='ui-datepicker-month'>" + monthNames[drawMonth] + "</span>";
9493                 } else {
9494                         inMinYear = (minDate && minDate.getFullYear() === drawYear);
9495                         inMaxYear = (maxDate && maxDate.getFullYear() === drawYear);
9496                         monthHtml += "<select class='ui-datepicker-month' data-handler='selectMonth' data-event='change'>";
9497                         for ( month = 0; month < 12; month++) {
9498                                 if ((!inMinYear || month >= minDate.getMonth()) && (!inMaxYear || month <= maxDate.getMonth())) {
9499                                         monthHtml += "<option value='" + month + "'" +
9500                                                 (month === drawMonth ? " selected='selected'" : "") +
9501                                                 ">" + monthNamesShort[month] + "</option>";
9502                                 }
9503                         }
9504                         monthHtml += "</select>";
9505                 }
9507                 if (!showMonthAfterYear) {
9508                         html += monthHtml + (secondary || !(changeMonth && changeYear) ? "&#xa0;" : "");
9509                 }
9511                 // year selection
9512                 if ( !inst.yearshtml ) {
9513                         inst.yearshtml = "";
9514                         if (secondary || !changeYear) {
9515                                 html += "<span class='ui-datepicker-year'>" + drawYear + "</span>";
9516                         } else {
9517                                 // determine range of years to display
9518                                 years = this._get(inst, "yearRange").split(":");
9519                                 thisYear = new Date().getFullYear();
9520                                 determineYear = function(value) {
9521                                         var year = (value.match(/c[+\-].*/) ? drawYear + parseInt(value.substring(1), 10) :
9522                                                 (value.match(/[+\-].*/) ? thisYear + parseInt(value, 10) :
9523                                                 parseInt(value, 10)));
9524                                         return (isNaN(year) ? thisYear : year);
9525                                 };
9526                                 year = determineYear(years[0]);
9527                                 endYear = Math.max(year, determineYear(years[1] || ""));
9528                                 year = (minDate ? Math.max(year, minDate.getFullYear()) : year);
9529                                 endYear = (maxDate ? Math.min(endYear, maxDate.getFullYear()) : endYear);
9530                                 inst.yearshtml += "<select class='ui-datepicker-year' data-handler='selectYear' data-event='change'>";
9531                                 for (; year <= endYear; year++) {
9532                                         inst.yearshtml += "<option value='" + year + "'" +
9533                                                 (year === drawYear ? " selected='selected'" : "") +
9534                                                 ">" + year + "</option>";
9535                                 }
9536                                 inst.yearshtml += "</select>";
9538                                 html += inst.yearshtml;
9539                                 inst.yearshtml = null;
9540                         }
9541                 }
9543                 html += this._get(inst, "yearSuffix");
9544                 if (showMonthAfterYear) {
9545                         html += (secondary || !(changeMonth && changeYear) ? "&#xa0;" : "") + monthHtml;
9546                 }
9547                 html += "</div>"; // Close datepicker_header
9548                 return html;
9549         },
9551         /* Adjust one of the date sub-fields. */
9552         _adjustInstDate: function(inst, offset, period) {
9553                 var year = inst.drawYear + (period === "Y" ? offset : 0),
9554                         month = inst.drawMonth + (period === "M" ? offset : 0),
9555                         day = Math.min(inst.selectedDay, this._getDaysInMonth(year, month)) + (period === "D" ? offset : 0),
9556                         date = this._restrictMinMax(inst, this._daylightSavingAdjust(new Date(year, month, day)));
9558                 inst.selectedDay = date.getDate();
9559                 inst.drawMonth = inst.selectedMonth = date.getMonth();
9560                 inst.drawYear = inst.selectedYear = date.getFullYear();
9561                 if (period === "M" || period === "Y") {
9562                         this._notifyChange(inst);
9563                 }
9564         },
9566         /* Ensure a date is within any min/max bounds. */
9567         _restrictMinMax: function(inst, date) {
9568                 var minDate = this._getMinMaxDate(inst, "min"),
9569                         maxDate = this._getMinMaxDate(inst, "max"),
9570                         newDate = (minDate && date < minDate ? minDate : date);
9571                 return (maxDate && newDate > maxDate ? maxDate : newDate);
9572         },
9574         /* Notify change of month/year. */
9575         _notifyChange: function(inst) {
9576                 var onChange = this._get(inst, "onChangeMonthYear");
9577                 if (onChange) {
9578                         onChange.apply((inst.input ? inst.input[0] : null),
9579                                 [inst.selectedYear, inst.selectedMonth + 1, inst]);
9580                 }
9581         },
9583         /* Determine the number of months to show. */
9584         _getNumberOfMonths: function(inst) {
9585                 var numMonths = this._get(inst, "numberOfMonths");
9586                 return (numMonths == null ? [1, 1] : (typeof numMonths === "number" ? [1, numMonths] : numMonths));
9587         },
9589         /* Determine the current maximum date - ensure no time components are set. */
9590         _getMinMaxDate: function(inst, minMax) {
9591                 return this._determineDate(inst, this._get(inst, minMax + "Date"), null);
9592         },
9594         /* Find the number of days in a given month. */
9595         _getDaysInMonth: function(year, month) {
9596                 return 32 - this._daylightSavingAdjust(new Date(year, month, 32)).getDate();
9597         },
9599         /* Find the day of the week of the first of a month. */
9600         _getFirstDayOfMonth: function(year, month) {
9601                 return new Date(year, month, 1).getDay();
9602         },
9604         /* Determines if we should allow a "next/prev" month display change. */
9605         _canAdjustMonth: function(inst, offset, curYear, curMonth) {
9606                 var numMonths = this._getNumberOfMonths(inst),
9607                         date = this._daylightSavingAdjust(new Date(curYear,
9608                         curMonth + (offset < 0 ? offset : numMonths[0] * numMonths[1]), 1));
9610                 if (offset < 0) {
9611                         date.setDate(this._getDaysInMonth(date.getFullYear(), date.getMonth()));
9612                 }
9613                 return this._isInRange(inst, date);
9614         },
9616         /* Is the given date in the accepted range? */
9617         _isInRange: function(inst, date) {
9618                 var yearSplit, currentYear,
9619                         minDate = this._getMinMaxDate(inst, "min"),
9620                         maxDate = this._getMinMaxDate(inst, "max"),
9621                         minYear = null,
9622                         maxYear = null,
9623                         years = this._get(inst, "yearRange");
9624                         if (years){
9625                                 yearSplit = years.split(":");
9626                                 currentYear = new Date().getFullYear();
9627                                 minYear = parseInt(yearSplit[0], 10);
9628                                 maxYear = parseInt(yearSplit[1], 10);
9629                                 if ( yearSplit[0].match(/[+\-].*/) ) {
9630                                         minYear += currentYear;
9631                                 }
9632                                 if ( yearSplit[1].match(/[+\-].*/) ) {
9633                                         maxYear += currentYear;
9634                                 }
9635                         }
9637                 return ((!minDate || date.getTime() >= minDate.getTime()) &&
9638                         (!maxDate || date.getTime() <= maxDate.getTime()) &&
9639                         (!minYear || date.getFullYear() >= minYear) &&
9640                         (!maxYear || date.getFullYear() <= maxYear));
9641         },
9643         /* Provide the configuration settings for formatting/parsing. */
9644         _getFormatConfig: function(inst) {
9645                 var shortYearCutoff = this._get(inst, "shortYearCutoff");
9646                 shortYearCutoff = (typeof shortYearCutoff !== "string" ? shortYearCutoff :
9647                         new Date().getFullYear() % 100 + parseInt(shortYearCutoff, 10));
9648                 return {shortYearCutoff: shortYearCutoff,
9649                         dayNamesShort: this._get(inst, "dayNamesShort"), dayNames: this._get(inst, "dayNames"),
9650                         monthNamesShort: this._get(inst, "monthNamesShort"), monthNames: this._get(inst, "monthNames")};
9651         },
9653         /* Format the given date for display. */
9654         _formatDate: function(inst, day, month, year) {
9655                 if (!day) {
9656                         inst.currentDay = inst.selectedDay;
9657                         inst.currentMonth = inst.selectedMonth;
9658                         inst.currentYear = inst.selectedYear;
9659                 }
9660                 var date = (day ? (typeof day === "object" ? day :
9661                         this._daylightSavingAdjust(new Date(year, month, day))) :
9662                         this._daylightSavingAdjust(new Date(inst.currentYear, inst.currentMonth, inst.currentDay)));
9663                 return this.formatDate(this._get(inst, "dateFormat"), date, this._getFormatConfig(inst));
9664         }
9668  * Bind hover events for datepicker elements.
9669  * Done via delegate so the binding only occurs once in the lifetime of the parent div.
9670  * Global datepicker_instActive, set by _updateDatepicker allows the handlers to find their way back to the active picker.
9671  */
9672 function datepicker_bindHover(dpDiv) {
9673         var selector = "button, .ui-datepicker-prev, .ui-datepicker-next, .ui-datepicker-calendar td a";
9674         return dpDiv.delegate(selector, "mouseout", function() {
9675                         $(this).removeClass("ui-state-hover");
9676                         if (this.className.indexOf("ui-datepicker-prev") !== -1) {
9677                                 $(this).removeClass("ui-datepicker-prev-hover");
9678                         }
9679                         if (this.className.indexOf("ui-datepicker-next") !== -1) {
9680                                 $(this).removeClass("ui-datepicker-next-hover");
9681                         }
9682                 })
9683                 .delegate(selector, "mouseover", function(){
9684                         if (!$.datepicker._isDisabledDatepicker( datepicker_instActive.inline ? dpDiv.parent()[0] : datepicker_instActive.input[0])) {
9685                                 $(this).parents(".ui-datepicker-calendar").find("a").removeClass("ui-state-hover");
9686                                 $(this).addClass("ui-state-hover");
9687                                 if (this.className.indexOf("ui-datepicker-prev") !== -1) {
9688                                         $(this).addClass("ui-datepicker-prev-hover");
9689                                 }
9690                                 if (this.className.indexOf("ui-datepicker-next") !== -1) {
9691                                         $(this).addClass("ui-datepicker-next-hover");
9692                                 }
9693                         }
9694                 });
9697 /* jQuery extend now ignores nulls! */
9698 function datepicker_extendRemove(target, props) {
9699         $.extend(target, props);
9700         for (var name in props) {
9701                 if (props[name] == null) {
9702                         target[name] = props[name];
9703                 }
9704         }
9705         return target;
9708 /* Invoke the datepicker functionality.
9709    @param  options  string - a command, optionally followed by additional parameters or
9710                                         Object - settings for attaching new datepicker functionality
9711    @return  jQuery object */
9712 $.fn.datepicker = function(options){
9714         /* Verify an empty collection wasn't passed - Fixes #6976 */
9715         if ( !this.length ) {
9716                 return this;
9717         }
9719         /* Initialise the date picker. */
9720         if (!$.datepicker.initialized) {
9721                 $(document).mousedown($.datepicker._checkExternalClick);
9722                 $.datepicker.initialized = true;
9723         }
9725         /* Append datepicker main container to body if not exist. */
9726         if ($("#"+$.datepicker._mainDivId).length === 0) {
9727                 $("body").append($.datepicker.dpDiv);
9728         }
9730         var otherArgs = Array.prototype.slice.call(arguments, 1);
9731         if (typeof options === "string" && (options === "isDisabled" || options === "getDate" || options === "widget")) {
9732                 return $.datepicker["_" + options + "Datepicker"].
9733                         apply($.datepicker, [this[0]].concat(otherArgs));
9734         }
9735         if (options === "option" && arguments.length === 2 && typeof arguments[1] === "string") {
9736                 return $.datepicker["_" + options + "Datepicker"].
9737                         apply($.datepicker, [this[0]].concat(otherArgs));
9738         }
9739         return this.each(function() {
9740                 typeof options === "string" ?
9741                         $.datepicker["_" + options + "Datepicker"].
9742                                 apply($.datepicker, [this].concat(otherArgs)) :
9743                         $.datepicker._attachDatepicker(this, options);
9744         });
9747 $.datepicker = new Datepicker(); // singleton instance
9748 $.datepicker.initialized = false;
9749 $.datepicker.uuid = new Date().getTime();
9750 $.datepicker.version = "1.11.0";
9752 var datepicker = $.datepicker;
9756  * jQuery UI Dialog 1.11.0
9757  * http://jqueryui.com
9759  * Copyright 2014 jQuery Foundation and other contributors
9760  * Released under the MIT license.
9761  * http://jquery.org/license
9763  * http://api.jqueryui.com/dialog/
9764  */
9767 var dialog = $.widget( "ui.dialog", {
9768         version: "1.11.0",
9769         options: {
9770                 appendTo: "body",
9771                 autoOpen: true,
9772                 buttons: [],
9773                 closeOnEscape: true,
9774                 closeText: "Close",
9775                 dialogClass: "",
9776                 draggable: true,
9777                 hide: null,
9778                 height: "auto",
9779                 maxHeight: null,
9780                 maxWidth: null,
9781                 minHeight: 150,
9782                 minWidth: 150,
9783                 modal: false,
9784                 position: {
9785                         my: "center",
9786                         at: "center",
9787                         of: window,
9788                         collision: "fit",
9789                         // Ensure the titlebar is always visible
9790                         using: function( pos ) {
9791                                 var topOffset = $( this ).css( pos ).offset().top;
9792                                 if ( topOffset < 0 ) {
9793                                         $( this ).css( "top", pos.top - topOffset );
9794                                 }
9795                         }
9796                 },
9797                 resizable: true,
9798                 show: null,
9799                 title: null,
9800                 width: 300,
9802                 // callbacks
9803                 beforeClose: null,
9804                 close: null,
9805                 drag: null,
9806                 dragStart: null,
9807                 dragStop: null,
9808                 focus: null,
9809                 open: null,
9810                 resize: null,
9811                 resizeStart: null,
9812                 resizeStop: null
9813         },
9815         sizeRelatedOptions: {
9816                 buttons: true,
9817                 height: true,
9818                 maxHeight: true,
9819                 maxWidth: true,
9820                 minHeight: true,
9821                 minWidth: true,
9822                 width: true
9823         },
9825         resizableRelatedOptions: {
9826                 maxHeight: true,
9827                 maxWidth: true,
9828                 minHeight: true,
9829                 minWidth: true
9830         },
9832         _create: function() {
9833                 this.originalCss = {
9834                         display: this.element[ 0 ].style.display,
9835                         width: this.element[ 0 ].style.width,
9836                         minHeight: this.element[ 0 ].style.minHeight,
9837                         maxHeight: this.element[ 0 ].style.maxHeight,
9838                         height: this.element[ 0 ].style.height
9839                 };
9840                 this.originalPosition = {
9841                         parent: this.element.parent(),
9842                         index: this.element.parent().children().index( this.element )
9843                 };
9844                 this.originalTitle = this.element.attr( "title" );
9845                 this.options.title = this.options.title || this.originalTitle;
9847                 this._createWrapper();
9849                 this.element
9850                         .show()
9851                         .removeAttr( "title" )
9852                         .addClass( "ui-dialog-content ui-widget-content" )
9853                         .appendTo( this.uiDialog );
9855                 this._createTitlebar();
9856                 this._createButtonPane();
9858                 if ( this.options.draggable && $.fn.draggable ) {
9859                         this._makeDraggable();
9860                 }
9861                 if ( this.options.resizable && $.fn.resizable ) {
9862                         this._makeResizable();
9863                 }
9865                 this._isOpen = false;
9867                 this._trackFocus();
9868         },
9870         _init: function() {
9871                 if ( this.options.autoOpen ) {
9872                         this.open();
9873                 }
9874         },
9876         _appendTo: function() {
9877                 var element = this.options.appendTo;
9878                 if ( element && (element.jquery || element.nodeType) ) {
9879                         return $( element );
9880                 }
9881                 return this.document.find( element || "body" ).eq( 0 );
9882         },
9884         _destroy: function() {
9885                 var next,
9886                         originalPosition = this.originalPosition;
9888                 this._destroyOverlay();
9890                 this.element
9891                         .removeUniqueId()
9892                         .removeClass( "ui-dialog-content ui-widget-content" )
9893                         .css( this.originalCss )
9894                         // Without detaching first, the following becomes really slow
9895                         .detach();
9897                 this.uiDialog.stop( true, true ).remove();
9899                 if ( this.originalTitle ) {
9900                         this.element.attr( "title", this.originalTitle );
9901                 }
9903                 next = originalPosition.parent.children().eq( originalPosition.index );
9904                 // Don't try to place the dialog next to itself (#8613)
9905                 if ( next.length && next[ 0 ] !== this.element[ 0 ] ) {
9906                         next.before( this.element );
9907                 } else {
9908                         originalPosition.parent.append( this.element );
9909                 }
9910         },
9912         widget: function() {
9913                 return this.uiDialog;
9914         },
9916         disable: $.noop,
9917         enable: $.noop,
9919         close: function( event ) {
9920                 var activeElement,
9921                         that = this;
9923                 if ( !this._isOpen || this._trigger( "beforeClose", event ) === false ) {
9924                         return;
9925                 }
9927                 this._isOpen = false;
9928                 this._focusedElement = null;
9929                 this._destroyOverlay();
9930                 this._untrackInstance();
9932                 if ( !this.opener.filter( ":focusable" ).focus().length ) {
9934                         // support: IE9
9935                         // IE9 throws an "Unspecified error" accessing document.activeElement from an <iframe>
9936                         try {
9937                                 activeElement = this.document[ 0 ].activeElement;
9939                                 // Support: IE9, IE10
9940                                 // If the <body> is blurred, IE will switch windows, see #4520
9941                                 if ( activeElement && activeElement.nodeName.toLowerCase() !== "body" ) {
9943                                         // Hiding a focused element doesn't trigger blur in WebKit
9944                                         // so in case we have nothing to focus on, explicitly blur the active element
9945                                         // https://bugs.webkit.org/show_bug.cgi?id=47182
9946                                         $( activeElement ).blur();
9947                                 }
9948                         } catch ( error ) {}
9949                 }
9951                 this._hide( this.uiDialog, this.options.hide, function() {
9952                         that._trigger( "close", event );
9953                 });
9954         },
9956         isOpen: function() {
9957                 return this._isOpen;
9958         },
9960         moveToTop: function() {
9961                 this._moveToTop();
9962         },
9964         _moveToTop: function( event, silent ) {
9965                 var moved = false,
9966                         zIndicies = this.uiDialog.siblings( ".ui-front:visible" ).map(function() {
9967                                 return +$( this ).css( "z-index" );
9968                         }).get(),
9969                         zIndexMax = Math.max.apply( null, zIndicies );
9971                 if ( zIndexMax >= +this.uiDialog.css( "z-index" ) ) {
9972                         this.uiDialog.css( "z-index", zIndexMax + 1 );
9973                         moved = true;
9974                 }
9976                 if ( moved && !silent ) {
9977                         this._trigger( "focus", event );
9978                 }
9979                 return moved;
9980         },
9982         open: function() {
9983                 var that = this;
9984                 if ( this._isOpen ) {
9985                         if ( this._moveToTop() ) {
9986                                 this._focusTabbable();
9987                         }
9988                         return;
9989                 }
9991                 this._isOpen = true;
9992                 this.opener = $( this.document[ 0 ].activeElement );
9994                 this._size();
9995                 this._position();
9996                 this._createOverlay();
9997                 this._moveToTop( null, true );
9998                 this._show( this.uiDialog, this.options.show, function() {
9999                         that._focusTabbable();
10000                         that._trigger( "focus" );
10001                 });
10003                 this._trigger( "open" );
10004         },
10006         _focusTabbable: function() {
10007                 // Set focus to the first match:
10008                 // 1. An element that was focused previously
10009                 // 2. First element inside the dialog matching [autofocus]
10010                 // 3. Tabbable element inside the content element
10011                 // 4. Tabbable element inside the buttonpane
10012                 // 5. The close button
10013                 // 6. The dialog itself
10014                 var hasFocus = this._focusedElement;
10015                 if ( !hasFocus ) {
10016                         hasFocus = this.element.find( "[autofocus]" );
10017                 }
10018                 if ( !hasFocus.length ) {
10019                         hasFocus = this.element.find( ":tabbable" );
10020                 }
10021                 if ( !hasFocus.length ) {
10022                         hasFocus = this.uiDialogButtonPane.find( ":tabbable" );
10023                 }
10024                 if ( !hasFocus.length ) {
10025                         hasFocus = this.uiDialogTitlebarClose.filter( ":tabbable" );
10026                 }
10027                 if ( !hasFocus.length ) {
10028                         hasFocus = this.uiDialog;
10029                 }
10030                 hasFocus.eq( 0 ).focus();
10031         },
10033         _keepFocus: function( event ) {
10034                 function checkFocus() {
10035                         var activeElement = this.document[0].activeElement,
10036                                 isActive = this.uiDialog[0] === activeElement ||
10037                                         $.contains( this.uiDialog[0], activeElement );
10038                         if ( !isActive ) {
10039                                 this._focusTabbable();
10040                         }
10041                 }
10042                 event.preventDefault();
10043                 checkFocus.call( this );
10044                 // support: IE
10045                 // IE <= 8 doesn't prevent moving focus even with event.preventDefault()
10046                 // so we check again later
10047                 this._delay( checkFocus );
10048         },
10050         _createWrapper: function() {
10051                 this.uiDialog = $("<div>")
10052                         .addClass( "ui-dialog ui-widget ui-widget-content ui-corner-all ui-front " +
10053                                 this.options.dialogClass )
10054                         .hide()
10055                         .attr({
10056                                 // Setting tabIndex makes the div focusable
10057                                 tabIndex: -1,
10058                                 role: "dialog"
10059                         })
10060                         .appendTo( this._appendTo() );
10062                 this._on( this.uiDialog, {
10063                         keydown: function( event ) {
10064                                 if ( this.options.closeOnEscape && !event.isDefaultPrevented() && event.keyCode &&
10065                                                 event.keyCode === $.ui.keyCode.ESCAPE ) {
10066                                         event.preventDefault();
10067                                         this.close( event );
10068                                         return;
10069                                 }
10071                                 // prevent tabbing out of dialogs
10072                                 if ( event.keyCode !== $.ui.keyCode.TAB || event.isDefaultPrevented() ) {
10073                                         return;
10074                                 }
10075                                 var tabbables = this.uiDialog.find( ":tabbable" ),
10076                                         first = tabbables.filter( ":first" ),
10077                                         last = tabbables.filter( ":last" );
10079                                 if ( ( event.target === last[0] || event.target === this.uiDialog[0] ) && !event.shiftKey ) {
10080                                         this._delay(function() {
10081                                                 first.focus();
10082                                         });
10083                                         event.preventDefault();
10084                                 } else if ( ( event.target === first[0] || event.target === this.uiDialog[0] ) && event.shiftKey ) {
10085                                         this._delay(function() {
10086                                                 last.focus();
10087                                         });
10088                                         event.preventDefault();
10089                                 }
10090                         },
10091                         mousedown: function( event ) {
10092                                 if ( this._moveToTop( event ) ) {
10093                                         this._focusTabbable();
10094                                 }
10095                         }
10096                 });
10098                 // We assume that any existing aria-describedby attribute means
10099                 // that the dialog content is marked up properly
10100                 // otherwise we brute force the content as the description
10101                 if ( !this.element.find( "[aria-describedby]" ).length ) {
10102                         this.uiDialog.attr({
10103                                 "aria-describedby": this.element.uniqueId().attr( "id" )
10104                         });
10105                 }
10106         },
10108         _createTitlebar: function() {
10109                 var uiDialogTitle;
10111                 this.uiDialogTitlebar = $( "<div>" )
10112                         .addClass( "ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix" )
10113                         .prependTo( this.uiDialog );
10114                 this._on( this.uiDialogTitlebar, {
10115                         mousedown: function( event ) {
10116                                 // Don't prevent click on close button (#8838)
10117                                 // Focusing a dialog that is partially scrolled out of view
10118                                 // causes the browser to scroll it into view, preventing the click event
10119                                 if ( !$( event.target ).closest( ".ui-dialog-titlebar-close" ) ) {
10120                                         // Dialog isn't getting focus when dragging (#8063)
10121                                         this.uiDialog.focus();
10122                                 }
10123                         }
10124                 });
10126                 // support: IE
10127                 // Use type="button" to prevent enter keypresses in textboxes from closing the
10128                 // dialog in IE (#9312)
10129                 this.uiDialogTitlebarClose = $( "<button type='button'></button>" )
10130                         .button({
10131                                 label: this.options.closeText,
10132                                 icons: {
10133                                         primary: "ui-icon-closethick"
10134                                 },
10135                                 text: false
10136                         })
10137                         .addClass( "ui-dialog-titlebar-close" )
10138                         .appendTo( this.uiDialogTitlebar );
10139                 this._on( this.uiDialogTitlebarClose, {
10140                         click: function( event ) {
10141                                 event.preventDefault();
10142                                 this.close( event );
10143                         }
10144                 });
10146                 uiDialogTitle = $( "<span>" )
10147                         .uniqueId()
10148                         .addClass( "ui-dialog-title" )
10149                         .prependTo( this.uiDialogTitlebar );
10150                 this._title( uiDialogTitle );
10152                 this.uiDialog.attr({
10153                         "aria-labelledby": uiDialogTitle.attr( "id" )
10154                 });
10155         },
10157         _title: function( title ) {
10158                 if ( !this.options.title ) {
10159                         title.html( "&#160;" );
10160                 }
10161                 title.text( this.options.title );
10162         },
10164         _createButtonPane: function() {
10165                 this.uiDialogButtonPane = $( "<div>" )
10166                         .addClass( "ui-dialog-buttonpane ui-widget-content ui-helper-clearfix" );
10168                 this.uiButtonSet = $( "<div>" )
10169                         .addClass( "ui-dialog-buttonset" )
10170                         .appendTo( this.uiDialogButtonPane );
10172                 this._createButtons();
10173         },
10175         _createButtons: function() {
10176                 var that = this,
10177                         buttons = this.options.buttons;
10179                 // if we already have a button pane, remove it
10180                 this.uiDialogButtonPane.remove();
10181                 this.uiButtonSet.empty();
10183                 if ( $.isEmptyObject( buttons ) || ($.isArray( buttons ) && !buttons.length) ) {
10184                         this.uiDialog.removeClass( "ui-dialog-buttons" );
10185                         return;
10186                 }
10188                 $.each( buttons, function( name, props ) {
10189                         var click, buttonOptions;
10190                         props = $.isFunction( props ) ?
10191                                 { click: props, text: name } :
10192                                 props;
10193                         // Default to a non-submitting button
10194                         props = $.extend( { type: "button" }, props );
10195                         // Change the context for the click callback to be the main element
10196                         click = props.click;
10197                         props.click = function() {
10198                                 click.apply( that.element[ 0 ], arguments );
10199                         };
10200                         buttonOptions = {
10201                                 icons: props.icons,
10202                                 text: props.showText
10203                         };
10204                         delete props.icons;
10205                         delete props.showText;
10206                         $( "<button></button>", props )
10207                                 .button( buttonOptions )
10208                                 .appendTo( that.uiButtonSet );
10209                 });
10210                 this.uiDialog.addClass( "ui-dialog-buttons" );
10211                 this.uiDialogButtonPane.appendTo( this.uiDialog );
10212         },
10214         _makeDraggable: function() {
10215                 var that = this,
10216                         options = this.options;
10218                 function filteredUi( ui ) {
10219                         return {
10220                                 position: ui.position,
10221                                 offset: ui.offset
10222                         };
10223                 }
10225                 this.uiDialog.draggable({
10226                         cancel: ".ui-dialog-content, .ui-dialog-titlebar-close",
10227                         handle: ".ui-dialog-titlebar",
10228                         containment: "document",
10229                         start: function( event, ui ) {
10230                                 $( this ).addClass( "ui-dialog-dragging" );
10231                                 that._blockFrames();
10232                                 that._trigger( "dragStart", event, filteredUi( ui ) );
10233                         },
10234                         drag: function( event, ui ) {
10235                                 that._trigger( "drag", event, filteredUi( ui ) );
10236                         },
10237                         stop: function( event, ui ) {
10238                                 var left = ui.offset.left - that.document.scrollLeft(),
10239                                         top = ui.offset.top - that.document.scrollTop();
10241                                 options.position = {
10242                                         my: "left top",
10243                                         at: "left" + (left >= 0 ? "+" : "") + left + " " +
10244                                                 "top" + (top >= 0 ? "+" : "") + top,
10245                                         of: that.window
10246                                 };
10247                                 $( this ).removeClass( "ui-dialog-dragging" );
10248                                 that._unblockFrames();
10249                                 that._trigger( "dragStop", event, filteredUi( ui ) );
10250                         }
10251                 });
10252         },
10254         _makeResizable: function() {
10255                 var that = this,
10256                         options = this.options,
10257                         handles = options.resizable,
10258                         // .ui-resizable has position: relative defined in the stylesheet
10259                         // but dialogs have to use absolute or fixed positioning
10260                         position = this.uiDialog.css("position"),
10261                         resizeHandles = typeof handles === "string" ?
10262                                 handles :
10263                                 "n,e,s,w,se,sw,ne,nw";
10265                 function filteredUi( ui ) {
10266                         return {
10267                                 originalPosition: ui.originalPosition,
10268                                 originalSize: ui.originalSize,
10269                                 position: ui.position,
10270                                 size: ui.size
10271                         };
10272                 }
10274                 this.uiDialog.resizable({
10275                         cancel: ".ui-dialog-content",
10276                         containment: "document",
10277                         alsoResize: this.element,
10278                         maxWidth: options.maxWidth,
10279                         maxHeight: options.maxHeight,
10280                         minWidth: options.minWidth,
10281                         minHeight: this._minHeight(),
10282                         handles: resizeHandles,
10283                         start: function( event, ui ) {
10284                                 $( this ).addClass( "ui-dialog-resizing" );
10285                                 that._blockFrames();
10286                                 that._trigger( "resizeStart", event, filteredUi( ui ) );
10287                         },
10288                         resize: function( event, ui ) {
10289                                 that._trigger( "resize", event, filteredUi( ui ) );
10290                         },
10291                         stop: function( event, ui ) {
10292                                 var offset = that.uiDialog.offset(),
10293                                         left = offset.left - that.document.scrollLeft(),
10294                                         top = offset.top - that.document.scrollTop();
10296                                 options.height = that.uiDialog.height();
10297                                 options.width = that.uiDialog.width();
10298                                 options.position = {
10299                                         my: "left top",
10300                                         at: "left" + (left >= 0 ? "+" : "") + left + " " +
10301                                                 "top" + (top >= 0 ? "+" : "") + top,
10302                                         of: that.window
10303                                 };
10304                                 $( this ).removeClass( "ui-dialog-resizing" );
10305                                 that._unblockFrames();
10306                                 that._trigger( "resizeStop", event, filteredUi( ui ) );
10307                         }
10308                 })
10309                 .css( "position", position );
10310         },
10312         _trackFocus: function() {
10313                 this._on( this.widget(), {
10314                         "focusin": function( event ) {
10315                                 this._untrackInstance();
10316                                 this._trackingInstances().unshift( this );
10317                                 this._focusedElement = $( event.target );
10318                         }
10319                 });
10320         },
10322         _untrackInstance: function() {
10323                 var instances = this._trackingInstances(),
10324                         exists = $.inArray( this, instances );
10325                 if ( exists !== -1 ) {
10326                         instances.splice( exists, 1 );
10327                 }
10328         },
10330         _trackingInstances: function() {
10331                 var instances = this.document.data( "ui-dialog-instances" );
10332                 if ( !instances ) {
10333                         instances = [];
10334                         this.document.data( "ui-dialog-instances", instances );
10335                 }
10336                 return instances;
10337         },
10339         _minHeight: function() {
10340                 var options = this.options;
10342                 return options.height === "auto" ?
10343                         options.minHeight :
10344                         Math.min( options.minHeight, options.height );
10345         },
10347         _position: function() {
10348                 // Need to show the dialog to get the actual offset in the position plugin
10349                 var isVisible = this.uiDialog.is( ":visible" );
10350                 if ( !isVisible ) {
10351                         this.uiDialog.show();
10352                 }
10353                 this.uiDialog.position( this.options.position );
10354                 if ( !isVisible ) {
10355                         this.uiDialog.hide();
10356                 }
10357         },
10359         _setOptions: function( options ) {
10360                 var that = this,
10361                         resize = false,
10362                         resizableOptions = {};
10364                 $.each( options, function( key, value ) {
10365                         that._setOption( key, value );
10367                         if ( key in that.sizeRelatedOptions ) {
10368                                 resize = true;
10369                         }
10370                         if ( key in that.resizableRelatedOptions ) {
10371                                 resizableOptions[ key ] = value;
10372                         }
10373                 });
10375                 if ( resize ) {
10376                         this._size();
10377                         this._position();
10378                 }
10379                 if ( this.uiDialog.is( ":data(ui-resizable)" ) ) {
10380                         this.uiDialog.resizable( "option", resizableOptions );
10381                 }
10382         },
10384         _setOption: function( key, value ) {
10385                 var isDraggable, isResizable,
10386                         uiDialog = this.uiDialog;
10388                 if ( key === "dialogClass" ) {
10389                         uiDialog
10390                                 .removeClass( this.options.dialogClass )
10391                                 .addClass( value );
10392                 }
10394                 if ( key === "disabled" ) {
10395                         return;
10396                 }
10398                 this._super( key, value );
10400                 if ( key === "appendTo" ) {
10401                         this.uiDialog.appendTo( this._appendTo() );
10402                 }
10404                 if ( key === "buttons" ) {
10405                         this._createButtons();
10406                 }
10408                 if ( key === "closeText" ) {
10409                         this.uiDialogTitlebarClose.button({
10410                                 // Ensure that we always pass a string
10411                                 label: "" + value
10412                         });
10413                 }
10415                 if ( key === "draggable" ) {
10416                         isDraggable = uiDialog.is( ":data(ui-draggable)" );
10417                         if ( isDraggable && !value ) {
10418                                 uiDialog.draggable( "destroy" );
10419                         }
10421                         if ( !isDraggable && value ) {
10422                                 this._makeDraggable();
10423                         }
10424                 }
10426                 if ( key === "position" ) {
10427                         this._position();
10428                 }
10430                 if ( key === "resizable" ) {
10431                         // currently resizable, becoming non-resizable
10432                         isResizable = uiDialog.is( ":data(ui-resizable)" );
10433                         if ( isResizable && !value ) {
10434                                 uiDialog.resizable( "destroy" );
10435                         }
10437                         // currently resizable, changing handles
10438                         if ( isResizable && typeof value === "string" ) {
10439                                 uiDialog.resizable( "option", "handles", value );
10440                         }
10442                         // currently non-resizable, becoming resizable
10443                         if ( !isResizable && value !== false ) {
10444                                 this._makeResizable();
10445                         }
10446                 }
10448                 if ( key === "title" ) {
10449                         this._title( this.uiDialogTitlebar.find( ".ui-dialog-title" ) );
10450                 }
10451         },
10453         _size: function() {
10454                 // If the user has resized the dialog, the .ui-dialog and .ui-dialog-content
10455                 // divs will both have width and height set, so we need to reset them
10456                 var nonContentHeight, minContentHeight, maxContentHeight,
10457                         options = this.options;
10459                 // Reset content sizing
10460                 this.element.show().css({
10461                         width: "auto",
10462                         minHeight: 0,
10463                         maxHeight: "none",
10464                         height: 0
10465                 });
10467                 if ( options.minWidth > options.width ) {
10468                         options.width = options.minWidth;
10469                 }
10471                 // reset wrapper sizing
10472                 // determine the height of all the non-content elements
10473                 nonContentHeight = this.uiDialog.css({
10474                                 height: "auto",
10475                                 width: options.width
10476                         })
10477                         .outerHeight();
10478                 minContentHeight = Math.max( 0, options.minHeight - nonContentHeight );
10479                 maxContentHeight = typeof options.maxHeight === "number" ?
10480                         Math.max( 0, options.maxHeight - nonContentHeight ) :
10481                         "none";
10483                 if ( options.height === "auto" ) {
10484                         this.element.css({
10485                                 minHeight: minContentHeight,
10486                                 maxHeight: maxContentHeight,
10487                                 height: "auto"
10488                         });
10489                 } else {
10490                         this.element.height( Math.max( 0, options.height - nonContentHeight ) );
10491                 }
10493                 if ( this.uiDialog.is( ":data(ui-resizable)" ) ) {
10494                         this.uiDialog.resizable( "option", "minHeight", this._minHeight() );
10495                 }
10496         },
10498         _blockFrames: function() {
10499                 this.iframeBlocks = this.document.find( "iframe" ).map(function() {
10500                         var iframe = $( this );
10502                         return $( "<div>" )
10503                                 .css({
10504                                         position: "absolute",
10505                                         width: iframe.outerWidth(),
10506                                         height: iframe.outerHeight()
10507                                 })
10508                                 .appendTo( iframe.parent() )
10509                                 .offset( iframe.offset() )[0];
10510                 });
10511         },
10513         _unblockFrames: function() {
10514                 if ( this.iframeBlocks ) {
10515                         this.iframeBlocks.remove();
10516                         delete this.iframeBlocks;
10517                 }
10518         },
10520         _allowInteraction: function( event ) {
10521                 if ( $( event.target ).closest( ".ui-dialog" ).length ) {
10522                         return true;
10523                 }
10525                 // TODO: Remove hack when datepicker implements
10526                 // the .ui-front logic (#8989)
10527                 return !!$( event.target ).closest( ".ui-datepicker" ).length;
10528         },
10530         _createOverlay: function() {
10531                 if ( !this.options.modal ) {
10532                         return;
10533                 }
10535                 // We use a delay in case the overlay is created from an
10536                 // event that we're going to be cancelling (#2804)
10537                 var isOpening = true;
10538                 this._delay(function() {
10539                         isOpening = false;
10540                 });
10542                 if ( !this.document.data( "ui-dialog-overlays" ) ) {
10544                         // Prevent use of anchors and inputs
10545                         // Using _on() for an event handler shared across many instances is
10546                         // safe because the dialogs stack and must be closed in reverse order
10547                         this._on( this.document, {
10548                                 focusin: function( event ) {
10549                                         if ( isOpening ) {
10550                                                 return;
10551                                         }
10553                                         if ( !this._allowInteraction( event ) ) {
10554                                                 event.preventDefault();
10555                                                 this._trackingInstances()[ 0 ]._focusTabbable();
10556                                         }
10557                                 }
10558                         });
10559                 }
10561                 this.overlay = $( "<div>" )
10562                         .addClass( "ui-widget-overlay ui-front" )
10563                         .appendTo( this._appendTo() );
10564                 this._on( this.overlay, {
10565                         mousedown: "_keepFocus"
10566                 });
10567                 this.document.data( "ui-dialog-overlays",
10568                         (this.document.data( "ui-dialog-overlays" ) || 0) + 1 );
10569         },
10571         _destroyOverlay: function() {
10572                 if ( !this.options.modal ) {
10573                         return;
10574                 }
10576                 if ( this.overlay ) {
10577                         var overlays = this.document.data( "ui-dialog-overlays" ) - 1;
10579                         if ( !overlays ) {
10580                                 this.document
10581                                         .unbind( "focusin" )
10582                                         .removeData( "ui-dialog-overlays" );
10583                         } else {
10584                                 this.document.data( "ui-dialog-overlays", overlays );
10585                         }
10587                         this.overlay.remove();
10588                         this.overlay = null;
10589                 }
10590         }
10595  * jQuery UI Progressbar 1.11.0
10596  * http://jqueryui.com
10598  * Copyright 2014 jQuery Foundation and other contributors
10599  * Released under the MIT license.
10600  * http://jquery.org/license
10602  * http://api.jqueryui.com/progressbar/
10603  */
10606 var progressbar = $.widget( "ui.progressbar", {
10607         version: "1.11.0",
10608         options: {
10609                 max: 100,
10610                 value: 0,
10612                 change: null,
10613                 complete: null
10614         },
10616         min: 0,
10618         _create: function() {
10619                 // Constrain initial value
10620                 this.oldValue = this.options.value = this._constrainedValue();
10622                 this.element
10623                         .addClass( "ui-progressbar ui-widget ui-widget-content ui-corner-all" )
10624                         .attr({
10625                                 // Only set static values, aria-valuenow and aria-valuemax are
10626                                 // set inside _refreshValue()
10627                                 role: "progressbar",
10628                                 "aria-valuemin": this.min
10629                         });
10631                 this.valueDiv = $( "<div class='ui-progressbar-value ui-widget-header ui-corner-left'></div>" )
10632                         .appendTo( this.element );
10634                 this._refreshValue();
10635         },
10637         _destroy: function() {
10638                 this.element
10639                         .removeClass( "ui-progressbar ui-widget ui-widget-content ui-corner-all" )
10640                         .removeAttr( "role" )
10641                         .removeAttr( "aria-valuemin" )
10642                         .removeAttr( "aria-valuemax" )
10643                         .removeAttr( "aria-valuenow" );
10645                 this.valueDiv.remove();
10646         },
10648         value: function( newValue ) {
10649                 if ( newValue === undefined ) {
10650                         return this.options.value;
10651                 }
10653                 this.options.value = this._constrainedValue( newValue );
10654                 this._refreshValue();
10655         },
10657         _constrainedValue: function( newValue ) {
10658                 if ( newValue === undefined ) {
10659                         newValue = this.options.value;
10660                 }
10662                 this.indeterminate = newValue === false;
10664                 // sanitize value
10665                 if ( typeof newValue !== "number" ) {
10666                         newValue = 0;
10667                 }
10669                 return this.indeterminate ? false :
10670                         Math.min( this.options.max, Math.max( this.min, newValue ) );
10671         },
10673         _setOptions: function( options ) {
10674                 // Ensure "value" option is set after other values (like max)
10675                 var value = options.value;
10676                 delete options.value;
10678                 this._super( options );
10680                 this.options.value = this._constrainedValue( value );
10681                 this._refreshValue();
10682         },
10684         _setOption: function( key, value ) {
10685                 if ( key === "max" ) {
10686                         // Don't allow a max less than min
10687                         value = Math.max( this.min, value );
10688                 }
10689                 if ( key === "disabled" ) {
10690                         this.element
10691                                 .toggleClass( "ui-state-disabled", !!value )
10692                                 .attr( "aria-disabled", value );
10693                 }
10694                 this._super( key, value );
10695         },
10697         _percentage: function() {
10698                 return this.indeterminate ? 100 : 100 * ( this.options.value - this.min ) / ( this.options.max - this.min );
10699         },
10701         _refreshValue: function() {
10702                 var value = this.options.value,
10703                         percentage = this._percentage();
10705                 this.valueDiv
10706                         .toggle( this.indeterminate || value > this.min )
10707                         .toggleClass( "ui-corner-right", value === this.options.max )
10708                         .width( percentage.toFixed(0) + "%" );
10710                 this.element.toggleClass( "ui-progressbar-indeterminate", this.indeterminate );
10712                 if ( this.indeterminate ) {
10713                         this.element.removeAttr( "aria-valuenow" );
10714                         if ( !this.overlayDiv ) {
10715                                 this.overlayDiv = $( "<div class='ui-progressbar-overlay'></div>" ).appendTo( this.valueDiv );
10716                         }
10717                 } else {
10718                         this.element.attr({
10719                                 "aria-valuemax": this.options.max,
10720                                 "aria-valuenow": value
10721                         });
10722                         if ( this.overlayDiv ) {
10723                                 this.overlayDiv.remove();
10724                                 this.overlayDiv = null;
10725                         }
10726                 }
10728                 if ( this.oldValue !== value ) {
10729                         this.oldValue = value;
10730                         this._trigger( "change" );
10731                 }
10732                 if ( value === this.options.max ) {
10733                         this._trigger( "complete" );
10734                 }
10735         }
10740  * jQuery UI Selectmenu 1.11.0
10741  * http://jqueryui.com
10743  * Copyright 2014 jQuery Foundation and other contributors
10744  * Released under the MIT license.
10745  * http://jquery.org/license
10747  * http://api.jqueryui.com/selectmenu
10748  */
10751 var selectmenu = $.widget( "ui.selectmenu", {
10752         version: "1.11.0",
10753         defaultElement: "<select>",
10754         options: {
10755                 appendTo: null,
10756                 disabled: null,
10757                 icons: {
10758                         button: "ui-icon-triangle-1-s"
10759                 },
10760                 position: {
10761                         my: "left top",
10762                         at: "left bottom",
10763                         collision: "none"
10764                 },
10765                 width: null,
10767                 // callbacks
10768                 change: null,
10769                 close: null,
10770                 focus: null,
10771                 open: null,
10772                 select: null
10773         },
10775         _create: function() {
10776                 var selectmenuId = this.element.uniqueId().attr( "id" );
10777                 this.ids = {
10778                         element: selectmenuId,
10779                         button: selectmenuId + "-button",
10780                         menu: selectmenuId + "-menu"
10781                 };
10783                 this._drawButton();
10784                 this._drawMenu();
10786                 if ( this.options.disabled ) {
10787                         this.disable();
10788                 }
10789         },
10791         _drawButton: function() {
10792                 var that = this,
10793                         tabindex = this.element.attr( "tabindex" );
10795                 // Associate existing label with the new button
10796                 this.label = $( "label[for='" + this.ids.element + "']" ).attr( "for", this.ids.button );
10797                 this._on( this.label, {
10798                         click: function( event ) {
10799                                 this.button.focus();
10800                                 event.preventDefault();
10801                         }
10802                 });
10804                 // Hide original select element
10805                 this.element.hide();
10807                 // Create button
10808                 this.button = $( "<span>", {
10809                         "class": "ui-selectmenu-button ui-widget ui-state-default ui-corner-all",
10810                         tabindex: tabindex || this.options.disabled ? -1 : 0,
10811                         id: this.ids.button,
10812                         role: "combobox",
10813                         "aria-expanded": "false",
10814                         "aria-autocomplete": "list",
10815                         "aria-owns": this.ids.menu,
10816                         "aria-haspopup": "true"
10817                 })
10818                         .insertAfter( this.element );
10820                 $( "<span>", {
10821                         "class": "ui-icon " + this.options.icons.button
10822                 })
10823                         .prependTo( this.button );
10825                 this.buttonText = $( "<span>", {
10826                         "class": "ui-selectmenu-text"
10827                 })
10828                         .appendTo( this.button );
10830                 this._setText( this.buttonText, this.element.find( "option:selected" ).text() );
10831                 this._setOption( "width", this.options.width );
10833                 this._on( this.button, this._buttonEvents );
10834                 this.button.one( "focusin", function() {
10836                         // Delay rendering the menu items until the button receives focus.
10837                         // The menu may have already been rendered via a programmatic open.
10838                         if ( !that.menuItems ) {
10839                                 that._refreshMenu();
10840                         }
10841                 });
10842                 this._hoverable( this.button );
10843                 this._focusable( this.button );
10844         },
10846         _drawMenu: function() {
10847                 var that = this;
10849                 // Create menu
10850                 this.menu = $( "<ul>", {
10851                         "aria-hidden": "true",
10852                         "aria-labelledby": this.ids.button,
10853                         id: this.ids.menu
10854                 });
10856                 // Wrap menu
10857                 this.menuWrap = $( "<div>", {
10858                         "class": "ui-selectmenu-menu ui-front"
10859                 })
10860                         .append( this.menu )
10861                         .appendTo( this._appendTo() );
10863                 // Initialize menu widget
10864                 this.menuInstance = this.menu
10865                         .menu({
10866                                 role: "listbox",
10867                                 select: function( event, ui ) {
10868                                         event.preventDefault();
10869                                         that._select( ui.item.data( "ui-selectmenu-item" ), event );
10870                                 },
10871                                 focus: function( event, ui ) {
10872                                         var item = ui.item.data( "ui-selectmenu-item" );
10874                                         // Prevent inital focus from firing and check if its a newly focused item
10875                                         if ( that.focusIndex != null && item.index !== that.focusIndex ) {
10876                                                 that._trigger( "focus", event, { item: item } );
10877                                                 if ( !that.isOpen ) {
10878                                                         that._select( item, event );
10879                                                 }
10880                                         }
10881                                         that.focusIndex = item.index;
10883                                         that.button.attr( "aria-activedescendant",
10884                                                 that.menuItems.eq( item.index ).attr( "id" ) );
10885                                 }
10886                         })
10887                         .menu( "instance" );
10889                 // Adjust menu styles to dropdown
10890                 this.menu
10891                         .addClass( "ui-corner-bottom" )
10892                         .removeClass( "ui-corner-all" );
10894                 // Don't close the menu on mouseleave
10895                 this.menuInstance._off( this.menu, "mouseleave" );
10897                 // Cancel the menu's collapseAll on document click
10898                 this.menuInstance._closeOnDocumentClick = function() {
10899                         return false;
10900                 };
10902                 // Selects often contain empty items, but never contain dividers
10903                 this.menuInstance._isDivider = function() {
10904                         return false;
10905                 };
10906         },
10908         refresh: function() {
10909                 this._refreshMenu();
10910                 this._setText( this.buttonText, this._getSelectedItem().text() );
10911                 this._setOption( "width", this.options.width );
10912         },
10914         _refreshMenu: function() {
10915                 this.menu.empty();
10917                 var item,
10918                         options = this.element.find( "option" );
10920                 if ( !options.length ) {
10921                         return;
10922                 }
10924                 this._parseOptions( options );
10925                 this._renderMenu( this.menu, this.items );
10927                 this.menuInstance.refresh();
10928                 this.menuItems = this.menu.find( "li" ).not( ".ui-selectmenu-optgroup" );
10930                 item = this._getSelectedItem();
10932                 // Update the menu to have the correct item focused
10933                 this.menuInstance.focus( null, item );
10934                 this._setAria( item.data( "ui-selectmenu-item" ) );
10936                 // Set disabled state
10937                 this._setOption( "disabled", this.element.prop( "disabled" ) );
10938         },
10940         open: function( event ) {
10941                 if ( this.options.disabled ) {
10942                         return;
10943                 }
10945                 // If this is the first time the menu is being opened, render the items
10946                 if ( !this.menuItems ) {
10947                         this._refreshMenu();
10948                 } else {
10950                         // Menu clears focus on close, reset focus to selected item
10951                         this.menu.find( ".ui-state-focus" ).removeClass( "ui-state-focus" );
10952                         this.menuInstance.focus( null, this._getSelectedItem() );
10953                 }
10955                 this.isOpen = true;
10956                 this._toggleAttr();
10957                 this._resizeMenu();
10958                 this._position();
10960                 this._on( this.document, this._documentClick );
10962                 this._trigger( "open", event );
10963         },
10965         _position: function() {
10966                 this.menuWrap.position( $.extend( { of: this.button }, this.options.position ) );
10967         },
10969         close: function( event ) {
10970                 if ( !this.isOpen ) {
10971                         return;
10972                 }
10974                 this.isOpen = false;
10975                 this._toggleAttr();
10977                 this._off( this.document );
10979                 this._trigger( "close", event );
10980         },
10982         widget: function() {
10983                 return this.button;
10984         },
10986         menuWidget: function() {
10987                 return this.menu;
10988         },
10990         _renderMenu: function( ul, items ) {
10991                 var that = this,
10992                         currentOptgroup = "";
10994                 $.each( items, function( index, item ) {
10995                         if ( item.optgroup !== currentOptgroup ) {
10996                                 $( "<li>", {
10997                                         "class": "ui-selectmenu-optgroup ui-menu-divider" +
10998                                                 ( item.element.parent( "optgroup" ).prop( "disabled" ) ?
10999                                                         " ui-state-disabled" :
11000                                                         "" ),
11001                                         text: item.optgroup
11002                                 })
11003                                         .appendTo( ul );
11005                                 currentOptgroup = item.optgroup;
11006                         }
11008                         that._renderItemData( ul, item );
11009                 });
11010         },
11012         _renderItemData: function( ul, item ) {
11013                 return this._renderItem( ul, item ).data( "ui-selectmenu-item", item );
11014         },
11016         _renderItem: function( ul, item ) {
11017                 var li = $( "<li>" );
11019                 if ( item.disabled ) {
11020                         li.addClass( "ui-state-disabled" );
11021                 }
11022                 this._setText( li, item.label );
11024                 return li.appendTo( ul );
11025         },
11027         _setText: function( element, value ) {
11028                 if ( value ) {
11029                         element.text( value );
11030                 } else {
11031                         element.html( "&#160;" );
11032                 }
11033         },
11035         _move: function( direction, event ) {
11036                 var item, next,
11037                         filter = ".ui-menu-item";
11039                 if ( this.isOpen ) {
11040                         item = this.menuItems.eq( this.focusIndex );
11041                 } else {
11042                         item = this.menuItems.eq( this.element[ 0 ].selectedIndex );
11043                         filter += ":not(.ui-state-disabled)";
11044                 }
11046                 if ( direction === "first" || direction === "last" ) {
11047                         next = item[ direction === "first" ? "prevAll" : "nextAll" ]( filter ).eq( -1 );
11048                 } else {
11049                         next = item[ direction + "All" ]( filter ).eq( 0 );
11050                 }
11052                 if ( next.length ) {
11053                         this.menuInstance.focus( event, next );
11054                 }
11055         },
11057         _getSelectedItem: function() {
11058                 return this.menuItems.eq( this.element[ 0 ].selectedIndex );
11059         },
11061         _toggle: function( event ) {
11062                 this[ this.isOpen ? "close" : "open" ]( event );
11063         },
11065         _documentClick: {
11066                 mousedown: function( event ) {
11067                         if ( !this.isOpen ) {
11068                                 return;
11069                         }
11071                         if ( !$( event.target ).closest( ".ui-selectmenu-menu, #" + this.ids.button ).length ) {
11072                                 this.close( event );
11073                         }
11074                 }
11075         },
11077         _buttonEvents: {
11078                 click: "_toggle",
11079                 keydown: function( event ) {
11080                         var preventDefault = true;
11081                         switch ( event.keyCode ) {
11082                                 case $.ui.keyCode.TAB:
11083                                 case $.ui.keyCode.ESCAPE:
11084                                         this.close( event );
11085                                         preventDefault = false;
11086                                         break;
11087                                 case $.ui.keyCode.ENTER:
11088                                         if ( this.isOpen ) {
11089                                                 this._selectFocusedItem( event );
11090                                         }
11091                                         break;
11092                                 case $.ui.keyCode.UP:
11093                                         if ( event.altKey ) {
11094                                                 this._toggle( event );
11095                                         } else {
11096                                                 this._move( "prev", event );
11097                                         }
11098                                         break;
11099                                 case $.ui.keyCode.DOWN:
11100                                         if ( event.altKey ) {
11101                                                 this._toggle( event );
11102                                         } else {
11103                                                 this._move( "next", event );
11104                                         }
11105                                         break;
11106                                 case $.ui.keyCode.SPACE:
11107                                         if ( this.isOpen ) {
11108                                                 this._selectFocusedItem( event );
11109                                         } else {
11110                                                 this._toggle( event );
11111                                         }
11112                                         break;
11113                                 case $.ui.keyCode.LEFT:
11114                                         this._move( "prev", event );
11115                                         break;
11116                                 case $.ui.keyCode.RIGHT:
11117                                         this._move( "next", event );
11118                                         break;
11119                                 case $.ui.keyCode.HOME:
11120                                 case $.ui.keyCode.PAGE_UP:
11121                                         this._move( "first", event );
11122                                         break;
11123                                 case $.ui.keyCode.END:
11124                                 case $.ui.keyCode.PAGE_DOWN:
11125                                         this._move( "last", event );
11126                                         break;
11127                                 default:
11128                                         this.menu.trigger( event );
11129                                         preventDefault = false;
11130                         }
11132                         if ( preventDefault ) {
11133                                 event.preventDefault();
11134                         }
11135                 }
11136         },
11138         _selectFocusedItem: function( event ) {
11139                 var item = this.menuItems.eq( this.focusIndex );
11140                 if ( !item.hasClass( "ui-state-disabled" ) ) {
11141                         this._select( item.data( "ui-selectmenu-item" ), event );
11142                 }
11143         },
11145         _select: function( item, event ) {
11146                 var oldIndex = this.element[ 0 ].selectedIndex;
11148                 // Change native select element
11149                 this.element[ 0 ].selectedIndex = item.index;
11150                 this._setText( this.buttonText, item.label );
11151                 this._setAria( item );
11152                 this._trigger( "select", event, { item: item } );
11154                 if ( item.index !== oldIndex ) {
11155                         this._trigger( "change", event, { item: item } );
11156                 }
11158                 this.close( event );
11159         },
11161         _setAria: function( item ) {
11162                 var id = this.menuItems.eq( item.index ).attr( "id" );
11164                 this.button.attr({
11165                         "aria-labelledby": id,
11166                         "aria-activedescendant": id
11167                 });
11168                 this.menu.attr( "aria-activedescendant", id );
11169         },
11171         _setOption: function( key, value ) {
11172                 if ( key === "icons" ) {
11173                         this.button.find( "span.ui-icon" )
11174                                 .removeClass( this.options.icons.button )
11175                                 .addClass( value.button );
11176                 }
11178                 this._super( key, value );
11180                 if ( key === "appendTo" ) {
11181                         this.menuWrap.appendTo( this._appendTo() );
11182                 }
11184                 if ( key === "disabled" ) {
11185                         this.menuInstance.option( "disabled", value );
11186                         this.button
11187                                 .toggleClass( "ui-state-disabled", value )
11188                                 .attr( "aria-disabled", value );
11190                         this.element.prop( "disabled", value );
11191                         if ( value ) {
11192                                 this.button.attr( "tabindex", -1 );
11193                                 this.close();
11194                         } else {
11195                                 this.button.attr( "tabindex", 0 );
11196                         }
11197                 }
11199                 if ( key === "width" ) {
11200                         if ( !value ) {
11201                                 value = this.element.outerWidth();
11202                         }
11203                         this.button.outerWidth( value );
11204                 }
11205         },
11207         _appendTo: function() {
11208                 var element = this.options.appendTo;
11210                 if ( element ) {
11211                         element = element.jquery || element.nodeType ?
11212                                 $( element ) :
11213                                 this.document.find( element ).eq( 0 );
11214                 }
11216                 if ( !element || !element[ 0 ] ) {
11217                         element = this.element.closest( ".ui-front" );
11218                 }
11220                 if ( !element.length ) {
11221                         element = this.document[ 0 ].body;
11222                 }
11224                 return element;
11225         },
11227         _toggleAttr: function() {
11228                 this.button
11229                         .toggleClass( "ui-corner-top", this.isOpen )
11230                         .toggleClass( "ui-corner-all", !this.isOpen )
11231                         .attr( "aria-expanded", this.isOpen );
11232                 this.menuWrap.toggleClass( "ui-selectmenu-open", this.isOpen );
11233                 this.menu.attr( "aria-hidden", !this.isOpen );
11234         },
11236         _resizeMenu: function() {
11237                 this.menu.outerWidth( Math.max(
11238                         this.button.outerWidth(),
11240                         // support: IE10
11241                         // IE10 wraps long text (possibly a rounding bug)
11242                         // so we add 1px to avoid the wrapping
11243                         this.menu.width( "" ).outerWidth() + 1
11244                 ) );
11245         },
11247         _getCreateOptions: function() {
11248                 return { disabled: this.element.prop( "disabled" ) };
11249         },
11251         _parseOptions: function( options ) {
11252                 var data = [];
11253                 options.each(function( index, item ) {
11254                         var option = $( item ),
11255                                 optgroup = option.parent( "optgroup" );
11256                         data.push({
11257                                 element: option,
11258                                 index: index,
11259                                 value: option.attr( "value" ),
11260                                 label: option.text(),
11261                                 optgroup: optgroup.attr( "label" ) || "",
11262                                 disabled: optgroup.prop( "disabled" ) || option.prop( "disabled" )
11263                         });
11264                 });
11265                 this.items = data;
11266         },
11268         _destroy: function() {
11269                 this.menuWrap.remove();
11270                 this.button.remove();
11271                 this.element.show();
11272                 this.element.removeUniqueId();
11273                 this.label.attr( "for", this.ids.element );
11274         }
11279  * jQuery UI Slider 1.11.0
11280  * http://jqueryui.com
11282  * Copyright 2014 jQuery Foundation and other contributors
11283  * Released under the MIT license.
11284  * http://jquery.org/license
11286  * http://api.jqueryui.com/slider/
11287  */
11290 var slider = $.widget( "ui.slider", $.ui.mouse, {
11291         version: "1.11.0",
11292         widgetEventPrefix: "slide",
11294         options: {
11295                 animate: false,
11296                 distance: 0,
11297                 max: 100,
11298                 min: 0,
11299                 orientation: "horizontal",
11300                 range: false,
11301                 step: 1,
11302                 value: 0,
11303                 values: null,
11305                 // callbacks
11306                 change: null,
11307                 slide: null,
11308                 start: null,
11309                 stop: null
11310         },
11312         // number of pages in a slider
11313         // (how many times can you page up/down to go through the whole range)
11314         numPages: 5,
11316         _create: function() {
11317                 this._keySliding = false;
11318                 this._mouseSliding = false;
11319                 this._animateOff = true;
11320                 this._handleIndex = null;
11321                 this._detectOrientation();
11322                 this._mouseInit();
11324                 this.element
11325                         .addClass( "ui-slider" +
11326                                 " ui-slider-" + this.orientation +
11327                                 " ui-widget" +
11328                                 " ui-widget-content" +
11329                                 " ui-corner-all");
11331                 this._refresh();
11332                 this._setOption( "disabled", this.options.disabled );
11334                 this._animateOff = false;
11335         },
11337         _refresh: function() {
11338                 this._createRange();
11339                 this._createHandles();
11340                 this._setupEvents();
11341                 this._refreshValue();
11342         },
11344         _createHandles: function() {
11345                 var i, handleCount,
11346                         options = this.options,
11347                         existingHandles = this.element.find( ".ui-slider-handle" ).addClass( "ui-state-default ui-corner-all" ),
11348                         handle = "<span class='ui-slider-handle ui-state-default ui-corner-all' tabindex='0'></span>",
11349                         handles = [];
11351                 handleCount = ( options.values && options.values.length ) || 1;
11353                 if ( existingHandles.length > handleCount ) {
11354                         existingHandles.slice( handleCount ).remove();
11355                         existingHandles = existingHandles.slice( 0, handleCount );
11356                 }
11358                 for ( i = existingHandles.length; i < handleCount; i++ ) {
11359                         handles.push( handle );
11360                 }
11362                 this.handles = existingHandles.add( $( handles.join( "" ) ).appendTo( this.element ) );
11364                 this.handle = this.handles.eq( 0 );
11366                 this.handles.each(function( i ) {
11367                         $( this ).data( "ui-slider-handle-index", i );
11368                 });
11369         },
11371         _createRange: function() {
11372                 var options = this.options,
11373                         classes = "";
11375                 if ( options.range ) {
11376                         if ( options.range === true ) {
11377                                 if ( !options.values ) {
11378                                         options.values = [ this._valueMin(), this._valueMin() ];
11379                                 } else if ( options.values.length && options.values.length !== 2 ) {
11380                                         options.values = [ options.values[0], options.values[0] ];
11381                                 } else if ( $.isArray( options.values ) ) {
11382                                         options.values = options.values.slice(0);
11383                                 }
11384                         }
11386                         if ( !this.range || !this.range.length ) {
11387                                 this.range = $( "<div></div>" )
11388                                         .appendTo( this.element );
11390                                 classes = "ui-slider-range" +
11391                                 // note: this isn't the most fittingly semantic framework class for this element,
11392                                 // but worked best visually with a variety of themes
11393                                 " ui-widget-header ui-corner-all";
11394                         } else {
11395                                 this.range.removeClass( "ui-slider-range-min ui-slider-range-max" )
11396                                         // Handle range switching from true to min/max
11397                                         .css({
11398                                                 "left": "",
11399                                                 "bottom": ""
11400                                         });
11401                         }
11403                         this.range.addClass( classes +
11404                                 ( ( options.range === "min" || options.range === "max" ) ? " ui-slider-range-" + options.range : "" ) );
11405                 } else {
11406                         if ( this.range ) {
11407                                 this.range.remove();
11408                         }
11409                         this.range = null;
11410                 }
11411         },
11413         _setupEvents: function() {
11414                 this._off( this.handles );
11415                 this._on( this.handles, this._handleEvents );
11416                 this._hoverable( this.handles );
11417                 this._focusable( this.handles );
11418         },
11420         _destroy: function() {
11421                 this.handles.remove();
11422                 if ( this.range ) {
11423                         this.range.remove();
11424                 }
11426                 this.element
11427                         .removeClass( "ui-slider" +
11428                                 " ui-slider-horizontal" +
11429                                 " ui-slider-vertical" +
11430                                 " ui-widget" +
11431                                 " ui-widget-content" +
11432                                 " ui-corner-all" );
11434                 this._mouseDestroy();
11435         },
11437         _mouseCapture: function( event ) {
11438                 var position, normValue, distance, closestHandle, index, allowed, offset, mouseOverHandle,
11439                         that = this,
11440                         o = this.options;
11442                 if ( o.disabled ) {
11443                         return false;
11444                 }
11446                 this.elementSize = {
11447                         width: this.element.outerWidth(),
11448                         height: this.element.outerHeight()
11449                 };
11450                 this.elementOffset = this.element.offset();
11452                 position = { x: event.pageX, y: event.pageY };
11453                 normValue = this._normValueFromMouse( position );
11454                 distance = this._valueMax() - this._valueMin() + 1;
11455                 this.handles.each(function( i ) {
11456                         var thisDistance = Math.abs( normValue - that.values(i) );
11457                         if (( distance > thisDistance ) ||
11458                                 ( distance === thisDistance &&
11459                                         (i === that._lastChangedValue || that.values(i) === o.min ))) {
11460                                 distance = thisDistance;
11461                                 closestHandle = $( this );
11462                                 index = i;
11463                         }
11464                 });
11466                 allowed = this._start( event, index );
11467                 if ( allowed === false ) {
11468                         return false;
11469                 }
11470                 this._mouseSliding = true;
11472                 this._handleIndex = index;
11474                 closestHandle
11475                         .addClass( "ui-state-active" )
11476                         .focus();
11478                 offset = closestHandle.offset();
11479                 mouseOverHandle = !$( event.target ).parents().addBack().is( ".ui-slider-handle" );
11480                 this._clickOffset = mouseOverHandle ? { left: 0, top: 0 } : {
11481                         left: event.pageX - offset.left - ( closestHandle.width() / 2 ),
11482                         top: event.pageY - offset.top -
11483                                 ( closestHandle.height() / 2 ) -
11484                                 ( parseInt( closestHandle.css("borderTopWidth"), 10 ) || 0 ) -
11485                                 ( parseInt( closestHandle.css("borderBottomWidth"), 10 ) || 0) +
11486                                 ( parseInt( closestHandle.css("marginTop"), 10 ) || 0)
11487                 };
11489                 if ( !this.handles.hasClass( "ui-state-hover" ) ) {
11490                         this._slide( event, index, normValue );
11491                 }
11492                 this._animateOff = true;
11493                 return true;
11494         },
11496         _mouseStart: function() {
11497                 return true;
11498         },
11500         _mouseDrag: function( event ) {
11501                 var position = { x: event.pageX, y: event.pageY },
11502                         normValue = this._normValueFromMouse( position );
11504                 this._slide( event, this._handleIndex, normValue );
11506                 return false;
11507         },
11509         _mouseStop: function( event ) {
11510                 this.handles.removeClass( "ui-state-active" );
11511                 this._mouseSliding = false;
11513                 this._stop( event, this._handleIndex );
11514                 this._change( event, this._handleIndex );
11516                 this._handleIndex = null;
11517                 this._clickOffset = null;
11518                 this._animateOff = false;
11520                 return false;
11521         },
11523         _detectOrientation: function() {
11524                 this.orientation = ( this.options.orientation === "vertical" ) ? "vertical" : "horizontal";
11525         },
11527         _normValueFromMouse: function( position ) {
11528                 var pixelTotal,
11529                         pixelMouse,
11530                         percentMouse,
11531                         valueTotal,
11532                         valueMouse;
11534                 if ( this.orientation === "horizontal" ) {
11535                         pixelTotal = this.elementSize.width;
11536                         pixelMouse = position.x - this.elementOffset.left - ( this._clickOffset ? this._clickOffset.left : 0 );
11537                 } else {
11538                         pixelTotal = this.elementSize.height;
11539                         pixelMouse = position.y - this.elementOffset.top - ( this._clickOffset ? this._clickOffset.top : 0 );
11540                 }
11542                 percentMouse = ( pixelMouse / pixelTotal );
11543                 if ( percentMouse > 1 ) {
11544                         percentMouse = 1;
11545                 }
11546                 if ( percentMouse < 0 ) {
11547                         percentMouse = 0;
11548                 }
11549                 if ( this.orientation === "vertical" ) {
11550                         percentMouse = 1 - percentMouse;
11551                 }
11553                 valueTotal = this._valueMax() - this._valueMin();
11554                 valueMouse = this._valueMin() + percentMouse * valueTotal;
11556                 return this._trimAlignValue( valueMouse );
11557         },
11559         _start: function( event, index ) {
11560                 var uiHash = {
11561                         handle: this.handles[ index ],
11562                         value: this.value()
11563                 };
11564                 if ( this.options.values && this.options.values.length ) {
11565                         uiHash.value = this.values( index );
11566                         uiHash.values = this.values();
11567                 }
11568                 return this._trigger( "start", event, uiHash );
11569         },
11571         _slide: function( event, index, newVal ) {
11572                 var otherVal,
11573                         newValues,
11574                         allowed;
11576                 if ( this.options.values && this.options.values.length ) {
11577                         otherVal = this.values( index ? 0 : 1 );
11579                         if ( ( this.options.values.length === 2 && this.options.range === true ) &&
11580                                         ( ( index === 0 && newVal > otherVal) || ( index === 1 && newVal < otherVal ) )
11581                                 ) {
11582                                 newVal = otherVal;
11583                         }
11585                         if ( newVal !== this.values( index ) ) {
11586                                 newValues = this.values();
11587                                 newValues[ index ] = newVal;
11588                                 // A slide can be canceled by returning false from the slide callback
11589                                 allowed = this._trigger( "slide", event, {
11590                                         handle: this.handles[ index ],
11591                                         value: newVal,
11592                                         values: newValues
11593                                 } );
11594                                 otherVal = this.values( index ? 0 : 1 );
11595                                 if ( allowed !== false ) {
11596                                         this.values( index, newVal );
11597                                 }
11598                         }
11599                 } else {
11600                         if ( newVal !== this.value() ) {
11601                                 // A slide can be canceled by returning false from the slide callback
11602                                 allowed = this._trigger( "slide", event, {
11603                                         handle: this.handles[ index ],
11604                                         value: newVal
11605                                 } );
11606                                 if ( allowed !== false ) {
11607                                         this.value( newVal );
11608                                 }
11609                         }
11610                 }
11611         },
11613         _stop: function( event, index ) {
11614                 var uiHash = {
11615                         handle: this.handles[ index ],
11616                         value: this.value()
11617                 };
11618                 if ( this.options.values && this.options.values.length ) {
11619                         uiHash.value = this.values( index );
11620                         uiHash.values = this.values();
11621                 }
11623                 this._trigger( "stop", event, uiHash );
11624         },
11626         _change: function( event, index ) {
11627                 if ( !this._keySliding && !this._mouseSliding ) {
11628                         var uiHash = {
11629                                 handle: this.handles[ index ],
11630                                 value: this.value()
11631                         };
11632                         if ( this.options.values && this.options.values.length ) {
11633                                 uiHash.value = this.values( index );
11634                                 uiHash.values = this.values();
11635                         }
11637                         //store the last changed value index for reference when handles overlap
11638                         this._lastChangedValue = index;
11640                         this._trigger( "change", event, uiHash );
11641                 }
11642         },
11644         value: function( newValue ) {
11645                 if ( arguments.length ) {
11646                         this.options.value = this._trimAlignValue( newValue );
11647                         this._refreshValue();
11648                         this._change( null, 0 );
11649                         return;
11650                 }
11652                 return this._value();
11653         },
11655         values: function( index, newValue ) {
11656                 var vals,
11657                         newValues,
11658                         i;
11660                 if ( arguments.length > 1 ) {
11661                         this.options.values[ index ] = this._trimAlignValue( newValue );
11662                         this._refreshValue();
11663                         this._change( null, index );
11664                         return;
11665                 }
11667                 if ( arguments.length ) {
11668                         if ( $.isArray( arguments[ 0 ] ) ) {
11669                                 vals = this.options.values;
11670                                 newValues = arguments[ 0 ];
11671                                 for ( i = 0; i < vals.length; i += 1 ) {
11672                                         vals[ i ] = this._trimAlignValue( newValues[ i ] );
11673                                         this._change( null, i );
11674                                 }
11675                                 this._refreshValue();
11676                         } else {
11677                                 if ( this.options.values && this.options.values.length ) {
11678                                         return this._values( index );
11679                                 } else {
11680                                         return this.value();
11681                                 }
11682                         }
11683                 } else {
11684                         return this._values();
11685                 }
11686         },
11688         _setOption: function( key, value ) {
11689                 var i,
11690                         valsLength = 0;
11692                 if ( key === "range" && this.options.range === true ) {
11693                         if ( value === "min" ) {
11694                                 this.options.value = this._values( 0 );
11695                                 this.options.values = null;
11696                         } else if ( value === "max" ) {
11697                                 this.options.value = this._values( this.options.values.length - 1 );
11698                                 this.options.values = null;
11699                         }
11700                 }
11702                 if ( $.isArray( this.options.values ) ) {
11703                         valsLength = this.options.values.length;
11704                 }
11706                 if ( key === "disabled" ) {
11707                         this.element.toggleClass( "ui-state-disabled", !!value );
11708                 }
11710                 this._super( key, value );
11712                 switch ( key ) {
11713                         case "orientation":
11714                                 this._detectOrientation();
11715                                 this.element
11716                                         .removeClass( "ui-slider-horizontal ui-slider-vertical" )
11717                                         .addClass( "ui-slider-" + this.orientation );
11718                                 this._refreshValue();
11719                                 break;
11720                         case "value":
11721                                 this._animateOff = true;
11722                                 this._refreshValue();
11723                                 this._change( null, 0 );
11724                                 this._animateOff = false;
11725                                 break;
11726                         case "values":
11727                                 this._animateOff = true;
11728                                 this._refreshValue();
11729                                 for ( i = 0; i < valsLength; i += 1 ) {
11730                                         this._change( null, i );
11731                                 }
11732                                 this._animateOff = false;
11733                                 break;
11734                         case "min":
11735                         case "max":
11736                                 this._animateOff = true;
11737                                 this._refreshValue();
11738                                 this._animateOff = false;
11739                                 break;
11740                         case "range":
11741                                 this._animateOff = true;
11742                                 this._refresh();
11743                                 this._animateOff = false;
11744                                 break;
11745                 }
11746         },
11748         //internal value getter
11749         // _value() returns value trimmed by min and max, aligned by step
11750         _value: function() {
11751                 var val = this.options.value;
11752                 val = this._trimAlignValue( val );
11754                 return val;
11755         },
11757         //internal values getter
11758         // _values() returns array of values trimmed by min and max, aligned by step
11759         // _values( index ) returns single value trimmed by min and max, aligned by step
11760         _values: function( index ) {
11761                 var val,
11762                         vals,
11763                         i;
11765                 if ( arguments.length ) {
11766                         val = this.options.values[ index ];
11767                         val = this._trimAlignValue( val );
11769                         return val;
11770                 } else if ( this.options.values && this.options.values.length ) {
11771                         // .slice() creates a copy of the array
11772                         // this copy gets trimmed by min and max and then returned
11773                         vals = this.options.values.slice();
11774                         for ( i = 0; i < vals.length; i+= 1) {
11775                                 vals[ i ] = this._trimAlignValue( vals[ i ] );
11776                         }
11778                         return vals;
11779                 } else {
11780                         return [];
11781                 }
11782         },
11784         // returns the step-aligned value that val is closest to, between (inclusive) min and max
11785         _trimAlignValue: function( val ) {
11786                 if ( val <= this._valueMin() ) {
11787                         return this._valueMin();
11788                 }
11789                 if ( val >= this._valueMax() ) {
11790                         return this._valueMax();
11791                 }
11792                 var step = ( this.options.step > 0 ) ? this.options.step : 1,
11793                         valModStep = (val - this._valueMin()) % step,
11794                         alignValue = val - valModStep;
11796                 if ( Math.abs(valModStep) * 2 >= step ) {
11797                         alignValue += ( valModStep > 0 ) ? step : ( -step );
11798                 }
11800                 // Since JavaScript has problems with large floats, round
11801                 // the final value to 5 digits after the decimal point (see #4124)
11802                 return parseFloat( alignValue.toFixed(5) );
11803         },
11805         _valueMin: function() {
11806                 return this.options.min;
11807         },
11809         _valueMax: function() {
11810                 return this.options.max;
11811         },
11813         _refreshValue: function() {
11814                 var lastValPercent, valPercent, value, valueMin, valueMax,
11815                         oRange = this.options.range,
11816                         o = this.options,
11817                         that = this,
11818                         animate = ( !this._animateOff ) ? o.animate : false,
11819                         _set = {};
11821                 if ( this.options.values && this.options.values.length ) {
11822                         this.handles.each(function( i ) {
11823                                 valPercent = ( that.values(i) - that._valueMin() ) / ( that._valueMax() - that._valueMin() ) * 100;
11824                                 _set[ that.orientation === "horizontal" ? "left" : "bottom" ] = valPercent + "%";
11825                                 $( this ).stop( 1, 1 )[ animate ? "animate" : "css" ]( _set, o.animate );
11826                                 if ( that.options.range === true ) {
11827                                         if ( that.orientation === "horizontal" ) {
11828                                                 if ( i === 0 ) {
11829                                                         that.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { left: valPercent + "%" }, o.animate );
11830                                                 }
11831                                                 if ( i === 1 ) {
11832                                                         that.range[ animate ? "animate" : "css" ]( { width: ( valPercent - lastValPercent ) + "%" }, { queue: false, duration: o.animate } );
11833                                                 }
11834                                         } else {
11835                                                 if ( i === 0 ) {
11836                                                         that.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { bottom: ( valPercent ) + "%" }, o.animate );
11837                                                 }
11838                                                 if ( i === 1 ) {
11839                                                         that.range[ animate ? "animate" : "css" ]( { height: ( valPercent - lastValPercent ) + "%" }, { queue: false, duration: o.animate } );
11840                                                 }
11841                                         }
11842                                 }
11843                                 lastValPercent = valPercent;
11844                         });
11845                 } else {
11846                         value = this.value();
11847                         valueMin = this._valueMin();
11848                         valueMax = this._valueMax();
11849                         valPercent = ( valueMax !== valueMin ) ?
11850                                         ( value - valueMin ) / ( valueMax - valueMin ) * 100 :
11851                                         0;
11852                         _set[ this.orientation === "horizontal" ? "left" : "bottom" ] = valPercent + "%";
11853                         this.handle.stop( 1, 1 )[ animate ? "animate" : "css" ]( _set, o.animate );
11855                         if ( oRange === "min" && this.orientation === "horizontal" ) {
11856                                 this.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { width: valPercent + "%" }, o.animate );
11857                         }
11858                         if ( oRange === "max" && this.orientation === "horizontal" ) {
11859                                 this.range[ animate ? "animate" : "css" ]( { width: ( 100 - valPercent ) + "%" }, { queue: false, duration: o.animate } );
11860                         }
11861                         if ( oRange === "min" && this.orientation === "vertical" ) {
11862                                 this.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { height: valPercent + "%" }, o.animate );
11863                         }
11864                         if ( oRange === "max" && this.orientation === "vertical" ) {
11865                                 this.range[ animate ? "animate" : "css" ]( { height: ( 100 - valPercent ) + "%" }, { queue: false, duration: o.animate } );
11866                         }
11867                 }
11868         },
11870         _handleEvents: {
11871                 keydown: function( event ) {
11872                         var allowed, curVal, newVal, step,
11873                                 index = $( event.target ).data( "ui-slider-handle-index" );
11875                         switch ( event.keyCode ) {
11876                                 case $.ui.keyCode.HOME:
11877                                 case $.ui.keyCode.END:
11878                                 case $.ui.keyCode.PAGE_UP:
11879                                 case $.ui.keyCode.PAGE_DOWN:
11880                                 case $.ui.keyCode.UP:
11881                                 case $.ui.keyCode.RIGHT:
11882                                 case $.ui.keyCode.DOWN:
11883                                 case $.ui.keyCode.LEFT:
11884                                         event.preventDefault();
11885                                         if ( !this._keySliding ) {
11886                                                 this._keySliding = true;
11887                                                 $( event.target ).addClass( "ui-state-active" );
11888                                                 allowed = this._start( event, index );
11889                                                 if ( allowed === false ) {
11890                                                         return;
11891                                                 }
11892                                         }
11893                                         break;
11894                         }
11896                         step = this.options.step;
11897                         if ( this.options.values && this.options.values.length ) {
11898                                 curVal = newVal = this.values( index );
11899                         } else {
11900                                 curVal = newVal = this.value();
11901                         }
11903                         switch ( event.keyCode ) {
11904                                 case $.ui.keyCode.HOME:
11905                                         newVal = this._valueMin();
11906                                         break;
11907                                 case $.ui.keyCode.END:
11908                                         newVal = this._valueMax();
11909                                         break;
11910                                 case $.ui.keyCode.PAGE_UP:
11911                                         newVal = this._trimAlignValue(
11912                                                 curVal + ( ( this._valueMax() - this._valueMin() ) / this.numPages )
11913                                         );
11914                                         break;
11915                                 case $.ui.keyCode.PAGE_DOWN:
11916                                         newVal = this._trimAlignValue(
11917                                                 curVal - ( (this._valueMax() - this._valueMin()) / this.numPages ) );
11918                                         break;
11919                                 case $.ui.keyCode.UP:
11920                                 case $.ui.keyCode.RIGHT:
11921                                         if ( curVal === this._valueMax() ) {
11922                                                 return;
11923                                         }
11924                                         newVal = this._trimAlignValue( curVal + step );
11925                                         break;
11926                                 case $.ui.keyCode.DOWN:
11927                                 case $.ui.keyCode.LEFT:
11928                                         if ( curVal === this._valueMin() ) {
11929                                                 return;
11930                                         }
11931                                         newVal = this._trimAlignValue( curVal - step );
11932                                         break;
11933                         }
11935                         this._slide( event, index, newVal );
11936                 },
11937                 keyup: function( event ) {
11938                         var index = $( event.target ).data( "ui-slider-handle-index" );
11940                         if ( this._keySliding ) {
11941                                 this._keySliding = false;
11942                                 this._stop( event, index );
11943                                 this._change( event, index );
11944                                 $( event.target ).removeClass( "ui-state-active" );
11945                         }
11946                 }
11947         }
11952  * jQuery UI Spinner 1.11.0
11953  * http://jqueryui.com
11955  * Copyright 2014 jQuery Foundation and other contributors
11956  * Released under the MIT license.
11957  * http://jquery.org/license
11959  * http://api.jqueryui.com/spinner/
11960  */
11963 function spinner_modifier( fn ) {
11964         return function() {
11965                 var previous = this.element.val();
11966                 fn.apply( this, arguments );
11967                 this._refresh();
11968                 if ( previous !== this.element.val() ) {
11969                         this._trigger( "change" );
11970                 }
11971         };
11974 var spinner = $.widget( "ui.spinner", {
11975         version: "1.11.0",
11976         defaultElement: "<input>",
11977         widgetEventPrefix: "spin",
11978         options: {
11979                 culture: null,
11980                 icons: {
11981                         down: "ui-icon-triangle-1-s",
11982                         up: "ui-icon-triangle-1-n"
11983                 },
11984                 incremental: true,
11985                 max: null,
11986                 min: null,
11987                 numberFormat: null,
11988                 page: 10,
11989                 step: 1,
11991                 change: null,
11992                 spin: null,
11993                 start: null,
11994                 stop: null
11995         },
11997         _create: function() {
11998                 // handle string values that need to be parsed
11999                 this._setOption( "max", this.options.max );
12000                 this._setOption( "min", this.options.min );
12001                 this._setOption( "step", this.options.step );
12003                 // Only format if there is a value, prevents the field from being marked
12004                 // as invalid in Firefox, see #9573.
12005                 if ( this.value() !== "" ) {
12006                         // Format the value, but don't constrain.
12007                         this._value( this.element.val(), true );
12008                 }
12010                 this._draw();
12011                 this._on( this._events );
12012                 this._refresh();
12014                 // turning off autocomplete prevents the browser from remembering the
12015                 // value when navigating through history, so we re-enable autocomplete
12016                 // if the page is unloaded before the widget is destroyed. #7790
12017                 this._on( this.window, {
12018                         beforeunload: function() {
12019                                 this.element.removeAttr( "autocomplete" );
12020                         }
12021                 });
12022         },
12024         _getCreateOptions: function() {
12025                 var options = {},
12026                         element = this.element;
12028                 $.each( [ "min", "max", "step" ], function( i, option ) {
12029                         var value = element.attr( option );
12030                         if ( value !== undefined && value.length ) {
12031                                 options[ option ] = value;
12032                         }
12033                 });
12035                 return options;
12036         },
12038         _events: {
12039                 keydown: function( event ) {
12040                         if ( this._start( event ) && this._keydown( event ) ) {
12041                                 event.preventDefault();
12042                         }
12043                 },
12044                 keyup: "_stop",
12045                 focus: function() {
12046                         this.previous = this.element.val();
12047                 },
12048                 blur: function( event ) {
12049                         if ( this.cancelBlur ) {
12050                                 delete this.cancelBlur;
12051                                 return;
12052                         }
12054                         this._stop();
12055                         this._refresh();
12056                         if ( this.previous !== this.element.val() ) {
12057                                 this._trigger( "change", event );
12058                         }
12059                 },
12060                 mousewheel: function( event, delta ) {
12061                         if ( !delta ) {
12062                                 return;
12063                         }
12064                         if ( !this.spinning && !this._start( event ) ) {
12065                                 return false;
12066                         }
12068                         this._spin( (delta > 0 ? 1 : -1) * this.options.step, event );
12069                         clearTimeout( this.mousewheelTimer );
12070                         this.mousewheelTimer = this._delay(function() {
12071                                 if ( this.spinning ) {
12072                                         this._stop( event );
12073                                 }
12074                         }, 100 );
12075                         event.preventDefault();
12076                 },
12077                 "mousedown .ui-spinner-button": function( event ) {
12078                         var previous;
12080                         // We never want the buttons to have focus; whenever the user is
12081                         // interacting with the spinner, the focus should be on the input.
12082                         // If the input is focused then this.previous is properly set from
12083                         // when the input first received focus. If the input is not focused
12084                         // then we need to set this.previous based on the value before spinning.
12085                         previous = this.element[0] === this.document[0].activeElement ?
12086                                 this.previous : this.element.val();
12087                         function checkFocus() {
12088                                 var isActive = this.element[0] === this.document[0].activeElement;
12089                                 if ( !isActive ) {
12090                                         this.element.focus();
12091                                         this.previous = previous;
12092                                         // support: IE
12093                                         // IE sets focus asynchronously, so we need to check if focus
12094                                         // moved off of the input because the user clicked on the button.
12095                                         this._delay(function() {
12096                                                 this.previous = previous;
12097                                         });
12098                                 }
12099                         }
12101                         // ensure focus is on (or stays on) the text field
12102                         event.preventDefault();
12103                         checkFocus.call( this );
12105                         // support: IE
12106                         // IE doesn't prevent moving focus even with event.preventDefault()
12107                         // so we set a flag to know when we should ignore the blur event
12108                         // and check (again) if focus moved off of the input.
12109                         this.cancelBlur = true;
12110                         this._delay(function() {
12111                                 delete this.cancelBlur;
12112                                 checkFocus.call( this );
12113                         });
12115                         if ( this._start( event ) === false ) {
12116                                 return;
12117                         }
12119                         this._repeat( null, $( event.currentTarget ).hasClass( "ui-spinner-up" ) ? 1 : -1, event );
12120                 },
12121                 "mouseup .ui-spinner-button": "_stop",
12122                 "mouseenter .ui-spinner-button": function( event ) {
12123                         // button will add ui-state-active if mouse was down while mouseleave and kept down
12124                         if ( !$( event.currentTarget ).hasClass( "ui-state-active" ) ) {
12125                                 return;
12126                         }
12128                         if ( this._start( event ) === false ) {
12129                                 return false;
12130                         }
12131                         this._repeat( null, $( event.currentTarget ).hasClass( "ui-spinner-up" ) ? 1 : -1, event );
12132                 },
12133                 // TODO: do we really want to consider this a stop?
12134                 // shouldn't we just stop the repeater and wait until mouseup before
12135                 // we trigger the stop event?
12136                 "mouseleave .ui-spinner-button": "_stop"
12137         },
12139         _draw: function() {
12140                 var uiSpinner = this.uiSpinner = this.element
12141                         .addClass( "ui-spinner-input" )
12142                         .attr( "autocomplete", "off" )
12143                         .wrap( this._uiSpinnerHtml() )
12144                         .parent()
12145                                 // add buttons
12146                                 .append( this._buttonHtml() );
12148                 this.element.attr( "role", "spinbutton" );
12150                 // button bindings
12151                 this.buttons = uiSpinner.find( ".ui-spinner-button" )
12152                         .attr( "tabIndex", -1 )
12153                         .button()
12154                         .removeClass( "ui-corner-all" );
12156                 // IE 6 doesn't understand height: 50% for the buttons
12157                 // unless the wrapper has an explicit height
12158                 if ( this.buttons.height() > Math.ceil( uiSpinner.height() * 0.5 ) &&
12159                                 uiSpinner.height() > 0 ) {
12160                         uiSpinner.height( uiSpinner.height() );
12161                 }
12163                 // disable spinner if element was already disabled
12164                 if ( this.options.disabled ) {
12165                         this.disable();
12166                 }
12167         },
12169         _keydown: function( event ) {
12170                 var options = this.options,
12171                         keyCode = $.ui.keyCode;
12173                 switch ( event.keyCode ) {
12174                 case keyCode.UP:
12175                         this._repeat( null, 1, event );
12176                         return true;
12177                 case keyCode.DOWN:
12178                         this._repeat( null, -1, event );
12179                         return true;
12180                 case keyCode.PAGE_UP:
12181                         this._repeat( null, options.page, event );
12182                         return true;
12183                 case keyCode.PAGE_DOWN:
12184                         this._repeat( null, -options.page, event );
12185                         return true;
12186                 }
12188                 return false;
12189         },
12191         _uiSpinnerHtml: function() {
12192                 return "<span class='ui-spinner ui-widget ui-widget-content ui-corner-all'></span>";
12193         },
12195         _buttonHtml: function() {
12196                 return "" +
12197                         "<a class='ui-spinner-button ui-spinner-up ui-corner-tr'>" +
12198                                 "<span class='ui-icon " + this.options.icons.up + "'>&#9650;</span>" +
12199                         "</a>" +
12200                         "<a class='ui-spinner-button ui-spinner-down ui-corner-br'>" +
12201                                 "<span class='ui-icon " + this.options.icons.down + "'>&#9660;</span>" +
12202                         "</a>";
12203         },
12205         _start: function( event ) {
12206                 if ( !this.spinning && this._trigger( "start", event ) === false ) {
12207                         return false;
12208                 }
12210                 if ( !this.counter ) {
12211                         this.counter = 1;
12212                 }
12213                 this.spinning = true;
12214                 return true;
12215         },
12217         _repeat: function( i, steps, event ) {
12218                 i = i || 500;
12220                 clearTimeout( this.timer );
12221                 this.timer = this._delay(function() {
12222                         this._repeat( 40, steps, event );
12223                 }, i );
12225                 this._spin( steps * this.options.step, event );
12226         },
12228         _spin: function( step, event ) {
12229                 var value = this.value() || 0;
12231                 if ( !this.counter ) {
12232                         this.counter = 1;
12233                 }
12235                 value = this._adjustValue( value + step * this._increment( this.counter ) );
12237                 if ( !this.spinning || this._trigger( "spin", event, { value: value } ) !== false) {
12238                         this._value( value );
12239                         this.counter++;
12240                 }
12241         },
12243         _increment: function( i ) {
12244                 var incremental = this.options.incremental;
12246                 if ( incremental ) {
12247                         return $.isFunction( incremental ) ?
12248                                 incremental( i ) :
12249                                 Math.floor( i * i * i / 50000 - i * i / 500 + 17 * i / 200 + 1 );
12250                 }
12252                 return 1;
12253         },
12255         _precision: function() {
12256                 var precision = this._precisionOf( this.options.step );
12257                 if ( this.options.min !== null ) {
12258                         precision = Math.max( precision, this._precisionOf( this.options.min ) );
12259                 }
12260                 return precision;
12261         },
12263         _precisionOf: function( num ) {
12264                 var str = num.toString(),
12265                         decimal = str.indexOf( "." );
12266                 return decimal === -1 ? 0 : str.length - decimal - 1;
12267         },
12269         _adjustValue: function( value ) {
12270                 var base, aboveMin,
12271                         options = this.options;
12273                 // make sure we're at a valid step
12274                 // - find out where we are relative to the base (min or 0)
12275                 base = options.min !== null ? options.min : 0;
12276                 aboveMin = value - base;
12277                 // - round to the nearest step
12278                 aboveMin = Math.round(aboveMin / options.step) * options.step;
12279                 // - rounding is based on 0, so adjust back to our base
12280                 value = base + aboveMin;
12282                 // fix precision from bad JS floating point math
12283                 value = parseFloat( value.toFixed( this._precision() ) );
12285                 // clamp the value
12286                 if ( options.max !== null && value > options.max) {
12287                         return options.max;
12288                 }
12289                 if ( options.min !== null && value < options.min ) {
12290                         return options.min;
12291                 }
12293                 return value;
12294         },
12296         _stop: function( event ) {
12297                 if ( !this.spinning ) {
12298                         return;
12299                 }
12301                 clearTimeout( this.timer );
12302                 clearTimeout( this.mousewheelTimer );
12303                 this.counter = 0;
12304                 this.spinning = false;
12305                 this._trigger( "stop", event );
12306         },
12308         _setOption: function( key, value ) {
12309                 if ( key === "culture" || key === "numberFormat" ) {
12310                         var prevValue = this._parse( this.element.val() );
12311                         this.options[ key ] = value;
12312                         this.element.val( this._format( prevValue ) );
12313                         return;
12314                 }
12316                 if ( key === "max" || key === "min" || key === "step" ) {
12317                         if ( typeof value === "string" ) {
12318                                 value = this._parse( value );
12319                         }
12320                 }
12321                 if ( key === "icons" ) {
12322                         this.buttons.first().find( ".ui-icon" )
12323                                 .removeClass( this.options.icons.up )
12324                                 .addClass( value.up );
12325                         this.buttons.last().find( ".ui-icon" )
12326                                 .removeClass( this.options.icons.down )
12327                                 .addClass( value.down );
12328                 }
12330                 this._super( key, value );
12332                 if ( key === "disabled" ) {
12333                         this.widget().toggleClass( "ui-state-disabled", !!value );
12334                         this.element.prop( "disabled", !!value );
12335                         this.buttons.button( value ? "disable" : "enable" );
12336                 }
12337         },
12339         _setOptions: spinner_modifier(function( options ) {
12340                 this._super( options );
12341         }),
12343         _parse: function( val ) {
12344                 if ( typeof val === "string" && val !== "" ) {
12345                         val = window.Globalize && this.options.numberFormat ?
12346                                 Globalize.parseFloat( val, 10, this.options.culture ) : +val;
12347                 }
12348                 return val === "" || isNaN( val ) ? null : val;
12349         },
12351         _format: function( value ) {
12352                 if ( value === "" ) {
12353                         return "";
12354                 }
12355                 return window.Globalize && this.options.numberFormat ?
12356                         Globalize.format( value, this.options.numberFormat, this.options.culture ) :
12357                         value;
12358         },
12360         _refresh: function() {
12361                 this.element.attr({
12362                         "aria-valuemin": this.options.min,
12363                         "aria-valuemax": this.options.max,
12364                         // TODO: what should we do with values that can't be parsed?
12365                         "aria-valuenow": this._parse( this.element.val() )
12366                 });
12367         },
12369         isValid: function() {
12370                 var value = this.value();
12372                 // null is invalid
12373                 if ( value === null ) {
12374                         return false;
12375                 }
12377                 // if value gets adjusted, it's invalid
12378                 return value === this._adjustValue( value );
12379         },
12381         // update the value without triggering change
12382         _value: function( value, allowAny ) {
12383                 var parsed;
12384                 if ( value !== "" ) {
12385                         parsed = this._parse( value );
12386                         if ( parsed !== null ) {
12387                                 if ( !allowAny ) {
12388                                         parsed = this._adjustValue( parsed );
12389                                 }
12390                                 value = this._format( parsed );
12391                         }
12392                 }
12393                 this.element.val( value );
12394                 this._refresh();
12395         },
12397         _destroy: function() {
12398                 this.element
12399                         .removeClass( "ui-spinner-input" )
12400                         .prop( "disabled", false )
12401                         .removeAttr( "autocomplete" )
12402                         .removeAttr( "role" )
12403                         .removeAttr( "aria-valuemin" )
12404                         .removeAttr( "aria-valuemax" )
12405                         .removeAttr( "aria-valuenow" );
12406                 this.uiSpinner.replaceWith( this.element );
12407         },
12409         stepUp: spinner_modifier(function( steps ) {
12410                 this._stepUp( steps );
12411         }),
12412         _stepUp: function( steps ) {
12413                 if ( this._start() ) {
12414                         this._spin( (steps || 1) * this.options.step );
12415                         this._stop();
12416                 }
12417         },
12419         stepDown: spinner_modifier(function( steps ) {
12420                 this._stepDown( steps );
12421         }),
12422         _stepDown: function( steps ) {
12423                 if ( this._start() ) {
12424                         this._spin( (steps || 1) * -this.options.step );
12425                         this._stop();
12426                 }
12427         },
12429         pageUp: spinner_modifier(function( pages ) {
12430                 this._stepUp( (pages || 1) * this.options.page );
12431         }),
12433         pageDown: spinner_modifier(function( pages ) {
12434                 this._stepDown( (pages || 1) * this.options.page );
12435         }),
12437         value: function( newVal ) {
12438                 if ( !arguments.length ) {
12439                         return this._parse( this.element.val() );
12440                 }
12441                 spinner_modifier( this._value ).call( this, newVal );
12442         },
12444         widget: function() {
12445                 return this.uiSpinner;
12446         }
12451  * jQuery UI Tabs 1.11.0
12452  * http://jqueryui.com
12454  * Copyright 2014 jQuery Foundation and other contributors
12455  * Released under the MIT license.
12456  * http://jquery.org/license
12458  * http://api.jqueryui.com/tabs/
12459  */
12462 var tabs = $.widget( "ui.tabs", {
12463         version: "1.11.0",
12464         delay: 300,
12465         options: {
12466                 active: null,
12467                 collapsible: false,
12468                 event: "click",
12469                 heightStyle: "content",
12470                 hide: null,
12471                 show: null,
12473                 // callbacks
12474                 activate: null,
12475                 beforeActivate: null,
12476                 beforeLoad: null,
12477                 load: null
12478         },
12480         _isLocal: (function() {
12481                 var rhash = /#.*$/;
12483                 return function( anchor ) {
12484                         var anchorUrl, locationUrl;
12486                         // support: IE7
12487                         // IE7 doesn't normalize the href property when set via script (#9317)
12488                         anchor = anchor.cloneNode( false );
12490                         anchorUrl = anchor.href.replace( rhash, "" );
12491                         locationUrl = location.href.replace( rhash, "" );
12493                         // decoding may throw an error if the URL isn't UTF-8 (#9518)
12494                         try {
12495                                 anchorUrl = decodeURIComponent( anchorUrl );
12496                         } catch ( error ) {}
12497                         try {
12498                                 locationUrl = decodeURIComponent( locationUrl );
12499                         } catch ( error ) {}
12501                         return anchor.hash.length > 1 && anchorUrl === locationUrl;
12502                 };
12503         })(),
12505         _create: function() {
12506                 var that = this,
12507                         options = this.options;
12509                 this.running = false;
12511                 this.element
12512                         .addClass( "ui-tabs ui-widget ui-widget-content ui-corner-all" )
12513                         .toggleClass( "ui-tabs-collapsible", options.collapsible )
12514                         // Prevent users from focusing disabled tabs via click
12515                         .delegate( ".ui-tabs-nav > li", "mousedown" + this.eventNamespace, function( event ) {
12516                                 if ( $( this ).is( ".ui-state-disabled" ) ) {
12517                                         event.preventDefault();
12518                                 }
12519                         })
12520                         // support: IE <9
12521                         // Preventing the default action in mousedown doesn't prevent IE
12522                         // from focusing the element, so if the anchor gets focused, blur.
12523                         // We don't have to worry about focusing the previously focused
12524                         // element since clicking on a non-focusable element should focus
12525                         // the body anyway.
12526                         .delegate( ".ui-tabs-anchor", "focus" + this.eventNamespace, function() {
12527                                 if ( $( this ).closest( "li" ).is( ".ui-state-disabled" ) ) {
12528                                         this.blur();
12529                                 }
12530                         });
12532                 this._processTabs();
12533                 options.active = this._initialActive();
12535                 // Take disabling tabs via class attribute from HTML
12536                 // into account and update option properly.
12537                 if ( $.isArray( options.disabled ) ) {
12538                         options.disabled = $.unique( options.disabled.concat(
12539                                 $.map( this.tabs.filter( ".ui-state-disabled" ), function( li ) {
12540                                         return that.tabs.index( li );
12541                                 })
12542                         ) ).sort();
12543                 }
12545                 // check for length avoids error when initializing empty list
12546                 if ( this.options.active !== false && this.anchors.length ) {
12547                         this.active = this._findActive( options.active );
12548                 } else {
12549                         this.active = $();
12550                 }
12552                 this._refresh();
12554                 if ( this.active.length ) {
12555                         this.load( options.active );
12556                 }
12557         },
12559         _initialActive: function() {
12560                 var active = this.options.active,
12561                         collapsible = this.options.collapsible,
12562                         locationHash = location.hash.substring( 1 );
12564                 if ( active === null ) {
12565                         // check the fragment identifier in the URL
12566                         if ( locationHash ) {
12567                                 this.tabs.each(function( i, tab ) {
12568                                         if ( $( tab ).attr( "aria-controls" ) === locationHash ) {
12569                                                 active = i;
12570                                                 return false;
12571                                         }
12572                                 });
12573                         }
12575                         // check for a tab marked active via a class
12576                         if ( active === null ) {
12577                                 active = this.tabs.index( this.tabs.filter( ".ui-tabs-active" ) );
12578                         }
12580                         // no active tab, set to false
12581                         if ( active === null || active === -1 ) {
12582                                 active = this.tabs.length ? 0 : false;
12583                         }
12584                 }
12586                 // handle numbers: negative, out of range
12587                 if ( active !== false ) {
12588                         active = this.tabs.index( this.tabs.eq( active ) );
12589                         if ( active === -1 ) {
12590                                 active = collapsible ? false : 0;
12591                         }
12592                 }
12594                 // don't allow collapsible: false and active: false
12595                 if ( !collapsible && active === false && this.anchors.length ) {
12596                         active = 0;
12597                 }
12599                 return active;
12600         },
12602         _getCreateEventData: function() {
12603                 return {
12604                         tab: this.active,
12605                         panel: !this.active.length ? $() : this._getPanelForTab( this.active )
12606                 };
12607         },
12609         _tabKeydown: function( event ) {
12610                 var focusedTab = $( this.document[0].activeElement ).closest( "li" ),
12611                         selectedIndex = this.tabs.index( focusedTab ),
12612                         goingForward = true;
12614                 if ( this._handlePageNav( event ) ) {
12615                         return;
12616                 }
12618                 switch ( event.keyCode ) {
12619                         case $.ui.keyCode.RIGHT:
12620                         case $.ui.keyCode.DOWN:
12621                                 selectedIndex++;
12622                                 break;
12623                         case $.ui.keyCode.UP:
12624                         case $.ui.keyCode.LEFT:
12625                                 goingForward = false;
12626                                 selectedIndex--;
12627                                 break;
12628                         case $.ui.keyCode.END:
12629                                 selectedIndex = this.anchors.length - 1;
12630                                 break;
12631                         case $.ui.keyCode.HOME:
12632                                 selectedIndex = 0;
12633                                 break;
12634                         case $.ui.keyCode.SPACE:
12635                                 // Activate only, no collapsing
12636                                 event.preventDefault();
12637                                 clearTimeout( this.activating );
12638                                 this._activate( selectedIndex );
12639                                 return;
12640                         case $.ui.keyCode.ENTER:
12641                                 // Toggle (cancel delayed activation, allow collapsing)
12642                                 event.preventDefault();
12643                                 clearTimeout( this.activating );
12644                                 // Determine if we should collapse or activate
12645                                 this._activate( selectedIndex === this.options.active ? false : selectedIndex );
12646                                 return;
12647                         default:
12648                                 return;
12649                 }
12651                 // Focus the appropriate tab, based on which key was pressed
12652                 event.preventDefault();
12653                 clearTimeout( this.activating );
12654                 selectedIndex = this._focusNextTab( selectedIndex, goingForward );
12656                 // Navigating with control key will prevent automatic activation
12657                 if ( !event.ctrlKey ) {
12658                         // Update aria-selected immediately so that AT think the tab is already selected.
12659                         // Otherwise AT may confuse the user by stating that they need to activate the tab,
12660                         // but the tab will already be activated by the time the announcement finishes.
12661                         focusedTab.attr( "aria-selected", "false" );
12662                         this.tabs.eq( selectedIndex ).attr( "aria-selected", "true" );
12664                         this.activating = this._delay(function() {
12665                                 this.option( "active", selectedIndex );
12666                         }, this.delay );
12667                 }
12668         },
12670         _panelKeydown: function( event ) {
12671                 if ( this._handlePageNav( event ) ) {
12672                         return;
12673                 }
12675                 // Ctrl+up moves focus to the current tab
12676                 if ( event.ctrlKey && event.keyCode === $.ui.keyCode.UP ) {
12677                         event.preventDefault();
12678                         this.active.focus();
12679                 }
12680         },
12682         // Alt+page up/down moves focus to the previous/next tab (and activates)
12683         _handlePageNav: function( event ) {
12684                 if ( event.altKey && event.keyCode === $.ui.keyCode.PAGE_UP ) {
12685                         this._activate( this._focusNextTab( this.options.active - 1, false ) );
12686                         return true;
12687                 }
12688                 if ( event.altKey && event.keyCode === $.ui.keyCode.PAGE_DOWN ) {
12689                         this._activate( this._focusNextTab( this.options.active + 1, true ) );
12690                         return true;
12691                 }
12692         },
12694         _findNextTab: function( index, goingForward ) {
12695                 var lastTabIndex = this.tabs.length - 1;
12697                 function constrain() {
12698                         if ( index > lastTabIndex ) {
12699                                 index = 0;
12700                         }
12701                         if ( index < 0 ) {
12702                                 index = lastTabIndex;
12703                         }
12704                         return index;
12705                 }
12707                 while ( $.inArray( constrain(), this.options.disabled ) !== -1 ) {
12708                         index = goingForward ? index + 1 : index - 1;
12709                 }
12711                 return index;
12712         },
12714         _focusNextTab: function( index, goingForward ) {
12715                 index = this._findNextTab( index, goingForward );
12716                 this.tabs.eq( index ).focus();
12717                 return index;
12718         },
12720         _setOption: function( key, value ) {
12721                 if ( key === "active" ) {
12722                         // _activate() will handle invalid values and update this.options
12723                         this._activate( value );
12724                         return;
12725                 }
12727                 if ( key === "disabled" ) {
12728                         // don't use the widget factory's disabled handling
12729                         this._setupDisabled( value );
12730                         return;
12731                 }
12733                 this._super( key, value);
12735                 if ( key === "collapsible" ) {
12736                         this.element.toggleClass( "ui-tabs-collapsible", value );
12737                         // Setting collapsible: false while collapsed; open first panel
12738                         if ( !value && this.options.active === false ) {
12739                                 this._activate( 0 );
12740                         }
12741                 }
12743                 if ( key === "event" ) {
12744                         this._setupEvents( value );
12745                 }
12747                 if ( key === "heightStyle" ) {
12748                         this._setupHeightStyle( value );
12749                 }
12750         },
12752         _sanitizeSelector: function( hash ) {
12753                 return hash ? hash.replace( /[!"$%&'()*+,.\/:;<=>?@\[\]\^`{|}~]/g, "\\$&" ) : "";
12754         },
12756         refresh: function() {
12757                 var options = this.options,
12758                         lis = this.tablist.children( ":has(a[href])" );
12760                 // get disabled tabs from class attribute from HTML
12761                 // this will get converted to a boolean if needed in _refresh()
12762                 options.disabled = $.map( lis.filter( ".ui-state-disabled" ), function( tab ) {
12763                         return lis.index( tab );
12764                 });
12766                 this._processTabs();
12768                 // was collapsed or no tabs
12769                 if ( options.active === false || !this.anchors.length ) {
12770                         options.active = false;
12771                         this.active = $();
12772                 // was active, but active tab is gone
12773                 } else if ( this.active.length && !$.contains( this.tablist[ 0 ], this.active[ 0 ] ) ) {
12774                         // all remaining tabs are disabled
12775                         if ( this.tabs.length === options.disabled.length ) {
12776                                 options.active = false;
12777                                 this.active = $();
12778                         // activate previous tab
12779                         } else {
12780                                 this._activate( this._findNextTab( Math.max( 0, options.active - 1 ), false ) );
12781                         }
12782                 // was active, active tab still exists
12783                 } else {
12784                         // make sure active index is correct
12785                         options.active = this.tabs.index( this.active );
12786                 }
12788                 this._refresh();
12789         },
12791         _refresh: function() {
12792                 this._setupDisabled( this.options.disabled );
12793                 this._setupEvents( this.options.event );
12794                 this._setupHeightStyle( this.options.heightStyle );
12796                 this.tabs.not( this.active ).attr({
12797                         "aria-selected": "false",
12798                         "aria-expanded": "false",
12799                         tabIndex: -1
12800                 });
12801                 this.panels.not( this._getPanelForTab( this.active ) )
12802                         .hide()
12803                         .attr({
12804                                 "aria-hidden": "true"
12805                         });
12807                 // Make sure one tab is in the tab order
12808                 if ( !this.active.length ) {
12809                         this.tabs.eq( 0 ).attr( "tabIndex", 0 );
12810                 } else {
12811                         this.active
12812                                 .addClass( "ui-tabs-active ui-state-active" )
12813                                 .attr({
12814                                         "aria-selected": "true",
12815                                         "aria-expanded": "true",
12816                                         tabIndex: 0
12817                                 });
12818                         this._getPanelForTab( this.active )
12819                                 .show()
12820                                 .attr({
12821                                         "aria-hidden": "false"
12822                                 });
12823                 }
12824         },
12826         _processTabs: function() {
12827                 var that = this;
12829                 this.tablist = this._getList()
12830                         .addClass( "ui-tabs-nav ui-helper-reset ui-helper-clearfix ui-widget-header ui-corner-all" )
12831                         .attr( "role", "tablist" );
12833                 this.tabs = this.tablist.find( "> li:has(a[href])" )
12834                         .addClass( "ui-state-default ui-corner-top" )
12835                         .attr({
12836                                 role: "tab",
12837                                 tabIndex: -1
12838                         });
12840                 this.anchors = this.tabs.map(function() {
12841                                 return $( "a", this )[ 0 ];
12842                         })
12843                         .addClass( "ui-tabs-anchor" )
12844                         .attr({
12845                                 role: "presentation",
12846                                 tabIndex: -1
12847                         });
12849                 this.panels = $();
12851                 this.anchors.each(function( i, anchor ) {
12852                         var selector, panel, panelId,
12853                                 anchorId = $( anchor ).uniqueId().attr( "id" ),
12854                                 tab = $( anchor ).closest( "li" ),
12855                                 originalAriaControls = tab.attr( "aria-controls" );
12857                         // inline tab
12858                         if ( that._isLocal( anchor ) ) {
12859                                 selector = anchor.hash;
12860                                 panelId = selector.substring( 1 );
12861                                 panel = that.element.find( that._sanitizeSelector( selector ) );
12862                         // remote tab
12863                         } else {
12864                                 // If the tab doesn't already have aria-controls,
12865                                 // generate an id by using a throw-away element
12866                                 panelId = tab.attr( "aria-controls" ) || $( {} ).uniqueId()[ 0 ].id;
12867                                 selector = "#" + panelId;
12868                                 panel = that.element.find( selector );
12869                                 if ( !panel.length ) {
12870                                         panel = that._createPanel( panelId );
12871                                         panel.insertAfter( that.panels[ i - 1 ] || that.tablist );
12872                                 }
12873                                 panel.attr( "aria-live", "polite" );
12874                         }
12876                         if ( panel.length) {
12877                                 that.panels = that.panels.add( panel );
12878                         }
12879                         if ( originalAriaControls ) {
12880                                 tab.data( "ui-tabs-aria-controls", originalAriaControls );
12881                         }
12882                         tab.attr({
12883                                 "aria-controls": panelId,
12884                                 "aria-labelledby": anchorId
12885                         });
12886                         panel.attr( "aria-labelledby", anchorId );
12887                 });
12889                 this.panels
12890                         .addClass( "ui-tabs-panel ui-widget-content ui-corner-bottom" )
12891                         .attr( "role", "tabpanel" );
12892         },
12894         // allow overriding how to find the list for rare usage scenarios (#7715)
12895         _getList: function() {
12896                 return this.tablist || this.element.find( "ol,ul" ).eq( 0 );
12897         },
12899         _createPanel: function( id ) {
12900                 return $( "<div>" )
12901                         .attr( "id", id )
12902                         .addClass( "ui-tabs-panel ui-widget-content ui-corner-bottom" )
12903                         .data( "ui-tabs-destroy", true );
12904         },
12906         _setupDisabled: function( disabled ) {
12907                 if ( $.isArray( disabled ) ) {
12908                         if ( !disabled.length ) {
12909                                 disabled = false;
12910                         } else if ( disabled.length === this.anchors.length ) {
12911                                 disabled = true;
12912                         }
12913                 }
12915                 // disable tabs
12916                 for ( var i = 0, li; ( li = this.tabs[ i ] ); i++ ) {
12917                         if ( disabled === true || $.inArray( i, disabled ) !== -1 ) {
12918                                 $( li )
12919                                         .addClass( "ui-state-disabled" )
12920                                         .attr( "aria-disabled", "true" );
12921                         } else {
12922                                 $( li )
12923                                         .removeClass( "ui-state-disabled" )
12924                                         .removeAttr( "aria-disabled" );
12925                         }
12926                 }
12928                 this.options.disabled = disabled;
12929         },
12931         _setupEvents: function( event ) {
12932                 var events = {};
12933                 if ( event ) {
12934                         $.each( event.split(" "), function( index, eventName ) {
12935                                 events[ eventName ] = "_eventHandler";
12936                         });
12937                 }
12939                 this._off( this.anchors.add( this.tabs ).add( this.panels ) );
12940                 // Always prevent the default action, even when disabled
12941                 this._on( true, this.anchors, {
12942                         click: function( event ) {
12943                                 event.preventDefault();
12944                         }
12945                 });
12946                 this._on( this.anchors, events );
12947                 this._on( this.tabs, { keydown: "_tabKeydown" } );
12948                 this._on( this.panels, { keydown: "_panelKeydown" } );
12950                 this._focusable( this.tabs );
12951                 this._hoverable( this.tabs );
12952         },
12954         _setupHeightStyle: function( heightStyle ) {
12955                 var maxHeight,
12956                         parent = this.element.parent();
12958                 if ( heightStyle === "fill" ) {
12959                         maxHeight = parent.height();
12960                         maxHeight -= this.element.outerHeight() - this.element.height();
12962                         this.element.siblings( ":visible" ).each(function() {
12963                                 var elem = $( this ),
12964                                         position = elem.css( "position" );
12966                                 if ( position === "absolute" || position === "fixed" ) {
12967                                         return;
12968                                 }
12969                                 maxHeight -= elem.outerHeight( true );
12970                         });
12972                         this.element.children().not( this.panels ).each(function() {
12973                                 maxHeight -= $( this ).outerHeight( true );
12974                         });
12976                         this.panels.each(function() {
12977                                 $( this ).height( Math.max( 0, maxHeight -
12978                                         $( this ).innerHeight() + $( this ).height() ) );
12979                         })
12980                         .css( "overflow", "auto" );
12981                 } else if ( heightStyle === "auto" ) {
12982                         maxHeight = 0;
12983                         this.panels.each(function() {
12984                                 maxHeight = Math.max( maxHeight, $( this ).height( "" ).height() );
12985                         }).height( maxHeight );
12986                 }
12987         },
12989         _eventHandler: function( event ) {
12990                 var options = this.options,
12991                         active = this.active,
12992                         anchor = $( event.currentTarget ),
12993                         tab = anchor.closest( "li" ),
12994                         clickedIsActive = tab[ 0 ] === active[ 0 ],
12995                         collapsing = clickedIsActive && options.collapsible,
12996                         toShow = collapsing ? $() : this._getPanelForTab( tab ),
12997                         toHide = !active.length ? $() : this._getPanelForTab( active ),
12998                         eventData = {
12999                                 oldTab: active,
13000                                 oldPanel: toHide,
13001                                 newTab: collapsing ? $() : tab,
13002                                 newPanel: toShow
13003                         };
13005                 event.preventDefault();
13007                 if ( tab.hasClass( "ui-state-disabled" ) ||
13008                                 // tab is already loading
13009                                 tab.hasClass( "ui-tabs-loading" ) ||
13010                                 // can't switch durning an animation
13011                                 this.running ||
13012                                 // click on active header, but not collapsible
13013                                 ( clickedIsActive && !options.collapsible ) ||
13014                                 // allow canceling activation
13015                                 ( this._trigger( "beforeActivate", event, eventData ) === false ) ) {
13016                         return;
13017                 }
13019                 options.active = collapsing ? false : this.tabs.index( tab );
13021                 this.active = clickedIsActive ? $() : tab;
13022                 if ( this.xhr ) {
13023                         this.xhr.abort();
13024                 }
13026                 if ( !toHide.length && !toShow.length ) {
13027                         $.error( "jQuery UI Tabs: Mismatching fragment identifier." );
13028                 }
13030                 if ( toShow.length ) {
13031                         this.load( this.tabs.index( tab ), event );
13032                 }
13033                 this._toggle( event, eventData );
13034         },
13036         // handles show/hide for selecting tabs
13037         _toggle: function( event, eventData ) {
13038                 var that = this,
13039                         toShow = eventData.newPanel,
13040                         toHide = eventData.oldPanel;
13042                 this.running = true;
13044                 function complete() {
13045                         that.running = false;
13046                         that._trigger( "activate", event, eventData );
13047                 }
13049                 function show() {
13050                         eventData.newTab.closest( "li" ).addClass( "ui-tabs-active ui-state-active" );
13052                         if ( toShow.length && that.options.show ) {
13053                                 that._show( toShow, that.options.show, complete );
13054                         } else {
13055                                 toShow.show();
13056                                 complete();
13057                         }
13058                 }
13060                 // start out by hiding, then showing, then completing
13061                 if ( toHide.length && this.options.hide ) {
13062                         this._hide( toHide, this.options.hide, function() {
13063                                 eventData.oldTab.closest( "li" ).removeClass( "ui-tabs-active ui-state-active" );
13064                                 show();
13065                         });
13066                 } else {
13067                         eventData.oldTab.closest( "li" ).removeClass( "ui-tabs-active ui-state-active" );
13068                         toHide.hide();
13069                         show();
13070                 }
13072                 toHide.attr( "aria-hidden", "true" );
13073                 eventData.oldTab.attr({
13074                         "aria-selected": "false",
13075                         "aria-expanded": "false"
13076                 });
13077                 // If we're switching tabs, remove the old tab from the tab order.
13078                 // If we're opening from collapsed state, remove the previous tab from the tab order.
13079                 // If we're collapsing, then keep the collapsing tab in the tab order.
13080                 if ( toShow.length && toHide.length ) {
13081                         eventData.oldTab.attr( "tabIndex", -1 );
13082                 } else if ( toShow.length ) {
13083                         this.tabs.filter(function() {
13084                                 return $( this ).attr( "tabIndex" ) === 0;
13085                         })
13086                         .attr( "tabIndex", -1 );
13087                 }
13089                 toShow.attr( "aria-hidden", "false" );
13090                 eventData.newTab.attr({
13091                         "aria-selected": "true",
13092                         "aria-expanded": "true",
13093                         tabIndex: 0
13094                 });
13095         },
13097         _activate: function( index ) {
13098                 var anchor,
13099                         active = this._findActive( index );
13101                 // trying to activate the already active panel
13102                 if ( active[ 0 ] === this.active[ 0 ] ) {
13103                         return;
13104                 }
13106                 // trying to collapse, simulate a click on the current active header
13107                 if ( !active.length ) {
13108                         active = this.active;
13109                 }
13111                 anchor = active.find( ".ui-tabs-anchor" )[ 0 ];
13112                 this._eventHandler({
13113                         target: anchor,
13114                         currentTarget: anchor,
13115                         preventDefault: $.noop
13116                 });
13117         },
13119         _findActive: function( index ) {
13120                 return index === false ? $() : this.tabs.eq( index );
13121         },
13123         _getIndex: function( index ) {
13124                 // meta-function to give users option to provide a href string instead of a numerical index.
13125                 if ( typeof index === "string" ) {
13126                         index = this.anchors.index( this.anchors.filter( "[href$='" + index + "']" ) );
13127                 }
13129                 return index;
13130         },
13132         _destroy: function() {
13133                 if ( this.xhr ) {
13134                         this.xhr.abort();
13135                 }
13137                 this.element.removeClass( "ui-tabs ui-widget ui-widget-content ui-corner-all ui-tabs-collapsible" );
13139                 this.tablist
13140                         .removeClass( "ui-tabs-nav ui-helper-reset ui-helper-clearfix ui-widget-header ui-corner-all" )
13141                         .removeAttr( "role" );
13143                 this.anchors
13144                         .removeClass( "ui-tabs-anchor" )
13145                         .removeAttr( "role" )
13146                         .removeAttr( "tabIndex" )
13147                         .removeUniqueId();
13149                 this.tabs.add( this.panels ).each(function() {
13150                         if ( $.data( this, "ui-tabs-destroy" ) ) {
13151                                 $( this ).remove();
13152                         } else {
13153                                 $( this )
13154                                         .removeClass( "ui-state-default ui-state-active ui-state-disabled " +
13155                                                 "ui-corner-top ui-corner-bottom ui-widget-content ui-tabs-active ui-tabs-panel" )
13156                                         .removeAttr( "tabIndex" )
13157                                         .removeAttr( "aria-live" )
13158                                         .removeAttr( "aria-busy" )
13159                                         .removeAttr( "aria-selected" )
13160                                         .removeAttr( "aria-labelledby" )
13161                                         .removeAttr( "aria-hidden" )
13162                                         .removeAttr( "aria-expanded" )
13163                                         .removeAttr( "role" );
13164                         }
13165                 });
13167                 this.tabs.each(function() {
13168                         var li = $( this ),
13169                                 prev = li.data( "ui-tabs-aria-controls" );
13170                         if ( prev ) {
13171                                 li
13172                                         .attr( "aria-controls", prev )
13173                                         .removeData( "ui-tabs-aria-controls" );
13174                         } else {
13175                                 li.removeAttr( "aria-controls" );
13176                         }
13177                 });
13179                 this.panels.show();
13181                 if ( this.options.heightStyle !== "content" ) {
13182                         this.panels.css( "height", "" );
13183                 }
13184         },
13186         enable: function( index ) {
13187                 var disabled = this.options.disabled;
13188                 if ( disabled === false ) {
13189                         return;
13190                 }
13192                 if ( index === undefined ) {
13193                         disabled = false;
13194                 } else {
13195                         index = this._getIndex( index );
13196                         if ( $.isArray( disabled ) ) {
13197                                 disabled = $.map( disabled, function( num ) {
13198                                         return num !== index ? num : null;
13199                                 });
13200                         } else {
13201                                 disabled = $.map( this.tabs, function( li, num ) {
13202                                         return num !== index ? num : null;
13203                                 });
13204                         }
13205                 }
13206                 this._setupDisabled( disabled );
13207         },
13209         disable: function( index ) {
13210                 var disabled = this.options.disabled;
13211                 if ( disabled === true ) {
13212                         return;
13213                 }
13215                 if ( index === undefined ) {
13216                         disabled = true;
13217                 } else {
13218                         index = this._getIndex( index );
13219                         if ( $.inArray( index, disabled ) !== -1 ) {
13220                                 return;
13221                         }
13222                         if ( $.isArray( disabled ) ) {
13223                                 disabled = $.merge( [ index ], disabled ).sort();
13224                         } else {
13225                                 disabled = [ index ];
13226                         }
13227                 }
13228                 this._setupDisabled( disabled );
13229         },
13231         load: function( index, event ) {
13232                 index = this._getIndex( index );
13233                 var that = this,
13234                         tab = this.tabs.eq( index ),
13235                         anchor = tab.find( ".ui-tabs-anchor" ),
13236                         panel = this._getPanelForTab( tab ),
13237                         eventData = {
13238                                 tab: tab,
13239                                 panel: panel
13240                         };
13242                 // not remote
13243                 if ( this._isLocal( anchor[ 0 ] ) ) {
13244                         return;
13245                 }
13247                 this.xhr = $.ajax( this._ajaxSettings( anchor, event, eventData ) );
13249                 // support: jQuery <1.8
13250                 // jQuery <1.8 returns false if the request is canceled in beforeSend,
13251                 // but as of 1.8, $.ajax() always returns a jqXHR object.
13252                 if ( this.xhr && this.xhr.statusText !== "canceled" ) {
13253                         tab.addClass( "ui-tabs-loading" );
13254                         panel.attr( "aria-busy", "true" );
13256                         this.xhr
13257                                 .success(function( response ) {
13258                                         // support: jQuery <1.8
13259                                         // http://bugs.jquery.com/ticket/11778
13260                                         setTimeout(function() {
13261                                                 panel.html( response );
13262                                                 that._trigger( "load", event, eventData );
13263                                         }, 1 );
13264                                 })
13265                                 .complete(function( jqXHR, status ) {
13266                                         // support: jQuery <1.8
13267                                         // http://bugs.jquery.com/ticket/11778
13268                                         setTimeout(function() {
13269                                                 if ( status === "abort" ) {
13270                                                         that.panels.stop( false, true );
13271                                                 }
13273                                                 tab.removeClass( "ui-tabs-loading" );
13274                                                 panel.removeAttr( "aria-busy" );
13276                                                 if ( jqXHR === that.xhr ) {
13277                                                         delete that.xhr;
13278                                                 }
13279                                         }, 1 );
13280                                 });
13281                 }
13282         },
13284         _ajaxSettings: function( anchor, event, eventData ) {
13285                 var that = this;
13286                 return {
13287                         url: anchor.attr( "href" ),
13288                         beforeSend: function( jqXHR, settings ) {
13289                                 return that._trigger( "beforeLoad", event,
13290                                         $.extend( { jqXHR: jqXHR, ajaxSettings: settings }, eventData ) );
13291                         }
13292                 };
13293         },
13295         _getPanelForTab: function( tab ) {
13296                 var id = $( tab ).attr( "aria-controls" );
13297                 return this.element.find( this._sanitizeSelector( "#" + id ) );
13298         }
13303  * jQuery UI Tooltip 1.11.0
13304  * http://jqueryui.com
13306  * Copyright 2014 jQuery Foundation and other contributors
13307  * Released under the MIT license.
13308  * http://jquery.org/license
13310  * http://api.jqueryui.com/tooltip/
13311  */
13314 var tooltip = $.widget( "ui.tooltip", {
13315         version: "1.11.0",
13316         options: {
13317                 content: function() {
13318                         // support: IE<9, Opera in jQuery <1.7
13319                         // .text() can't accept undefined, so coerce to a string
13320                         var title = $( this ).attr( "title" ) || "";
13321                         // Escape title, since we're going from an attribute to raw HTML
13322                         return $( "<a>" ).text( title ).html();
13323                 },
13324                 hide: true,
13325                 // Disabled elements have inconsistent behavior across browsers (#8661)
13326                 items: "[title]:not([disabled])",
13327                 position: {
13328                         my: "left top+15",
13329                         at: "left bottom",
13330                         collision: "flipfit flip"
13331                 },
13332                 show: true,
13333                 tooltipClass: null,
13334                 track: false,
13336                 // callbacks
13337                 close: null,
13338                 open: null
13339         },
13341         _addDescribedBy: function( elem, id ) {
13342                 var describedby = (elem.attr( "aria-describedby" ) || "").split( /\s+/ );
13343                 describedby.push( id );
13344                 elem
13345                         .data( "ui-tooltip-id", id )
13346                         .attr( "aria-describedby", $.trim( describedby.join( " " ) ) );
13347         },
13349         _removeDescribedBy: function( elem ) {
13350                 var id = elem.data( "ui-tooltip-id" ),
13351                         describedby = (elem.attr( "aria-describedby" ) || "").split( /\s+/ ),
13352                         index = $.inArray( id, describedby );
13354                 if ( index !== -1 ) {
13355                         describedby.splice( index, 1 );
13356                 }
13358                 elem.removeData( "ui-tooltip-id" );
13359                 describedby = $.trim( describedby.join( " " ) );
13360                 if ( describedby ) {
13361                         elem.attr( "aria-describedby", describedby );
13362                 } else {
13363                         elem.removeAttr( "aria-describedby" );
13364                 }
13365         },
13367         _create: function() {
13368                 this._on({
13369                         mouseover: "open",
13370                         focusin: "open"
13371                 });
13373                 // IDs of generated tooltips, needed for destroy
13374                 this.tooltips = {};
13375                 // IDs of parent tooltips where we removed the title attribute
13376                 this.parents = {};
13378                 if ( this.options.disabled ) {
13379                         this._disable();
13380                 }
13382                 // Append the aria-live region so tooltips announce correctly
13383                 this.liveRegion = $( "<div>" )
13384                         .attr({
13385                                 role: "log",
13386                                 "aria-live": "assertive",
13387                                 "aria-relevant": "additions"
13388                         })
13389                         .addClass( "ui-helper-hidden-accessible" )
13390                         .appendTo( this.document[ 0 ].body );
13391         },
13393         _setOption: function( key, value ) {
13394                 var that = this;
13396                 if ( key === "disabled" ) {
13397                         this[ value ? "_disable" : "_enable" ]();
13398                         this.options[ key ] = value;
13399                         // disable element style changes
13400                         return;
13401                 }
13403                 this._super( key, value );
13405                 if ( key === "content" ) {
13406                         $.each( this.tooltips, function( id, element ) {
13407                                 that._updateContent( element );
13408                         });
13409                 }
13410         },
13412         _disable: function() {
13413                 var that = this;
13415                 // close open tooltips
13416                 $.each( this.tooltips, function( id, element ) {
13417                         var event = $.Event( "blur" );
13418                         event.target = event.currentTarget = element[0];
13419                         that.close( event, true );
13420                 });
13422                 // remove title attributes to prevent native tooltips
13423                 this.element.find( this.options.items ).addBack().each(function() {
13424                         var element = $( this );
13425                         if ( element.is( "[title]" ) ) {
13426                                 element
13427                                         .data( "ui-tooltip-title", element.attr( "title" ) )
13428                                         .removeAttr( "title" );
13429                         }
13430                 });
13431         },
13433         _enable: function() {
13434                 // restore title attributes
13435                 this.element.find( this.options.items ).addBack().each(function() {
13436                         var element = $( this );
13437                         if ( element.data( "ui-tooltip-title" ) ) {
13438                                 element.attr( "title", element.data( "ui-tooltip-title" ) );
13439                         }
13440                 });
13441         },
13443         open: function( event ) {
13444                 var that = this,
13445                         target = $( event ? event.target : this.element )
13446                                 // we need closest here due to mouseover bubbling,
13447                                 // but always pointing at the same event target
13448                                 .closest( this.options.items );
13450                 // No element to show a tooltip for or the tooltip is already open
13451                 if ( !target.length || target.data( "ui-tooltip-id" ) ) {
13452                         return;
13453                 }
13455                 if ( target.attr( "title" ) ) {
13456                         target.data( "ui-tooltip-title", target.attr( "title" ) );
13457                 }
13459                 target.data( "ui-tooltip-open", true );
13461                 // kill parent tooltips, custom or native, for hover
13462                 if ( event && event.type === "mouseover" ) {
13463                         target.parents().each(function() {
13464                                 var parent = $( this ),
13465                                         blurEvent;
13466                                 if ( parent.data( "ui-tooltip-open" ) ) {
13467                                         blurEvent = $.Event( "blur" );
13468                                         blurEvent.target = blurEvent.currentTarget = this;
13469                                         that.close( blurEvent, true );
13470                                 }
13471                                 if ( parent.attr( "title" ) ) {
13472                                         parent.uniqueId();
13473                                         that.parents[ this.id ] = {
13474                                                 element: this,
13475                                                 title: parent.attr( "title" )
13476                                         };
13477                                         parent.attr( "title", "" );
13478                                 }
13479                         });
13480                 }
13482                 this._updateContent( target, event );
13483         },
13485         _updateContent: function( target, event ) {
13486                 var content,
13487                         contentOption = this.options.content,
13488                         that = this,
13489                         eventType = event ? event.type : null;
13491                 if ( typeof contentOption === "string" ) {
13492                         return this._open( event, target, contentOption );
13493                 }
13495                 content = contentOption.call( target[0], function( response ) {
13496                         // ignore async response if tooltip was closed already
13497                         if ( !target.data( "ui-tooltip-open" ) ) {
13498                                 return;
13499                         }
13500                         // IE may instantly serve a cached response for ajax requests
13501                         // delay this call to _open so the other call to _open runs first
13502                         that._delay(function() {
13503                                 // jQuery creates a special event for focusin when it doesn't
13504                                 // exist natively. To improve performance, the native event
13505                                 // object is reused and the type is changed. Therefore, we can't
13506                                 // rely on the type being correct after the event finished
13507                                 // bubbling, so we set it back to the previous value. (#8740)
13508                                 if ( event ) {
13509                                         event.type = eventType;
13510                                 }
13511                                 this._open( event, target, response );
13512                         });
13513                 });
13514                 if ( content ) {
13515                         this._open( event, target, content );
13516                 }
13517         },
13519         _open: function( event, target, content ) {
13520                 var tooltip, events, delayedShow, a11yContent,
13521                         positionOption = $.extend( {}, this.options.position );
13523                 if ( !content ) {
13524                         return;
13525                 }
13527                 // Content can be updated multiple times. If the tooltip already
13528                 // exists, then just update the content and bail.
13529                 tooltip = this._find( target );
13530                 if ( tooltip.length ) {
13531                         tooltip.find( ".ui-tooltip-content" ).html( content );
13532                         return;
13533                 }
13535                 // if we have a title, clear it to prevent the native tooltip
13536                 // we have to check first to avoid defining a title if none exists
13537                 // (we don't want to cause an element to start matching [title])
13538                 //
13539                 // We use removeAttr only for key events, to allow IE to export the correct
13540                 // accessible attributes. For mouse events, set to empty string to avoid
13541                 // native tooltip showing up (happens only when removing inside mouseover).
13542                 if ( target.is( "[title]" ) ) {
13543                         if ( event && event.type === "mouseover" ) {
13544                                 target.attr( "title", "" );
13545                         } else {
13546                                 target.removeAttr( "title" );
13547                         }
13548                 }
13550                 tooltip = this._tooltip( target );
13551                 this._addDescribedBy( target, tooltip.attr( "id" ) );
13552                 tooltip.find( ".ui-tooltip-content" ).html( content );
13554                 // Support: Voiceover on OS X, JAWS on IE <= 9
13555                 // JAWS announces deletions even when aria-relevant="additions"
13556                 // Voiceover will sometimes re-read the entire log region's contents from the beginning
13557                 this.liveRegion.children().hide();
13558                 if ( content.clone ) {
13559                         a11yContent = content.clone();
13560                         a11yContent.removeAttr( "id" ).find( "[id]" ).removeAttr( "id" );
13561                 } else {
13562                         a11yContent = content;
13563                 }
13564                 $( "<div>" ).html( a11yContent ).appendTo( this.liveRegion );
13566                 function position( event ) {
13567                         positionOption.of = event;
13568                         if ( tooltip.is( ":hidden" ) ) {
13569                                 return;
13570                         }
13571                         tooltip.position( positionOption );
13572                 }
13573                 if ( this.options.track && event && /^mouse/.test( event.type ) ) {
13574                         this._on( this.document, {
13575                                 mousemove: position
13576                         });
13577                         // trigger once to override element-relative positioning
13578                         position( event );
13579                 } else {
13580                         tooltip.position( $.extend({
13581                                 of: target
13582                         }, this.options.position ) );
13583                 }
13585                 tooltip.hide();
13587                 this._show( tooltip, this.options.show );
13588                 // Handle tracking tooltips that are shown with a delay (#8644). As soon
13589                 // as the tooltip is visible, position the tooltip using the most recent
13590                 // event.
13591                 if ( this.options.show && this.options.show.delay ) {
13592                         delayedShow = this.delayedShow = setInterval(function() {
13593                                 if ( tooltip.is( ":visible" ) ) {
13594                                         position( positionOption.of );
13595                                         clearInterval( delayedShow );
13596                                 }
13597                         }, $.fx.interval );
13598                 }
13600                 this._trigger( "open", event, { tooltip: tooltip } );
13602                 events = {
13603                         keyup: function( event ) {
13604                                 if ( event.keyCode === $.ui.keyCode.ESCAPE ) {
13605                                         var fakeEvent = $.Event(event);
13606                                         fakeEvent.currentTarget = target[0];
13607                                         this.close( fakeEvent, true );
13608                                 }
13609                         }
13610                 };
13612                 // Only bind remove handler for delegated targets. Non-delegated
13613                 // tooltips will handle this in destroy.
13614                 if ( target[ 0 ] !== this.element[ 0 ] ) {
13615                         events.remove = function() {
13616                                 this._removeTooltip( tooltip );
13617                         };
13618                 }
13620                 if ( !event || event.type === "mouseover" ) {
13621                         events.mouseleave = "close";
13622                 }
13623                 if ( !event || event.type === "focusin" ) {
13624                         events.focusout = "close";
13625                 }
13626                 this._on( true, target, events );
13627         },
13629         close: function( event ) {
13630                 var that = this,
13631                         target = $( event ? event.currentTarget : this.element ),
13632                         tooltip = this._find( target );
13634                 // disabling closes the tooltip, so we need to track when we're closing
13635                 // to avoid an infinite loop in case the tooltip becomes disabled on close
13636                 if ( this.closing ) {
13637                         return;
13638                 }
13640                 // Clear the interval for delayed tracking tooltips
13641                 clearInterval( this.delayedShow );
13643                 // only set title if we had one before (see comment in _open())
13644                 // If the title attribute has changed since open(), don't restore
13645                 if ( target.data( "ui-tooltip-title" ) && !target.attr( "title" ) ) {
13646                         target.attr( "title", target.data( "ui-tooltip-title" ) );
13647                 }
13649                 this._removeDescribedBy( target );
13651                 tooltip.stop( true );
13652                 this._hide( tooltip, this.options.hide, function() {
13653                         that._removeTooltip( $( this ) );
13654                 });
13656                 target.removeData( "ui-tooltip-open" );
13657                 this._off( target, "mouseleave focusout keyup" );
13659                 // Remove 'remove' binding only on delegated targets
13660                 if ( target[ 0 ] !== this.element[ 0 ] ) {
13661                         this._off( target, "remove" );
13662                 }
13663                 this._off( this.document, "mousemove" );
13665                 if ( event && event.type === "mouseleave" ) {
13666                         $.each( this.parents, function( id, parent ) {
13667                                 $( parent.element ).attr( "title", parent.title );
13668                                 delete that.parents[ id ];
13669                         });
13670                 }
13672                 this.closing = true;
13673                 this._trigger( "close", event, { tooltip: tooltip } );
13674                 this.closing = false;
13675         },
13677         _tooltip: function( element ) {
13678                 var tooltip = $( "<div>" )
13679                                 .attr( "role", "tooltip" )
13680                                 .addClass( "ui-tooltip ui-widget ui-corner-all ui-widget-content " +
13681                                         ( this.options.tooltipClass || "" ) ),
13682                         id = tooltip.uniqueId().attr( "id" );
13684                 $( "<div>" )
13685                         .addClass( "ui-tooltip-content" )
13686                         .appendTo( tooltip );
13688                 tooltip.appendTo( this.document[0].body );
13689                 this.tooltips[ id ] = element;
13690                 return tooltip;
13691         },
13693         _find: function( target ) {
13694                 var id = target.data( "ui-tooltip-id" );
13695                 return id ? $( "#" + id ) : $();
13696         },
13698         _removeTooltip: function( tooltip ) {
13699                 tooltip.remove();
13700                 delete this.tooltips[ tooltip.attr( "id" ) ];
13701         },
13703         _destroy: function() {
13704                 var that = this;
13706                 // close open tooltips
13707                 $.each( this.tooltips, function( id, element ) {
13708                         // Delegate to close method to handle common cleanup
13709                         var event = $.Event( "blur" );
13710                         event.target = event.currentTarget = element[0];
13711                         that.close( event, true );
13713                         // Remove immediately; destroying an open tooltip doesn't use the
13714                         // hide animation
13715                         $( "#" + id ).remove();
13717                         // Restore the title
13718                         if ( element.data( "ui-tooltip-title" ) ) {
13719                                 // If the title attribute has changed since open(), don't restore
13720                                 if ( !element.attr( "title" ) ) {
13721                                         element.attr( "title", element.data( "ui-tooltip-title" ) );
13722                                 }
13723                                 element.removeData( "ui-tooltip-title" );
13724                         }
13725                 });
13726                 this.liveRegion.remove();
13727         }
13732  * jQuery UI Effects 1.11.0
13733  * http://jqueryui.com
13735  * Copyright 2014 jQuery Foundation and other contributors
13736  * Released under the MIT license.
13737  * http://jquery.org/license
13739  * http://api.jqueryui.com/category/effects-core/
13740  */
13743 var dataSpace = "ui-effects-";
13745 $.effects = {
13746         effect: {}
13750  * jQuery Color Animations v2.1.2
13751  * https://github.com/jquery/jquery-color
13753  * Copyright 2014 jQuery Foundation and other contributors
13754  * Released under the MIT license.
13755  * http://jquery.org/license
13757  * Date: Wed Jan 16 08:47:09 2013 -0600
13758  */
13759 (function( jQuery, undefined ) {
13761         var stepHooks = "backgroundColor borderBottomColor borderLeftColor borderRightColor borderTopColor color columnRuleColor outlineColor textDecorationColor textEmphasisColor",
13763         // plusequals test for += 100 -= 100
13764         rplusequals = /^([\-+])=\s*(\d+\.?\d*)/,
13765         // a set of RE's that can match strings and generate color tuples.
13766         stringParsers = [ {
13767                         re: /rgba?\(\s*(\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(\d{1,3})\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/,
13768                         parse: function( execResult ) {
13769                                 return [
13770                                         execResult[ 1 ],
13771                                         execResult[ 2 ],
13772                                         execResult[ 3 ],
13773                                         execResult[ 4 ]
13774                                 ];
13775                         }
13776                 }, {
13777                         re: /rgba?\(\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/,
13778                         parse: function( execResult ) {
13779                                 return [
13780                                         execResult[ 1 ] * 2.55,
13781                                         execResult[ 2 ] * 2.55,
13782                                         execResult[ 3 ] * 2.55,
13783                                         execResult[ 4 ]
13784                                 ];
13785                         }
13786                 }, {
13787                         // this regex ignores A-F because it's compared against an already lowercased string
13788                         re: /#([a-f0-9]{2})([a-f0-9]{2})([a-f0-9]{2})/,
13789                         parse: function( execResult ) {
13790                                 return [
13791                                         parseInt( execResult[ 1 ], 16 ),
13792                                         parseInt( execResult[ 2 ], 16 ),
13793                                         parseInt( execResult[ 3 ], 16 )
13794                                 ];
13795                         }
13796                 }, {
13797                         // this regex ignores A-F because it's compared against an already lowercased string
13798                         re: /#([a-f0-9])([a-f0-9])([a-f0-9])/,
13799                         parse: function( execResult ) {
13800                                 return [
13801                                         parseInt( execResult[ 1 ] + execResult[ 1 ], 16 ),
13802                                         parseInt( execResult[ 2 ] + execResult[ 2 ], 16 ),
13803                                         parseInt( execResult[ 3 ] + execResult[ 3 ], 16 )
13804                                 ];
13805                         }
13806                 }, {
13807                         re: /hsla?\(\s*(\d+(?:\.\d+)?)\s*,\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/,
13808                         space: "hsla",
13809                         parse: function( execResult ) {
13810                                 return [
13811                                         execResult[ 1 ],
13812                                         execResult[ 2 ] / 100,
13813                                         execResult[ 3 ] / 100,
13814                                         execResult[ 4 ]
13815                                 ];
13816                         }
13817                 } ],
13819         // jQuery.Color( )
13820         color = jQuery.Color = function( color, green, blue, alpha ) {
13821                 return new jQuery.Color.fn.parse( color, green, blue, alpha );
13822         },
13823         spaces = {
13824                 rgba: {
13825                         props: {
13826                                 red: {
13827                                         idx: 0,
13828                                         type: "byte"
13829                                 },
13830                                 green: {
13831                                         idx: 1,
13832                                         type: "byte"
13833                                 },
13834                                 blue: {
13835                                         idx: 2,
13836                                         type: "byte"
13837                                 }
13838                         }
13839                 },
13841                 hsla: {
13842                         props: {
13843                                 hue: {
13844                                         idx: 0,
13845                                         type: "degrees"
13846                                 },
13847                                 saturation: {
13848                                         idx: 1,
13849                                         type: "percent"
13850                                 },
13851                                 lightness: {
13852                                         idx: 2,
13853                                         type: "percent"
13854                                 }
13855                         }
13856                 }
13857         },
13858         propTypes = {
13859                 "byte": {
13860                         floor: true,
13861                         max: 255
13862                 },
13863                 "percent": {
13864                         max: 1
13865                 },
13866                 "degrees": {
13867                         mod: 360,
13868                         floor: true
13869                 }
13870         },
13871         support = color.support = {},
13873         // element for support tests
13874         supportElem = jQuery( "<p>" )[ 0 ],
13876         // colors = jQuery.Color.names
13877         colors,
13879         // local aliases of functions called often
13880         each = jQuery.each;
13882 // determine rgba support immediately
13883 supportElem.style.cssText = "background-color:rgba(1,1,1,.5)";
13884 support.rgba = supportElem.style.backgroundColor.indexOf( "rgba" ) > -1;
13886 // define cache name and alpha properties
13887 // for rgba and hsla spaces
13888 each( spaces, function( spaceName, space ) {
13889         space.cache = "_" + spaceName;
13890         space.props.alpha = {
13891                 idx: 3,
13892                 type: "percent",
13893                 def: 1
13894         };
13897 function clamp( value, prop, allowEmpty ) {
13898         var type = propTypes[ prop.type ] || {};
13900         if ( value == null ) {
13901                 return (allowEmpty || !prop.def) ? null : prop.def;
13902         }
13904         // ~~ is an short way of doing floor for positive numbers
13905         value = type.floor ? ~~value : parseFloat( value );
13907         // IE will pass in empty strings as value for alpha,
13908         // which will hit this case
13909         if ( isNaN( value ) ) {
13910                 return prop.def;
13911         }
13913         if ( type.mod ) {
13914                 // we add mod before modding to make sure that negatives values
13915                 // get converted properly: -10 -> 350
13916                 return (value + type.mod) % type.mod;
13917         }
13919         // for now all property types without mod have min and max
13920         return 0 > value ? 0 : type.max < value ? type.max : value;
13923 function stringParse( string ) {
13924         var inst = color(),
13925                 rgba = inst._rgba = [];
13927         string = string.toLowerCase();
13929         each( stringParsers, function( i, parser ) {
13930                 var parsed,
13931                         match = parser.re.exec( string ),
13932                         values = match && parser.parse( match ),
13933                         spaceName = parser.space || "rgba";
13935                 if ( values ) {
13936                         parsed = inst[ spaceName ]( values );
13938                         // if this was an rgba parse the assignment might happen twice
13939                         // oh well....
13940                         inst[ spaces[ spaceName ].cache ] = parsed[ spaces[ spaceName ].cache ];
13941                         rgba = inst._rgba = parsed._rgba;
13943                         // exit each( stringParsers ) here because we matched
13944                         return false;
13945                 }
13946         });
13948         // Found a stringParser that handled it
13949         if ( rgba.length ) {
13951                 // if this came from a parsed string, force "transparent" when alpha is 0
13952                 // chrome, (and maybe others) return "transparent" as rgba(0,0,0,0)
13953                 if ( rgba.join() === "0,0,0,0" ) {
13954                         jQuery.extend( rgba, colors.transparent );
13955                 }
13956                 return inst;
13957         }
13959         // named colors
13960         return colors[ string ];
13963 color.fn = jQuery.extend( color.prototype, {
13964         parse: function( red, green, blue, alpha ) {
13965                 if ( red === undefined ) {
13966                         this._rgba = [ null, null, null, null ];
13967                         return this;
13968                 }
13969                 if ( red.jquery || red.nodeType ) {
13970                         red = jQuery( red ).css( green );
13971                         green = undefined;
13972                 }
13974                 var inst = this,
13975                         type = jQuery.type( red ),
13976                         rgba = this._rgba = [];
13978                 // more than 1 argument specified - assume ( red, green, blue, alpha )
13979                 if ( green !== undefined ) {
13980                         red = [ red, green, blue, alpha ];
13981                         type = "array";
13982                 }
13984                 if ( type === "string" ) {
13985                         return this.parse( stringParse( red ) || colors._default );
13986                 }
13988                 if ( type === "array" ) {
13989                         each( spaces.rgba.props, function( key, prop ) {
13990                                 rgba[ prop.idx ] = clamp( red[ prop.idx ], prop );
13991                         });
13992                         return this;
13993                 }
13995                 if ( type === "object" ) {
13996                         if ( red instanceof color ) {
13997                                 each( spaces, function( spaceName, space ) {
13998                                         if ( red[ space.cache ] ) {
13999                                                 inst[ space.cache ] = red[ space.cache ].slice();
14000                                         }
14001                                 });
14002                         } else {
14003                                 each( spaces, function( spaceName, space ) {
14004                                         var cache = space.cache;
14005                                         each( space.props, function( key, prop ) {
14007                                                 // if the cache doesn't exist, and we know how to convert
14008                                                 if ( !inst[ cache ] && space.to ) {
14010                                                         // if the value was null, we don't need to copy it
14011                                                         // if the key was alpha, we don't need to copy it either
14012                                                         if ( key === "alpha" || red[ key ] == null ) {
14013                                                                 return;
14014                                                         }
14015                                                         inst[ cache ] = space.to( inst._rgba );
14016                                                 }
14018                                                 // this is the only case where we allow nulls for ALL properties.
14019                                                 // call clamp with alwaysAllowEmpty
14020                                                 inst[ cache ][ prop.idx ] = clamp( red[ key ], prop, true );
14021                                         });
14023                                         // everything defined but alpha?
14024                                         if ( inst[ cache ] && jQuery.inArray( null, inst[ cache ].slice( 0, 3 ) ) < 0 ) {
14025                                                 // use the default of 1
14026                                                 inst[ cache ][ 3 ] = 1;
14027                                                 if ( space.from ) {
14028                                                         inst._rgba = space.from( inst[ cache ] );
14029                                                 }
14030                                         }
14031                                 });
14032                         }
14033                         return this;
14034                 }
14035         },
14036         is: function( compare ) {
14037                 var is = color( compare ),
14038                         same = true,
14039                         inst = this;
14041                 each( spaces, function( _, space ) {
14042                         var localCache,
14043                                 isCache = is[ space.cache ];
14044                         if (isCache) {
14045                                 localCache = inst[ space.cache ] || space.to && space.to( inst._rgba ) || [];
14046                                 each( space.props, function( _, prop ) {
14047                                         if ( isCache[ prop.idx ] != null ) {
14048                                                 same = ( isCache[ prop.idx ] === localCache[ prop.idx ] );
14049                                                 return same;
14050                                         }
14051                                 });
14052                         }
14053                         return same;
14054                 });
14055                 return same;
14056         },
14057         _space: function() {
14058                 var used = [],
14059                         inst = this;
14060                 each( spaces, function( spaceName, space ) {
14061                         if ( inst[ space.cache ] ) {
14062                                 used.push( spaceName );
14063                         }
14064                 });
14065                 return used.pop();
14066         },
14067         transition: function( other, distance ) {
14068                 var end = color( other ),
14069                         spaceName = end._space(),
14070                         space = spaces[ spaceName ],
14071                         startColor = this.alpha() === 0 ? color( "transparent" ) : this,
14072                         start = startColor[ space.cache ] || space.to( startColor._rgba ),
14073                         result = start.slice();
14075                 end = end[ space.cache ];
14076                 each( space.props, function( key, prop ) {
14077                         var index = prop.idx,
14078                                 startValue = start[ index ],
14079                                 endValue = end[ index ],
14080                                 type = propTypes[ prop.type ] || {};
14082                         // if null, don't override start value
14083                         if ( endValue === null ) {
14084                                 return;
14085                         }
14086                         // if null - use end
14087                         if ( startValue === null ) {
14088                                 result[ index ] = endValue;
14089                         } else {
14090                                 if ( type.mod ) {
14091                                         if ( endValue - startValue > type.mod / 2 ) {
14092                                                 startValue += type.mod;
14093                                         } else if ( startValue - endValue > type.mod / 2 ) {
14094                                                 startValue -= type.mod;
14095                                         }
14096                                 }
14097                                 result[ index ] = clamp( ( endValue - startValue ) * distance + startValue, prop );
14098                         }
14099                 });
14100                 return this[ spaceName ]( result );
14101         },
14102         blend: function( opaque ) {
14103                 // if we are already opaque - return ourself
14104                 if ( this._rgba[ 3 ] === 1 ) {
14105                         return this;
14106                 }
14108                 var rgb = this._rgba.slice(),
14109                         a = rgb.pop(),
14110                         blend = color( opaque )._rgba;
14112                 return color( jQuery.map( rgb, function( v, i ) {
14113                         return ( 1 - a ) * blend[ i ] + a * v;
14114                 }));
14115         },
14116         toRgbaString: function() {
14117                 var prefix = "rgba(",
14118                         rgba = jQuery.map( this._rgba, function( v, i ) {
14119                                 return v == null ? ( i > 2 ? 1 : 0 ) : v;
14120                         });
14122                 if ( rgba[ 3 ] === 1 ) {
14123                         rgba.pop();
14124                         prefix = "rgb(";
14125                 }
14127                 return prefix + rgba.join() + ")";
14128         },
14129         toHslaString: function() {
14130                 var prefix = "hsla(",
14131                         hsla = jQuery.map( this.hsla(), function( v, i ) {
14132                                 if ( v == null ) {
14133                                         v = i > 2 ? 1 : 0;
14134                                 }
14136                                 // catch 1 and 2
14137                                 if ( i && i < 3 ) {
14138                                         v = Math.round( v * 100 ) + "%";
14139                                 }
14140                                 return v;
14141                         });
14143                 if ( hsla[ 3 ] === 1 ) {
14144                         hsla.pop();
14145                         prefix = "hsl(";
14146                 }
14147                 return prefix + hsla.join() + ")";
14148         },
14149         toHexString: function( includeAlpha ) {
14150                 var rgba = this._rgba.slice(),
14151                         alpha = rgba.pop();
14153                 if ( includeAlpha ) {
14154                         rgba.push( ~~( alpha * 255 ) );
14155                 }
14157                 return "#" + jQuery.map( rgba, function( v ) {
14159                         // default to 0 when nulls exist
14160                         v = ( v || 0 ).toString( 16 );
14161                         return v.length === 1 ? "0" + v : v;
14162                 }).join("");
14163         },
14164         toString: function() {
14165                 return this._rgba[ 3 ] === 0 ? "transparent" : this.toRgbaString();
14166         }
14168 color.fn.parse.prototype = color.fn;
14170 // hsla conversions adapted from:
14171 // https://code.google.com/p/maashaack/source/browse/packages/graphics/trunk/src/graphics/colors/HUE2RGB.as?r=5021
14173 function hue2rgb( p, q, h ) {
14174         h = ( h + 1 ) % 1;
14175         if ( h * 6 < 1 ) {
14176                 return p + ( q - p ) * h * 6;
14177         }
14178         if ( h * 2 < 1) {
14179                 return q;
14180         }
14181         if ( h * 3 < 2 ) {
14182                 return p + ( q - p ) * ( ( 2 / 3 ) - h ) * 6;
14183         }
14184         return p;
14187 spaces.hsla.to = function( rgba ) {
14188         if ( rgba[ 0 ] == null || rgba[ 1 ] == null || rgba[ 2 ] == null ) {
14189                 return [ null, null, null, rgba[ 3 ] ];
14190         }
14191         var r = rgba[ 0 ] / 255,
14192                 g = rgba[ 1 ] / 255,
14193                 b = rgba[ 2 ] / 255,
14194                 a = rgba[ 3 ],
14195                 max = Math.max( r, g, b ),
14196                 min = Math.min( r, g, b ),
14197                 diff = max - min,
14198                 add = max + min,
14199                 l = add * 0.5,
14200                 h, s;
14202         if ( min === max ) {
14203                 h = 0;
14204         } else if ( r === max ) {
14205                 h = ( 60 * ( g - b ) / diff ) + 360;
14206         } else if ( g === max ) {
14207                 h = ( 60 * ( b - r ) / diff ) + 120;
14208         } else {
14209                 h = ( 60 * ( r - g ) / diff ) + 240;
14210         }
14212         // chroma (diff) == 0 means greyscale which, by definition, saturation = 0%
14213         // otherwise, saturation is based on the ratio of chroma (diff) to lightness (add)
14214         if ( diff === 0 ) {
14215                 s = 0;
14216         } else if ( l <= 0.5 ) {
14217                 s = diff / add;
14218         } else {
14219                 s = diff / ( 2 - add );
14220         }
14221         return [ Math.round(h) % 360, s, l, a == null ? 1 : a ];
14224 spaces.hsla.from = function( hsla ) {
14225         if ( hsla[ 0 ] == null || hsla[ 1 ] == null || hsla[ 2 ] == null ) {
14226                 return [ null, null, null, hsla[ 3 ] ];
14227         }
14228         var h = hsla[ 0 ] / 360,
14229                 s = hsla[ 1 ],
14230                 l = hsla[ 2 ],
14231                 a = hsla[ 3 ],
14232                 q = l <= 0.5 ? l * ( 1 + s ) : l + s - l * s,
14233                 p = 2 * l - q;
14235         return [
14236                 Math.round( hue2rgb( p, q, h + ( 1 / 3 ) ) * 255 ),
14237                 Math.round( hue2rgb( p, q, h ) * 255 ),
14238                 Math.round( hue2rgb( p, q, h - ( 1 / 3 ) ) * 255 ),
14239                 a
14240         ];
14243 each( spaces, function( spaceName, space ) {
14244         var props = space.props,
14245                 cache = space.cache,
14246                 to = space.to,
14247                 from = space.from;
14249         // makes rgba() and hsla()
14250         color.fn[ spaceName ] = function( value ) {
14252                 // generate a cache for this space if it doesn't exist
14253                 if ( to && !this[ cache ] ) {
14254                         this[ cache ] = to( this._rgba );
14255                 }
14256                 if ( value === undefined ) {
14257                         return this[ cache ].slice();
14258                 }
14260                 var ret,
14261                         type = jQuery.type( value ),
14262                         arr = ( type === "array" || type === "object" ) ? value : arguments,
14263                         local = this[ cache ].slice();
14265                 each( props, function( key, prop ) {
14266                         var val = arr[ type === "object" ? key : prop.idx ];
14267                         if ( val == null ) {
14268                                 val = local[ prop.idx ];
14269                         }
14270                         local[ prop.idx ] = clamp( val, prop );
14271                 });
14273                 if ( from ) {
14274                         ret = color( from( local ) );
14275                         ret[ cache ] = local;
14276                         return ret;
14277                 } else {
14278                         return color( local );
14279                 }
14280         };
14282         // makes red() green() blue() alpha() hue() saturation() lightness()
14283         each( props, function( key, prop ) {
14284                 // alpha is included in more than one space
14285                 if ( color.fn[ key ] ) {
14286                         return;
14287                 }
14288                 color.fn[ key ] = function( value ) {
14289                         var vtype = jQuery.type( value ),
14290                                 fn = ( key === "alpha" ? ( this._hsla ? "hsla" : "rgba" ) : spaceName ),
14291                                 local = this[ fn ](),
14292                                 cur = local[ prop.idx ],
14293                                 match;
14295                         if ( vtype === "undefined" ) {
14296                                 return cur;
14297                         }
14299                         if ( vtype === "function" ) {
14300                                 value = value.call( this, cur );
14301                                 vtype = jQuery.type( value );
14302                         }
14303                         if ( value == null && prop.empty ) {
14304                                 return this;
14305                         }
14306                         if ( vtype === "string" ) {
14307                                 match = rplusequals.exec( value );
14308                                 if ( match ) {
14309                                         value = cur + parseFloat( match[ 2 ] ) * ( match[ 1 ] === "+" ? 1 : -1 );
14310                                 }
14311                         }
14312                         local[ prop.idx ] = value;
14313                         return this[ fn ]( local );
14314                 };
14315         });
14318 // add cssHook and .fx.step function for each named hook.
14319 // accept a space separated string of properties
14320 color.hook = function( hook ) {
14321         var hooks = hook.split( " " );
14322         each( hooks, function( i, hook ) {
14323                 jQuery.cssHooks[ hook ] = {
14324                         set: function( elem, value ) {
14325                                 var parsed, curElem,
14326                                         backgroundColor = "";
14328                                 if ( value !== "transparent" && ( jQuery.type( value ) !== "string" || ( parsed = stringParse( value ) ) ) ) {
14329                                         value = color( parsed || value );
14330                                         if ( !support.rgba && value._rgba[ 3 ] !== 1 ) {
14331                                                 curElem = hook === "backgroundColor" ? elem.parentNode : elem;
14332                                                 while (
14333                                                         (backgroundColor === "" || backgroundColor === "transparent") &&
14334                                                         curElem && curElem.style
14335                                                 ) {
14336                                                         try {
14337                                                                 backgroundColor = jQuery.css( curElem, "backgroundColor" );
14338                                                                 curElem = curElem.parentNode;
14339                                                         } catch ( e ) {
14340                                                         }
14341                                                 }
14343                                                 value = value.blend( backgroundColor && backgroundColor !== "transparent" ?
14344                                                         backgroundColor :
14345                                                         "_default" );
14346                                         }
14348                                         value = value.toRgbaString();
14349                                 }
14350                                 try {
14351                                         elem.style[ hook ] = value;
14352                                 } catch( e ) {
14353                                         // wrapped to prevent IE from throwing errors on "invalid" values like 'auto' or 'inherit'
14354                                 }
14355                         }
14356                 };
14357                 jQuery.fx.step[ hook ] = function( fx ) {
14358                         if ( !fx.colorInit ) {
14359                                 fx.start = color( fx.elem, hook );
14360                                 fx.end = color( fx.end );
14361                                 fx.colorInit = true;
14362                         }
14363                         jQuery.cssHooks[ hook ].set( fx.elem, fx.start.transition( fx.end, fx.pos ) );
14364                 };
14365         });
14369 color.hook( stepHooks );
14371 jQuery.cssHooks.borderColor = {
14372         expand: function( value ) {
14373                 var expanded = {};
14375                 each( [ "Top", "Right", "Bottom", "Left" ], function( i, part ) {
14376                         expanded[ "border" + part + "Color" ] = value;
14377                 });
14378                 return expanded;
14379         }
14382 // Basic color names only.
14383 // Usage of any of the other color names requires adding yourself or including
14384 // jquery.color.svg-names.js.
14385 colors = jQuery.Color.names = {
14386         // 4.1. Basic color keywords
14387         aqua: "#00ffff",
14388         black: "#000000",
14389         blue: "#0000ff",
14390         fuchsia: "#ff00ff",
14391         gray: "#808080",
14392         green: "#008000",
14393         lime: "#00ff00",
14394         maroon: "#800000",
14395         navy: "#000080",
14396         olive: "#808000",
14397         purple: "#800080",
14398         red: "#ff0000",
14399         silver: "#c0c0c0",
14400         teal: "#008080",
14401         white: "#ffffff",
14402         yellow: "#ffff00",
14404         // 4.2.3. "transparent" color keyword
14405         transparent: [ null, null, null, 0 ],
14407         _default: "#ffffff"
14410 })( jQuery );
14412 /******************************************************************************/
14413 /****************************** CLASS ANIMATIONS ******************************/
14414 /******************************************************************************/
14415 (function() {
14417 var classAnimationActions = [ "add", "remove", "toggle" ],
14418         shorthandStyles = {
14419                 border: 1,
14420                 borderBottom: 1,
14421                 borderColor: 1,
14422                 borderLeft: 1,
14423                 borderRight: 1,
14424                 borderTop: 1,
14425                 borderWidth: 1,
14426                 margin: 1,
14427                 padding: 1
14428         };
14430 $.each([ "borderLeftStyle", "borderRightStyle", "borderBottomStyle", "borderTopStyle" ], function( _, prop ) {
14431         $.fx.step[ prop ] = function( fx ) {
14432                 if ( fx.end !== "none" && !fx.setAttr || fx.pos === 1 && !fx.setAttr ) {
14433                         jQuery.style( fx.elem, prop, fx.end );
14434                         fx.setAttr = true;
14435                 }
14436         };
14439 function getElementStyles( elem ) {
14440         var key, len,
14441                 style = elem.ownerDocument.defaultView ?
14442                         elem.ownerDocument.defaultView.getComputedStyle( elem, null ) :
14443                         elem.currentStyle,
14444                 styles = {};
14446         if ( style && style.length && style[ 0 ] && style[ style[ 0 ] ] ) {
14447                 len = style.length;
14448                 while ( len-- ) {
14449                         key = style[ len ];
14450                         if ( typeof style[ key ] === "string" ) {
14451                                 styles[ $.camelCase( key ) ] = style[ key ];
14452                         }
14453                 }
14454         // support: Opera, IE <9
14455         } else {
14456                 for ( key in style ) {
14457                         if ( typeof style[ key ] === "string" ) {
14458                                 styles[ key ] = style[ key ];
14459                         }
14460                 }
14461         }
14463         return styles;
14466 function styleDifference( oldStyle, newStyle ) {
14467         var diff = {},
14468                 name, value;
14470         for ( name in newStyle ) {
14471                 value = newStyle[ name ];
14472                 if ( oldStyle[ name ] !== value ) {
14473                         if ( !shorthandStyles[ name ] ) {
14474                                 if ( $.fx.step[ name ] || !isNaN( parseFloat( value ) ) ) {
14475                                         diff[ name ] = value;
14476                                 }
14477                         }
14478                 }
14479         }
14481         return diff;
14484 // support: jQuery <1.8
14485 if ( !$.fn.addBack ) {
14486         $.fn.addBack = function( selector ) {
14487                 return this.add( selector == null ?
14488                         this.prevObject : this.prevObject.filter( selector )
14489                 );
14490         };
14493 $.effects.animateClass = function( value, duration, easing, callback ) {
14494         var o = $.speed( duration, easing, callback );
14496         return this.queue( function() {
14497                 var animated = $( this ),
14498                         baseClass = animated.attr( "class" ) || "",
14499                         applyClassChange,
14500                         allAnimations = o.children ? animated.find( "*" ).addBack() : animated;
14502                 // map the animated objects to store the original styles.
14503                 allAnimations = allAnimations.map(function() {
14504                         var el = $( this );
14505                         return {
14506                                 el: el,
14507                                 start: getElementStyles( this )
14508                         };
14509                 });
14511                 // apply class change
14512                 applyClassChange = function() {
14513                         $.each( classAnimationActions, function(i, action) {
14514                                 if ( value[ action ] ) {
14515                                         animated[ action + "Class" ]( value[ action ] );
14516                                 }
14517                         });
14518                 };
14519                 applyClassChange();
14521                 // map all animated objects again - calculate new styles and diff
14522                 allAnimations = allAnimations.map(function() {
14523                         this.end = getElementStyles( this.el[ 0 ] );
14524                         this.diff = styleDifference( this.start, this.end );
14525                         return this;
14526                 });
14528                 // apply original class
14529                 animated.attr( "class", baseClass );
14531                 // map all animated objects again - this time collecting a promise
14532                 allAnimations = allAnimations.map(function() {
14533                         var styleInfo = this,
14534                                 dfd = $.Deferred(),
14535                                 opts = $.extend({}, o, {
14536                                         queue: false,
14537                                         complete: function() {
14538                                                 dfd.resolve( styleInfo );
14539                                         }
14540                                 });
14542                         this.el.animate( this.diff, opts );
14543                         return dfd.promise();
14544                 });
14546                 // once all animations have completed:
14547                 $.when.apply( $, allAnimations.get() ).done(function() {
14549                         // set the final class
14550                         applyClassChange();
14552                         // for each animated element,
14553                         // clear all css properties that were animated
14554                         $.each( arguments, function() {
14555                                 var el = this.el;
14556                                 $.each( this.diff, function(key) {
14557                                         el.css( key, "" );
14558                                 });
14559                         });
14561                         // this is guarnteed to be there if you use jQuery.speed()
14562                         // it also handles dequeuing the next anim...
14563                         o.complete.call( animated[ 0 ] );
14564                 });
14565         });
14568 $.fn.extend({
14569         addClass: (function( orig ) {
14570                 return function( classNames, speed, easing, callback ) {
14571                         return speed ?
14572                                 $.effects.animateClass.call( this,
14573                                         { add: classNames }, speed, easing, callback ) :
14574                                 orig.apply( this, arguments );
14575                 };
14576         })( $.fn.addClass ),
14578         removeClass: (function( orig ) {
14579                 return function( classNames, speed, easing, callback ) {
14580                         return arguments.length > 1 ?
14581                                 $.effects.animateClass.call( this,
14582                                         { remove: classNames }, speed, easing, callback ) :
14583                                 orig.apply( this, arguments );
14584                 };
14585         })( $.fn.removeClass ),
14587         toggleClass: (function( orig ) {
14588                 return function( classNames, force, speed, easing, callback ) {
14589                         if ( typeof force === "boolean" || force === undefined ) {
14590                                 if ( !speed ) {
14591                                         // without speed parameter
14592                                         return orig.apply( this, arguments );
14593                                 } else {
14594                                         return $.effects.animateClass.call( this,
14595                                                 (force ? { add: classNames } : { remove: classNames }),
14596                                                 speed, easing, callback );
14597                                 }
14598                         } else {
14599                                 // without force parameter
14600                                 return $.effects.animateClass.call( this,
14601                                         { toggle: classNames }, force, speed, easing );
14602                         }
14603                 };
14604         })( $.fn.toggleClass ),
14606         switchClass: function( remove, add, speed, easing, callback) {
14607                 return $.effects.animateClass.call( this, {
14608                         add: add,
14609                         remove: remove
14610                 }, speed, easing, callback );
14611         }
14614 })();
14616 /******************************************************************************/
14617 /*********************************** EFFECTS **********************************/
14618 /******************************************************************************/
14620 (function() {
14622 $.extend( $.effects, {
14623         version: "1.11.0",
14625         // Saves a set of properties in a data storage
14626         save: function( element, set ) {
14627                 for ( var i = 0; i < set.length; i++ ) {
14628                         if ( set[ i ] !== null ) {
14629                                 element.data( dataSpace + set[ i ], element[ 0 ].style[ set[ i ] ] );
14630                         }
14631                 }
14632         },
14634         // Restores a set of previously saved properties from a data storage
14635         restore: function( element, set ) {
14636                 var val, i;
14637                 for ( i = 0; i < set.length; i++ ) {
14638                         if ( set[ i ] !== null ) {
14639                                 val = element.data( dataSpace + set[ i ] );
14640                                 // support: jQuery 1.6.2
14641                                 // http://bugs.jquery.com/ticket/9917
14642                                 // jQuery 1.6.2 incorrectly returns undefined for any falsy value.
14643                                 // We can't differentiate between "" and 0 here, so we just assume
14644                                 // empty string since it's likely to be a more common value...
14645                                 if ( val === undefined ) {
14646                                         val = "";
14647                                 }
14648                                 element.css( set[ i ], val );
14649                         }
14650                 }
14651         },
14653         setMode: function( el, mode ) {
14654                 if (mode === "toggle") {
14655                         mode = el.is( ":hidden" ) ? "show" : "hide";
14656                 }
14657                 return mode;
14658         },
14660         // Translates a [top,left] array into a baseline value
14661         // this should be a little more flexible in the future to handle a string & hash
14662         getBaseline: function( origin, original ) {
14663                 var y, x;
14664                 switch ( origin[ 0 ] ) {
14665                         case "top": y = 0; break;
14666                         case "middle": y = 0.5; break;
14667                         case "bottom": y = 1; break;
14668                         default: y = origin[ 0 ] / original.height;
14669                 }
14670                 switch ( origin[ 1 ] ) {
14671                         case "left": x = 0; break;
14672                         case "center": x = 0.5; break;
14673                         case "right": x = 1; break;
14674                         default: x = origin[ 1 ] / original.width;
14675                 }
14676                 return {
14677                         x: x,
14678                         y: y
14679                 };
14680         },
14682         // Wraps the element around a wrapper that copies position properties
14683         createWrapper: function( element ) {
14685                 // if the element is already wrapped, return it
14686                 if ( element.parent().is( ".ui-effects-wrapper" )) {
14687                         return element.parent();
14688                 }
14690                 // wrap the element
14691                 var props = {
14692                                 width: element.outerWidth(true),
14693                                 height: element.outerHeight(true),
14694                                 "float": element.css( "float" )
14695                         },
14696                         wrapper = $( "<div></div>" )
14697                                 .addClass( "ui-effects-wrapper" )
14698                                 .css({
14699                                         fontSize: "100%",
14700                                         background: "transparent",
14701                                         border: "none",
14702                                         margin: 0,
14703                                         padding: 0
14704                                 }),
14705                         // Store the size in case width/height are defined in % - Fixes #5245
14706                         size = {
14707                                 width: element.width(),
14708                                 height: element.height()
14709                         },
14710                         active = document.activeElement;
14712                 // support: Firefox
14713                 // Firefox incorrectly exposes anonymous content
14714                 // https://bugzilla.mozilla.org/show_bug.cgi?id=561664
14715                 try {
14716                         active.id;
14717                 } catch( e ) {
14718                         active = document.body;
14719                 }
14721                 element.wrap( wrapper );
14723                 // Fixes #7595 - Elements lose focus when wrapped.
14724                 if ( element[ 0 ] === active || $.contains( element[ 0 ], active ) ) {
14725                         $( active ).focus();
14726                 }
14728                 wrapper = element.parent(); //Hotfix for jQuery 1.4 since some change in wrap() seems to actually lose the reference to the wrapped element
14730                 // transfer positioning properties to the wrapper
14731                 if ( element.css( "position" ) === "static" ) {
14732                         wrapper.css({ position: "relative" });
14733                         element.css({ position: "relative" });
14734                 } else {
14735                         $.extend( props, {
14736                                 position: element.css( "position" ),
14737                                 zIndex: element.css( "z-index" )
14738                         });
14739                         $.each([ "top", "left", "bottom", "right" ], function(i, pos) {
14740                                 props[ pos ] = element.css( pos );
14741                                 if ( isNaN( parseInt( props[ pos ], 10 ) ) ) {
14742                                         props[ pos ] = "auto";
14743                                 }
14744                         });
14745                         element.css({
14746                                 position: "relative",
14747                                 top: 0,
14748                                 left: 0,
14749                                 right: "auto",
14750                                 bottom: "auto"
14751                         });
14752                 }
14753                 element.css(size);
14755                 return wrapper.css( props ).show();
14756         },
14758         removeWrapper: function( element ) {
14759                 var active = document.activeElement;
14761                 if ( element.parent().is( ".ui-effects-wrapper" ) ) {
14762                         element.parent().replaceWith( element );
14764                         // Fixes #7595 - Elements lose focus when wrapped.
14765                         if ( element[ 0 ] === active || $.contains( element[ 0 ], active ) ) {
14766                                 $( active ).focus();
14767                         }
14768                 }
14770                 return element;
14771         },
14773         setTransition: function( element, list, factor, value ) {
14774                 value = value || {};
14775                 $.each( list, function( i, x ) {
14776                         var unit = element.cssUnit( x );
14777                         if ( unit[ 0 ] > 0 ) {
14778                                 value[ x ] = unit[ 0 ] * factor + unit[ 1 ];
14779                         }
14780                 });
14781                 return value;
14782         }
14785 // return an effect options object for the given parameters:
14786 function _normalizeArguments( effect, options, speed, callback ) {
14788         // allow passing all options as the first parameter
14789         if ( $.isPlainObject( effect ) ) {
14790                 options = effect;
14791                 effect = effect.effect;
14792         }
14794         // convert to an object
14795         effect = { effect: effect };
14797         // catch (effect, null, ...)
14798         if ( options == null ) {
14799                 options = {};
14800         }
14802         // catch (effect, callback)
14803         if ( $.isFunction( options ) ) {
14804                 callback = options;
14805                 speed = null;
14806                 options = {};
14807         }
14809         // catch (effect, speed, ?)
14810         if ( typeof options === "number" || $.fx.speeds[ options ] ) {
14811                 callback = speed;
14812                 speed = options;
14813                 options = {};
14814         }
14816         // catch (effect, options, callback)
14817         if ( $.isFunction( speed ) ) {
14818                 callback = speed;
14819                 speed = null;
14820         }
14822         // add options to effect
14823         if ( options ) {
14824                 $.extend( effect, options );
14825         }
14827         speed = speed || options.duration;
14828         effect.duration = $.fx.off ? 0 :
14829                 typeof speed === "number" ? speed :
14830                 speed in $.fx.speeds ? $.fx.speeds[ speed ] :
14831                 $.fx.speeds._default;
14833         effect.complete = callback || options.complete;
14835         return effect;
14838 function standardAnimationOption( option ) {
14839         // Valid standard speeds (nothing, number, named speed)
14840         if ( !option || typeof option === "number" || $.fx.speeds[ option ] ) {
14841                 return true;
14842         }
14844         // Invalid strings - treat as "normal" speed
14845         if ( typeof option === "string" && !$.effects.effect[ option ] ) {
14846                 return true;
14847         }
14849         // Complete callback
14850         if ( $.isFunction( option ) ) {
14851                 return true;
14852         }
14854         // Options hash (but not naming an effect)
14855         if ( typeof option === "object" && !option.effect ) {
14856                 return true;
14857         }
14859         // Didn't match any standard API
14860         return false;
14863 $.fn.extend({
14864         effect: function( /* effect, options, speed, callback */ ) {
14865                 var args = _normalizeArguments.apply( this, arguments ),
14866                         mode = args.mode,
14867                         queue = args.queue,
14868                         effectMethod = $.effects.effect[ args.effect ];
14870                 if ( $.fx.off || !effectMethod ) {
14871                         // delegate to the original method (e.g., .show()) if possible
14872                         if ( mode ) {
14873                                 return this[ mode ]( args.duration, args.complete );
14874                         } else {
14875                                 return this.each( function() {
14876                                         if ( args.complete ) {
14877                                                 args.complete.call( this );
14878                                         }
14879                                 });
14880                         }
14881                 }
14883                 function run( next ) {
14884                         var elem = $( this ),
14885                                 complete = args.complete,
14886                                 mode = args.mode;
14888                         function done() {
14889                                 if ( $.isFunction( complete ) ) {
14890                                         complete.call( elem[0] );
14891                                 }
14892                                 if ( $.isFunction( next ) ) {
14893                                         next();
14894                                 }
14895                         }
14897                         // If the element already has the correct final state, delegate to
14898                         // the core methods so the internal tracking of "olddisplay" works.
14899                         if ( elem.is( ":hidden" ) ? mode === "hide" : mode === "show" ) {
14900                                 elem[ mode ]();
14901                                 done();
14902                         } else {
14903                                 effectMethod.call( elem[0], args, done );
14904                         }
14905                 }
14907                 return queue === false ? this.each( run ) : this.queue( queue || "fx", run );
14908         },
14910         show: (function( orig ) {
14911                 return function( option ) {
14912                         if ( standardAnimationOption( option ) ) {
14913                                 return orig.apply( this, arguments );
14914                         } else {
14915                                 var args = _normalizeArguments.apply( this, arguments );
14916                                 args.mode = "show";
14917                                 return this.effect.call( this, args );
14918                         }
14919                 };
14920         })( $.fn.show ),
14922         hide: (function( orig ) {
14923                 return function( option ) {
14924                         if ( standardAnimationOption( option ) ) {
14925                                 return orig.apply( this, arguments );
14926                         } else {
14927                                 var args = _normalizeArguments.apply( this, arguments );
14928                                 args.mode = "hide";
14929                                 return this.effect.call( this, args );
14930                         }
14931                 };
14932         })( $.fn.hide ),
14934         toggle: (function( orig ) {
14935                 return function( option ) {
14936                         if ( standardAnimationOption( option ) || typeof option === "boolean" ) {
14937                                 return orig.apply( this, arguments );
14938                         } else {
14939                                 var args = _normalizeArguments.apply( this, arguments );
14940                                 args.mode = "toggle";
14941                                 return this.effect.call( this, args );
14942                         }
14943                 };
14944         })( $.fn.toggle ),
14946         // helper functions
14947         cssUnit: function(key) {
14948                 var style = this.css( key ),
14949                         val = [];
14951                 $.each( [ "em", "px", "%", "pt" ], function( i, unit ) {
14952                         if ( style.indexOf( unit ) > 0 ) {
14953                                 val = [ parseFloat( style ), unit ];
14954                         }
14955                 });
14956                 return val;
14957         }
14960 })();
14962 /******************************************************************************/
14963 /*********************************** EASING ***********************************/
14964 /******************************************************************************/
14966 (function() {
14968 // based on easing equations from Robert Penner (http://www.robertpenner.com/easing)
14970 var baseEasings = {};
14972 $.each( [ "Quad", "Cubic", "Quart", "Quint", "Expo" ], function( i, name ) {
14973         baseEasings[ name ] = function( p ) {
14974                 return Math.pow( p, i + 2 );
14975         };
14978 $.extend( baseEasings, {
14979         Sine: function( p ) {
14980                 return 1 - Math.cos( p * Math.PI / 2 );
14981         },
14982         Circ: function( p ) {
14983                 return 1 - Math.sqrt( 1 - p * p );
14984         },
14985         Elastic: function( p ) {
14986                 return p === 0 || p === 1 ? p :
14987                         -Math.pow( 2, 8 * (p - 1) ) * Math.sin( ( (p - 1) * 80 - 7.5 ) * Math.PI / 15 );
14988         },
14989         Back: function( p ) {
14990                 return p * p * ( 3 * p - 2 );
14991         },
14992         Bounce: function( p ) {
14993                 var pow2,
14994                         bounce = 4;
14996                 while ( p < ( ( pow2 = Math.pow( 2, --bounce ) ) - 1 ) / 11 ) {}
14997                 return 1 / Math.pow( 4, 3 - bounce ) - 7.5625 * Math.pow( ( pow2 * 3 - 2 ) / 22 - p, 2 );
14998         }
15001 $.each( baseEasings, function( name, easeIn ) {
15002         $.easing[ "easeIn" + name ] = easeIn;
15003         $.easing[ "easeOut" + name ] = function( p ) {
15004                 return 1 - easeIn( 1 - p );
15005         };
15006         $.easing[ "easeInOut" + name ] = function( p ) {
15007                 return p < 0.5 ?
15008                         easeIn( p * 2 ) / 2 :
15009                         1 - easeIn( p * -2 + 2 ) / 2;
15010         };
15013 })();
15015 var effect = $.effects;
15019  * jQuery UI Effects Blind 1.11.0
15020  * http://jqueryui.com
15022  * Copyright 2014 jQuery Foundation and other contributors
15023  * Released under the MIT license.
15024  * http://jquery.org/license
15026  * http://api.jqueryui.com/blind-effect/
15027  */
15030 var effectBlind = $.effects.effect.blind = function( o, done ) {
15031         // Create element
15032         var el = $( this ),
15033                 rvertical = /up|down|vertical/,
15034                 rpositivemotion = /up|left|vertical|horizontal/,
15035                 props = [ "position", "top", "bottom", "left", "right", "height", "width" ],
15036                 mode = $.effects.setMode( el, o.mode || "hide" ),
15037                 direction = o.direction || "up",
15038                 vertical = rvertical.test( direction ),
15039                 ref = vertical ? "height" : "width",
15040                 ref2 = vertical ? "top" : "left",
15041                 motion = rpositivemotion.test( direction ),
15042                 animation = {},
15043                 show = mode === "show",
15044                 wrapper, distance, margin;
15046         // if already wrapped, the wrapper's properties are my property. #6245
15047         if ( el.parent().is( ".ui-effects-wrapper" ) ) {
15048                 $.effects.save( el.parent(), props );
15049         } else {
15050                 $.effects.save( el, props );
15051         }
15052         el.show();
15053         wrapper = $.effects.createWrapper( el ).css({
15054                 overflow: "hidden"
15055         });
15057         distance = wrapper[ ref ]();
15058         margin = parseFloat( wrapper.css( ref2 ) ) || 0;
15060         animation[ ref ] = show ? distance : 0;
15061         if ( !motion ) {
15062                 el
15063                         .css( vertical ? "bottom" : "right", 0 )
15064                         .css( vertical ? "top" : "left", "auto" )
15065                         .css({ position: "absolute" });
15067                 animation[ ref2 ] = show ? margin : distance + margin;
15068         }
15070         // start at 0 if we are showing
15071         if ( show ) {
15072                 wrapper.css( ref, 0 );
15073                 if ( !motion ) {
15074                         wrapper.css( ref2, margin + distance );
15075                 }
15076         }
15078         // Animate
15079         wrapper.animate( animation, {
15080                 duration: o.duration,
15081                 easing: o.easing,
15082                 queue: false,
15083                 complete: function() {
15084                         if ( mode === "hide" ) {
15085                                 el.hide();
15086                         }
15087                         $.effects.restore( el, props );
15088                         $.effects.removeWrapper( el );
15089                         done();
15090                 }
15091         });
15096  * jQuery UI Effects Bounce 1.11.0
15097  * http://jqueryui.com
15099  * Copyright 2014 jQuery Foundation and other contributors
15100  * Released under the MIT license.
15101  * http://jquery.org/license
15103  * http://api.jqueryui.com/bounce-effect/
15104  */
15107 var effectBounce = $.effects.effect.bounce = function( o, done ) {
15108         var el = $( this ),
15109                 props = [ "position", "top", "bottom", "left", "right", "height", "width" ],
15111                 // defaults:
15112                 mode = $.effects.setMode( el, o.mode || "effect" ),
15113                 hide = mode === "hide",
15114                 show = mode === "show",
15115                 direction = o.direction || "up",
15116                 distance = o.distance,
15117                 times = o.times || 5,
15119                 // number of internal animations
15120                 anims = times * 2 + ( show || hide ? 1 : 0 ),
15121                 speed = o.duration / anims,
15122                 easing = o.easing,
15124                 // utility:
15125                 ref = ( direction === "up" || direction === "down" ) ? "top" : "left",
15126                 motion = ( direction === "up" || direction === "left" ),
15127                 i,
15128                 upAnim,
15129                 downAnim,
15131                 // we will need to re-assemble the queue to stack our animations in place
15132                 queue = el.queue(),
15133                 queuelen = queue.length;
15135         // Avoid touching opacity to prevent clearType and PNG issues in IE
15136         if ( show || hide ) {
15137                 props.push( "opacity" );
15138         }
15140         $.effects.save( el, props );
15141         el.show();
15142         $.effects.createWrapper( el ); // Create Wrapper
15144         // default distance for the BIGGEST bounce is the outer Distance / 3
15145         if ( !distance ) {
15146                 distance = el[ ref === "top" ? "outerHeight" : "outerWidth" ]() / 3;
15147         }
15149         if ( show ) {
15150                 downAnim = { opacity: 1 };
15151                 downAnim[ ref ] = 0;
15153                 // if we are showing, force opacity 0 and set the initial position
15154                 // then do the "first" animation
15155                 el.css( "opacity", 0 )
15156                         .css( ref, motion ? -distance * 2 : distance * 2 )
15157                         .animate( downAnim, speed, easing );
15158         }
15160         // start at the smallest distance if we are hiding
15161         if ( hide ) {
15162                 distance = distance / Math.pow( 2, times - 1 );
15163         }
15165         downAnim = {};
15166         downAnim[ ref ] = 0;
15167         // Bounces up/down/left/right then back to 0 -- times * 2 animations happen here
15168         for ( i = 0; i < times; i++ ) {
15169                 upAnim = {};
15170                 upAnim[ ref ] = ( motion ? "-=" : "+=" ) + distance;
15172                 el.animate( upAnim, speed, easing )
15173                         .animate( downAnim, speed, easing );
15175                 distance = hide ? distance * 2 : distance / 2;
15176         }
15178         // Last Bounce when Hiding
15179         if ( hide ) {
15180                 upAnim = { opacity: 0 };
15181                 upAnim[ ref ] = ( motion ? "-=" : "+=" ) + distance;
15183                 el.animate( upAnim, speed, easing );
15184         }
15186         el.queue(function() {
15187                 if ( hide ) {
15188                         el.hide();
15189                 }
15190                 $.effects.restore( el, props );
15191                 $.effects.removeWrapper( el );
15192                 done();
15193         });
15195         // inject all the animations we just queued to be first in line (after "inprogress")
15196         if ( queuelen > 1) {
15197                 queue.splice.apply( queue,
15198                         [ 1, 0 ].concat( queue.splice( queuelen, anims + 1 ) ) );
15199         }
15200         el.dequeue();
15206  * jQuery UI Effects Clip 1.11.0
15207  * http://jqueryui.com
15209  * Copyright 2014 jQuery Foundation and other contributors
15210  * Released under the MIT license.
15211  * http://jquery.org/license
15213  * http://api.jqueryui.com/clip-effect/
15214  */
15217 var effectClip = $.effects.effect.clip = function( o, done ) {
15218         // Create element
15219         var el = $( this ),
15220                 props = [ "position", "top", "bottom", "left", "right", "height", "width" ],
15221                 mode = $.effects.setMode( el, o.mode || "hide" ),
15222                 show = mode === "show",
15223                 direction = o.direction || "vertical",
15224                 vert = direction === "vertical",
15225                 size = vert ? "height" : "width",
15226                 position = vert ? "top" : "left",
15227                 animation = {},
15228                 wrapper, animate, distance;
15230         // Save & Show
15231         $.effects.save( el, props );
15232         el.show();
15234         // Create Wrapper
15235         wrapper = $.effects.createWrapper( el ).css({
15236                 overflow: "hidden"
15237         });
15238         animate = ( el[0].tagName === "IMG" ) ? wrapper : el;
15239         distance = animate[ size ]();
15241         // Shift
15242         if ( show ) {
15243                 animate.css( size, 0 );
15244                 animate.css( position, distance / 2 );
15245         }
15247         // Create Animation Object:
15248         animation[ size ] = show ? distance : 0;
15249         animation[ position ] = show ? 0 : distance / 2;
15251         // Animate
15252         animate.animate( animation, {
15253                 queue: false,
15254                 duration: o.duration,
15255                 easing: o.easing,
15256                 complete: function() {
15257                         if ( !show ) {
15258                                 el.hide();
15259                         }
15260                         $.effects.restore( el, props );
15261                         $.effects.removeWrapper( el );
15262                         done();
15263                 }
15264         });
15270  * jQuery UI Effects Drop 1.11.0
15271  * http://jqueryui.com
15273  * Copyright 2014 jQuery Foundation and other contributors
15274  * Released under the MIT license.
15275  * http://jquery.org/license
15277  * http://api.jqueryui.com/drop-effect/
15278  */
15281 var effectDrop = $.effects.effect.drop = function( o, done ) {
15283         var el = $( this ),
15284                 props = [ "position", "top", "bottom", "left", "right", "opacity", "height", "width" ],
15285                 mode = $.effects.setMode( el, o.mode || "hide" ),
15286                 show = mode === "show",
15287                 direction = o.direction || "left",
15288                 ref = ( direction === "up" || direction === "down" ) ? "top" : "left",
15289                 motion = ( direction === "up" || direction === "left" ) ? "pos" : "neg",
15290                 animation = {
15291                         opacity: show ? 1 : 0
15292                 },
15293                 distance;
15295         // Adjust
15296         $.effects.save( el, props );
15297         el.show();
15298         $.effects.createWrapper( el );
15300         distance = o.distance || el[ ref === "top" ? "outerHeight": "outerWidth" ]( true ) / 2;
15302         if ( show ) {
15303                 el
15304                         .css( "opacity", 0 )
15305                         .css( ref, motion === "pos" ? -distance : distance );
15306         }
15308         // Animation
15309         animation[ ref ] = ( show ?
15310                 ( motion === "pos" ? "+=" : "-=" ) :
15311                 ( motion === "pos" ? "-=" : "+=" ) ) +
15312                 distance;
15314         // Animate
15315         el.animate( animation, {
15316                 queue: false,
15317                 duration: o.duration,
15318                 easing: o.easing,
15319                 complete: function() {
15320                         if ( mode === "hide" ) {
15321                                 el.hide();
15322                         }
15323                         $.effects.restore( el, props );
15324                         $.effects.removeWrapper( el );
15325                         done();
15326                 }
15327         });
15332  * jQuery UI Effects Explode 1.11.0
15333  * http://jqueryui.com
15335  * Copyright 2014 jQuery Foundation and other contributors
15336  * Released under the MIT license.
15337  * http://jquery.org/license
15339  * http://api.jqueryui.com/explode-effect/
15340  */
15343 var effectExplode = $.effects.effect.explode = function( o, done ) {
15345         var rows = o.pieces ? Math.round( Math.sqrt( o.pieces ) ) : 3,
15346                 cells = rows,
15347                 el = $( this ),
15348                 mode = $.effects.setMode( el, o.mode || "hide" ),
15349                 show = mode === "show",
15351                 // show and then visibility:hidden the element before calculating offset
15352                 offset = el.show().css( "visibility", "hidden" ).offset(),
15354                 // width and height of a piece
15355                 width = Math.ceil( el.outerWidth() / cells ),
15356                 height = Math.ceil( el.outerHeight() / rows ),
15357                 pieces = [],
15359                 // loop
15360                 i, j, left, top, mx, my;
15362         // children animate complete:
15363         function childComplete() {
15364                 pieces.push( this );
15365                 if ( pieces.length === rows * cells ) {
15366                         animComplete();
15367                 }
15368         }
15370         // clone the element for each row and cell.
15371         for ( i = 0; i < rows ; i++ ) { // ===>
15372                 top = offset.top + i * height;
15373                 my = i - ( rows - 1 ) / 2 ;
15375                 for ( j = 0; j < cells ; j++ ) { // |||
15376                         left = offset.left + j * width;
15377                         mx = j - ( cells - 1 ) / 2 ;
15379                         // Create a clone of the now hidden main element that will be absolute positioned
15380                         // within a wrapper div off the -left and -top equal to size of our pieces
15381                         el
15382                                 .clone()
15383                                 .appendTo( "body" )
15384                                 .wrap( "<div></div>" )
15385                                 .css({
15386                                         position: "absolute",
15387                                         visibility: "visible",
15388                                         left: -j * width,
15389                                         top: -i * height
15390                                 })
15392                         // select the wrapper - make it overflow: hidden and absolute positioned based on
15393                         // where the original was located +left and +top equal to the size of pieces
15394                                 .parent()
15395                                 .addClass( "ui-effects-explode" )
15396                                 .css({
15397                                         position: "absolute",
15398                                         overflow: "hidden",
15399                                         width: width,
15400                                         height: height,
15401                                         left: left + ( show ? mx * width : 0 ),
15402                                         top: top + ( show ? my * height : 0 ),
15403                                         opacity: show ? 0 : 1
15404                                 }).animate({
15405                                         left: left + ( show ? 0 : mx * width ),
15406                                         top: top + ( show ? 0 : my * height ),
15407                                         opacity: show ? 1 : 0
15408                                 }, o.duration || 500, o.easing, childComplete );
15409                 }
15410         }
15412         function animComplete() {
15413                 el.css({
15414                         visibility: "visible"
15415                 });
15416                 $( pieces ).remove();
15417                 if ( !show ) {
15418                         el.hide();
15419                 }
15420                 done();
15421         }
15426  * jQuery UI Effects Fade 1.11.0
15427  * http://jqueryui.com
15429  * Copyright 2014 jQuery Foundation and other contributors
15430  * Released under the MIT license.
15431  * http://jquery.org/license
15433  * http://api.jqueryui.com/fade-effect/
15434  */
15437 var effectFade = $.effects.effect.fade = function( o, done ) {
15438         var el = $( this ),
15439                 mode = $.effects.setMode( el, o.mode || "toggle" );
15441         el.animate({
15442                 opacity: mode
15443         }, {
15444                 queue: false,
15445                 duration: o.duration,
15446                 easing: o.easing,
15447                 complete: done
15448         });
15453  * jQuery UI Effects Fold 1.11.0
15454  * http://jqueryui.com
15456  * Copyright 2014 jQuery Foundation and other contributors
15457  * Released under the MIT license.
15458  * http://jquery.org/license
15460  * http://api.jqueryui.com/fold-effect/
15461  */
15464 var effectFold = $.effects.effect.fold = function( o, done ) {
15466         // Create element
15467         var el = $( this ),
15468                 props = [ "position", "top", "bottom", "left", "right", "height", "width" ],
15469                 mode = $.effects.setMode( el, o.mode || "hide" ),
15470                 show = mode === "show",
15471                 hide = mode === "hide",
15472                 size = o.size || 15,
15473                 percent = /([0-9]+)%/.exec( size ),
15474                 horizFirst = !!o.horizFirst,
15475                 widthFirst = show !== horizFirst,
15476                 ref = widthFirst ? [ "width", "height" ] : [ "height", "width" ],
15477                 duration = o.duration / 2,
15478                 wrapper, distance,
15479                 animation1 = {},
15480                 animation2 = {};
15482         $.effects.save( el, props );
15483         el.show();
15485         // Create Wrapper
15486         wrapper = $.effects.createWrapper( el ).css({
15487                 overflow: "hidden"
15488         });
15489         distance = widthFirst ?
15490                 [ wrapper.width(), wrapper.height() ] :
15491                 [ wrapper.height(), wrapper.width() ];
15493         if ( percent ) {
15494                 size = parseInt( percent[ 1 ], 10 ) / 100 * distance[ hide ? 0 : 1 ];
15495         }
15496         if ( show ) {
15497                 wrapper.css( horizFirst ? {
15498                         height: 0,
15499                         width: size
15500                 } : {
15501                         height: size,
15502                         width: 0
15503                 });
15504         }
15506         // Animation
15507         animation1[ ref[ 0 ] ] = show ? distance[ 0 ] : size;
15508         animation2[ ref[ 1 ] ] = show ? distance[ 1 ] : 0;
15510         // Animate
15511         wrapper
15512                 .animate( animation1, duration, o.easing )
15513                 .animate( animation2, duration, o.easing, function() {
15514                         if ( hide ) {
15515                                 el.hide();
15516                         }
15517                         $.effects.restore( el, props );
15518                         $.effects.removeWrapper( el );
15519                         done();
15520                 });
15526  * jQuery UI Effects Highlight 1.11.0
15527  * http://jqueryui.com
15529  * Copyright 2014 jQuery Foundation and other contributors
15530  * Released under the MIT license.
15531  * http://jquery.org/license
15533  * http://api.jqueryui.com/highlight-effect/
15534  */
15537 var effectHighlight = $.effects.effect.highlight = function( o, done ) {
15538         var elem = $( this ),
15539                 props = [ "backgroundImage", "backgroundColor", "opacity" ],
15540                 mode = $.effects.setMode( elem, o.mode || "show" ),
15541                 animation = {
15542                         backgroundColor: elem.css( "backgroundColor" )
15543                 };
15545         if (mode === "hide") {
15546                 animation.opacity = 0;
15547         }
15549         $.effects.save( elem, props );
15551         elem
15552                 .show()
15553                 .css({
15554                         backgroundImage: "none",
15555                         backgroundColor: o.color || "#ffff99"
15556                 })
15557                 .animate( animation, {
15558                         queue: false,
15559                         duration: o.duration,
15560                         easing: o.easing,
15561                         complete: function() {
15562                                 if ( mode === "hide" ) {
15563                                         elem.hide();
15564                                 }
15565                                 $.effects.restore( elem, props );
15566                                 done();
15567                         }
15568                 });
15573  * jQuery UI Effects Size 1.11.0
15574  * http://jqueryui.com
15576  * Copyright 2014 jQuery Foundation and other contributors
15577  * Released under the MIT license.
15578  * http://jquery.org/license
15580  * http://api.jqueryui.com/size-effect/
15581  */
15584 var effectSize = $.effects.effect.size = function( o, done ) {
15586         // Create element
15587         var original, baseline, factor,
15588                 el = $( this ),
15589                 props0 = [ "position", "top", "bottom", "left", "right", "width", "height", "overflow", "opacity" ],
15591                 // Always restore
15592                 props1 = [ "position", "top", "bottom", "left", "right", "overflow", "opacity" ],
15594                 // Copy for children
15595                 props2 = [ "width", "height", "overflow" ],
15596                 cProps = [ "fontSize" ],
15597                 vProps = [ "borderTopWidth", "borderBottomWidth", "paddingTop", "paddingBottom" ],
15598                 hProps = [ "borderLeftWidth", "borderRightWidth", "paddingLeft", "paddingRight" ],
15600                 // Set options
15601                 mode = $.effects.setMode( el, o.mode || "effect" ),
15602                 restore = o.restore || mode !== "effect",
15603                 scale = o.scale || "both",
15604                 origin = o.origin || [ "middle", "center" ],
15605                 position = el.css( "position" ),
15606                 props = restore ? props0 : props1,
15607                 zero = {
15608                         height: 0,
15609                         width: 0,
15610                         outerHeight: 0,
15611                         outerWidth: 0
15612                 };
15614         if ( mode === "show" ) {
15615                 el.show();
15616         }
15617         original = {
15618                 height: el.height(),
15619                 width: el.width(),
15620                 outerHeight: el.outerHeight(),
15621                 outerWidth: el.outerWidth()
15622         };
15624         if ( o.mode === "toggle" && mode === "show" ) {
15625                 el.from = o.to || zero;
15626                 el.to = o.from || original;
15627         } else {
15628                 el.from = o.from || ( mode === "show" ? zero : original );
15629                 el.to = o.to || ( mode === "hide" ? zero : original );
15630         }
15632         // Set scaling factor
15633         factor = {
15634                 from: {
15635                         y: el.from.height / original.height,
15636                         x: el.from.width / original.width
15637                 },
15638                 to: {
15639                         y: el.to.height / original.height,
15640                         x: el.to.width / original.width
15641                 }
15642         };
15644         // Scale the css box
15645         if ( scale === "box" || scale === "both" ) {
15647                 // Vertical props scaling
15648                 if ( factor.from.y !== factor.to.y ) {
15649                         props = props.concat( vProps );
15650                         el.from = $.effects.setTransition( el, vProps, factor.from.y, el.from );
15651                         el.to = $.effects.setTransition( el, vProps, factor.to.y, el.to );
15652                 }
15654                 // Horizontal props scaling
15655                 if ( factor.from.x !== factor.to.x ) {
15656                         props = props.concat( hProps );
15657                         el.from = $.effects.setTransition( el, hProps, factor.from.x, el.from );
15658                         el.to = $.effects.setTransition( el, hProps, factor.to.x, el.to );
15659                 }
15660         }
15662         // Scale the content
15663         if ( scale === "content" || scale === "both" ) {
15665                 // Vertical props scaling
15666                 if ( factor.from.y !== factor.to.y ) {
15667                         props = props.concat( cProps ).concat( props2 );
15668                         el.from = $.effects.setTransition( el, cProps, factor.from.y, el.from );
15669                         el.to = $.effects.setTransition( el, cProps, factor.to.y, el.to );
15670                 }
15671         }
15673         $.effects.save( el, props );
15674         el.show();
15675         $.effects.createWrapper( el );
15676         el.css( "overflow", "hidden" ).css( el.from );
15678         // Adjust
15679         if (origin) { // Calculate baseline shifts
15680                 baseline = $.effects.getBaseline( origin, original );
15681                 el.from.top = ( original.outerHeight - el.outerHeight() ) * baseline.y;
15682                 el.from.left = ( original.outerWidth - el.outerWidth() ) * baseline.x;
15683                 el.to.top = ( original.outerHeight - el.to.outerHeight ) * baseline.y;
15684                 el.to.left = ( original.outerWidth - el.to.outerWidth ) * baseline.x;
15685         }
15686         el.css( el.from ); // set top & left
15688         // Animate
15689         if ( scale === "content" || scale === "both" ) { // Scale the children
15691                 // Add margins/font-size
15692                 vProps = vProps.concat([ "marginTop", "marginBottom" ]).concat(cProps);
15693                 hProps = hProps.concat([ "marginLeft", "marginRight" ]);
15694                 props2 = props0.concat(vProps).concat(hProps);
15696                 el.find( "*[width]" ).each( function() {
15697                         var child = $( this ),
15698                                 c_original = {
15699                                         height: child.height(),
15700                                         width: child.width(),
15701                                         outerHeight: child.outerHeight(),
15702                                         outerWidth: child.outerWidth()
15703                                 };
15704                         if (restore) {
15705                                 $.effects.save(child, props2);
15706                         }
15708                         child.from = {
15709                                 height: c_original.height * factor.from.y,
15710                                 width: c_original.width * factor.from.x,
15711                                 outerHeight: c_original.outerHeight * factor.from.y,
15712                                 outerWidth: c_original.outerWidth * factor.from.x
15713                         };
15714                         child.to = {
15715                                 height: c_original.height * factor.to.y,
15716                                 width: c_original.width * factor.to.x,
15717                                 outerHeight: c_original.height * factor.to.y,
15718                                 outerWidth: c_original.width * factor.to.x
15719                         };
15721                         // Vertical props scaling
15722                         if ( factor.from.y !== factor.to.y ) {
15723                                 child.from = $.effects.setTransition( child, vProps, factor.from.y, child.from );
15724                                 child.to = $.effects.setTransition( child, vProps, factor.to.y, child.to );
15725                         }
15727                         // Horizontal props scaling
15728                         if ( factor.from.x !== factor.to.x ) {
15729                                 child.from = $.effects.setTransition( child, hProps, factor.from.x, child.from );
15730                                 child.to = $.effects.setTransition( child, hProps, factor.to.x, child.to );
15731                         }
15733                         // Animate children
15734                         child.css( child.from );
15735                         child.animate( child.to, o.duration, o.easing, function() {
15737                                 // Restore children
15738                                 if ( restore ) {
15739                                         $.effects.restore( child, props2 );
15740                                 }
15741                         });
15742                 });
15743         }
15745         // Animate
15746         el.animate( el.to, {
15747                 queue: false,
15748                 duration: o.duration,
15749                 easing: o.easing,
15750                 complete: function() {
15751                         if ( el.to.opacity === 0 ) {
15752                                 el.css( "opacity", el.from.opacity );
15753                         }
15754                         if ( mode === "hide" ) {
15755                                 el.hide();
15756                         }
15757                         $.effects.restore( el, props );
15758                         if ( !restore ) {
15760                                 // we need to calculate our new positioning based on the scaling
15761                                 if ( position === "static" ) {
15762                                         el.css({
15763                                                 position: "relative",
15764                                                 top: el.to.top,
15765                                                 left: el.to.left
15766                                         });
15767                                 } else {
15768                                         $.each([ "top", "left" ], function( idx, pos ) {
15769                                                 el.css( pos, function( _, str ) {
15770                                                         var val = parseInt( str, 10 ),
15771                                                                 toRef = idx ? el.to.left : el.to.top;
15773                                                         // if original was "auto", recalculate the new value from wrapper
15774                                                         if ( str === "auto" ) {
15775                                                                 return toRef + "px";
15776                                                         }
15778                                                         return val + toRef + "px";
15779                                                 });
15780                                         });
15781                                 }
15782                         }
15784                         $.effects.removeWrapper( el );
15785                         done();
15786                 }
15787         });
15793  * jQuery UI Effects Scale 1.11.0
15794  * http://jqueryui.com
15796  * Copyright 2014 jQuery Foundation and other contributors
15797  * Released under the MIT license.
15798  * http://jquery.org/license
15800  * http://api.jqueryui.com/scale-effect/
15801  */
15804 var effectScale = $.effects.effect.scale = function( o, done ) {
15806         // Create element
15807         var el = $( this ),
15808                 options = $.extend( true, {}, o ),
15809                 mode = $.effects.setMode( el, o.mode || "effect" ),
15810                 percent = parseInt( o.percent, 10 ) ||
15811                         ( parseInt( o.percent, 10 ) === 0 ? 0 : ( mode === "hide" ? 0 : 100 ) ),
15812                 direction = o.direction || "both",
15813                 origin = o.origin,
15814                 original = {
15815                         height: el.height(),
15816                         width: el.width(),
15817                         outerHeight: el.outerHeight(),
15818                         outerWidth: el.outerWidth()
15819                 },
15820                 factor = {
15821                         y: direction !== "horizontal" ? (percent / 100) : 1,
15822                         x: direction !== "vertical" ? (percent / 100) : 1
15823                 };
15825         // We are going to pass this effect to the size effect:
15826         options.effect = "size";
15827         options.queue = false;
15828         options.complete = done;
15830         // Set default origin and restore for show/hide
15831         if ( mode !== "effect" ) {
15832                 options.origin = origin || [ "middle", "center" ];
15833                 options.restore = true;
15834         }
15836         options.from = o.from || ( mode === "show" ? {
15837                 height: 0,
15838                 width: 0,
15839                 outerHeight: 0,
15840                 outerWidth: 0
15841         } : original );
15842         options.to = {
15843                 height: original.height * factor.y,
15844                 width: original.width * factor.x,
15845                 outerHeight: original.outerHeight * factor.y,
15846                 outerWidth: original.outerWidth * factor.x
15847         };
15849         // Fade option to support puff
15850         if ( options.fade ) {
15851                 if ( mode === "show" ) {
15852                         options.from.opacity = 0;
15853                         options.to.opacity = 1;
15854                 }
15855                 if ( mode === "hide" ) {
15856                         options.from.opacity = 1;
15857                         options.to.opacity = 0;
15858                 }
15859         }
15861         // Animate
15862         el.effect( options );
15868  * jQuery UI Effects Puff 1.11.0
15869  * http://jqueryui.com
15871  * Copyright 2014 jQuery Foundation and other contributors
15872  * Released under the MIT license.
15873  * http://jquery.org/license
15875  * http://api.jqueryui.com/puff-effect/
15876  */
15879 var effectPuff = $.effects.effect.puff = function( o, done ) {
15880         var elem = $( this ),
15881                 mode = $.effects.setMode( elem, o.mode || "hide" ),
15882                 hide = mode === "hide",
15883                 percent = parseInt( o.percent, 10 ) || 150,
15884                 factor = percent / 100,
15885                 original = {
15886                         height: elem.height(),
15887                         width: elem.width(),
15888                         outerHeight: elem.outerHeight(),
15889                         outerWidth: elem.outerWidth()
15890                 };
15892         $.extend( o, {
15893                 effect: "scale",
15894                 queue: false,
15895                 fade: true,
15896                 mode: mode,
15897                 complete: done,
15898                 percent: hide ? percent : 100,
15899                 from: hide ?
15900                         original :
15901                         {
15902                                 height: original.height * factor,
15903                                 width: original.width * factor,
15904                                 outerHeight: original.outerHeight * factor,
15905                                 outerWidth: original.outerWidth * factor
15906                         }
15907         });
15909         elem.effect( o );
15914  * jQuery UI Effects Pulsate 1.11.0
15915  * http://jqueryui.com
15917  * Copyright 2014 jQuery Foundation and other contributors
15918  * Released under the MIT license.
15919  * http://jquery.org/license
15921  * http://api.jqueryui.com/pulsate-effect/
15922  */
15925 var effectPulsate = $.effects.effect.pulsate = function( o, done ) {
15926         var elem = $( this ),
15927                 mode = $.effects.setMode( elem, o.mode || "show" ),
15928                 show = mode === "show",
15929                 hide = mode === "hide",
15930                 showhide = ( show || mode === "hide" ),
15932                 // showing or hiding leaves of the "last" animation
15933                 anims = ( ( o.times || 5 ) * 2 ) + ( showhide ? 1 : 0 ),
15934                 duration = o.duration / anims,
15935                 animateTo = 0,
15936                 queue = elem.queue(),
15937                 queuelen = queue.length,
15938                 i;
15940         if ( show || !elem.is(":visible")) {
15941                 elem.css( "opacity", 0 ).show();
15942                 animateTo = 1;
15943         }
15945         // anims - 1 opacity "toggles"
15946         for ( i = 1; i < anims; i++ ) {
15947                 elem.animate({
15948                         opacity: animateTo
15949                 }, duration, o.easing );
15950                 animateTo = 1 - animateTo;
15951         }
15953         elem.animate({
15954                 opacity: animateTo
15955         }, duration, o.easing);
15957         elem.queue(function() {
15958                 if ( hide ) {
15959                         elem.hide();
15960                 }
15961                 done();
15962         });
15964         // We just queued up "anims" animations, we need to put them next in the queue
15965         if ( queuelen > 1 ) {
15966                 queue.splice.apply( queue,
15967                         [ 1, 0 ].concat( queue.splice( queuelen, anims + 1 ) ) );
15968         }
15969         elem.dequeue();
15974  * jQuery UI Effects Shake 1.11.0
15975  * http://jqueryui.com
15977  * Copyright 2014 jQuery Foundation and other contributors
15978  * Released under the MIT license.
15979  * http://jquery.org/license
15981  * http://api.jqueryui.com/shake-effect/
15982  */
15985 var effectShake = $.effects.effect.shake = function( o, done ) {
15987         var el = $( this ),
15988                 props = [ "position", "top", "bottom", "left", "right", "height", "width" ],
15989                 mode = $.effects.setMode( el, o.mode || "effect" ),
15990                 direction = o.direction || "left",
15991                 distance = o.distance || 20,
15992                 times = o.times || 3,
15993                 anims = times * 2 + 1,
15994                 speed = Math.round( o.duration / anims ),
15995                 ref = (direction === "up" || direction === "down") ? "top" : "left",
15996                 positiveMotion = (direction === "up" || direction === "left"),
15997                 animation = {},
15998                 animation1 = {},
15999                 animation2 = {},
16000                 i,
16002                 // we will need to re-assemble the queue to stack our animations in place
16003                 queue = el.queue(),
16004                 queuelen = queue.length;
16006         $.effects.save( el, props );
16007         el.show();
16008         $.effects.createWrapper( el );
16010         // Animation
16011         animation[ ref ] = ( positiveMotion ? "-=" : "+=" ) + distance;
16012         animation1[ ref ] = ( positiveMotion ? "+=" : "-=" ) + distance * 2;
16013         animation2[ ref ] = ( positiveMotion ? "-=" : "+=" ) + distance * 2;
16015         // Animate
16016         el.animate( animation, speed, o.easing );
16018         // Shakes
16019         for ( i = 1; i < times; i++ ) {
16020                 el.animate( animation1, speed, o.easing ).animate( animation2, speed, o.easing );
16021         }
16022         el
16023                 .animate( animation1, speed, o.easing )
16024                 .animate( animation, speed / 2, o.easing )
16025                 .queue(function() {
16026                         if ( mode === "hide" ) {
16027                                 el.hide();
16028                         }
16029                         $.effects.restore( el, props );
16030                         $.effects.removeWrapper( el );
16031                         done();
16032                 });
16034         // inject all the animations we just queued to be first in line (after "inprogress")
16035         if ( queuelen > 1) {
16036                 queue.splice.apply( queue,
16037                         [ 1, 0 ].concat( queue.splice( queuelen, anims + 1 ) ) );
16038         }
16039         el.dequeue();
16045  * jQuery UI Effects Slide 1.11.0
16046  * http://jqueryui.com
16048  * Copyright 2014 jQuery Foundation and other contributors
16049  * Released under the MIT license.
16050  * http://jquery.org/license
16052  * http://api.jqueryui.com/slide-effect/
16053  */
16056 var effectSlide = $.effects.effect.slide = function( o, done ) {
16058         // Create element
16059         var el = $( this ),
16060                 props = [ "position", "top", "bottom", "left", "right", "width", "height" ],
16061                 mode = $.effects.setMode( el, o.mode || "show" ),
16062                 show = mode === "show",
16063                 direction = o.direction || "left",
16064                 ref = (direction === "up" || direction === "down") ? "top" : "left",
16065                 positiveMotion = (direction === "up" || direction === "left"),
16066                 distance,
16067                 animation = {};
16069         // Adjust
16070         $.effects.save( el, props );
16071         el.show();
16072         distance = o.distance || el[ ref === "top" ? "outerHeight" : "outerWidth" ]( true );
16074         $.effects.createWrapper( el ).css({
16075                 overflow: "hidden"
16076         });
16078         if ( show ) {
16079                 el.css( ref, positiveMotion ? (isNaN(distance) ? "-" + distance : -distance) : distance );
16080         }
16082         // Animation
16083         animation[ ref ] = ( show ?
16084                 ( positiveMotion ? "+=" : "-=") :
16085                 ( positiveMotion ? "-=" : "+=")) +
16086                 distance;
16088         // Animate
16089         el.animate( animation, {
16090                 queue: false,
16091                 duration: o.duration,
16092                 easing: o.easing,
16093                 complete: function() {
16094                         if ( mode === "hide" ) {
16095                                 el.hide();
16096                         }
16097                         $.effects.restore( el, props );
16098                         $.effects.removeWrapper( el );
16099                         done();
16100                 }
16101         });
16106  * jQuery UI Effects Transfer 1.11.0
16107  * http://jqueryui.com
16109  * Copyright 2014 jQuery Foundation and other contributors
16110  * Released under the MIT license.
16111  * http://jquery.org/license
16113  * http://api.jqueryui.com/transfer-effect/
16114  */
16117 var effectTransfer = $.effects.effect.transfer = function( o, done ) {
16118         var elem = $( this ),
16119                 target = $( o.to ),
16120                 targetFixed = target.css( "position" ) === "fixed",
16121                 body = $("body"),
16122                 fixTop = targetFixed ? body.scrollTop() : 0,
16123                 fixLeft = targetFixed ? body.scrollLeft() : 0,
16124                 endPosition = target.offset(),
16125                 animation = {
16126                         top: endPosition.top - fixTop,
16127                         left: endPosition.left - fixLeft,
16128                         height: target.innerHeight(),
16129                         width: target.innerWidth()
16130                 },
16131                 startPosition = elem.offset(),
16132                 transfer = $( "<div class='ui-effects-transfer'></div>" )
16133                         .appendTo( document.body )
16134                         .addClass( o.className )
16135                         .css({
16136                                 top: startPosition.top - fixTop,
16137                                 left: startPosition.left - fixLeft,
16138                                 height: elem.innerHeight(),
16139                                 width: elem.innerWidth(),
16140                                 position: targetFixed ? "fixed" : "absolute"
16141                         })
16142                         .animate( animation, o.duration, o.easing, function() {
16143                                 transfer.remove();
16144                                 done();
16145                         });
16150 }));